curl --request POST \
--url https://api.paycrest.io/v2/sender/orders \
--header 'API-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": "100",
"source": {
"type": "crypto",
"currency": "USDT",
"network": "base",
"refundAddress": "0xYourAddress"
},
"destination": {
"type": "fiat",
"currency": "NGN",
"recipient": {
"institution": "GTBINGLA",
"accountIdentifier": "1234567890",
"accountName": "John Doe",
"memo": "Payment"
}
}
}
'{
"status": "success",
"message": "Payment order created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "initiated",
"orderType": "regular",
"timestamp": "2026-09-24T05:15:00Z",
"amount": "100",
"rate": "1650",
"senderFee": "4.9",
"senderFeePercent": "0",
"transactionFee": "0.1",
"reference": "invoice-123",
"providerAccount": {
"network": "solana",
"receiveAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"validUntil": "2026-09-24T05:45:00Z",
"amountToTransfer": "105",
"currency": "USDC"
},
"source": {
"type": "crypto",
"currency": "USDC",
"network": "solana",
"refundAddress": "4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T"
},
"destination": {
"type": "fiat",
"currency": "NGN",
"recipient": {
"institution": "GTBINGLA",
"accountIdentifier": "1234567890",
"accountName": "John Doe",
"memo": "Payment"
}
}
}
}Initiate Order
Creates a new payment order.
- Offramp (stablecoin → fiat): set
source.type = "crypto"anddestination.type = "fiat". The responseproviderAccountcontains areceiveAddressto send tokens to. - Onramp (fiat → stablecoin): set
source.type = "fiat"anddestination.type = "crypto". The responseproviderAccountcontains a virtual bank account for the user to deposit fiat into.
Offramp deposit. Send exactly providerAccount.amountToTransfer of providerAccount.currency — that is
amount + senderFee + transactionFee. When providerAccount.memo is present, include it with the deposit
or the deposit cannot be credited.
Transaction fee. By default the sender pays the transaction fee out of their sender fee, so the returned
senderFee is what the sender earns and the customer only tops up a shortfall. Set transactionFeePayer: "customer" (or change the token’s setting in the dashboard) to add the transaction fee on top of the full
sender fee instead.
Solana (solana) is available through this endpoint only; v1 order endpoints reject it. On onramp to
Solana, the recipient wallet must already have a token account for the stablecoin’s mint.
Provider routing. On offramp, leave destination.providerIds unset and the API resolves a ranked
queue of up to 3 providers at creation; assignment walks it in order. Set destination.providerIds to
supply your own queue — typically the ids from a rate quote — or a
one-entry queue to route to a single provider. Queue exhaustion is not an immediate refund: fallback
assignment runs first, then the refund window.
On onramp, the provider is selected when the order is created, so destination.providerIds accepts at
most one entry and acts as a pin.
The singular destination.providerId is retained for backward compatibility on both flows and is mutually
exclusive with providerIds. Routing validation failures return 400 with data as a single
{ field, message } object rather than an array.
curl --request POST \
--url https://api.paycrest.io/v2/sender/orders \
--header 'API-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": "100",
"source": {
"type": "crypto",
"currency": "USDT",
"network": "base",
"refundAddress": "0xYourAddress"
},
"destination": {
"type": "fiat",
"currency": "NGN",
"recipient": {
"institution": "GTBINGLA",
"accountIdentifier": "1234567890",
"accountName": "John Doe",
"memo": "Payment"
}
}
}
'{
"status": "success",
"message": "Payment order created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "initiated",
"orderType": "regular",
"timestamp": "2026-09-24T05:15:00Z",
"amount": "100",
"rate": "1650",
"senderFee": "4.9",
"senderFeePercent": "0",
"transactionFee": "0.1",
"reference": "invoice-123",
"providerAccount": {
"network": "solana",
"receiveAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"validUntil": "2026-09-24T05:45:00Z",
"amountToTransfer": "105",
"currency": "USDC"
},
"source": {
"type": "crypto",
"currency": "USDC",
"network": "solana",
"refundAddress": "4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T"
},
"destination": {
"type": "fiat",
"currency": "NGN",
"recipient": {
"institution": "GTBINGLA",
"accountIdentifier": "1234567890",
"accountName": "John Doe",
"memo": "Payment"
}
}
}
}Authorizations
Body
Payment amount. Denomination is determined by amountIn (defaults to crypto units).
"100"
Polymorphic source — set type: "crypto" for offramp or type: "fiat" for onramp.
- Option 1
- Option 2
Show child attributes
Show child attributes
Polymorphic destination — set type: "fiat" for offramp or type: "crypto" for onramp.
- Option 1
- Option 2
Show child attributes
Show child attributes
Specifies whether amount is denominated in crypto or fiat. Defaults to crypto.
crypto, fiat Quoted exchange rate (fiat per crypto unit). Optional — protocol uses best available rate if omitted.
Fixed sender fee in crypto units. Mutually exclusive with senderFeePercent. When the effective sender fee is greater than zero, senderFeeAddress (or a fee address configured on the sender profile) is required.
"0.5"
Sender fee as a percentage of the order amount (alternative to senderFee). Mutually exclusive with senderFee. When the effective sender fee is greater than zero, senderFeeAddress (or a fee address configured on the sender profile) is required.
"1"
Optional fee recipient address for this order. Required when the effective sender fee is greater than zero
(from senderFee, senderFeePercent, or a profile-configured fee) and no fee address is configured on the
sender profile for the token. Not required when the effective fee is zero. Must be a valid address for the
order's crypto source or destination network (a Solana address for Solana orders). Fees on some networks are
collected and paid out to it in batches rather than per order.
"0xYourFeeRecipientAddress"
Who pays the order's transaction fee (its network cost). Overrides the token's setting in your dashboard,
which defaults to sender.
sender: the transaction fee comes out of your sender fee first; your customer only pays the difference when your fee is smaller. You earnmax(0, fee − transactionFee), and the customer sendsamount + max(fee, transactionFee).customer: your customer pays the transaction fee on top of your full sender fee.
With no sender fee, both modes are the same.
sender, customer "sender"
Your internal reference ID for this order.