Confirm On-Ramp Checkout
Confirm a pending on-ramp from the hosted checkout (called by the checkout UI).
Confirms a PENDING on-ramp created via Initiate On-Ramp Checkout. On success the transaction moves to INITIATED and the response contains the virtual account / payment details the customer pays into.
You usually do not call this endpoint. The IvoryPay hosted checkout calls it on the customer's behalf after they authenticate (email OTP → customer JWT). It's documented here so you understand the lifecycle, and for the case where you build your own checkout UI on top of the API.
Endpoint
POST /v1/onramp/:reference/checkout/confirm:reference is the reference returned by checkout/initiate.
Authentication
Protected by HybridCheckoutHTTPAuthGuard — accepts any of:
Customer JWT
Authorization: Bearer <jwt>
The standard hosted-checkout path
Business-user JWT
Authorization: Bearer <jwt>
When a dashboard user drives checkout
Merchant API key
Authorization: <api_key>
Server-to-server
Under a customer JWT, the on-ramp is scoped to that customer — they can only confirm their own transactions. See Customer authentication.
Request body
walletAddress
string
No
Override the destination wallet. If omitted, the address supplied at checkout/initiate is used.
phoneNumber
string
Conditional
Required for mobile-money currencies (UGX, GHS, KES, …) when the customer has no phone number on file. Persisted to the customer for future on-ramps.
For bank-transfer currencies (NGN, ZAR, USD) no extra fields are needed — an empty body {} is valid if the wallet address was set at initiate.
Example request
Example response
Returns 200 OK. The transferDetails are now fully populated.
For mobile-money currencies, the customer pays from their wallet rather than a bank account — accountNumber/bank may be absent and the customer is directed via checkoutUrl / an in-app prompt instead. Always render whichever of accountNumber / checkoutUrl is present.
Response fields
firstName, lastName, email, phoneNumber
string
Customer identity
refCode
string
IvoryPay's customer reference
reference
string
Your transaction reference
transferDetails.accountName
string
Virtual account holder name (bank-transfer rails)
transferDetails.accountNumber
string
Virtual account number to pay into
transferDetails.bank
string
Bank name for the virtual account
transferDetails.amountPayable
number
Exact fiat amount to pay
transferDetails.expiresAt
string
ISO 8601 expiry of the payment session
transferDetails.currency
string
Fiat currency
transferDetails.businessFee
number
Your fee
transferDetails.platformFee
number
IvoryPay platform fee
transferDetails.gasFee
number
Blockchain gas fee
transferDetails.checkoutUrl
string
Hosted payment page (used for mobile-money / card-style collection)
transferDetails.cryptoAmount
number
Crypto the customer receives
transferDetails.status
string
INITIATED after a successful confirm
transferDetails.blockchain
string
Destination blockchain
transferDetails.token
string
Destination token
transferDetails.walletAddress
string
Destination wallet (post-override)
Getting a customer JWT
The hosted checkout obtains a customer JWT via email OTP. If you're building your own UI:
POST /v1/auth/customer-twofactor— body{ "email": "...", "context": "LIVE" }. Emails a 6-digit code.POST /v1/auth/customer-twofactor/verify— body{ "token": "123456" }. Returnsdata.jwt.accessToken.
Send that token as Authorization: Bearer <accessToken> on the confirm call.
Errors
401 CUSTOMER_CONTEXT_REQUIRED
No customer context (confirm requires a customer JWT under the customer path)
404
No PENDING on-ramp matches this reference for the caller
403 CUSTOMER_KYC_REQUIRED
KYC re-check failed
400
Mobile-money currency but no phone number on file or in the body
Related
Last updated