> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.crisscross.money/api-reference/collect/per-session/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.crisscross.money/_mcp/server. # Per Session > How Adaptive Currency Conversion prices a checkout with a per-session rate — no endpoint to call, the quote is minted at session creation and returned as fxCommit. The per-session rate is the default way [Adaptive Currency Conversion](/adaptive-currency-conversion) prices a conversion — the alternative to a pre-fetched [rate lock](/rate-locks). There is **no endpoint to call and no field to set**: when a session needs a conversion and no `rateLockId` is supplied, an implicit FX quote is minted at session creation, valid for minutes, and refreshed automatically on the hosted page if it expires. ## When it applies A per-session rate prices the session when, at [Create Checkout Session](/api-reference/collect/payments/payment-initiation/create-checkout-session): 1. The session `currency` (the currency you price in) differs from the payer's `collectionCurrency` — or from the primary currency of `payerDetails.location` when `collectionCurrency` is omitted, and 2. no `rateLockId` is supplied. If a `rateLockId` is supplied, the session is priced by the [rate lock](/rate-locks) instead. If no conversion is needed, the payer is simply charged in the initiation currency and no FX commit is written. ## Reading the rate back The committed conversion is returned inline on [Get Checkout Session](/api-reference/collect/payments/payment-initiation/get-checkout-session) as `fxCommit`. For a per-session rate, `pricingModel` is `SPOT_QUOTE` and `quoteId` is the upstream quote identifier, preserved for audit: ```json { "session": { "id": "01951c8a-7c3d-7e1f-9d4a-2b3c4d5e6f70", "merchantId": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "merchantReference": "ORDER-20260624-001", "amount": 10000, "currencyId": "USD", "expiresAt": "2026-06-24T11:00:00Z", "customerId": "9b2d7f3a-8c4e-4f1a-9d3e-1a2b3c4d5e6f", "payerLocation": "KEN", "redirectUrl": "https://merchant.example.com/order/confirmation", "paymentAttributes": { "paymentMethod": "card", "platform": "web" }, "fxCommit": { "quoteId": "qut_01951c8a-9d5e-7f3b-bc4f-6e7d8c9b0a21", "pricingModel": "SPOT_QUOTE", "collectionCurrency": "KES", "collectionAmount": "13260.00", "midRate": "130.00", "markupBps": 200, "allInRate": "132.60", "fee": "260.00", "expiresAt": "2026-06-24T10:35:00Z" } } } ``` Compare with a rate-locked session, where `pricingModel` is `RATE_LOCK` and `quoteId` is the `rlk_` rate lock id — see the response examples on [Get Checkout Session](/api-reference/collect/payments/payment-initiation/get-checkout-session). ## Expiry and refresh A per-session quote is valid for **minutes, not hours** — note `fxCommit.expiresAt` above versus the session's own `expiresAt`: * **On the hosted checkout page** — the rate refreshes automatically in place when the quote expires; the payer proceeds at the refreshed rate with no merchant action needed. * **At payment initiation** — a payment submitted against an expired `fxCommit` is rejected with `422` (stale quote). Refresh the session and re-submit against the current rate. This is the safety net for direct-API integrations. The expiry check runs when the payment is **initiated**, and this is the same for both flows. A payment initiated inside the validity window settles at the rate snapshotted onto the transaction, even if the quote expires while the payment is still being authorized — expiry never fails an in-flight payment, for a per-session rate or a rate lock alike. Because of the refresh, `fxCommit` on the session reflects the *latest* committed conversion. The rate a payer actually transacted at is snapshotted per-attempt on the [transaction](/api-reference/collect/payments/manage-payments/get-transaction) (`collection`, `fxMidRate`, `fxAllInRate`, `fxMarkupBps`) — immutable once written, and authoritative for reconciliation. ## When to use a rate lock instead Use the per-session rate when you just need the payer's currency converted at the moment of purchase. If you want one rate to hold across many checkouts — steady-state pricing, valid for hours and reusable until expiry — fetch a [rate lock](/rate-locks) and pass its `rateLockId` at session creation. > The default ACC pricing — an implicit FX quote minted at session creation