# Card Fees

[API Documentation](/api/card-program/card-program-fee-object)

A card program can charge its cardholders fees on their card transactions. Column calculates each fee, holds it with
the authorization, charges it when the transaction clears, gives it back when the transaction is reversed or refunded,
and settles the fees your card program earns to its operating account. Fees are available on debit, charge, and credit
card programs. Column enables card fees on your card program, and you then configure the fees it charges.

## Fee Types

| Fee Type ::min | Description                                                                                                                                                                                                                                                                                  |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fx`           | The foreign transaction fee, charged on a transaction made in a currency other than the cardholder's, such as a purchase from a merchant in `EUR` by a cardholder billed in `USD`. It is not charged on refunds, original credits, balance inquiries, account verifications, or adjustments. |

A fee is charged in the cardholder's currency.

## Configuring Fees

Once Column has enabled card fees on your card program, configure each fee type with the
[card program fee endpoints](/api/card-program/card-program-fee-object):

- [Set a fee](/api/card-program/set-card-program-fee) with `PUT /issuing/card-programs/{card_program_id}/fees/{fee_type}`.
  The request replaces the fee's whole configuration, so fields you leave out return to their defaults. The fee's
  `currency_code` must be the card program's currency, and an `fx` fee's `bps` can be at most `500` (5%).
- [List the fees](/api/card-program/list-card-program-fees) a card program charges, enabled or not, with
  `GET /issuing/card-programs/{card_program_id}/fees`.
- [Delete a fee](/api/card-program/delete-card-program-fee) to stop charging it. To pause a fee and keep its
  configuration, set it with `enabled` set to `false` instead.

```bash
curl https://api.column.com/issuing/card-programs/<card_program_id>/fees/fx \
  -XPUT \
  -H 'Content-Type: application/json' \
  -u :<YOUR API KEY> \
  -d '{
    "currency_code": "USD",
    "bps": 300,
    "min_amount": 50,
    "refund_on_merchant_refund": true
  }'
```

Setting a fee before Column has enabled card fees on the card program returns a `409`. A change applies from the next
event Column calculates a fee for, including the next event on an authorization made before the change, such as an
incremental authorization or its clearing. Fees already charged keep how they were calculated.

## Calculating a Fee

Each fee is configured with a fixed amount, a percentage of the transaction amount in basis points, or both, and
optionally a minimum and maximum. Column calculates the fee on the amount billed to the cardholder (the base amount):

1. It takes the basis points of the base amount, rounded to the smallest unit of the currency, half to even.
2. It adds the fixed amount.
3. It raises the result to the minimum and lowers it to the maximum, when they are set.

For example, a 3% (300 bps) foreign transaction fee on a `USD` 37.50 purchase is `USD` 1.12 (1.125, rounded half to
even). With a fee of `USD` 0.50 plus 1% (100 bps), a minimum of `USD` 1.00, and a maximum of `USD` 2.50:

| Base Amount ::min | Fee ::min  | Why                               |
| ----------------- | ---------- | --------------------------------- |
| `USD` 10.00       | `USD` 1.00 | 0.50 + 0.10 is below the minimum. |
| `USD` 100.00      | `USD` 1.50 | 0.50 + 1.00.                      |
| `USD` 300.00      | `USD` 2.50 | 0.50 + 3.00 is above the maximum. |

Each charge records how it was calculated in its `calculation`: the `base_amount` it was charged on, and the
`fixed_amount`, `bps`, `min_amount`, and `max_amount` the card program charged.

## Fee Lifecycle

### Authorization

When Column approves an authorization that charges a fee, it holds the fee from the cardholder's available balance
together with the authorization. The fee held always matches the fee on what the authorization still holds, so it grows
with an incremental authorization and shrinks or is released on a reversal or when the authorization expires. A held
fee is not yet a card fee: it isn't listed in the transaction's `card_fees`.

The cardholder's available balance must cover the authorization and its fees, so a purchase the balance covers only
without its fee is declined with `insufficient_funds`. On a charge or credit card program, the available balance is the
loan's available credit, which on a secured program is also limited by the collateral available to secure it. Your [real-time decisioning](/card-issuing/card-real-time-decisioning)
endpoint receives the fees an authorization holds in `card_fees`, and Column includes them in
[partial approvals](/card-issuing/card-real-time-decisioning#partial-approvals) and in what it moves for
[just-in-time funding](/card-issuing/card-real-time-decisioning#just-in-time-funding).

### Clearing

When the transaction clears, Column releases the held fee and charges the fee on the amount that cleared, as a card fee
of kind `charge`. A clearing for more than was authorized is charged the fee on the full amount it cleared, and a
full-financial transaction, which has no authorization, is charged when it posts. Like a force post, a fee is charged
even when it overdraws the cardholder's account or, on a charge or credit card program, takes the loan past its maximum
principal balance.

### Reversals and Refunds

- **Reversal before the fee settles:** If the clearing is reversed in full before the charge settles, the charge is
  `released` and the cardholder is credited back.
- **Other reversals:** A partial reversal, or a reversal after the charge settled, gives the fee back as a card fee of
  kind `refund`, in proportion to the amount credited back, with `reversed_card_fee_id` set to the charge it refunds.
- **Merchant refunds:** A merchant refund linked to the original purchase gives back the purchase's fee in the same
  way, when your card program refunds fees on merchant refunds. A refund that isn't linked to the original purchase
  doesn't give back a fee.
- **Reversed refunds:** If the credit of a refund is reversed after it was applied, the fee it gave back is charged
  again, as a card fee of kind `charge` with `reversed_card_fee_id` set to the refund it takes back.

## Card Fees on Card Transactions

Each fee charged on a card transaction, or refunded to the cardholder, is listed in the transaction's `card_fees`
array. There are no separate card fee webhooks: a fee appears in the `card_transaction` of the webhook for the event
that charged or refunded it, which is its `card_transaction_event_id`.

```json
"card_fees": [
  {
    "id": "cfee_3Li2lqLEESt7SNdzyK172vnoBrg",
    "card_transaction_event_id": "ctxe_3Li2lt5HZoXlniu0ERHbjrXXh2p",
    "fee_type": "fx",
    "kind": "charge",
    "status": "pending",
    "currency_code": "USD",
    "amount": 132,
    "reversed_card_fee_id": null,
    "calculation": {
      "base_amount": 4400,
      "bps": 300,
      "fixed_amount": 0,
      "min_amount": null,
      "max_amount": null
    },
    "created_at": "2026-11-05T23:52:06Z"
  }
]
```

| Status ::min | Description                                                                                        |
| ------------ | -------------------------------------------------------------------------------------------------- |
| `pending`    | The fee has debited or credited the cardholder but has not yet been settled with the card program. |
| `settled`    | The fee has been settled with the card program's operating account.                                |
| `released`   | The charge was reversed in full before it settled, and the cardholder was credited back.           |

> **Note**
>
> Card fees are never included in a transaction's `total_amounts` or in an event's `amounts`, which describe only the
> purchase. To find everything a transaction cost the cardholder, add its `charge` card fees to its settled amount and
> subtract its `refund` card fees.

## Balances, Activity, and Statements

### Debit Card Programs

A fee moves the cardholder's bank account like the transaction it belongs to: a held fee lowers the available balance
and is part of the holding balance until it is charged or released, and a charge or refund debits or credits the
available balance. Fees are separate lines from their purchase, with the type `Card Fee` and the merchant's name:

- Each charge and refund is a line on the bank account's activity and statements, described as a foreign transaction
  fee, with the card fee's ID as its `transaction_id`.
- Each fee hold, and each release of one, is a line on the bank account's activity, with the card transaction event that
  moved it as its `transaction_id`.

### Charge and Credit Card Programs

A fee moves the card account's loan like the purchase it belongs to. A held fee is part of the loan's `principal_holding`
and lowers its available credit until it is charged or released. A charge adds the fee to the loan's
`principal_outstanding`, where it is treated like the rest of the principal, including any interest the loan accrues,
and a refund takes it off. On a secured program, the fee locks collateral along with the purchase.

## Settlement

Card fees settle with your card program when its network settlements complete. Each completed settlement settles the
pending fees on the transactions it settled, along with fees that aren't tied to a network clearing, as one
administrative transfer of their net amount to your card program's operating account, or from it when refunds exceed
charges. Fees on transactions whose clearing hasn't settled yet wait for a later settlement.

The [admin transfer](/api/admin-transfer/admin-transfer-object)'s `details_type` is `card_fee_sweep`, and its `details`
list what it settled:

| Field ::min                          | Description                                              |
| ------------------------------------ | -------------------------------------------------------- |
| `card_program_id`                    | The card program the fees were charged on.               |
| `card_program_network_settlement_id` | The network settlement the fees settled with.            |
| `sweep_date`                         | The date the fees were settled.                          |
| `currency`                           | The currency of the fees.                                |
| `charge_count`, `charge_amount`      | The number and total amount of charges settled.          |
| `refund_count`, `refund_amount`      | The number and total amount of refunds settled.          |
| `net_amount`                         | The charges minus the refunds, which the transfer moves. |
| `fee_types`                          | The same counts and amounts for each fee type.           |

Once settled, a card fee's `status` is `settled`.

## Testing in Sandbox

The [simulation endpoints](/card-issuing/card-sandbox-simulation) hold, charge, and give back fees like live
transactions on a sandbox card program that charges them. Ask Column to enable card fees on your sandbox card program,
[set a fee](/api/card-program/set-card-program-fee), then:

1. Simulate an authorization with a `merchant_currency` other than `USD` and a `cardholder_fx_rate`, and check that the
   card account's available balance drops by the amount and its fee.
2. Capture it, and check that the transaction lists the `charge` in `card_fees` and that the bank account's activity
   has a `Card Fee` line.
3. Reverse or refund it to see the fee released or refunded. Sandbox refunds credit the cardholder, and give back their
   fee, when the simulated network settlement runs each day.
