# FX Quotes
FX quotes let you state a payment price in one currency while the customer is charged, and the merchant settles, in the currency of the merchant account. A quote locks the applicable rate and the resulting settlement amount for a short time.
For example, a KES merchant can price a collection at USD 10.00. After obtaining a quote, submit 10.00 as the request amount together with the quote details; the payment rail receives the locked KES amount.
# Before you start
- The merchant account must be active and must have a local settlement currency.
- An active rate for the pricing/settlement pair must exist in the rate book. The platform uses a corporate rate when available and otherwise uses the system rate. Both direct and inverse pairs are supported.
- Obtain an access token as described in Authentication. Authenticated API requests use the normal developer API authentication and include the merchant code in the body.
- Quotes are short-lived and single-use. Create a fresh quote if it has expired or has already been submitted.
The amount in an FX-enabled payment request is always a JSON number representing the pricing amount. The API calculates and locks the local settlement amount in the quote response. Do not replace the request amount with payable_amount.
# Create an authenticated quote
Use this endpoint before a receive-money/collection request or a send-money/disbursement request.
POST https://api.sandbox.pesaway.com/api/fx/quote/# Request fields
| Field | Required | Description |
|---|---|---|
merchant_code | Yes | Active merchant account number. |
amount | Yes | Positive JSON number in pricing_currency. |
pricing_currency | Yes | Active ISO currency code for the price, for example USD. |
flow | No | collection for receiving money or disbursement for sending money. Defaults to collection. |
payable_currency | No | Must equal the merchant account settlement currency when provided. |
curl --request POST 'https://api.sandbox.pesaway.com/api/fx/quote/' \
--header 'Authorization: Bearer <access-token>' \
--header 'Content-Type: application/json' \
--data '{
"merchant_code": "MERCHANT-001",
"amount": 10.00,
"pricing_currency": "USD",
"flow": "collection"
}'# Successful response
{
"code": "200.001",
"data": {
"quote_id": "c0da3f3a-7a8e-4b7a-9bbf-1e8b4b15c093",
"pricing_currency": "USD",
"pricing_amount": "10.00",
"payable_currency": "KES",
"payable_amount": "1305",
"rate": "130.50000",
"flow": "collection",
"expires_at": "2026-08-04T12:05:00+00:00"
}
}
payable_amount is rounded for the settlement currency. For configured zero-decimal currencies it is a whole unit. Store the returned quote_id, but do not attempt to calculate or alter the returned rate or payable amount.
# Use the quote in a payment request
Pass these fields into the existing receive-money, send-money, bank-payout, direct-collection, internal-transfer, or checkout initiation request:
| Field | Value |
|---|---|
Amount / amount | JSON number: the original pricing amount, exactly matching pricing_amount. |
pricing_currency | The quote's pricing_currency. |
fx_quote_id | The quote's quote_id. |
For a collection, create the quote with flow: "collection". For a payout or internal transfer, create it with flow: "disbursement". The quote must belong to the merchant account used by the payment and its flow, price, currency, and settlement currency must all match.
Example: extend an existing mobile-money collection request with:
{
"Amount": 10.00,
"pricing_currency": "USD",
"fx_quote_id": "c0da3f3a-7a8e-4b7a-9bbf-1e8b4b15c093"
}
The quote is consumed when the transaction is created. It cannot be reused by a retry; obtain another quote for a new payment attempt.
# Checkout quote endpoint
Checkout clients can obtain a collection quote without developer credentials. The checkout configuration response provides an fx_quote_token; submit it to the public checkout quote endpoint:
POST https://api.sandbox.pesaway.com/api/checkout/fx/quote/{
"merchant_code": "MERCHANT-001",
"amount": 10.00,
"pricing_currency": "USD",
"checkout_quote_token": "<token from checkout configuration>"
}
The response has the same data format as the authenticated endpoint. This endpoint always creates a collection quote: it cannot create disbursement quotes. The signed token is short-lived and requests are rate-limited. Never expose authenticated API credentials in a browser application.
Supply the returned fx_quote_id and pricing_currency with the normal checkout initiation request, while retaining the pricing amount as its amount.
# Foreign-priced checkout services
When creating or updating a fixed-price checkout service, use these fields to set a foreign price:
| Field | Required | Description |
|---|---|---|
fixed_amount | Yes | Set to true. |
pricing_currency | Yes | Active price currency, different from the merchant settlement currency. |
pricing_amount | Yes | Positive fixed price in pricing_currency. |
Do not set the local amount at the same time. A service may have either a local fixed amount or a foreign fixed price, never both. A foreign-priced service requires a matching FX quote at checkout; the checkout response exposes its pricing and settlement currencies plus an fx_quote_token for this purpose.
# Limits and validation
- Quotes expire at the timestamp returned in
expires_atand can be consumed only once. - A quote is valid only for the merchant account, flow, pricing amount, pricing currency, and settlement currency for which it was created.
merchant_codeis mandatory when creating a developer FX quote.- Crypto payment rails and scheduled payouts do not support FX quotes.
- Invalid, non-finite, zero, negative, or oversized prices are rejected. A request is also rejected if no active rate exists for the currency pair.
An invalid or unavailable quote returns a 400.020/400.016 response with a message describing the validation failure. A missing merchant account returns 404.001. Treat these responses as non-retriable with the same quote; create a new quote only after correcting the request or refreshing an expired quote.
← Bank Transfer Airtime →