Multiple NGN Wallets
SaySwitch supports multiple NGN wallets for merchants who have been enabled for this feature. The default NGN wallet continues to work exactly as before. Merchants can create additional custom NGN wallets, receive payments into a specific wallet, initiate payouts from a selected wallet, and move funds between SaySwitch wallets.
How It Works
- Multiple NGN wallet support is only available for
NGN. - Merchants must be enabled for multiple NGN wallets before using custom wallet APIs.
- The default wallet remains the merchant’s main wallet.
- Existing default-wallet APIs continue to use the default wallet.
- Normal/default S2S endpoints do not accept
wallet_code. - Wallet-specific S2S endpoints require
wallet_code.
Wallet Types
| Type | Description |
|---|---|
| Default wallet | Automatically created during onboarding or activation. Existing integrations use this wallet. |
| Custom wallet | Manually created by the merchant. It has its own wallet_code and dedicated virtual account where applicable. |
wallet_code | Unique wallet identifier used for wallet-specific API operations. |
Create NGN Wallet
Create a custom NGN wallet for a merchant enabled for multiple NGN wallets.
Endpoint
POST /api/s2s/v1/wallet/create-ngnHeaders
Authorization: Bearer sk_live_xxxxx
Content-Type: application/jsonRequest Body
{
"title": "Operations Wallet"
}Sample Response
{
"success": true,
"message": "Wallet created successfully",
"data": {
"wallet": {
"id": 123,
"title": "Operations Wallet",
"wallet_code": "NGN169XXXX",
"currency": "NGN",
"is_default": 0,
"is_custom": 1,
"domain": "live",
"status": 1
},
"virtual_account": {
"account_number": "1234567890",
"bank_name": "Wema Bank"
}
}
}Notes
- Custom NGN wallet creation is only available to merchants enabled for multiple NGN wallets.
- Custom wallet creation should be used in live mode.
- Store the returned
wallet_codefor wallet-specific payments, payouts, and wallet transfers.
Wallet-To-Wallet Transfer
Move funds from one SaySwitch NGN wallet to another.
Endpoint
POST /api/s2s/v1/wallet/transferRequest Body
{
"source_wallet_code": "NGN169SOURCE",
"destination_wallet_code": "NGN200DEST",
"amount": 5000,
"reference": "WTW_1234567890123456",
"narration": "Move funds"
}Sample Response
{
"success": true,
"message": "Wallet transfer successful",
"data": {
"reference": "WTW_1234567890123456",
"amount": 5000,
"fee": 0,
"currency": "NGN",
"status": "success",
"wallet_id": 123,
"wallet_code": "NGN169SOURCE",
"account_number": "NGN200DEST",
"bank_name": "SaySwitch Wallet"
}
}Rules
source_wallet_codemust belong to the authenticated merchant.destination_wallet_codecan belong to any merchant on SaySwitch.- Source and destination wallets must both be
NGN. - Source and destination wallets must be on the same domain.
- Test wallets cannot transfer to live wallets, and live wallets cannot transfer to test wallets.
- Source wallet must have sufficient balance.
- Wallet-to-wallet transfer fee is
0. - A webhook is sent using the existing payout/transfer webhook flow.
Wallet-Specific S2S Collections
| Action | Endpoint |
|---|---|
| Create NGN wallet | POST /api/s2s/v1/wallet/create-ngn |
| Initialize S2S card payment with wallet | POST /api/s2s/v1/transaction/initialize/wallet |
| Initialize S2S OPay payment with wallet | POST /api/s2s/v1/transaction/opay/initialize/wallet |
| Initialize S2S bank transfer with wallet | POST /api/s2s/v1/banktransfer/initialize/wallet |
| Initialize S2S USSD payment with wallet | POST /api/s2s/v1/ussd/initialize/wallet |
| Wallet-to-wallet transfer | POST /api/s2s/v1/wallet/transfer |
| Initiate payout from wallet | POST /api/v1/bank_transfer/wallet |
| Get specific wallet balance | GET /api/v1/wallet_balance/NGN/{wallet_code} |
Only NGN multiple-wallet balance is supported for now.
Common Errors
Wallet Not Found
{
"success": false,
"message": "Wallet not found"
}Multiple Wallet Not Enabled
{
"status": false,
"message": "Multiple NGN wallets is not enabled for this business"
}Missing wallet_code
{
"status": false,
"message": "wallet_code is required for this endpoint"
}wallet_code Sent To Default Endpoint
{
"status": false,
"message": "wallet_code is only allowed on the wallet-specific endpoint"
}Insufficient Wallet Balance
{
"success": false,
"message": "Insufficient wallet balance"
}