The flow
1
(Optional) Get a quote
If
fromCurrency and toCurrency differ, fetch a quote first to show your customer the converted amount and lock in a rate. See Quotes & FX.2
Initiate the collection
Call
POST /api/initiate-payment with an amount, currency pair, and a paymentReference you generate and control — it must be unique per attempt.Response
3
Display the payment instructions
Show the
paymentInstruction array to your customer — typically a virtual account number, account name, and bank name. Ask them to include the payRefrence (not your paymentReference) as the transfer narration/memo so the inbound payment matches automatically.4
Convert your currencies? Pass a rateKey
If
fromCurrency and toCurrency differ, this is a currency conversion — pass the rateKey from a prior quote so the conversion uses the rate you showed the customer, and a conversion fee is applied. Without a rateKey, toAmount defaults to the same numeric amount as amount.5
Collecting crypto↔fiat? Pass receipent instead of a rateKey
When
fromCurrency and toCurrency are on opposite sides of the fiat/crypto line (e.g. NGN → CNGN, or CNGN → NGN) and Paycrest is the active provider for that pair, the collection settles through Paycrest instead of a standard virtual account. No rateKey is needed — Paycrest quotes the rate at order time — but receipent becomes required, with different fields depending on direction:- Fiat → crypto (onramp)
- Crypto → fiat (offramp)
Your customer pays fiat in; you deliver crypto to their wallet. Show the customer
receipent.address and receipent.network are required — the wallet address and network to deliver to.Response
paymentInstruction[0] — this is a one-off Paycrest-issued bank account. Ask them to pay amountToTransfer (already inclusive of fees, may differ from amount) before validUntil, or the collection expires and a new one must be created.6
Track status
Poll
GET /api/transaction/:paymentReference using the reference you supplied in step 2, or register a webhook to be notified the moment it settles instead.Response
Statuses
status reflects the underlying transaction/payment status. Treat any value other than a completed/settled state as “still pending” — don’t hard-code an exhaustive list, since it can include provider-specific intermediate states. At minimum, expect to see a Pending state immediately after creation.
Finding your virtual account details directly
If you just need the standing account details for a currency — independent of any specific collection — useGET /api/account/:currency instead of creating a deposit:
Checking your balance
Response
Full endpoint reference
See exact request/response schemas for every field above.