Skip to main content
Grid lets you charge your own fee on the payments your customers send. You set the pricing, Grid collects the fee as part of the transaction, and the proceeds are credited to your platform internal account. Your fee is additive: it sits on top of the fees Grid charges you, and the two are never netted against each other.
Configuring your own fee does not change Grid’s rates — Grid’s variable rate and fixed fee stay exactly as contracted. It can still change the absolute amount Grid collects, because Grid’s variable fee is proportional to the amount being sent. When you lock the receiving amount, adding your fee raises the sending amount needed to deliver it, so the absolute amount Grid takes rises with it.

What you can charge

A platform fee has two components, and you can use either or both: Both are denominated in the sending currency and are charged on the sending side of the payment — your customer bears the fee as part of the transaction rather than you being billed for it separately. Which side absorbs it depends on lockedCurrencySide: lock the sending amount and your fee comes out of what the recipient receives; lock the receiving amount and the recipient still gets that amount, so the sender pays more. Fees are configured per fee type, which identifies the activity being charged:
  • CROSS_CURRENCY_TRANSACTION — a transfer where the sending currency differs from the receiving currency.
Current limits. Platform fees are supported for a USD sending currency only, and the fixed fee must be denominated in that same sending currency — other currencies return NOT_IMPLEMENTED. CROSS_CURRENCY_TRANSACTION is the only fee type you can configure today.Both are expanding: a RAIL fee type (charged for use of a payment rail) and support for stablecoin sending currencies such as USDC are planned. Watch the changelog for when they land rather than assuming today’s limits are permanent.
A fee can only be charged on a transaction if you hold a platform internal account in that transaction’s sending currency — that account is where the fee is credited. As more sending currencies become chargeable, add the matching platform account before you enable a fee for them.

How the amount is calculated

Every fixed fee on the transaction — yours and Grid’s — is subtracted first. The variable rates are then applied together to what remains:
Your share of that total is your own rate’s portion of it. Each component is rounded independently to the smallest currency unit, so your fee and Grid’s are each exact. For a $10.00 USD payment where your fee is 30 bps + $0.50 and Grid charges 100 bps with no fixed fee:
The variable component is charged on the sending amount net of all fixed fees, not on the gross sending amount — so Grid’s fixed fee reduces the base your variable rate applies to, and yours reduces Grid’s.

Configuring your fees

Standing fees

Standing fees apply to every matching transaction until you change them. Set them with PATCH /config:
Set a standing platform fee
feeConfigs is a merge-by-key upsert keyed by (feeType, sourceCurrency):
  • Only the keys you send are touched. Configs you omit are left unchanged.
  • Omitting feeConfigs entirely leaves all your fee configuration unchanged.
  • There is at most one active config per key.
To read your current fees back, call GET /config — the response includes a feeConfigs array with every currently-active config.
Read current fee configuration

Turning a fee off

Set both variableFeeBps and fixedFee.amount to 0 for that key. The config is deactivated and stops applying to new transactions:

Per-transaction overrides

For promotions, negotiated rates, or VIP pricing, you can override your fee on a single transaction by passing platformFeeOverride when you create the quote. The override replaces every platform fee that would otherwise have applied to that transaction — it is not added to your standing fee.
Quote with a discounted platform fee
Both platformFixedFee and platformVariableFeeBps are required inside the override object — pass 0 for a component you want to waive. To waive your fee entirely on a transaction, send 0 for both.
An override applies only to the quote it is sent on. It never changes your standing configuration, and it does not carry over to the next quote.
Overrides are rejected with a 400 INVALID_INPUT when:
  • The quote’s sending currency is not USD.
  • platformFixedFee.currency does not match the quote’s sending currency.
  • Either value is negative, or platformVariableFeeBps is above 10000 (100%).

When fees are assessed

A platform fee moves through three stages:
1

Priced at quote time

When you create a quote, Grid resolves your fee (standing config or override) and prices it into the quote. The amount is returned as platformFeesIncluded and is locked for the lifetime of the quote.
2

Charged when the payment executes

Executing the quote charges the fee as part of the sending amount. Your customer pays it — you are not invoiced for it separately.
3

Credited during settlement

The fee is credited to your platform internal account in the sending currency as one step of the payment’s settlement, not in a single moment at the end. It can land before the transaction reaches COMPLETED.
Because the credit happens partway through settlement, a payment that is refunded after the fee has landed reverses that credit — the fee is pulled back out of your platform account and returned to your customer. You will see the corresponding balance updates in both directions.Treat a fee as earned only once its transaction is COMPLETED. A fee visible in your balance while the payment is still in flight is not final.
Every quote returns platformFeesIncluded, the portion of feesIncluded that you collect. It is 0 when no fee applies. Continuing the worked example above — a $10.00 send with your 30 bps + $0.50 fee and Grid’s 100 bps:
Quote response
platformFeesIncluded is already counted inside feesIncluded — do not add the two together. Subtract it from feesIncluded to get Grid’s portion.
Without a platform internal account in the sending currency, a payment carrying a fee fails rather than silently dropping the fee. See Internal accounts to check that yours exists.Platform fees are also not yet supported on every payment flow. When a quote’s fee cannot be delivered by the flow that would settle it, the quote is rejected at creation rather than at settlement — so you find out before your customer is charged.

Webhooks

Platform fees do not introduce new webhook types. Two existing events carry the information you need: To reconcile fee revenue as it accrues, listen for OUTGOING_PAYMENT.COMPLETED and read platformFees from the payload:
OUTGOING_PAYMENT.COMPLETED
A fee is only earned once the payment completes. A transaction that fails or is refunded generates no revenue — and if the fee had already been credited, the refund reverses it — so reconcile against terminal statuses rather than counting platformFees on every event you receive.
See Webhooks for signature verification and delivery behavior.

Querying transactions and revenue

Per-transaction fees

Every outgoing transaction carries platformFees, the portion of fees that you collected. Fetch a single transaction:
Or list transactions over a date range and sum platformFees across the completed ones:
Results are paginated — follow nextCursor until hasMore is false so your totals cover the whole period. See List transactions for the full set of filters.

Accrued balance

Collected fees accumulate in your platform internal account. Query its balance for the running total credited to you and not yet withdrawn — bearing in mind it includes fees from payments still in flight, which a refund can still reverse:
Your platform account is a single pool, like a bank balance — fee revenue is not held in a separate sub-balance. If you deposit or spend from the same account, derive fee revenue by summing platformFees across transactions rather than reading the balance.

Testing in sandbox

Platform fees work end to end in sandbox, so you can verify your pricing before going live. Money movements are simulated, but fees are calculated and credited exactly as they are in production.
1

Confirm you have a platform account

Call GET /platform/internal-accounts?currency=USD. If no account exists, fees have nowhere to land and payments carrying them will fail.
2

Configure a fee

PATCH /config with a feeConfigs entry, then GET /config to confirm it is active.
3

Fund a customer account

Use POST /sandbox/internal-accounts/{accountId}/fund to add a test balance. See Sandbox testing.
4

Create a quote and check the math

POST /quotes and confirm platformFeesIncluded matches what you expect for the amount you sent. This is the fastest way to validate a fee change — no execution needed.
5

Execute and verify the credit

Execute the quote, wait for the transaction to reach COMPLETED, then re-read your platform account balance. It should have increased by exactly platformFeesIncluded.
Quote-only testing is cheap and repeatable: because the fee is priced at quote creation, you can sweep a range of amounts and compare platformFeesIncluded against your own pricing model without moving any money.
To test an override, add platformFeeOverride to step 4 and confirm platformFeesIncluded reflects the override rather than your standing config.

Next steps