With CryptoLike you can price an order in US dollars, euros, hryvnias, pounds or Canadian dollars and still be paid in Bitcoin, USDT or another asset. You create the payment with currency: "USD"; as soon as the asset is known, the exchange rate is locked and the exact crypto amount is fixed until the payment's deadline. The payer sends that amount, and the payment is paid when it is confirmed. This article explains when the lock happens, what the amount is made of and what happens when the payer is late.
How a fiat price becomes a crypto amount
CryptoLike converts a fiat price into crypto once, at the moment the asset of the payment is known, and never again for that payment. The conversion takes the current market rate, adds no spread and rounds the result up to the smallest unit of the asset, so the payer never sends less than the price.
| Step | What happens | Where you see it |
|---|---|---|
| 1. You create the payment | amount: "49.90", currency: "USD" |
amount, currency in the response |
| 2. The asset becomes known | At creation with coin_id, or when the payer picks an asset on the payment page |
coin_id, ticker, network |
| 3. The rate is locked | The latest market quote, at most 5 minutes old | rate_locked, rate_locked_at |
| 4. The amount is fixed | Price ÷ rate, rounded up to the asset's decimals; no spread | amount_crypto; payer_amount if the payer bears the fee |
| 5. The lock holds | Until the deadline of the payment | ttl_expires_at |
Checked against the CryptoLike API on 2026-10-09. The fiat amount and currency stay on the payment as amount_fiat and fiat_currency, so your records show both prices.
When exactly is the rate locked?
CryptoLike locks the rate at the moment the asset is known, and there are two such moments. If you pass coin_id when creating the payment, the lock happens in that same request and the response already contains the address and the exact amount. If you leave coin_id out, the payer chooses the asset on the payment page — from the coins you offer for invoices, or only from those you list in allowed_coin_ids — and the lock happens at that click.
Leaving the choice to the payer is the usual option for shops: the customer pays in what they hold. The choice can be made once, while the payment is new and before its deadline. Until then, coin_id, address, amount_crypto and rate_locked are null. The page shows the fiat price and, next to each coin, an approximate amount marked ≈, calculated the same way as the lock would be at that moment. It is not a lock: the choice prices the payment again, so the locked amount can differ slightly from the estimate the payer saw.
rate_locked_at is the time of the market quote, not the time of the click. Quotes are refreshed regularly, and CryptoLike uses a quote only if it is at most 5 minutes old, so rate_locked_at can be up to a few minutes earlier than the lock itself.
How long does the locked rate hold?
The locked rate holds until ttl_expires_at, the deadline of the payment; there is no separate lock timer. You set the deadline per payment with ttl_seconds, from 60 seconds to 30 days. Without it, your account's default applies — 30 minutes unless it was changed. The payment page shows the payer "Rate locked for N min: 1 BTC = … USD" next to the amount.
A longer deadline is convenient for a B2B bill that is paid the next day; a shorter one limits how far the market can move while the amount is fixed. For volatile assets such as Bitcoin, keep the deadline close to the time a payer needs, plus the time for confirmations. For bills with long payment terms, price them in a stablecoin instead.
Is there a conversion spread?
No. A conversion spread is a margin added to the market rate when a fiat price is converted into crypto. CryptoLike adds none: amount_crypto is the price divided by rate_locked, the market quote, rounded up to the smallest unit of the asset. The rounding is at most one unit, for example 0.00000001 BTC, and it is in your favour.
Without a spread, the market movement while the amount is locked stays with you: the rate is fixed for up to the whole deadline, while the asset's price keeps moving. Keep the deadline short for volatile assets, or price in a stablecoin. A payment priced in the asset itself — currency: "USDT" or "BTC" — has nothing to convert: amount_crypto equals your amount, and rate_locked stays null. The platform fee is the only CryptoLike charge on a fiat-priced payment; how the fees add up is explained in crypto payment fees explained, and the current schedule is on the pricing page.
Which fiat currencies can you price in?
CryptoLike prices payments in five fiat currencies, and all five are enabled for every account by default: USD, EUR, UAH, GBP and CAD. currency also takes a coin ticker, and then nothing is converted.
| Code | Currency | Decimals in amount |
|---|---|---|
| USD | US dollar | 2 |
| EUR | Euro | 2 |
| UAH | Ukrainian hryvnia | 2 |
| GBP | Pound sterling | 2 |
| CAD | Canadian dollar | 2 |
An amount with more decimals than the currency allows, such as 10.005 in GBP, answers 400 validation_error. GET /v1/fiat-currencies returns the list for your account: each code with its decimals and invoice_enabled, which tells whether you can create a payment in it. Checked against the CryptoLike API on 2026-10-11.
When two sources quote a pair, CryptoLike compares them on every rate refresh. If they disagree by more than a set limit, the pair is not updated, and a payment in that currency for that coin answers 503 unavailable until the sources agree again: CryptoLike refuses rather than guesses. Need another currency? Write to support: a currency is added only when two independent sources quote its rate.
What happens if no fresh rate is available?
CryptoLike never locks a stale rate. If the latest quote for the asset is older than 5 minutes, or the rate sources disagree on the pair, creating a fiat-priced payment with coin_id answers 503 unavailable with the message "exchange rate unavailable right now; retry later or create the invoice in crypto", and the payer's asset choice on the payment page answers 503 with "exchange rate unavailable, try again shortly". Before the choice, such a coin shows "Rate updating" instead of an estimate and can still be picked. Nothing is created with an outdated price.
What to do in your integration:
- Retry with backoff. Rates recover without any action on your side; send the same request with the same
Idempotency-Key. - Fall back to crypto pricing if the order cannot wait: convert the price yourself and create the payment in the asset, or in USDT.
- Leave the choice to the payer when you do not need a specific asset: create the payment without
coin_id, and the lock happens later, on the payment page, where the payer can retry the choice.
GET /v1/rates?fiat=USD returns the current quotes with rate, at and a stale flag, so you can check them before showing a crypto price anywhere else in your product.
What if the payer sends the wrong amount or pays late?
A locked payment compares what arrives with payer_amount, in crypto. The fiat price no longer matters at this point: the market may have moved, but the amount the payer owes does not change. A small shortfall within the underpayment tolerance of your account still counts as paid; a bigger one makes the payment underpaid, and the payer can top up the difference to the same address until the deadline.
After the deadline the payment is closed: expired if nothing was confirmed, or finally underpaid if part of the amount arrived. Money that arrives later is still credited, by the crypto amount actually received, with late_payment: true and an invoice.late_payment webhook. CryptoLike does not recalculate the old rate: whether a late payment covers the order at today's prices is a decision for you and the customer. If the customer still wants to pay, create a new payment — it gets a new rate. Each case is described in underpaid, overpaid and late payments.
Create a payment priced in USD
A payment priced in US dollars with USDT on TRON fixed at creation: the rate is locked in this request, and the response carries the exact amount to show. Signing is shown in the Node.js guide.
POST /v1/invoices
Idempotency-Key: bill-2026-0917
{
"amount": "1200.00",
"currency": "USD",
"coin_id": "<id of USDT on tron from GET /v1/currencies>",
"ttl_seconds": 86400,
"description": "Invoice 2026-0917, design services"
}The response contains amount_fiat: "1200.00", fiat_currency: "USD", rate_locked, rate_locked_at, amount_crypto, payer_amount, address, checkout_url and ttl_expires_at. Without coin_id, the same fields are filled when the payer picks the asset. The error 400 validation_error on currency means the code is not among the fiat currencies of your account (see the table above).
Fiat pricing or stablecoin pricing?
If your prices are in US dollars, you can skip the conversion altogether and price in USDT or USDC. A payment in currency: "USDT" has no rate and no market movement between the lock and the payment; the payer chooses between USDT on TRON and on Ethereum on the payment page. See USDT TRC20 vs ERC20 for the difference between the two networks.
| Aspect | Priced in USD or EUR | Priced in USDT or USDC |
|---|---|---|
| Payer can pay with | The coins you offer for invoices, or the ones you list in allowed_coin_ids |
That stablecoin, on the networks where you accept it |
| Market movement during the lock | Yours, until the deadline | None |
503 on a stale rate |
Possible | Not applicable |
| Value on your balance | The asset the payer chose, exposed to its price | A dollar stablecoin |
| Suits | Shops that want to offer Bitcoin and other assets | Bills, B2B, prices already in dollars |
Your balance stays in the asset the payer sent; CryptoLike does not exchange it into fiat. Statements record the fiat value of each posting at the time it was made, which is what accounting needs. The business side of fiat-priced bills is covered on B2B crypto invoicing.
FAQ
When is the exchange rate locked?
At the moment the asset of the payment is known: when you create the payment with coin_id, or when the payer picks the asset on the payment page. From then on the crypto amount stays fixed until the payment's deadline, ttl_expires_at.
Can the payer lose the locked rate?
Only by missing the deadline. After ttl_expires_at the payment closes, and money sent later is credited by the crypto actually received, without recalculation. For a new attempt create a new payment, which gets a new rate.
Why can the crypto amount be slightly higher than price divided by rate?
Only because of rounding. CryptoLike adds no conversion spread: rate_locked is the plain market quote, and the price divided by it is rounded up to the smallest unit of the asset, so the payer never sends less than the price. The address expects amount_crypto, or payer_amount when the payer bears the platform fee.
Which fiat currencies can I price in?
USD, EUR, UAH, GBP and CAD, all enabled for every account by default; currency also takes a coin ticker. A code outside your account's list answers 400 validation_error on the currency field, and CMS plugins show that crypto payment is not available for the store currency. Another currency is added only when two independent sources quote its rate: write to support to ask for one.
What does 503 unavailable mean when I create a payment in USD?
No quote fresher than 5 minutes was available for the asset, or two rate sources disagreed on the pair by more than the limit, so the rate could not be locked. Retry with the same Idempotency-Key after a short pause, or create the payment in crypto. Nothing is created with an outdated rate.