Merchant Wallets
Overview
The Merchant Wallet Public API provides a comprehensive set of endpoints for managing merchant wallets, including wallet creation, balance inquiries, transactions, and transfers. This API enables merchants to programmatically manage their wallet operations within the Interswitch ecosystem.
Base URL: https://merchant-wallet.k8.isw.la/merchant-wallet
API Version: v1
Authentication
All API requests require Bearer token authentication. Include the token in the Authorization header:
Authorization: Bearer {your_access_token}
The Bearer token should be obtained through the Interswitch OAuth2 authentication flow and will contain merchant-specific claims.
You can view how to generate an access token here Authentication
Endpoints
Create Wallet
Creates a new merchant wallet for transaction management.
Endpoint: POST /api/v1/wallet
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Request Body:
{
"name": "string",
"merchantCode": "string",
"status": "ACTIVE",
"mobileNo": "string",
"provider": "PRIME",
"firstName": "string",
"pin": "string",
"email": "string"
}Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Wallet name/identifier |
| merchantCode | string | Yes | Merchant code (e.g., "MX6072") |
| status | string | Yes | Wallet status (typically "ACTIVE") |
| mobileNo | string | Yes | Mobile number associated with wallet |
| provider | string | Yes | Wallet provider (e.g., "PRIME") |
| firstName | string | Yes | Wallet owner's first name |
| pin | string | Yes | 4-digit PIN for wallet authentication |
| string | Yes | Account Holder's email |
Success Response:
{
"id": 2678,
"provider": "PRIME",
"currencyCode": "566",
"walletId": "2700007687",
"merchantCode": "MX6072",
"status": "ACTIVE",
"walletCreationStatus": "COMPLETED",
"virtualAccount": {
"id": 2368,
"walletId": 2678,
"merchantCode": "MX6072",
"accountPayableCode": "27000076871770121171442",
"accountName": "pavejidd44ddee",
"accountNumber": "7620588514",
"bankName": "Wema Bank",
"bankCode": "WEMA",
"currencyCode": "566"
}
}Get Merchant Wallet
Retrieves wallet information for a specific merchant.
Endpoint: GET /api/v1/wallet/details/{merchantCode}?walletId={walletId}
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantCode | string | Yes | Merchant code (e.g., "MX16174") |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| walletId | string | Yes | Wallet identifier (e.g., "3570000409") |
Success Response:
{
"id": 2678,
"provider": "PRIME",
"currencyCode": "566",
"walletId": "2700007687",
"merchantCode": "MX6072",
"mobileNo": "07065871087",
"status": "ACTIVE",
"walletCreationStatus": "COMPLETED",
"settlementAccountNumber": "2700007687",
"createdOn": "2026-02-03T13:16:02.143+00:00"
}Get Wallet Balance
Retrieves the current balance for a specific wallet.
Endpoint: GET api/v1/wallet/balance/{merchantCode}?walletId={walletId}
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantCode | string | Yes | Merchant code |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| walletId | string | Yes | Wallet identifier (e.g., "3570000409") |
Example Request:
GET /api/v1/wallet/balance/MX6072?walletId=2700007687
Success Response:
{
"statusCode": "200",
"responseCode": "00",
"responseMessage": "Balance retrieved successfully!",
"count": 0,
"availableBalance": 0,
"ledgerBalance": 0,
"successful": true
} Transact (Debit Wallet)
Debits a merchant wallet for a transaction.
Endpoint: POST /api/v1/transaction/transact
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Request Body:
{
"walletId": "string",
"amount": "string",
"pin": "string",
"reference": "string",
"transactionCode": "string",
"narration": "string"
}Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| walletId | string | Yes | Wallet identifier |
| amount | string | Yes | Transaction amount (e.g., "100") |
| pin | string | Yes | 4-digit wallet PIN |
| reference | string | Yes | Unique transaction reference |
| transactionCode | string | Yes | Transaction code (e.g., "api-charge") |
| narration | string | Yes | Transaction description |
Success Response:
{
"statusCode": "200",
"responseCode": "00",
"responseMessage": "SUCCESSFUL",
"transactionCode": "api-charge",
"reference": "bdgeyweiektj",
"data": {
"amount": 100,
"walletId": "3570011881",
"transactionCode": "api-charge",
"narration": "prevvv everyyyyyyyeveryyyyyyydemoo",
"reference": "bdgeyweiektj",
"multiple": false
}
} Reverse Transaction
Reverses a previously completed transaction.
Endpoint: POST /api/v1/transaction/reverse
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Request Body:
{
"walletId": "string",
"reference": "string",
"reversalReference": "string"
}Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| walletId | string | Yes | Wallet identifier |
| reference | string | Yes | Original transaction reference |
| reversalReference | string | Yes | Unique reference for the reversal |
Success Response:
{
"statusCode": "200",
"responseCode": "00",
"responseMessage": "SUCCESSFUL",
"data": {
"reversalReference": "string",
"originalReference": "string",
"status": "REVERSED"
}
}Success Response:
{
"statusCode": "200",
"responseCode": "00",
"responseMessage": "SUCCESSFUL",
"data": {
"transactionReference": "string",
"status": "PROCESSING",
"details": []
}
} Get Transaction by Reference
Retrieves a specific transaction by its reference number.
Endpoint: GET /api/v1/transaction/
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantCode | string | Yes | Merchant code |
| reference | string | Yes | Transaction reference |
Example Request:
GET /api/v1/transaction/?merchantCode=MX16174&reference=edeydomewawawaw
Success Response:
[
{
"id": 2,
"merchantCode": "MX6072",
"merchantWalletId": 6,
"narration": "Settlement for wallet",
"transactionCode": "wallet-settlement",
"transactionDirection": "CREDIT",
"amount": 5000,
"fee": 0,
"responseCode": "00",
"responseDescription": "Successful",
"requestDate": "2023-09-11T10:36:28.973+00:00",
"paymentReference": "MX6072QMO8FZBN1VRVJ5T",
"reference": "MX6072QMO8FZBN1VRVJ5T",
"reversed": false,
"currencyCode": "566"
}
]Response Codes
The API uses standard response codes to indicate the status of requests:
| Response Code | Description |
|---|---|
| 00 | Successful transaction |
| 91 | Issuer or switch inoperative |
Error Handling
All API responses follow a standard error format
Common Error Scenarios:
-
Authentication Failure (401)
- Invalid or expired Bearer token
- Missing Authorization header
-
Validation Error (400)
- Missing required fields
- Invalid data format
- Invalid PIN
-
Not Found (404)
- Wallet not found
- Transaction reference not found
-
Insufficient Funds (400)
- responseCode: "51"
- Wallet balance insufficient for transaction
-
System Error (500)
- Internal server error
- Service temporarily unavailable
Best Practices
Security
-
Token Management
- Store Bearer tokens securely
- Implement token refresh mechanism
- Never expose tokens in client-side code
-
PIN Handling
- Never log or store PINs in plain text
- Use HTTPS for all API communications
- Implement PIN retry limits
-
Reference Generation
- Generate unique references for each transaction
- Use timestamp + random string for uniqueness
- Store references for reconciliation
Transaction Management
-
Idempotency
- Use unique references to prevent duplicate transactions
- Implement transaction status checking
- Handle timeout scenarios gracefully
-
Balance Verification
- Check wallet balance before initiating transactions
- Handle insufficient fund scenarios
-
Transaction Monitoring
- Use re-query endpoint to verify transaction status
- Implement webhook handlers for transaction notifications
- Reconcile transactions regularly
Error Recovery
-
Retry Logic
- Implement exponential backoff for retries
- Don't retry transactions that have completed
- Log all retry attempts
-
Status Verification
- Always verify transaction status before retry
- Use the re-query endpoint for status checks
- Implement timeout handling
Testing
Test Environment
- Base URL: (Contact support for test environment URL)
- Test Merchant Code: (Provided upon registration)
- Test Wallet IDs: (Provided upon registration)
Test Cards/Wallets
Test wallets are provided with pre-loaded balances for testing various scenarios including successful transactions, insufficient funds, and error conditions.
Pay with Merchant Wallet
This API allows for debiting merchant wallets through the WalletPay service when `provider = "MWALLET". You can use the API to debit wallets you've created and have been funded and recognise the money as revenue.
Base Information
- Base URL:
https://{host}/collectionsuat- qa.interswitchng.com, prod - api.interswitchng.com - Authentication: OAuth2 Bearer token (same token used across other APIs). When
merchantCode/payableCodeare omitted, WalletPay derives them from the token, but supplying them explicitly is recommended for automation. - Content-Type:
application/json - Provider flag: Always send
"provider": "MWALLET"to ensure the request is routed to the merchant-wallet adapter.
Split Settlement
You can decide to settle multiple settlement accounts in whatever sturcture you want with each wallet debit. You can view the guide on creating split accounts here Split Payments
POST /api/v2/wallet-pay/initialize
/api/v2/wallet-pay/initializeInitiates a debit from an existing merchant wallet and credits the configured settlement account(s).
Request Schema
| Field | Type | Required | Notes |
|---|---|---|---|
merchantCode | string | Yes (unless derived from token) | Merchant identifier registered on Collections |
payableCode | string | Yes (unless derived from token) | Payable to which settlement will be recorded |
transactionReference | string | Yes | Must be unique per merchant; duplicates are rejected |
amount | number | Required if paymentId absent | Amount in minor units (e.g. 5000 = ₦50.00) |
walletId | string | Yes | Merchant wallet identifier to debit |
pin | string | Yes | Wallet PIN for authentication |
currencyCode | string | Optional (default 566) | ISO numeric currency |
splitSettlementInformation | array | Optional | List of split instructions; each entry mirrors SplitSettlementInstruction (alias, amount, isPrimary, optional banking metadata) |
Sample – Direct Debit
{
"amount": 5000,
"provider": "MWALLET",
"walletId": "2700000145",
"pin": "1234",
"transactionReference": "abcde12834xfm75dy6729g3"
}Sample – Debit With Split Settlement
{
"amount": 5000,
"provider": "MWALLET",
"walletId": "2700000145",
"pin": "1234",
"transactionReference": "a22y672909886g8fr3",
"splitSettlementInformation": [
{ "alias": "MERCHANT ACCOUNT", "amount": "500", "isPrimary": false },
{ "alias": "GTB Account", "amount": "4500", "isPrimary": true }
]
}Successful Response
{
"responseCode": "00",
"transactionReference": "abcde12834xfm75dy6729g3",
"authenticationType": "PUSH"
}responseCode–00indicates a completed debit; other proprietary codes may surface depending on the provider response.authenticationType– MWALLET returnsPUSH, signalling no OTP redirection is required.
Error Responses
| HTTP Status | Response Body | Description |
|---|---|---|
400 | {"code":"10400","description":"Bad request","errors":[...]} | Validation failure (missing fields, malformed splits). |
401 | {"code":"INVALID_CREDENTIAL","description":"Invalid pin!"} | Wallet PIN or credential failure surfaced from MWALLET. |
409 | {"code":"10409","description":"A transaction with the same reference already exists"} | Duplicate transaction reference for the merchant. |
422/500+ | {"code":"01","description":"Merchant wallet transaction failed"} | Upstream errors; HTTP status mirrors MWALLET response when available. |
POST /api/v2/wallet-pay/status
/api/v2/wallet-pay/statusRetrieves the state of a previously initialized wallet transaction.
Request Schema
{
"reference": "abcde12834xfm75dy6729g3",
"merchantCode": "MX6072"
}referenceis mandatory.merchantCodeis optional when inferable from the OAuth token.
Possible Responses
| Scenario | Sample |
|---|---|
| Processing | {"responseCode":"09","transactionReference":"abc...","displayMessage":"Transaction is processing","authenticationType":"PUSH"} |
| Successful | Same as initialize success (responseCode = "00"). |
| Failed | HTTP status and body mirror upstream MWALLET decision (e.g., insufficient funds). |
Behaviour Notes
- At least one split instruction must have
isPrimary = truewhensplitSettlementInformationis supplied. Amounts should sum to the requestamount. - When
paymentIdis provided, the service ignoresamountand uses the persisted payment record. - All remote exceptions from MWALLET now bubble up with their original HTTP status and
responseMessage, providing deterministic error handling for merchants and automation suites.
Updated 17 days ago