Skip to main content

Inbound Funding API

The Inbound Funding API is how a bank, mobile money operator or payment service provider pushes funds from its own channel into an SmartPay SmartPay subscriber wallet.

Money moves in only. Payouts back out to a bank are a separate outbound API and are not part of v1.

Info

Base path /api/v1/inbound  ·  Currency SLE  ·  Amounts integer minor units (50000 is Le 500.00)

The four calls that matter

Name enquiry

Confirm who the money would reach, and show that name to your customer before you debit them.

Credit

Post the funds. Idempotent on your own reference.

Status query

After a timeout, ask what actually happened. Never assume.

Reversal

Return the value if the transfer needs to be undone.

Endpoints


Settlement

You do not prefund. There is no float to top up and nothing to maintain before you can send.

Instead SmartPay keeps a receivable account for you. Every credit you post raises what you owe; when you settle, it comes back down. What remains is your live position.

You credit a wallet

The subscriber gets the value immediately, and your receivable rises by the same amount.

You collect on your side

You already debited your own customer, so you are holding the real money.

You settle with SmartPay

You wire the accumulated value. SmartPay records it and your receivable falls.

GET /api/v1/inbound/balance gives you three figures:

FieldMeaning
outstandingWhat you owe SmartPay right now — credits posted, less settled
total_receivedLifetime value you have pushed in, net of reversals. Never reduced by settlement
total_settledLifetime value you have paid SmartPay
Note

outstanding is what you reconcile against and settle. total_received is your volume figure. They answer different questions, so both are returned.

Exposure limits

Some accounts carry an exposure_limit: a ceiling on outstanding. Reach it and further credits are refused with 402 PARTNER_EXPOSURE_LIMIT_EXCEEDED until you settle.

If no limit is set for you, exposure_limit is 0 and available_exposure is null — you are uncapped.

Warning

A 402 is not a rejected request. Nothing moved, nothing is wrong with the payload. Settle what you owe, then retry with the same reference.

Watch available_exposure and settle before it reaches zero, rather than discovering the ceiling through a wall of refusals mid-morning.


Idempotency

This is the most important part of the integration.

Every write is keyed on (your partner account, your reference). That gives you one guarantee worth designing around:

Check

Retrying a credit with the same reference can never credit the customer twice.

What you sendWhat you get
Same reference, same body200 with the original response and header Idempotent-Replay: true
Same reference, different body409 REFERENCE_CONFLICT — nothing is applied
Same reference, still in flight409 REQUEST_IN_PROGRESS with Retry-After

So on a timeout or a 5xx, retry with the identical reference. Do not mint a new one — a new reference is a new transfer.

If you would rather check first, call GET /api/v1/inbound/transactions/{reference}. A 404 REFERENCE_NOT_FOUND means we never saw it and it is safe to send.


Beneficiaries

Supply exactly one identifier per request.

FieldNotes
account_numberSmartPay-native and unambiguous. Preferred.
msisdnPhone number, E.164. Formatting is normalised.
card_serialThe card must be assigned to a subscriber.

Sending more than one is a 400 AMBIGUOUS_BENEFICIARY. We refuse rather than guess which one you meant.

Note

Wallet accounts are never created for you. If a beneficiary has no account, you get BENEFICIARY_NO_ACCOUNT — that customer is not onboarded with SmartPay, and you should learn that before you debit anyone.


Fees

v1 is zero-rated: fee is always 0 and net_credited always equals amount. Both fields are in every response so that if charging is ever enabled for your integration, nothing about your parsing has to change.


Next