Skip to main content

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. Call POST /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: true so Portal forwards the recipient to Due without attempting any Portal-wallet address defaulting.
  • The exact details fields depend on the channel’s bank schema (for example bank_sepa or bank_us): account or IBAN, beneficiary address, and entity type. Due validates them and returns field-level errors for anything missing.
  • The Idempotency-Key header is optional and deduplicates retries.
Example response:

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.
Example response:

5. Create the transfer

POST /transfers turns a quote into a transfer. Pass the quote token and the recipient id.
  • memo and purposeCode are optional. Whether they are required, and which values are valid, comes from the channel’s memoConfig and purposeCodes from step 2.
  • The Idempotency-Key header is optional and deduplicates retries.
Example response:

6. Get the deposit address

While the transfer is awaiting_funds, call POST /transfers/{transferId}/funding-address to get the onchain address to send the source crypto to.
Example response:
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 deposit details.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.
Acknowledge webhook deliveries quickly with a 2XX, then process events asynchronously.

Next steps