Skip to content
MultigateAPI
Support Staff

Use cases

Remittance companies (IMTOs)

Pay out money that senders abroad paid you, into beneficiaries' local bank accounts, with the sender and beneficiary details regulators require.

Who it's for: remittance companies, that is licensed international money transfer operators (IMTOs), paying out into African corridors.

Architecture

flowchart LR
    sender([Sender abroad]) -->|pays you| app[Your app and backend]
    app -->|pre-fund| acct[(Your NGN account on Multigate)]
    app -->|name enquiry, then remittance| mg[Multigate API]
    acct -->|debited amount + fee| mg
    mg -->|local payment| bank([Beneficiary's bank])
    mg -.->|transfer_completed or transfer_failed| app
sequenceDiagram
    autonumber
    participant App as Your app (sender abroad)
    participant You as Your backend
    participant MG as Multigate
    participant Bank as Beneficiary bank
    App->>You: Sender pays you abroad
    You->>MG: Look up the beneficiary's account name
    MG-->>You: responseCode 00, bankAccountName
    You->>MG: Initiate a remittance (sender, beneficiary, uniqueRequestId)
    MG-->>You: 200, data.status pending, pending_approval or processing
    Note over MG: Screening, approval, debit
    MG->>Bank: Local payment
    MG-)You: transfer / transfer_completed or transfer_failed
    You-->>App: Notify the sender

Before you start

  • A sandbox API key, and MG_BASE_URL and MG_API_KEY set as in the Quickstart.
  • A webhook URL registered (Webhooks overview).
  • Your API user has the initiate payment or approve payment permission. Whether its remittances also wait for an approver follows the same rules as transfers: see Approvals.
  • NGN: Multigate has set up your remittance collection account. Without it, NGN remittances are accepted, then fail with "Unable to process remittance transaction".
  • An active NGN account of your own business (remittances can't be sent for a customer), funded for the amounts plus fees.

Build plan

Pre-fund your account

Find your NGN account with List accounts and note its account number (the wallet's own number or one of its fundingDetails[].accountNumber values). Fund it by bank transfer to that number. In the sandbox, use Simulate an inflow.

Before each remittance, you can check that the balance covers the amount plus the fee with Get an account balance and Get a transfer fee.

Check the beneficiary's account

A remittance doesn't check the beneficiary's account for you, so a wrong number or name is only caught by the bank. Call Look up an account name for every new beneficiary, with the bank code from List banks:

curl -X POST "$MG_BASE_URL/payment-service/api/v1/transfer/name-enquiry" \
  -H "mp-api-key: $MG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "bankCode": "058", "bankAccountNumber": "0123456789", "currencyIso3Code": "NGN", "countryIso3Code": "NGA" }'

The answer is HTTP 200 even when the account isn't found: only responseCode 00 means found. Show bankAccountName to your sender to confirm before you pay. Nigerian account numbers (NUBAN) are exactly 10 digits.

Send the remittance

Generate a uniqueRequestId (your unique ID for this remittance, unique across all of Multigate: use a UUID or your own prefix), store it, then call Initiate a remittance:

curl -X POST "$MG_BASE_URL/payment-service/api/v1/transfer/remittance" \
  -H "mp-api-key: $MG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uniqueRequestId": "acme_rm_20261010_0001",
    "sourceAccountNumber": "1029384756",
    "currencyIso3Code": "NGN",
    "amount": 180000,
    "narration": "Family support Oct",
    "sender": {
      "firstName": "John", "lastName": "Mensah",
      "emailAddress": "john.mensah@example.com", "phoneNumber": "+447700900123",
      "address": "10 High Street", "city": "London", "countryIso3Code": "GBR"
    },
    "beneficiary": {
      "firstName": "Ama", "lastName": "Mensah",
      "accountName": "AMA MENSAH", "accountNumber": "0123456789",
      "bankBicOrCode": "058", "bankName": "Guaranty Trust Bank", "countryIso3Code": "NGA"
    }
  }'
  • The currency field is currencyIso3Code here (a transfer uses sourceCurrencyIso3Code).
  • Send every sender detail you hold, and sender.bvn (Bank Verification Number) for Nigerian senders: they're used for compliance screening.
  • Use accountName as the bank returned it in the previous step.
  • The response is nested under data. Store data.transactionId (PMT-…) with your uniqueRequestId.

Field rules and errors: Remittance.

Handle the outcome

Wait for transfer / transfer_completed or transfer_failed, matched by uniqueRequestId, then notify the sender.

Some outcomes send no webhook (an approver's decline, a compliance decline), so poll Get a remittance with your uniqueRequestId or the transactionId for remittances that stay non-final. data.failureReason explains a failed one.

On failure, either refund your sender in your own system, or fix the details and send a new remittance with a new uniqueRequestId.

If the create call times out or returns 5xx, the outcome is unknown: look the remittance up with Get a remittance before doing anything else, and retry only with the same uniqueRequestId. See Idempotency.

Statuses

data.status Final What to tell the sender
pending No Processing (being screened).
pending_approval No Processing (waiting for an approver in your business).
processing No Processing (sent for payment).
completed Yes Paid.
failed Yes Not paid; any debit is reversed. Read failureReason.
rejected Yes Not paid; declined by your approver.

See Transfer statuses for the responseCode behind each.

Data to store

Field From Used for
uniqueRequestId (stored before the call) your own Lookups after a timeout, matching webhooks
data.transactionId (PMT-…) Initiate a remittance Support, statements, receipts
Sender and beneficiary details, and the name enquiry result your app, Look up an account name Compliance records
Final status, responseMessage or failureReason webhook or Get a remittance Notifying the sender

Webhooks to handle

Event What to do
transfer / transfer_completed Mark paid; notify the sender.
transfer / transfer_failed Mark failed; show the reason; refund or resend with a new ID.

Remittances send no "Transfer Notification" emails; only "Transaction Declined" if an approver declines one. See Outcomes without a webhook.

Reconciliation

Each day, pull yesterday's Get an account statement for your funding account. Match each debit to a remittance by customReference (your uniqueRequestId), account for Fee lines, and compare closingBalance with your own records. Remittances also appear in Find transfers. See Balances and statements.

Go-live notes

  • Ask Multigate to set up your production remittance collection account before your first NGN remittance.
  • Agree your approval rules: a remittance waiting for an approver stays pending_approval.
  • Keep each remittance within the per-payment maximum (List payment methods): remittances are never split. Send several, each with its own uniqueRequestId.
  • Plan for local-currency payouts: USD remittances to a third party are refused today, because the endpoint can't take supporting documents.
  • Keep sender data complete; it's used for compliance screening.
  • Work through the go-live checklist.