For the complete documentation index, see llms.txt. This page is also available as Markdown.

Initiate On-Ramp

Initiate an on-ramp transaction for an existing customer.

Initiates a fiat-to-crypto on-ramp transaction for a customer that already exists in your IvoryPay account.

Endpoint

POST /v1/onramp/initiate

Authentication

This endpoint accepts any one of three credentials in the Authorization header:

Credential
Header value

Merchant API key

Authorization: <api_key>

Business-user JWT

Authorization: Bearer <jwt>

Customer JWT

Authorization: Bearer <jwt>

When a customer JWT is used, the request is scoped to that customer.

Request body

Field
Type
Required
Description

email

string

Yes

Existing customer's email address

phoneNumber

string

No

Customer's phone number (E.164 format)

walletAddress

string

Yes

Destination crypto wallet address

blockchain

string

Yes

Blockchain network. See Supported Blockchains

reference

string

Yes

Your unique reference (must be a UUID)

token

string

Yes

Cryptocurrency to receive. See Supported Networks & Tokens

fiatCurrency

string

Yes

Fiat currency to pay in. See Supported Currencies

fiatAmount

number

No*

Amount in fiat

cryptoAmount

number

No*

Amount in crypto

businessFeeInFiat

number

No

Your business fee in fiat. Send 0 (or omit) if you are not charging a fee

businessFeeInCrypto

number

No

Your business fee in crypto. Pair with cryptoAmount

redirectUrl

string

No

Redirect URL after checkout

note

string

No

Transaction note

fiatCurrency: "ZAR" — you must redirect the customer

For most BANK_TRANSFER currencies (NGN, USD) the response gives you a virtual account (accountName/accountNumber/bank) to display. ZAR is the exception: the fiat-payment provider hands back a hosted checkout page instead, so accountName/accountNumber/bank come back null and transferDetails.checkoutUrl is populated. You must redirect (or embed) the customer at checkoutUrl yourself — since you're on the direct endpoint rather than the hosted checkout flow, nothing does this for you. Always branch on which field is present rather than assuming NGN's shape applies to every BANK_TRANSFER currency.

Example request

Example response

Returns HTTP 201 Created.

For fiatCurrency: "ZAR", the shape flips — accountName/accountNumber/bank are null and checkoutUrl is populated:

Redirect the customer to transferDetails.checkoutUrl to complete payment — there's no account number to display for ZAR.

Error cases

Error code
Description

ONOFFRAMP0053

Customer not found — use the with-customer endpoint instead

Last updated