1. Getting Started
Arcanum Pay
  • Arcanum API
    • Getting Started
      • Documentation Overview
      • Request Authorization
    • API Reference V1
      • Create Deposit
      • Create Withdrawal
      • Get Deposit Status
      • Get Withdrawal Status
      • Get Merchant Balance
    • Webhooks
      • Callback Verification
      • Callback Payload
    • Schemas
      • DepositResponseDto
      • UserDataDto
      • CreateDepositDto
      • WithdrawalResponseDto
      • CreateWithdrawalDto
      • StatusResponseDto
      • MerchantBalanceDto
      • MerchantBalancesResponseDto
  1. Getting Started

Request Authorization

All requests to the Merchant API require two headers for authentication:
HeaderTypeRequiredDescription
merchant-idstringYesYour unique merchant identifier
x-signaturestringYesHMAC-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.

Payload Format#

{merchantId}:{path}:{body}
Where:
PartDescription
merchantIdValue of the merchant-id header
pathFull request path without query parameters (e.g. /api/v1/deposits)
bodyJSON-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
Previous
Documentation Overview
Next
Create Deposit
Built with