Multicurrency
Charge every customer in their own currency with the same integration — currency is just a field. The distinction that matters is presentment vs. settlement: what the customer pays in, and what lands in your bank. Conversion, when you want it, happens at settlement — never mid-payment.
Presentment vs. settlement currency
| Presentment currency | Settlement currency | |
|---|---|---|
| What it is | The currency the customer is charged in — the payment's currency. | The currency your payout arrives in. |
| Who picks it | You, per payment — usually the customer's local currency. | Your account configuration — by default, same as presentment (one payout per currency). |
| Where it lives | payment.currency, and every derived amount on the payment. | settlement_report.currency and payout.currency. |
| When conversion happens | Never — the customer always pays exactly amount. | At settlement, only if you consolidate currencies. Every conversion is itemized on the report. |
Charging in the local currency isn't cosmetic: issuers approve domestic-looking transactions more readily, local methods are currency-bound anyway, and the customer sees a price they recognize instead of a converted surprise on their statement.
How the currencies flow
Charging in another currency
Same call, different currency — here a Polish customer paying by BLIK. Remember minor units follow the currency's ISO 4217 exponent (see Amounts & minor units for the zero- and three-decimal cases):
curl https://api.finscale.dev/v1/payments \
-H "Authorization: Bearer sk_test_51FinscaleDemo…" \
-H "Idempotency-Key: idem_ord_9f21_0716_pl" \
-H "Content-Type: application/json" \
-d '{
"amount": 8900,
"currency": "PLN",
"payment_method": "blik",
"reference": "ord_9f21_0716",
"return_url": "https://shop.example.com/checkout/return"
}'
# 8900 = 89.00 PLN — the customer pays exactly this, no conversion
The currency value does three things at once:
- Filters methods. Methods are currency-bound:
blikis PLN-only,pixis BRL-only,swishis SEK-only. The method catalog lists each method's currencies — offering a method the currency doesn't support fails validation. - Filters providers. Currency is a hard filter in the routing decision; only providers licensed and enabled for the corridor are candidates.
- Buckets settlement. Every captured payment lands in its currency's balance, settles on that currency's reports, and pays out on that currency's schedule.
FX at settlement
By default there is no FX anywhere: EUR payments arrive as a EUR payout, PLN as PLN, BRL as BRL — one payout per currency, each backed by its own settlement report. If you'd rather not hold accounts in every currency, configure a single payout currency and Finscale converts at settlement time:
- Conversion happens once, when the settlement report is assembled — never at authorization. The customer's charge and any refund stay in the presentment currency.
- The rate is the rate at settlement. Between capture and settlement, the value rides in the presentment currency. Price in the currency you'll settle in if you want to eliminate that exposure — or keep per-currency payouts.
- Every conversion is itemized on the settlement report: source amount, converted amount, and the rate applied per line. Your reconciliation stays integer-exact in both currencies.
- Refunds convert back at the refund's settlement date — so a refund in a moved market may not net to the same settled amount as the original. The report shows both legs.
amount, amount_captured, amount_refunded — is in the payment's currency. Every amount on a settlement report or payout is in the report's currency. Cross-currency arithmetic on your side is a bug; the report's itemized conversions are the join.
Webhook events
Nothing multicurrency-specific — the standard lifecycle events fire with the payment's presentment currency in the payload, and settlement.report.ready fires per report (so, per currency and provider). Consume the currency field rather than assuming one.
Error scenarios
| Scenario | Response |
|---|---|
Method not available in the currency (pix + EUR) | 400 invalid_request_error, code parameter_invalid — check the catalog before offering the method. |
| Currency not enabled on your account | 400 invalid_request_error — your account configuration lists enabled currencies; ask your Finscale representative to add corridors. |
Wrong minor-unit exponent (charging ¥49.00 as 4900 JPY when you meant ¥4,900… or vice versa) | Accepted — it's a valid integer. This is the classic multicurrency bug: validate exponents against ISO 4217 in your own code. |
| Amount as a float or a string | 400 invalid_request_error — amounts are integers in minor units, always. |
Related
- Amounts & minor units — zero- and three-decimal currencies.
- Settlement & payouts — report structure and payout schedules.
- Balance — available vs. pending, per currency.
- Payment methods — which methods exist per currency and region.