Overview
A Due payout is the mirror of a payin: crypto leaves your client’s Portal wallet and Due settles the equivalent fiat to a bank beneficiary. You discover a channel, create the fiat recipient, quote the transfer, create it, then send crypto to the onchain deposit address Due returns.Portal proxies these endpoints to Due and returns Due’s responses verbatim. Example
responses below are illustrative; exact fields come from Due and may evolve.
1. Prerequisite: approved KYC
Transfers require a provisioned Due customer with approved KYC. Some channels additionally require endorsements. See KYC onboarding.2. Discover a channel
GET /channels lists the rails and currencies available to the customer. Pass
onlyAvailable=true to filter to channels the customer can use today. Pick a crypto source
rail (for example base-sepolia / USDC) and a fiat destination rail and currency (for
example sepa / EUR). Each channel also exposes purposeCodes and memoConfig, which you
will need when creating the transfer.
3. Create the fiat recipient
The recipient is the bank beneficiary that receives the fiat. CallPOST /recipients with
isExternal: true. Unlike a payin recipient, this is a bank account, not a wallet, so the
CAIP-2 chainId defaulting does not apply.
- Set
isExternal: trueso Portal forwards the recipient to Due without attempting any Portal-wallet address defaulting. - The exact
detailsfields depend on the channel’s bank schema (for examplebank_sepaorbank_us): account or IBAN, beneficiary address, and entity type. Due validates them and returns field-level errors for anything missing. - The
Idempotency-Keyheader is optional and deduplicates retries.
4. Quote the transfer
POST /transfers/quote prices the transfer. source is the crypto side and destination
is the fiat side. Set the destination amount to "0" to let Due compute the fiat the
beneficiary receives from the crypto amount sent.
Application fees are enforced by the custodian’s Portal Dashboard configuration and injected
server-side. Any
applicationFeeBps or applicationFeeAmount you send is stripped, so
clients cannot override them. See Application fees.5. Create the transfer
POST /transfers turns a quote into a transfer. Pass the quote token and the recipient
id.
memoandpurposeCodeare optional. Whether they are required, and which values are valid, comes from the channel’smemoConfigandpurposeCodesfrom step 2.- The
Idempotency-Keyheader is optional and deduplicates retries.
6. Get the deposit address
While the transfer isawaiting_funds, call POST /transfers/{transferId}/funding-address
to get the onchain address to send the source crypto to.
For some rails Due returns a
kind of external_action, meaning the deposit needs an
onchain signature rather than a plain transfer. Read details for the specific action.7. Send crypto and track settlement
Send the source crypto from your client’s Portal wallet to the depositdetails.address
(for example with the SDK’s sendAsset). Once the deposit lands, subscribe to
webhooks to track settlement. The status progresses
awaiting_funds -> funds_received -> approved -> payment_submitted ->
payment_processed.
GET /transfers/{transferId} returns a transfer’s current state whenever you need to read it
directly.