Fees
Understand Due transaction fees, application-fee markups and subsidies, validation rules, and monthly invoicing.
Understand how transaction fees are built up, add your own markup or subsidise Due fees, and determine when collected fees appear on your invoice.
The key idea is that fees are additive layers, not competing rules. Every transaction can include up to four components: two channel fees, an FX markup, and an optional application fee that you set. Two validation rules apply only to the application-fee component.
On-chain payouts
All on-chain payouts are free, including cross-chain payouts (bridging assets across networks). Due charges no separate network or withdrawal fee for sending crypto on-chain: an on-chain rail's channel fee is 0 bps and 0 fixed.
For a fiat-to-crypto conversion, the quote can still show a fee on the destination crypto leg. In most cases, this is the source fee restated in the destination currency, not an additional charge. See Example 3.
The FX markup is included in fxRate and disclosed separately as fxMarkup. It is not a line-item amount, and the on-chain send itself is free.
Fiat transfers and conversions
Fiat payout, pay-in, and conversion fees vary by payment method, currency, and corridor.
For tailored pricing, book a demo or contact [email protected].
How fees fit together
Every transaction's total cost is the sum of these components:
| Component | What it is | Where it comes from |
|---|---|---|
| Source-channel fee | The inbound (deposit) rail's variable fee, feeBps (sourceChannelBps), plus its fixed fee, feeFixed (sourceChannelFeeAmount). | GET /v1/channels, on the source rail |
| Destination-channel fee | The outbound rail's variable fee (destinationChannelBps) plus any fixed fee. On-chain rails are free: 0 bps and 0 fixed. | GET /v1/channels, on the destination rail |
| FX markup | The conversion spread in basis points (fxMarkupBps), included in the quoted fxRate. | The quote (fxMarkup) |
| Application fee | An optional fee you set: your markup on top of Due fees, or a subsidy of them. | Your virtual-account or transfer request (applicationFeeBps, applicationFeeAmount) |
The first three components are Due fees: fixed inputs for a given rail and quote. The application fee is the component you control. The components add together; none overrides another.
Total variable fee (bps) = fxMarkupBps + sourceChannelBps + destinationChannelBps + applicationFeeBps
Total fixed fee = feeFixed (source) + any fixed destination fee + applicationFeeAmountBps means basis points: 100 bps equals 1%, so 10 bps equals 0.1%. Fixed fees (feeFixed and applicationFeeAmount) are never part of the basis-point calculation.
Count each fee once. A fiat-to-crypto quote can restate the source fixed fee in the destination currency on the destination leg. It is the same fee shown in two currencies, not two separate charges. On-chain destination rails add no fixed fee of their own.
Application fees: markup and subsidy
Use applicationFeeBps and applicationFeeAmount to add your own markup or fully or partially subsidise Due fees, including FX fees.
- Add markup: Use positive values. They stack on top of Due fees.
- Subsidise: Use negative values. They reduce or cover Due fees.
The validation rule depends on whether you set the application fee on a virtual account or a transfer quote.
Virtual accounts
For virtual accounts, the sum of all variable fees cannot be negative:
fxMarkupBps + sourceChannelBps + destinationChannelBps + applicationFeeBps >= 0A negative applicationFeeBps can fully or partially cover Due's markup in basis points, provided the combined variable fee remains at least 0. When you subsidise with a fixed amount, applicationFeeAmount must be less than sourceChannelFeeAmount (the source rail's feeFixed).
Transfer quotes
For transfer quotes, validation uses the total subsidised amount. The total subsidy from applicationFeeAmount and the amount implied by applicationFeeBps cannot be greater than Due's fee.
Your platform can cover Due's fee in full, but not more. For example, if Due's transaction fee is $5, applicationFeeAmount is -2, and applicationFeeBps produces a $1 subsidy, the total subsidy is $3. This is valid because it does not exceed Due's $5 fee. A total subsidy of $6 exceeds the fee and the transaction is not validated.
Worked examples
1. Find the source-channel fee from the rail
This ACH rail accepts USD deposits with feeBps of 20. This is sourceChannelBps. Its feeFixed of 1.5 is a separate fixed fee (sourceChannelFeeAmount) and is not part of the basis-point calculation.
{
"rail": "ach",
"currencyCode": "USD",
"feeBps": 20,
"feeFixed": "1.5",
"type": "static_deposit",
"accountType": "business",
"railSettings": {
"rail": "ach",
"speed": "1-2 days",
"schemas": ["bank_us"]
}
}Therefore, sourceChannelBps = 20 and the fixed source fee is $1.50.
2. Calculate the combined variable fee for a virtual account
With fxMarkupBps = 10, sourceChannelBps = 20, destinationChannelBps = 5, and applicationFeeBps = -10:
fxMarkupBps: 10 bps
sourceChannelBps: 20 bps
destinationChannelBps: 5 bps
applicationFeeBps: -10 bps
--------------------------------
Combined variable fee: 25 bps (0.25%)10 + 20 + 5 - 10 = 25. The negative applicationFeeBps offsets 10 bps of the other components. This is valid because the combined variable fee is at least 0.
3. Read a quote against the model (SEPA to Base)
{
"source": {
"rail": "sepa",
"currency": "EUR",
"amount": "200",
"fee": "0.9"
},
"destination": {
"rail": "base",
"currency": "USDC",
"amount": "229.410275",
"fee": "1.037013"
},
"fxRate": 0.86787743028,
"fxMarkup": 20
}Map this quote to the fee components:
sourceChannelBps = 0; the fixed source fee is€0.90, from the SEPA rail (feeBps: 0,feeFixed: 0.9) and shown assource.fee.fxMarkupBps = 20; it is included infxRateand disclosed asfxMarkup, not as a separate line-item amount.destinationChannelBps = 0with no fixed Base fee; Base is a free on-chain rail. Thedestination.feeof1.037013USDC is the€0.90source fee restated in USDC, not an extra charge.applicationFeeBps = 0andapplicationFeeAmount = 0; no application fee was set on this quote.
0.90 ÷ 0.86787743028 = 1.037013 (the €0.90 source fee, in USDC)
200 ÷ 0.86787743028 = 230.447288 (gross conversion of the full deposit)
230.447288 − 1.037013 = 229.410275 (= destination.amount, the net USDC delivered)The combined variable fee is 0 + 20 + 0 + 0 = 20 bps, which is valid. The only cash fee on the transaction is the single €0.90 SEPA fee, shown as €0.90 on the source leg and 1.037013 USDC on the destination leg. Count it once.
4. Add an application fee (your markup)
This request uses the ACH rail's bank_us schema and adds a 10 bps (0.1%) application fee plus a fixed application-fee amount of 1. The fixed amount is below the $1.50 sourceChannelFeeAmount.
{
"destination": "wlt_eD5zrQA4xEXS2mLJ",
"schemaIn": "bank_us",
"currencyIn": "USD",
"railOut": "base",
"currencyOut": "USDC",
"reference": "test_fee",
"applicationFeeBps": 10,
"applicationFeeAmount": 1
}These values stack on top of the other components. The combined variable fee becomes fxMarkupBps + 20 + destinationChannelBps + 10, plus your fixed fee of 1.
5. Subsidise Due fees
Use negative values to offset Due's markup.
- Virtual account: If
fxMarkupBps + sourceChannelBps + destinationChannelBps = 20, thenapplicationFeeBps: -10produces a combined fee of10bps and is accepted.applicationFeeBps: -30produces-10bps and is rejected because a virtual account's combined variable fee cannot be negative. - Transfer quote: If Due's fee is
$5,applicationFeeAmount: -2plus a$1subsidy fromapplicationFeeBpsproduces a$3total subsidy. This is valid because it does not exceed Due's$5fee. A$6total subsidy is not valid.
Fee invoicing
Fees collected are netted at the end of each month on your invoice.
Updated about 1 month ago