Skip to content

Concepts ​

Learn the vocabulary first and the endpoint pages become much easier to read. This page only explains what each thing is and why it is designed that way; for fields, see the relevant endpoint page.

Core concepts ​

ConceptFieldWhat it isWhy it matters
Merchant numbermerchantNoYour public identifier on the platformUsed in checkout links and QR entry points. It is a public identifier, not a credential — leaking it at worst reveals your collection name
API KEYapiKey (header X-Pay-Api-Key)Your server's credential for the Open APIIt is also the callback signing key. Leaking it means someone can forge "your order was paid", so keep it server-side and store only a hash
Merchant order nomerchantOrderNoYour own order numberIt is the idempotency key. Retries must reuse it, and that is how we guarantee no duplicate orders
Platform order noorderNoThe order number we generateAlso the source of the on-chain identify code. It is public to the buyer too (the checkout page looks up an order by knowing its number)
Collection addresspayAddressWhere this payment should be sentSnapshotted at order creation. Changing your address later does not affect existing orders
CheckoutcashierThe page the buyer seesTwo entry points: the fixed counter (/pay/cashier/m/{merchantNo}) and the per-order checkout page
Open API/api/pay/open/Server-to-server endpointsThe caller is your server; identity comes only from the API KEY, and no identity parameter is accepted in the request
ChainchainId / chainKeyWhich blockchain the payment is collected onchainKey is the short code used in code (e.g. tron, bsc); chainId is the internal number
TokentokenId / tokenSymbolWhich coin on that chainA chain may carry several tokens; precision is per token and all amount conversion depends on it
DecimalsdecimalsThe token's smallest-unit precisionUSDT is commonly 6, but another token may be 18. One digit of difference is a factor of ten
Smallest unit*MinimalAmount expressed as an integer in the smallest unitAvoids floating-point error. Callback and query amounts are integer strings in the smallest unit
Identify dataidentifyThe marker that lets us match an on-chain payment to this orderThe scanner uses it to separate two identical transfers to the same address. Pass it through untouched
CallbacknotifyUrlWhere we notify you of the order resultIt is "we notify you" — it can fail and be missed, which is why the query API exists
SignatureX-Pay-SignatureThe proof that a callback is genuineHMAC-SHA256 with your API KEY as the key and timestamp concatenated with the raw body

Order states ​

An order state is a finite state machine, not a continuous measure of "how paid" it is. Compare by name; never use >=.

ValueNameMeaning
1PendingOrder created; the payment is not on-chain yet
2SubmittedThe transaction is on-chain but confirmations are not enough
3ConfirmedConfirmations are met. The only state that triggers a merchant callback
4FinishedCallback succeeded; final state
5ExpiredThe validity window passed with no valid payment
6ManualAn on-chain payment could not be attributed to exactly one order; a human must decide — the system will not guess

Do not use numeric comparison to decide "paid"

The values are not ordered by degree of payment: Expired (5) and Manual (6) are numerically greater than Confirmed (3) while meaning something unrelated to being paid. Treat only 3 and 4 as paid.

Order types ​

ValueNameDescription
1Online (SDK)Created by your server through the Open API, carrying your merchantOrderNo
2In-person QRCreated by the buyer entering an amount on the checkout page; the merchant order no is generated for you

This field decides whether we call the merchant back — only online orders get callbacks. Do not use "is the merchant order number empty" to decide, because both types carry a value.

The Open API trust model ​

The Open API and the buyer-facing public endpoints are two entirely different trust lines. This is the most common source of confusion:

Open API /api/pay/open/*Buyer-facing public /api/pay/*
Who callsYour serverAnyone who opens the checkout page (buyers have no account)
Where identity comes fromHeader X-Pay-Api-Key"Knowing something" (merchant number, platform order no)
Identity in the requestNot accepted; passing one has no way to be readMerchant id not accepted; the merchant is resolved from the merchant number
Response fieldsYour full fields (including received amount and your order number)Field-by-field trimmed public fields
Middleware orderPer-IP fallback limit → API KEY auth → per-merchant limitPer-IP fallback limit (write endpoints add a per-merchant one)

The first two limits matter for this reason: before authentication there is no merchant identity, so only IP can stop a flood of "scripts hammering the KEY". After authentication we limit per merchant, because one merchant can rotate IPs — and the party that suffers is its own order table.

Deployment shape: merchant side and platform side ​

The platform keeps platform-level and merchant-level configuration apart:

  • Platform side owns chains and tokens, rates and rules, which merchants may use which chains, and the public checkout domain.
  • Merchant side owns only its own collection addresses, credentials, orders and reports.

The two run as separate deployments. Merchants see their own business data in the console, never platform configuration; and the platform side has read-only access to merchant collection addresses — changing an address is always the merchant's own action, so that "who swapped the address" has an auditable answer.

A few things that do not exist yet ​

Not yet available

The following are not part of the MVP. These docs deliberately do not give URLs for them; use the website registration entry point or email us instead:

  • Merchant self-service registration and its email verification code — accounts are opened by our team.
  • Passwordless access to the merchant console — the console still requires a username and password.
  • Anonymous live chat — reach us by email or through the existing channels.

Web3 payment infrastructure for global merchants