Skip to main content

Overview

A Due payin moves fiat into your client’s Portal wallet: the client sends a bank transfer, and Due settles the equivalent crypto onchain. Unlike a single-call payin, Due uses a quote-then-transfer model: discover a channel, create the crypto recipient, quote the transfer, create it, then show the client the funding instructions.
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.
For a persistent bank account that auto-converts every deposit (rather than one transfer at a time), see Virtual accounts.

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 fiat source rail (for example ach or sepa) and a crypto destination rail and currency (for example base-sepolia and USDC).

3. Create the destination recipient

The recipient is where the crypto settles: your client’s Portal wallet. Call POST /recipients. Portal maps a CAIP-2 chainId to the Due recipient schema and defaults the address to the client’s Portal wallet, so you can omit the address entirely.
  • Pass a CAIP-2 chainId and leave details.address unset to default both the schema and the address to the client’s Portal wallet. Supported namespaces map as eip155:* -> evm, solana:* -> solana, tron:* -> tron.
  • To send to an address the client does not custody in Portal, set an explicit details.address and isExternal: true. External recipients are never defaulted.
  • details.address is the chain’s native address string: 0x-hex for EVM, base58 for Solana (for example Bxi9R9ckm4qQZdha85LGY66xyhoo2eaAzfsSpjQJQJ4G), base58check for Tron.
  • The Idempotency-Key header is optional and deduplicates retries.
Example response:

4. Quote the transfer

POST /transfers/quote prices the transfer. source is the fiat side and destination is the crypto side. Set the destination amount to "0" to let Due compute it from the source amount.
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 and forwarded to Due.
  • The Idempotency-Key header is optional and deduplicates retries.
Example response:

6. Get funding instructions

While the transfer is awaiting_funds, call POST /transfers/{transferId}/funding-address to get the fiat payment details. Show details to your client so they can send the bank transfer.
Example response:

7. Track settlement

After the client sends funds, 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