All requests to the Merchant API require two headers for authentication:| Header | Type | Required | Description |
|---|
merchant-id | string | Yes | Your unique merchant identifier |
x-signature | string | Yes | HMAC-SHA256 signature of the request (hex) |
Authentication Flow#
Request
|
v
1. Validate `merchant-id` header --> 401 if missing
2. Check merchant exists --> 404 if not found
3. Check merchant is active --> 403 if disabled
4. Validate `x-signature` header --> 401 if missing
5. Lookup secret key by merchant + operation type --> 401 if not configured
6. Verify signature --> 401 if invalid
7. (POST only) Check KYB status --> 403 if not approved
|
v
Request processed
Secret Keys#
Each merchant has separate secret keys per operation type:Deposit secret — used for all endpoints containing /deposits and /balances
Withdrawal secret — used for all endpoints containing /withdrawals
Secret keys are issued during merchant onboarding.Signature Generation#
The signature is computed as HMAC-SHA256 over a payload string, using the corresponding secret key.{merchantId}:{path}:{body}
| Part | Description |
|---|
merchantId | Value of the merchant-id header |
path | Full request path without query parameters (e.g. /api/v1/deposits) |
body | JSON-stringified request body with keys sorted alphabetically. For GET requests use {} |
Stable JSON Serialization#
Request body keys must be sorted alphabetically before serialization. This ensures deterministic output regardless of the original key order.// Input
{ "userId": "user-123", "amount": "100.00", "currency": "USDT" }
// Sorted output
{"amount":"100.00","currency":"USDT","userId":"user-123"}
Algorithm#
1.
Build the payload string: ${merchantId}:${path}:${stableStringify(body)}
2.
Compute HMAC-SHA256(payload, secretKey)
3.
Encode the result as a hex string
Node.js Example#
Modified at 2026-05-28 13:55:20