Skip to main content
Every API request to XPayLabs must include a cryptographic signature. This page details the exact signing algorithm, the purpose of each field, and common pitfalls.

Signing Algorithm

The sign field is computed as:
Where:
  • data is the request body payload (the data field of ReqPayload)
  • merchant_token is your configured secret token
  • HMAC-SHA256 produces a binary digest
  • HEX converts it to a lowercase hexadecimal string (64 characters)

Important: JSON Serialization

The data object must be serialized to JSON with no extra whitespace. Different JSON libraries may produce different output:
LibraryOutputValid?
JSON.stringify(obj){"amount":"100.00","symbol":"USDT","chain":"TRON"}✅ Yes
json.dumps(obj, separators=(",",":")){"amount":"100.00","symbol":"USDT","chain":"TRON"}✅ Yes
json.dumps(obj, indent=2)Formatted with spaces/newlines❌ No
The signature is computed over the data field only — not over the full ReqPayload envelope. The sign, timestamp, and nonce fields are excluded from signing.

Request Envelope

Each request must include these four fields as a JSON object:

Language Examples

Node.js

Python

Java

Go

Verification

XPayLabs verifies each request by:
  1. Recomputing the HMAC-SHA256 signature from the data field and your stored merchant token.
  2. Checking that the computed signature matches the provided sign value.
  3. Validating that the timestamp is within 5 minutes of the server clock.
  4. Ensuring the nonce has not been used before.
If any check fails, the gateway returns a 401 Unauthorized response:

GET Request Signing

For GET requests that require authentication (e.g., /v1/order/status/{orderId}, /v1/order/pay, /v1/order/getOrderStatus), the sign parameter is passed as a query string value. The signature is computed over the relevant parameters (typically orderId):
Last modified on June 26, 2026