Guides
Accept deposits
Users fund their wallets with fiat. Ndeipi credits points at a fixed price per currency, which GET /rates returns with type fixed.
There are two ways in: standing bank details the user can pay into at any time, and one-off top-ups for a specific amount. Both create an onramp transfer for each payment, so you track deposits exactly like any other transfer.
Standing deposit details
Create a deposit account for a user, currency and rail, and show the user the returned deposit_instructions: bank, account number, branch code and a reference they must quote.
curl -X POST "$NDEIPI/users/usr_01JA8Z2F5G6H7J8K9M0N1P2Q3R/deposit_accounts" \
-H "Api-Key: $NDEIPI_API_KEY" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "source": { "currency": "zar", "rail": "absa_eft" },
"destination": { "wallet_id": "wal_01JA8Z4K2V9QW3H6Y7XKD2M0RS" } }'Every payment that arrives with that reference creates its own on-ramp transfer into the wallet. List them with deposit activity. Deposits to a deactivated account are returned to the sender. Only bank rails have standing details.
One-off top-ups
Create a transfer with a fiat source. It returns awaiting_funds with deposit_instructions for that one payment, including the amount and an expiry. For PayPal the instructions carry an approval_url: send the user there to approve the payment.
curl -X POST "$NDEIPI/transfers" \
-H "Api-Key: $NDEIPI_API_KEY" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "source": { "type": "fiat", "currency": "zar", "rail": "paypal" },
"destination": { "type": "wallet", "wallet_id": "wal_01JA8Z4K2V9QW3H6Y7XKD2M0RS" },
"amount": "100.00" }'If the payment never comes, the transfer is canceled at its expiry, and money that arrives later is returned.
When the money arrives
You get deposit.received, then transfer.state_changed as the transfer moves awaiting_funds → funds_received → completed. The receipt shows amount_expected, amount_received, the rate, fees and amount_credited.
- Over- or under-payment. Whatever actually arrives is credited, even if it differs from what was expected.
- Below the minimum. A payment below the route's minimum is returned to the sender instead. The transfer ends
returnedand you getdeposit.returnedwith the reason. - Review. A deposit can be held
in_reviewafter it arrives, before it's credited.
Which rails are available
Read GET /routes at run time to see which currencies and rails can fund a wallet, with each route's minimum, maximum and typical settlement time. Don't hard-code rails: new ones are added as data.