Skip to main content

Overview

Send money to any Nigerian bank account in seconds using FossaPay’s Payouts API. This guide covers single payouts, bulk disbursements, and handling payout failures.

Prerequisites

  • Sufficient balance in your FossaPay wallet or bank account
  • Verified business account
  • Live API keys (test keys for sandbox)

Single Payout

Basic Transfer

curl -X POST https://api-staging.fossapay.com/api/v1/transfers/fiat/inter-bank \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cus_123",
    "destinationBankCode": "058",
    "destinationAccountName": "Jane Smith",
    "destinationAccountNumber": "0123456789",
    "destinationBankName": "GTBank",
    "reference": "transfer-1705315200000",
    "remarks": "Salary payment - January 2024",
    "amount": 25000
  }'
Response:
{
  "status": true,
  "statusCode": 200,
  "message": "Transfer request is being processed",
  "data": {
    "reference": "transfer-1705315200000"
  }
}

Validate Account First

curl -X POST https://api-staging.fossapay.com/api/v1/transfers/fiat/bank-name-enquiry \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountNumber": "0123456789",
    "bankCode": "058"
  }'
Response:
{
  "success": true,
  "message": "Account details retrieved successfully",
  "data": {
    "accountNumber": "0123456789",
    "accountName": "JANE SMITH",
    "bankCode": "058",
    "bankName": "GTBank"
  }
}
Proceed with transfer if name matches.

Multiple Transfers

For multiple transfers, make individual API calls or implement batch processing in your application.

Handling Webhooks

app.post('/webhooks/fossapay', async (req, res) => {
  res.status(200).send('OK');

  const { event, data } = req.body;

  switch (event) {
    case 'withdrawal.completed':
      await handleTransferCompleted(data);
      break;

    case 'withdrawal.failed':
      await handleTransferFailed(data);
      break;
  }
});

async function handleTransferCompleted(transfer) {
  // Update transaction status
  await db.transactions.update({
    reference: transfer.reference
  }, {
    status: 'completed',
    completed_at: transfer.completed_at
  });

  // Notify recipient
  await sendNotification(transfer.customerId, {
    title: 'Transfer Completed',
    message: `₦${transfer.amount.toLocaleString()} has been sent to your account`
  });
}

async function handleTransferFailed(transfer) {
  // Update status
  await db.transactions.update({
    reference: transfer.reference
  }, {
    status: 'failed',
    failure_reason: transfer.failure_reason
  });

  // Alert admin
  await sendAlert({
    type: 'transfer_failed',
    reference: transfer.reference,
    reason: transfer.failure_reason
  });
}

Checking Payout Status

const payout = await client.payouts.getStatus('pay_abc123');

console.log(payout);
// {
//   "payout_id": "pay_abc123",
//   "amount": 25000,
//   "status": "completed",
//   "account_number": "0123456789",
//   "bank_name": "GTBank",
//   "reference": "payout-1705315200000",
//   "completed_at": "2024-01-15T11:05:23Z"
// }

Bank Codes

Common Nigerian bank codes:
Bank CodeBank Name
044Access Bank
063Access Bank (Diamond)
050Ecobank Nigeria
070Fidelity Bank
011First Bank of Nigeria
214First City Monument Bank
058Guaranty Trust Bank
030Heritage Bank
301Jaiz Bank
082Keystone Bank
50211Kuda Bank
090175Rubies MFB
221Stanbic IBTC Bank
068Standard Chartered
232Sterling Bank
100Suntrust Bank
032Union Bank
033United Bank for Africa
215Unity Bank
035Wema Bank
057Zenith Bank
Get the full list of supported banks via the API: /v1/transfers/fiat/get-supported-banks

Error Handling

try {
  const payout = await client.payouts.create({
    amount: 25000,
    account_number: '0123456789',
    bank_code: '058'
  });
} catch (error) {
  if (error.code === 'INSUFFICIENT_BALANCE') {
    // Handle insufficient balance
    await notifyAdmin('Insufficient balance for payout');
  } else if (error.code === 'INVALID_ACCOUNT') {
    // Handle invalid account
    await notifyUser('Invalid account details');
  } else {
    // Handle other errors
    console.error('Payout failed:', error);
  }
}

Common Error Codes

CodeDescriptionSolution
INSUFFICIENT_BALANCENot enough fundsTop up your balance
INVALID_ACCOUNTAccount doesn’t existVerify account details
DAILY_LIMIT_EXCEEDEDExceeded daily limitWait or request increase
BANK_UNAVAILABLEBank temporarily unavailableRetry later
DUPLICATE_REFERENCEReference already usedUse unique reference

Best Practices

Use account validation before payouts to prevent failures:
const validation = await client.payouts.validateAccount({
  account_number: accountNumber,
  bank_code: bankCode
});
Generate unique references for each payout:
const reference = `payout-${Date.now()}-${userId}`;
Verify sufficient balance before initiating payouts:
const balance = await client.wallets.getBalance();
if (balance.available >= totalAmount) {
  // Proceed with payout
}
Always implement webhook handlers for real-time status updates.
Save payout IDs for reconciliation and support.

Next Steps

Inter-Bank Transfer API

API reference for transfers

Bank Name Enquiry API

Validate account details

Webhooks

Handle transfer webhooks

Wallets

Fund transfers from wallets