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:

ComponentWhat it isWhere it comes from
Source-channel feeThe inbound (deposit) rail's variable fee, feeBps (sourceChannelBps), plus its fixed fee, feeFixed (sourceChannelFeeAmount).GET /v1/channels, on the source rail
Destination-channel feeThe 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 markupThe conversion spread in basis points (fxMarkupBps), included in the quoted fxRate.The quote (fxMarkup)
Application feeAn 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 + applicationFeeAmount

Bps 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 >= 0

A 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 as source.fee.
  • fxMarkupBps = 20; it is included in fxRate and disclosed as fxMarkup, not as a separate line-item amount.
  • destinationChannelBps = 0 with no fixed Base fee; Base is a free on-chain rail. The destination.fee of 1.037013 USDC is the €0.90 source fee restated in USDC, not an extra charge.
  • applicationFeeBps = 0 and applicationFeeAmount = 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, then applicationFeeBps: -10 produces a combined fee of 10 bps and is accepted. applicationFeeBps: -30 produces -10 bps and is rejected because a virtual account's combined variable fee cannot be negative.
  • Transfer quote: If Due's fee is $5, applicationFeeAmount: -2 plus a $1 subsidy from applicationFeeBps produces a $3 total subsidy. This is valid because it does not exceed Due's $5 fee. A $6 total subsidy is not valid.

Fee invoicing

Fees collected are netted at the end of each month on your invoice.


Did this page help you?