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

Confirm Off-Ramp Checkout

Confirm a pending off-ramp by selecting a payout account (called by the checkout UI).

Confirms a PENDING off-ramp created via Initiate Off-Ramp Checkout by attaching the customer's chosen payout account. On success the transaction moves to INITIATED and the response contains the receiver crypto address the customer sends funds to.

Endpoint

POST /v1/offramp/:reference/checkout/confirm

:reference is the reference returned by checkout/initiate.

Authentication

Protected by HybridCheckoutHTTPAuthGuard — accepts customer JWT (standard), business-user JWT, or merchant API key. Under a customer JWT the off-ramp is scoped to that customer. See Customer authentication.

Prerequisite — a saved payout account

The customer must have a saved bank / mobile-money account whose type and currency match the off-ramp. Accounts are created via Customer Bank Accounts:

Off-ramp fiatCurrency

Required account type

Required fields when adding

NGN, ZAR, USD

BANK_TRANSFER

accountNumber, bankCode, accountName

UGX, GHS, KES, …

MOBILE_MONEY

accountNumber (E.164 phone), operator

The bankAccountId passed below is the id of one of those saved accounts.

Request body

Field
Type
Required
Description

bankAccountId

string (UUID)

Yes

ID of one of the customer's saved bank / mobile-money accounts. Its currency must match the off-ramp's fiatCurrency.

Example request

Example response

Returns 200 OK. The transferDetails now include the receiver address and session.

For mobile-money payout accounts, accountNumber is the E.164 phone number and bankCode carries the mobile-money operator (e.g. MTN_MOMO_UGA). For bank-transfer accounts these are the bank account number and bank code.

Response fields

Field
Type
Description

firstName, lastName, email

string

Customer identity

refCode

string

IvoryPay's customer reference

reference

string

Your transaction reference

transferDetails.token

string

Token the customer sends

transferDetails.blockchain

string

Source blockchain

transferDetails.amountPayable

number

Crypto the customer must send

transferDetails.walletAddress

string

Receiver address — the customer sends crypto here

transferDetails.expiresAt

string

ISO 8601 expiry of the send window

transferDetails.sessionId

string

Settlement session id

transferDetails.duration

number

Session duration in seconds

transferDetails.businessFee / platformFee

number

Fees

transferDetails.fiatAmount

number

Fiat the customer receives

transferDetails.fiatCurrency

string

Payout currency

transferDetails.accountName

string

Payout account holder name

transferDetails.accountNumber

string

Bank account number, or E.164 phone for mobile money

transferDetails.bankCode

string

Bank code, or mobile-money operator

transferDetails.bankName

string

Bank / mobile-money provider name

transferDetails.status

string

INITIATED after a successful confirm

transferDetails.receivedToken / receivedCryptoAmount

nullable

Populated once the customer's crypto is received

transferDetails.failureReason

nullable

Set if the transaction later fails

Getting a customer JWT

Same flow as on-ramp:

  1. POST /v1/auth/customer-twofactor — body { "email": "...", "context": "LIVE" }.

  2. POST /v1/auth/customer-twofactor/verify — body { "token": "123456" }data.jwt.accessToken.

Send it as Authorization: Bearer <accessToken>.

Errors

HTTP
When

401 CUSTOMER_CONTEXT_REQUIRED

No customer context on the confirm call

404 OFFRAMP_NOT_FOUND_OR_CONFIRMED

No PENDING off-ramp matches this reference for the caller

404

bankAccountId doesn't belong to the customer or isn't active

400 BANK_ACCOUNT_CURRENCY_MISMATCH

Saved account currency ≠ off-ramp fiatCurrency

403 CUSTOMER_KYC_REQUIRED

KYC re-check failed

Last updated