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, plus its fixed fee, feeFixed.GET /v1/channels, on the source rail
Destination-channel feeThe outbound rail's variable fee, feeBps, 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, 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 quote, estimate, or virtual-account 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) = fxMarkup + source rail feeBps + destination rail feeBps + applicationFeeBps
Total fixed fee          = source rail feeFixed + 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.

Where to set an application fee

Set an application fee on the quote, on a transfer estimate, or on a virtual account.

On a quote or an estimate, add the fields inside the source or destination object, not at the top level of the request body. A fee placed at the top level is ignored silently.

{
  "source": {
    "rail": "sepa",
    "currency": "EUR",
    "amount": "200",
    "applicationFeeAmount": 1
  },
  "destination": {
    "rail": "base-sepolia",
    "currency": "USDC"
  }
}

Three constraints apply:

  • One side only: Set the fee on either source or destination, never both. Setting both returns err_quote_application_fee_one_side_only.
  • Platforms only: Application fees are available to platform accounts. Other accounts receive err_quote_application_fee_outside_platform.
  • Subsidies cannot exceed Due's fee: A negative application fee may offset Due's fee in full but not beyond it. An excess subsidy returns err_quote_application_fee_exceeds_internal_fee.

You do not need to pass the fee again when creating the transfer. The quote response includes a signed token that carries the application fee, and the transfer created from that token applies it.

Reading a fee response

Each side of a quote or estimate returns three fee fields.

FieldMeaning
feeThe Due channel fee for that rail, in that side's currency.
applicationFeeYour application fee, in that side's currency. Returned only on the side where you set it.
totalFeeThe sum of fee and applicationFee for that side, in that side's currency.

Handle these response behaviours:

  • Missing application fee: applicationFee is omitted when there is none; it is not returned as "0". Treat a missing field as zero.
  • Restated opposite leg: On a conversion, the destination fee and totalFee restate the source figures in the destination currency. They do not add new fees, so never add the two legs together. Count each fee once.

The FX markup is not a fee field. It is contained in fxRate and disclosed separately as fxMarkup in basis points.

Application fees: markup and subsidy

Use applicationFeeBps and applicationFeeAmount to add your own markup to Due’s fees, or to subsidise them in full or in part, including the FX markup.

  • Add a markup: Use positive values. They stack on top of Due’s fees.
  • Subsidise: Use negative values. They reduce or fully cover Due’s fees.

A subsidy can cover Due’s fee in full but never exceed it. How this is validated depends on where you set the application fee.

Virtual accounts

The variable and fixed parts are validated separately.

Variable fee. The combined variable fee can’t be negative:

fxMarkup + source rail feeBps + destination rail feeBps + applicationFeeBps >= 0

A negative applicationFeeBps can offset Due’s variable fees in full, as long as the combined variable fee is at least 0.

Fixed fee. A negative applicationFeeAmount can offset the source rail’s feeFixed in full but not exceed it. Against a feeFixed of 1.50, applicationFeeAmount: -1.50 is valid and -1.51 is rejected.

Transfer quotes

The total subsidy, combining applicationFeeAmount and the amount implied by applicationFeeBps, can’t be greater than Due’s fee on that transfer. If Due’s fee is $5, a total subsidy of $3 or $5 is valid. A total subsidy of $6 is rejected with err_quote_application_fee_exceeds_internal_fee.

Which side to set the fee on

Set the application fee on the side whose fee you want to offset:

  • Pay-in fees are charged on source, in the source currency.
  • Payout fees are charged on destination, in the payout currency. For example, an ACH payout’s fixed fee is in USD on the destination leg.

A subsidy on the same side as the fee offsets it exactly. A subsidy on the other side is converted at the quote’s rate and may not match the fee.

Subsidising fees in full

To cover fees in full without hardcoding values:

  1. Read feeBps and feeFixed for each rail from GET /v1/channels. It returns your platform’s own rates.
  2. Set applicationFeeBps and applicationFeeAmount to the negatives of those values.
  3. To also cover the FX markup, add the quote’s fxMarkup to the negative applicationFeeBps.

Your application fees then follow your rates automatically if they change.

Example: an ACH rail at 20 bps + USD 1.50, with no FX markup

FlowWhere to set itValues
Pay-in to a virtual accountThe virtual accountapplicationFeeBps: -20, applicationFeeAmount: -1.50
Payout (USDC → USD ACH)destination on the quoteapplicationFeeBps: -20, applicationFeeAmount: -1.50

The end user receives the full amount, and the subsidised fees are billed to you (see Fee invoicing).

Worked examples

1. Find the source-channel fee from the rail

This ACH rail accepts USD deposits with feeBps of 20. Its feeFixed of 1.5 is a separate fixed fee 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, the source rail's feeBps is 20 and its fixed fee is $1.50.

2. Calculate the combined variable fee for a virtual account

With fxMarkup = 10, source rail feeBps = 20, destination rail feeBps = 5, and applicationFeeBps = -10:

fxMarkup:                 10 bps
Source rail feeBps:       20 bps
Destination rail feeBps:   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:

  • The source rail's feeBps is 0; its feeFixed is €0.90, shown as source.fee.
  • fxMarkup is 20 bps. It is included in fxRate and disclosed separately, not as a line-item amount.
  • The destination rail's feeBps is 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.
  • No application fee was set, so applicationFee is omitted.
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. Quote with an application fee

Send a quote request with applicationFeeAmount inside one side of the request. This example adds a €1.00 application fee to the source side.

POST /v1/transfers/quote

{
  "source": {
    "rail": "sepa",
    "currency": "EUR",
    "amount": "200",
    "applicationFeeAmount": 1
  },
  "destination": {
    "rail": "base",
    "currency": "USDC"
  }
}

The response returns the channel fee, application fee, and total fee on the source. The destination restates the channel and total fees in USDC.

{
  "source": {
    "rail": "sepa",
    "currency": "EUR",
    "amount": "200",
    "fee": "0.9",
    "applicationFee": "1",
    "totalFee": "1.9"
  },
  "destination": {
    "rail": "base",
    "currency": "USDC",
    "amount": "226.82637",
    "fee": "1.030509",
    "totalFee": "2.175518"
  },
  "fxRate": 0.8733552440400001,
  "fxMarkup": 20,
  "token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."
}

Reconcile the response line by line:

Source channel fee (SEPA feeFixed)      0.90 EUR
Application fee (yours)                 1.00 EUR
                                        --------
source.totalFee                         1.90 EUR

200.00 - 1.90                       =  198.10 EUR   net amount converted
198.10 / 0.8733552440400001         =  226.82637    = destination.amount

0.90 / 0.8733552440400001           =    1.030509   = destination.fee (restated)
1.90 / 0.8733552440400001           =    2.175518   = destination.totalFee (restated)

Both fees are deducted from the source before conversion. The destination figures are the same two fees expressed in USDC, not additional charges. Base is a free on-chain rail, so it adds no fee of its own. The 20 bps FX markup is already inside fxRate.

5. Combine a BPS and fixed application fee

applicationFeeBps and applicationFeeAmount are independent components and combine. Neither overrides the other, and both are optional.

POST /v1/transfers/quote

{
  "source": {
    "rail": "tron",
    "currency": "USDT",
    "amount": "100",
    "channelType": "static_deposit",
    "applicationFeeBps": 7,
    "applicationFeeAmount": 1
  },
  "destination": {
    "rail": "mena_local",
    "currency": "AED"
  }
}
{
  "source": {
    "rail": "tron",
    "currency": "USDT",
    "amount": "100",
    "fee": "0",
    "applicationFee": "1.07",
    "totalFee": "1.07"
  },
  "destination": {
    "rail": "mena_local",
    "currency": "AED",
    "amount": "361.87",
    "fee": "0",
    "totalFee": "3.92"
  },
  "fxRate": 0.2733832539142274,
  "fxMarkup": 40
}
7 bps of 100 USDT     = 0.07
applicationFeeAmount  = 1.00
                        ------
applicationFee        = 1.07 USDT

6. Subsidise Due fees

Use negative values to offset Due's markup.

  • Virtual account: If fxMarkup + source rail feeBps + destination rail feeBps = 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

Application fees are settled at the end of each month on your invoice:

  • Markups you add are credited to you.
  • Subsidies are billed to you as a separate line.

For questions about your invoice or the commercial terms of your agreement, contact your account manager.


Did this page help you?