Create a hosted-checkout payment
/paymentsCreates a payment and returns the hosted checkout URL the customer must be redirected to.
Synchronous 200: the resource and its checkout link are produced from our own data. The
customer's payment itself is asynchronous — the resource starts in status: pending and the
terminal outcome arrives through the payment.completed or payment.expired webhook (or
GET /payments/{paymentId}). Never read the outcome from the returnUrl redirect.
A failed attempt does not end the payment: the customer can retry until checkout.expiresAt, and the payment
stays pending meanwhile. A customer who committed just before the deadline can still complete it after
payment.expired — the money has then moved, so handle payment.completed even for an order you closed.
Retrying. After a timeout or a 5xx, retry with the same Idempotency-Key: you get the payment the
first attempt made, never a second one and never duplicate_merchant_reference. Within 24 hours the original
response is replayed. Past that, or when the first attempt ended in a 5xx, the payment is answered as it
stands: while nobody has started paying it, with a new checkout.url — the token behind the earlier link is
replaced, so that link stops working — and its checkout.expiresAt unchanged; once a customer has started
paying it, or it has ended, without a url.
Parameters
Idempotency-KeystringheaderrequiredClient-generated unique key for this logical request (UUID recommended). See Idempotency.min length 1 · max length 255
Request body application/jsonrequired
description, metadata and a per-payment expiresIn are not accepted yet; the checkout TTL is the
platform default (15 minutes) and is reported back in checkout.expiresAt.merchantReferencestringrequiredYour own unique reference for this payment — typically your order number. Unique per merchant for good; a repeat under a differentIdempotency-Keyis400 duplicate_merchant_reference.min length 1 · max length 100
amountMoneyrequiredDecimal amount as a string — never a float, never minor units. An amount you send may carry no more decimal places than its currency has (and never more than 8); trailing zeros do not count, so10.100 EURis fine and10.123 EURis400 validation_failedonamount.value. An amount the API returns is written with exactly as many decimal places as its currency has (at most 8):10.10 EUR, never10.1.valuestringrequiredExample:
149.90pattern ^-?\d{1,18}(\.\d{1,18})?$
currencystringrequiredISO 4217 code for fiat (EUR), asset ticker for crypto (USDT).Example:
EURpattern ^[A-Z0-9]{3,10}$
methodstringrequiredOne of the methodsGET /payment-methodslists as enabled for you. Unlike other enums you send, a method the API does not know is notvalidation_failed: it is400 payment_method_not_enabled, as a disabled one is.Allowed values:
jeton_walletreturnUrlstring (uri)requiredHTTPS URL the customer is sent back to after checkout (success or failure — read the outcome from the API or webhooks, never from the redirect).languagestringThe checkout page's language, ISO 639-1 — the one language field a payment has. Left out, the checkout picks its own.Example:
enpattern ^[a-z]{2}$
customerCustomerThe payer. Only the e-mail is reported for now; name, phone and country are not provided yet. The checkout page's language is the payment's ownlanguage, not a customer field.emailstring (email)max length 100
Responses
The payment.
Headers
X-Request-IdstringThe request's trace id: the same value a problem body carries astraceId. Quote it when you contact support. A replayed response (Idempotent-Replayed: true) carries the replay's own; its body keeps the original request'straceId.RateLimit-LimitintegerRateLimit-RemainingintegerRateLimit-ResetintegerSeconds until the window resets.Idempotent-Replayedbooleantruewhen this response was replayed from an earlier request with the sameIdempotency-Key.
Schema application/json
idstringrequiredA payment's id. Opaque — use it as you received it.Example:
pay_019985c24a6e7c3b9f102d5e8a1b3c4dpattern ^pay_[0-9a-f]{32}$
merchantReferencestringrequiredYour own reference for this payment, as you sent it.statusstringrequiredpendingawaiting the customer — also after a failed attempt, while the customer may retry ·processingcustomer acted, settlement in flight ·completedfunds credited ·failednot used for payments: one never paid endsexpired·cancelled·expiredcheckout TTL elapsed unpaid (a customer who committed just before the deadline can still turn itcompleted) ·refunded. (partially_refundedis not reported yet.)Allowed values:
pendingprocessingcompletedfailedcancelledexpiredrefundedamountMoneyrequiredDecimal amount as a string — never a float, never minor units. An amount you send may carry no more decimal places than its currency has (and never more than 8); trailing zeros do not count, so10.100 EURis fine and10.123 EURis400 validation_failedonamount.value. An amount the API returns is written with exactly as many decimal places as its currency has (at most 8):10.10 EUR, never10.1.valuestringrequiredExample:
149.90pattern ^-?\d{1,18}(\.\d{1,18})?$
currencystringrequiredISO 4217 code for fiat (EUR), asset ticker for crypto (USDT).Example:
EURpattern ^[A-Z0-9]{3,10}$
feeobjectPresent once the payment is completed: the fee charged to you on it, in the payment's currency. You were creditedamountless this.valuestringrequiredExample:
149.90pattern ^-?\d{1,18}(\.\d{1,18})?$
currencystringrequiredISO 4217 code for fiat (EUR), asset ticker for crypto (USDT).Example:
EURpattern ^[A-Z0-9]{3,10}$
methodstringrequiredHow the customer pays — the same vocabulary asPayoutMethod.jeton_wallet: the customer pays from their Jeton account on the checkout page. More methods will come;GET /payment-methodslists those enabled for you.Allowed values:
jeton_walletcheckoutobjectPresent while the payment ispendingorprocessing.urlstring (uri)Redirect the customer here. Returned in the create response only — the checkout token is stored hashed, soGETcannot reproduce it. Persist it with your order. A retry of the create under itsIdempotency-Keyissues a new one while nobody has started paying (see Retrying onPOST /payments).expiresAtstring (date-time)requiredRFC 3339, UTC, with millisecond precision.Example:
2026-09-18T10:15:30.123Z
customerCustomerThe payer. Only the e-mail is reported for now; name, phone and country are not provided yet. The checkout page's language is the payment's ownlanguage, not a customer field.emailstring (email)max length 100
payerobjectPresent once the payment is completed: the Jeton user who actually paid. Distinct fromcustomer, which is what you sent. Passpayer.customerNumberasdestination.customerNumberonPOST /payoutsto pay the same customer back.customerNumberstringrequired
languagestringThe checkout page's language as you sent it. Absent when you sent none.pattern ^[a-z]{2}$
createdAtstring (date-time)requiredRFC 3339, UTC, with millisecond precision.Example:
2026-09-18T10:15:30.123ZupdatedAtstring (date-time)requiredLast change. It never moves backwards, so use it to discard stale webhook snapshots.Example:
2026-09-18T10:15:30.123ZcompletedAtstring (date-time)Present once the payment is completed — when the funds were credited.Example:
2026-09-18T10:15:30.123Z