Skip to main content
POST
Create an offramp order
Opens an order to convert a token into fiat and pay it into a bank account. This is the explicit alternative to the bank account address flow: instead of a standing address that pays out whatever it receives, you state the amount up front, get back a quote and a one-off funding address, and send the tokens there. Reach for this when the amount matters — you are quoting a user a specific naira figure, or you need the payout tied to a single deposit rather than to an address that anyone can pay at any time.

Naming the destination

The bank account is given as a bankCode (from Get banks) plus an accountNumber. Before any order is written, Paj confirms that pair with the payout rail. An account number the bank cannot resolve is a 400 and leaves nothing behind — there is no half-created order to clean up. The confirmed account holder’s name comes back on the response as accountName. It is the bank’s answer, not an echo of your input, so it is worth showing to the user as a last check before they part with funds.

Amount: token or fiat, never both

Send exactly one of:
  • amount — the quantity of mint you are selling. Paj prices it and tells you the fiatAmount that will land.
  • fiatAmount — the payout you want the recipient to receive. Paj works backwards and tells you the amount of mint to send.
Sending both is a 400; so is sending neither. mint is required either way, and chain defaults to SOLANA.

Choosing the chain

Orders open on any supported chain: SOLANA, TON, ETHEREUM, BASE, BSC, MONAD or ARC. This is the only way to pay out from a chain other than Solana — the bank account address is Solana only. mint is the token’s address on that chain: a Solana mint, an ERC-20 contract, or a TON jetton master ("TON" for Toncoin). It is checked against chain, so an EVM contract sent without a chain — which defaults to SOLANA — is a 400. The chain’s settlement stablecoin — USDC, or USDT on TON — pays out directly; anything else is priced at its USD value when it lands.
The address that comes back is in that chain’s format, and is watched on that chain alone. On the EVM chains the address is valid on all five networks, so a user sending from a multi-chain wallet can easily pick the wrong one — make the chain as prominent as the address when you show it.

Attributing the order to a user

bvn is optional and identifies the end user the order belongs to. When you send one, Paj traces it to that user through their KYC record; if the BVN is new to Paj, it is verified with the identity provider and the user is registered from the verified bio before the order is created. A BVN that fails verification is a 400. Omit it and the order is simply not attributed to any individual — it stays a business-level order under your API key. The payout still works, but it goes out without a payer name attached.

Funding the order

The response address is where the tokens go. Send amount of mint on chain to that address and the order settles on its own — the deposit is the instruction, and there is no second call to confirm it. Track progress by status, which starts at INIT and ends at COMPLETED or ERROR.
Funding addresses are drawn from a shared pool and reused. Creating a new order deprecates any earlier order sitting on the same address, so always send to the address from the response you are acting on — never to one you cached from a previous order.
Orders are not kept forever: an unfunded order is deleted 72 hours after it was created. Treat the quote as good for that window, and re-create the order rather than funding a stale one.

Getting told when it settles

Paj POSTs the order back to you on every status change, in the same shape as this endpoint’s response. It goes to the order’s webhookURL if you set one, and otherwise to the rampWebhookURL configured on your API key — so a key set up once with Update your webhook URLs covers every order without repeating the URL. With neither, you are polling. Deliveries are signed; see Webhook signatures.

Authorizations

x-api-key
string
header
required

Body

application/json
accountNumber
string
required

Account Number to receive funds

Example:

"679be2527f99f556d77b8cc2"

currency
object
required

Currency to receive funds

Example:

"NGN"

bankCode
string
required

Code of the bank that receives the payout

Example:

"000016"

mint
string
required

Mint address of the token being sold, on the given chain. On TON, a jetton master address or "TON" for Toncoin.

Example:

"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"

amount
number

Token amount (provide either amount or fiatAmount, not both)

Example:

100

fiatAmount
number

Fiat amount (provide either amount or fiatAmount, not both)

Example:

100

chain
object

Chain

Example:

"SOLANA"

webhookURL
string

Callback webhook url

Example:

"https://mydomain.com/webhook"

saveBeneficiary
boolean

Save beneficiary

Example:

true

description
string

Payment description

Example:

"Payment for order #123"

businessUSDCFee
number
default:0

Business fee

Example:

0.5

bvn
string

BVN of the end user the order is created for. It is traced to that user's KYC record; if the BVN is not on file it is verified and the user is registered before the order is opened.

Example:

"22222222222"

Response

The created offramp order

id
string
required

Transaction Id

Example:

"679be2527f99f556d77b8cc2"

address
string
required

Address

Example:

"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"

signature
string
required

Transaction Signature

Example:

"2oLx7XrXP7Df9dZca1difJ91ZFmA44EEadNqrZTecta6ugcX8BAETbpvKQs54r58fmJTQVLzUSuzvRBFwS1GfJLo"

mint
string
required

Mint Address

Example:

"So11111111111111111111111111111111111111112"

currency
object
required

Currency

Example:

"NGN"

amount
number
required

Mint Amount

Example:

100000

usdcAmount
number
required

Usdc Amount

Example:

100

fiatAmount
number
required

Fiat Amount

Example:

100

sender
string
required

Wallet Public Key

Example:

"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"

recipient
string
required

Recipient Public Key

Example:

"4KSLE7EU1P7PQ8Rc4hdb2ZKq2JmWHD8UXJp7guEdyT9j"

rate
number
required

Rate of currency to usdc

Example:

9

status
object
required

Transaction Status

Example:

"PENDDING"

transactionType
object
required

Transaction Type

Example:

"OFF_RAMP"

createdAt
string<date-time>
required

Transaction creation date

Example:

"2026-09-28T14:55:27.097Z"

accountNumber
string
required

Account Number (for onramp transactions)

Example:

"0025635480"

accountName
string
required

Account Name (for onramp transactions)

Example:

"Paj Inc."

bank
string
required

Bank Name (for onramp transactions)

Example:

"First Bank"

fee
number
required

Transaction fee in usdc

Example:

0.2

chain
object
required

Chain

Example:

"SOLANA"