Skip to main content
XPayLabs authenticates every API request using HMAC-SHA256 request signing. Unlike traditional Bearer token authentication, XPayLabs requires each request to include a cryptographic signature computed over the request payload. This ensures request integrity and prevents replay attacks.

What is the HMAC-SHA256 signing format?

Every API request includes a ReqPayload wrapper with four fields: The sign field is computed using your merchant token as the HMAC secret key.

How to compute the HMAC signature

Algorithm

  1. Serialize the data object as a JSON string (no pretty-printing, no extra whitespace).
  2. Compute HMAC-SHA256(data_json, merchant_token).
  3. Convert the result to a lowercase hex string.
  4. Set this value as the sign field.

Node.js

Python

Go

The JSON serialization must be compact — no spaces, no newlines between key-value pairs. Different JSON serializers may produce different output; always test your signature computation against a known working example.

What are the timestamp and nonce requirements?

The timestamp and nonce fields prevent replay attacks:
  • Timestamp: Your server clock must be within 5 minutes of XPayLabs server time. Requests with timestamps older than 5 minutes are rejected.
  • Nonce: Each request must use a unique nonce. XPayLabs tracks used nonces and rejects duplicates. UUIDs or cryptographically random strings work well.

How does XPayLabs verify signatures server-side?

XPayLabs verifies every request by recomputing the HMAC-SHA256 signature using your stored merchant token. If the signatures don’t match, or if the timestamp is outside the tolerance window, the request is rejected with a 401 Unauthorized response.

How to keep your merchant token secure

  • Store your merchant token in an environment variable or secrets manager.
  • Never hardcode the token in source code or client-side applications.
  • Rotate the token periodically and update your configuration.
  • The token is a shared secret between your merchant server and the XPayLabs gateway. It is not sent over the network in API requests.
Last modified on June 26, 2026