Skip to main content

Crypto Pay-In

TOPPAY TeamAbout 4 min

Overview

The Crypto Pay-In API collects on-chain transfers from payers. The platform assigns a deposit address to the order, the payer transfers the specified quantity to that address, and once the transfer is confirmed on-chain the platform notifies the merchant via callback.

Two ordering modes are supported:

ModeProduction pathDescription
Cashier mode/crypto/pay/prePayDefault mode. currency and netWork may be omitted; the response returns cashierUrl and the payer picks a coin-chain pair on the platform cashier to obtain a deposit address
Direct API mode/crypto/pay/orderDirectlycurrency and netWork are mandatory; the response returns the deposit address inAddress directly

Access note

Both modes are gated by the merchant's cashier open mode (availablePayMode): prePay requires H5 to be enabled and orderDirectly requires API. Otherwise 0001 is returned with merchant do not support H5/API ordering!. Contact support to enable a mode.

Common request headers (including the mandatory Nonce), common body fields and the unified response envelope are described in Crypto Integration Overview.


Cashier mode (prePay)

Request path

Domain: Prefer unified host openapi.toppayment.com (path unchanged); legacy crypto domain (global-digit-openapi.toppayment.com) remains available.

EnvironmentURL
Sandboxhttps://openapi.toppayment.com/crypto/sandbox/pay/prePay
Productionhttps://openapi.toppayment.com/crypto/pay/prePay

Request headers

FieldRequiredTypeDescription
Content-TypeMStringFixed value: application/json
NonceMString(16-64)Anti-replay random string, unique within 10 minutes, excluded from the signature

Request body

FieldRequiredTypeDescription
mchNoMString(32)Merchant number
In sandbox use the SD-prefixed sandbox merchant number
mchUserIdMString(32)Merchant-side user identifier
Used to link the payer to your own system
payMoneyMStringCollection quantity
Numeric string with at most 6 decimal places
Subject to the platform pre-order amount limits; out-of-range returns 0001
Example: 10.5
downNotifyUrlMString(255)Asynchronous notification URL
Must be a publicly reachable HTTP/HTTPS URL, see Callback
timestampMString(13)Request timestamp (13-digit milliseconds), within ±5 minutes
signMStringSignature, see Signature
orderNumOString(64)Merchant order number
Generated by the platform when omitted. Must be unique per merchant; duplicates return 0001
currencyOString(16)Coin
May be omitted in cashier mode so the payer chooses it; if provided the cashier is locked to this coin
Charset A-Z a-z 0-9 _, example: USDT
netWorkOString(100)Chain network
Only effective when sent together with currency, example: TRC20
expiryPeriodOStringOrder validity in minutes
Range 19999, defaults to 1440 (24 hours)
orderVersionOString(20)Order version marker agreed with the platform, normally not needed
nameOString(64)Payer name
emailOString(64)Payer email
phoneOString(32)Payer phone
tenantCodeOString(32)Sub-tenant code, defaults to the default tenant
countryCodeOString(16)Country code, not needed for crypto

Request example

Content-Type: application/json
Nonce: 8f3c1a92b74e5d60c1f2

Response body

FieldRequiredTypeDescription
successMBooleanWhether the request succeeded
codeMStringResponse code
9999: success; otherwise see Exception Codes
msgOStringResponse message, null on success
timeStampMNumberServer response time (milliseconds)
dataMObjectResponse payload
orderNumMStringMerchant order number
Platform-generated when omitted in the request
platOrderNumMStringPlatform order number
The key used for later inquiries and callbacks
payMoneyMNumberCollection quantity
currencyOStringCoin
null when not specified in the request, decided once the payer picks on the cashier
netWorkOStringChain network, same as above
cashierUrlMStringCashier URL
Redirect the payer here to complete the payment
inAddressOStringDeposit address
null at cashier-mode order creation; generated once the payer selects a coin-chain pair

Response example

{
    "success": true,
    "code": "9999",
    "msg": null,
    "timeStamp": 1767840272829,
    "data": {
        "orderNum": "CR1788506800926",
        "platOrderNum": "CR20260904152640640",
        "payMoney": 10.500000,
        "currency": null,
        "netWork": null,
        "cashierUrl": "https://cashier.example.com/CR20260904152640640",
        "inAddress": null
    }
}

No redirect after payment

The crypto cashier does not support redirecting back to the merchant page once payment completes. The payer must return to your site on their own, and you should confirm the result through the Callback or Order Inquiry.


Direct API mode (orderDirectly)

The merchant specifies currency and netWork in the request. The platform requests a deposit address from the channel and returns inAddress directly, without going through the cashier.

Request path

Domain: Prefer unified host openapi.toppayment.com (path unchanged); legacy crypto domain (global-digit-openapi.toppayment.com) remains available.

EnvironmentURL
Sandboxhttps://openapi.toppayment.com/crypto/sandbox/pay/directlyPay
Productionhttps://openapi.toppayment.com/crypto/pay/orderDirectly

Sandbox path difference

The sandbox direct-order path is /crypto/sandbox/pay/directlyPay (/crypto/sandbox/pay/transOrder is also accepted), which differs in name from the production /crypto/pay/orderDirectly. Request and response bodies are identical.

Request body

Differences compared with cashier mode:

FieldRequiredTypeDescription
currencyMString(16)Coin
Mandatory in direct mode, example: USDT
netWorkMString(100)Chain network
Mandatory in direct mode, example: TRC20

All other fields are the same as cashier mode. A missing currency or netWork returns 0001; no available channel for the coin returns 0003.

Request example

Content-Type: application/json
Nonce: 2b7de401a5c96f83d0e1

Response body

Fields are identical to cashier mode. In direct mode, focus on:

FieldRequiredTypeDescription
inAddressMStringDeposit address
Instruct the payer to transfer payMoney of currency to this address
cashierUrlOStringCashier URL
Still returned in direct mode, but rely on inAddress

Response example

{
    "success": true,
    "code": "9999",
    "msg": null,
    "timeStamp": 1767840272829,
    "data": {
        "orderNum": "CRAPI1788506800931",
        "platOrderNum": "CR20260904152640642",
        "payMoney": 10.500000,
        "currency": "USDT",
        "netWork": "TRC20",
        "cashierUrl": "https://cashier.example.com/CR20260904152640642",
        "inAddress": "TP5wzCqNsJFNT83m1VXdF2Aj1ageFWgqW2"
    }
}

Notes

The transferred quantity must match the order

The on-chain transfer must match payMoney exactly and must use the currency and netWork of the order. A mismatched quantity, wrong chain or wrong coin may prevent automatic crediting and require manual intervention.

  • The deposit address is bound to the order. Never reuse an inAddress from a previous order.
  • Orders expire after expiryPeriod; expired orders return status EXPIRED on inquiry.
  • Reusing the same mchNo + orderNum returns 0001 (The order already exists!); concurrent duplicate submissions return 0004.

Next steps