# Fee subsidization

Cover onramp fees and let Stripe bill you instead.

Fee subsidization lets you cover onramp transaction fees. When enabled for a session, the user pays no network or transaction fees, so their total charge is only the source amount. Stripe bills you for those fees instead, through your existing Stripe billing relationship.

Fee subsidization is currently a binary feature: a session’s fees are either fully subsidized or not at all. There’s no partial subsidy.

Fee subsidization is only available for users in the US. Contact your Stripe account team to confirm availability for your use case.

## Before you begin

Before you can subsidize fees, you need:

- **Access to fee subsidization**: Fee subsidization isn’t enabled for every account. Contact your Stripe account team to request access.
- **Embedded components**: Fee subsidization is currently only supported for [embedded components onramp sessions](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md) (`ui_mode: headless`). Sessions created with any other UI mode can’t use `fee_responsibility: merchant`.
- **No revenue share**: Fee subsidization and revenue share are mutually exclusive. If your account has an active revenue share agreement with a non-zero partner fee, we reject requests with `fee_responsibility: merchant` until the fee is removed or the configuration is zeroed out.

## Enable fee subsidization for a session

Pass `fee_responsibility` when you create a crypto onramp session or fetch a quote. Setting it to `merchant` requires `ui_mode=headless`—without it, the request fails with a 400 and `error.code` set to `crypto_onramp_fee_subsidy_unavailable`, even if the session itself uses embedded components. Check `error.message` for the specific cause. `fee_responsibility` is a preview-only parameter: use a [private preview SDK](https://docs.stripe.com/sdks/versioning.md#private-preview-release-channel), or include a [preview API version](https://docs.stripe.com/release-phases.md) in the `Stripe-Version` header if you’re calling the API directly—requests on a general availability version don’t recognize it.

#### curl

```shell
curl https://api.stripe.com/v1/crypto/onramp_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -H "Stripe-Version: 2026-09-30.preview;crypto_onramp_beta=v2" \
  -H "Stripe-OAuth-Token: $ACCESS_TOKEN" \
  -d ui_mode=headless \
  -d fee_responsibility=merchant \
  ...
```

The same two parameters apply to a quote request:

#### curl

```shell
curl -G https://api.stripe.com/v1/crypto/onramp_quotes \
  -u <<YOUR_SECRET_KEY>>: \
  -H "Stripe-Version: 2026-09-30.preview;crypto_onramp_beta=v2" \
  -d ui_mode=headless \
  -d fee_responsibility=merchant \
  ...
```

`fee_responsibility` accepts:

| Value | Description |
| --- | --- |
| `consumer` (default) | The user pays the transaction fees. |
| `merchant` | You pay all transaction fees on behalf of the user. |

### Verify it in a sandbox

Create an embedded components sandbox session with `fee_responsibility: merchant` and fetch a quote. Confirm that:

- The quote’s `source_total_amount` equals the pre-fee source amount (no fee added for the user).
- The quote’s `fees.subsidy` object is present. See [Reconciling subsidized fees](https://docs.stripe.com/crypto/onramp/fee-subsidization.md#reconciling-subsidized-fees).

## How billing works

When you subsidize a session’s fees, Stripe doesn’t waive those fees. Instead, it bills you for them rather than collecting them from the user. Stripe aggregates subsidized fees across your subsidized sessions and invoices you asynchronously. Charges don’t appear against an individual session in real time. Refer to your Dashboard’s billing and invoices for the itemized charges after they’re issued.

If a subsidized session is later refunded, Stripe automatically reverses the corresponding billed amount—you’re not billed for fees on refunded transactions.

Subsidized fees are billed through your standard Stripe invoicing relationship and follow the normal Stripe invoice collection process if your account doesn’t have enough balance. There’s no onramp-specific handling.

## Reconciling subsidized fees

Both the quote response and session retrieval include a `subsidy` object when a quote’s fees become available and `fee_responsibility` is `merchant`. The `subsidy` object is omitted entirely when `fee_responsibility` isn’t `merchant`, and it’s also absent early in a session’s lifecycle, before a quote with fees has been selected.

Quote response—each individual quote is nested under `destination_network_quotes.<network>[]`:

```json
{
  "destination_network_quotes": {
    "ethereum": [
      {
        "fees": {
          "network_fee_monetary": "1.25",
          "transaction_fee_monetary": "0.50",
          "subsidy": {
            "original_fee": "1.75",
            "total_fee_after_subsidization": "0.00"
          }
        }
      }
    ]
  }
}
```

Retrieved session:

```json
{
  "transaction_details": {
    "fees": {
      "network_fee_amount": "1.25",
      "transaction_fee_amount": "0.50",
      "subsidy": {
        "original_fee": "1.75",
        "total_fee_after_subsidization": "0.00"
      }
    }
  }
}
```

- `original_fee`: the total fee (network fee plus transaction fee) before subsidization.
- `total_fee_after_subsidization`: the fee actually charged to the user. Currently, this is always `0.00`.

The `original_fee` for the quote response  is only an estimate for that network and amount, and it isn’t billable until a session completes with those terms. Use the `original_fee` from the completed session (not from a quote) to reconcile against the charges on your Stripe invoice.
