---
title: Processing Fees
slug: processing-fees
docTags: 
createdAt: 2026-08-27T21:02:31.255Z
---

A processing fee is an optional percentage fee your organization charges on payments moving through a Voltage wallet. It is set independently for sends and receives and is currency-agnostic — the same configuration applies to BTC and USD wallets.

Processing fees are **off by default**. Until a rate is set, `processing_fee` is omitted from payment responses, so existing integrations are unaffected.

## See the Demo

If you want to see processing fees applied to live payments, you can view a working example [here](https://voltage-battleleague.netlify.app/). Battle League runs on MutinyNet test sats and charges a 1% (100 basis point) league processing fee on the payments that fund each competitor.

::Image[]{src="https://api.archbee.com/api/optimize/CGGF0VLgJQypTJbZ1FbQy/JuomdeXvHcbyEyUyMKKux_screenshot-2026-08-28-at-24325-pm.png" size="100" isUploading="false" position="center" width="3008" height="1492" darkWidth="3008" darkHeight="1492" showCaption="false" link="{&#x22;externalHref&#x22;:&#x22;https://voltage-battleleague.netlify.app/&#x22;,&#x22;docId&#x22;:&#x22;&#x22;,&#x22;docAnchorId&#x22;:&#x22;&#x22;,&#x22;openInNewTab&#x22;:true,&#x22;noFollow&#x22;:false}"}

[Battle League Demo](https://voltage-battleleague.netlify.app/)

## How rates are expressed

Rates use **basis points** applied to the payment principal.

| `basis_points` | Rate                          |
| -------------- | ----------------------------- |
| `0`            | Disabled for that direction   |
| `100`          | 1%                            |
| `250`          | 2.5%                          |
| `10000`        | 100% (maximum accepted value) |

Your organization may have a lower ceiling than `10000`. If you exceed it, the rate is rejected and the error reports the applicable `max_basis_points`. Contact your Voltage support team to discuss your ceiling.

## Where the rate lives

A processing fee can be configured in two places, and only one of them is yours to set:

- **On the line of credit**, as an organization-wide default. This is not exposed by the wallet policies endpoint and cannot be set through the customer API. Voltage configures it for your account, usually during onboarding.
- **On a wallet**, as a `processing_fee` wallet policy. You set and change this yourself through the API, as described below.

A rate on the line of credit is what turns processing fees on. Until Voltage has defined a rate on your line of credit, no processing fees are charged, and setting a wallet policy on its own will not change that. To start charging processing fees, contact your Voltage support team to have a rate configured on your line of credit.

Once that is in place, a wallet policy **overrides** the line-of-credit rate for that wallet — the two do not stack. A wallet inheriting 250 basis points that is then given a 100 basis point wallet policy is charged 100 basis points on the next payment, not 350. Sending `"processing_fee": null` removes the wallet override and restores the line-of-credit rate.

Because the line-of-credit rate is not returned by the policies endpoint, a wallet with no policy of its own can still charge a rate it inherits. Treat the payment response, not the wallet policy, as the authoritative record of what was charged.

## Who pays the fee

Direction determines where the fee lands:

- **Send** — the processing fee is part of the amount debited from your wallet, alongside the network fee.
- **Receive** — the processing fee is included in the payer-facing amount on the generated invoice, address, or BIP21 URI. The payer funds it, and it sits outside the amount credited to your wallet.

## Viewing current rates

### Endpoint

```text
GET
https://voltageapi.com/v1/organizations/{organization_id}/wallets/{wallet_id}/policies
```

Wallet policies are addressed by organization and wallet. Unlike the Payments endpoints, this route is not environment-scoped.

### Headers

```text
x-api-key: your-api-key
```

### Response

Returns every policy on the wallet. The processing fee policy has type `processing_fee`:

```json
{
  "id": "9f0f8e5c-8a7b-4a3f-9f1e-2b6d4c7a1e55",
  "organization_id": "4b2f1a63-0f9d-4a2e-9d3b-5c8e2a1f7b04",
  "policies": [
    {
      "type": "processing_fee",
      "data": {
        "id": "c1d2e3f4-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
        "rates": {
          "send_basis_points": 100,
          "receive_basis_points": 250
        },
        "created_at": "2026-08-01T12:00:00.000Z",
        "updated_at": "2026-08-20T09:31:44.117Z"
      }
    }
  ],
  "updated_at": "2026-08-20T09:31:44.117Z"
}
```

A wallet with no processing fee configured simply has no `processing_fee` entry in `policies`.

## Setting rates

### Endpoint

```text
PATCH
https://voltageapi.com/v1/organizations/{organization_id}/wallets/{wallet_id}/policies
```

Requires organization **WRITE** access. A successful request returns `202 Accepted`.

### Headers

```text
x-api-key: your-api-key
Content-Type: application/json
```

### Request Body

```json
{
  "processing_fee": {
    "send_basis_points": 100,
    "receive_basis_points": 250
  }
}
```

Both fields are required when you supply a `processing_fee` object.

The field supports three distinct actions:

- **Set an override** — supply exact rates, as above.
- **Restore inheritance** — send `"processing_fee": null` to drop the wallet override and fall back to the line-of-credit configuration.
- **Leave unchanged** — omit the field entirely.

To charge on one direction only, set the other to `0`:

```json
{
  "processing_fee": {
    "send_basis_points": 0,
    "receive_basis_points": 250
  }
}
```

### Example

```bash
curl 'https://voltageapi.com/v1/organizations/{organization_id}/wallets/{wallet_id}/policies' \
  --request PATCH \
  --header 'x-api-key: your-api-key' \
  --header 'Content-Type: application/json' \
  --data '{
    "processing_fee": {
      "send_basis_points": 100,
      "receive_basis_points": 250
    }
  }'
```

The same request body updates other wallet policies alongside the fee, such as `max_payment_size_sats`, `transactions_per_minute`, `send_volume_limit_sats`, and `ofac_compliant`. Any field you omit is left unchanged.

## Reading the fee on a payment

Once a rate is set, send and receive payment responses include a `processing_fee` object and a `payment_breakdown`:

```json
{
  "processing_fee": {
    "basis_points": 100,
    "amount": { "currency": "btc", "amount": 1500, "unit": "msats" }
  },
  "payment_breakdown": {
    "principal":      { "currency": "btc", "amount": 150000, "unit": "msats" },
    "network_fee":    { "currency": "btc", "amount": 1000,   "unit": "msats" },
    "processing_fee": { "currency": "btc", "amount": 1500,   "unit": "msats" }
  }
}
```

- `processing_fee.basis_points` — the exact configured rate applied to this payment.
- `processing_fee.amount` — the server-calculated fee, in the principal's assessment currency. It is available before settlement and stays stable across quote refreshes, and for receives across partial or excess payments.
- `payment_breakdown.processing_fee` — the **authoritative settled fee**. Use this for reconciliation and accounting.

Both fields are omitted when no processing fee applies to the payment.

## Errors

Responses from the wallet policies endpoints:

- `400` – badly formatted request, or no updates provided (`no_updates_provided`)
- `401` – authentication failed
- `403` – organization access required (READ to view, WRITE to update)
- `404` – no wallet found for that id in the organization, or no policies found for the wallet
- `422` – request JSON is invalid
- `500` – server error

Policy validation problems are reported in the `error` field of the wallet policies response, with `type` set to one of:

- `invalid_processing_fee_rates` – a rate is outside the accepted range. The context reports the offending `direction`, the submitted `basis_points`, and the applicable `max_basis_points`.
- `multiple_processing_fee_policies` – more than one processing fee policy resolved for the wallet.
- `policy_not_found` – the referenced policy does not exist.

## Scheduled billing and settlement fees (v6.10.0)

Payment processing fees are separate from contract billing, processing-fee sharing, and settlement fees. The billing features below currently require a USD line of credit and are configured by Voltage. Contact your Voltage support team to discuss the terms for your account; these settings are not wallet policies.

### Processing-fee sharing

A configured share of collected processing fees can be credited to the counterparty on a monthly, quarterly, or annual schedule. Shares use integer basis points (`100` means 1%, up to `10000`), and split credits round down. This scheduled credit is separate from the per-payment processing fee paid by the sender or external payer.

### Contract charges

Contract billing supports a one-time charge or an annual contract value paid in monthly, quarterly, or annual installments. Annual installments are billed in advance. Contract charges and processing-fee sharing can coexist, with schedules separate from the line of credit's regular reconciliation cycle.

### Settlement fees

An optional settlement fee applies to the gross USD ACH payout after holdback, when the regular reconciliation cycle is due. Collections do not reduce the fee base. Processing-fee split credits and other fees are excluded from it.

For example, a $3,000 payout balance with a $1,000 holdback produces a $2,000 ACH payout. At an illustrative 1% settlement rate, a separate ACH debit collects a $20 settlement fee through the Fee bank account. The fee does not reduce the $2,000 principal payout.

Settlement fees round up once to the nearest cent. The configured rate is captured when the bill is initiated, and defaults to zero (disabled). A holdback retains funds; it is not a fee.

Contract and processing-fee-sharing terms are managed through administrator APIs and are omitted from customer line-of-credit responses. Existing volume fees and interest remain separate charges.

## Related Guides

- [Sending](docId\:IjESwowXJHpgYt6FV1KK1)
- [Receiving](docId:-UQ9knquoC9SGq0KuoGMY)
