πŸ”ŒAPI Doc - Webhook Signing & Payload Guide

AllScale Open API Version: v3 Last Updated: 2026-03-06


Overview

AllScale delivers event notifications to your server via Webhook callbacks.

Each webhook request is authenticated using HMAC-SHA256 request signing, providing:

  • Sender authentication (shared secret)

  • Payload integrity (tamper-proof)

  • Replay attack protection (timestamp + nonce)

  • Stateless verification (no session required)

Webhook payloads are plaintext JSON (not encrypted).


Credentials

When your integration/store is created, you receive:

Field
Description

api_key

Public identifier

api_secret

Secret key used for signature verification

Important Notes

  • api_secret is shown only once

  • It cannot be retrieved again

  • Store it securely

  • Treat it like a password or private key


Webhook Request

Method

Content-Type

Required Headers

Header
Description

X-API-Key

API key

X-Webhook-Id

Unique webhook ID

X-Webhook-Timestamp

Unix timestamp(seconds)

X-Webhook-Nonce

Unique per-request nonce

X-Webhook-Signature

HMAC signature


Signature Header Format


Replay Protection

To prevent replay attacks:

Requirements

  • Timestamp must be within Β±5 minutes

  • Each nonce must be used only once

  • Store nonce in Redis

  • TTL: 600 seconds

  • Reject duplicate nonces


Canonical String (v1)

Webhook signatures are generated using a canonical string.

Canonical Format


Field Description

Field
Description

METHOD

HTTP method (uppercase)

PATH

URL path only

QUERY_STRING

Query string without ?

WEBHOOK_ID

From X-Webhook-Id

TIMESTAMP

From X-Webhook-Timestamp

NONCE

From X-Webhook-Nonce

BODY_SHA256

SHA256 hex of raw body bytes

⚠️ Important

BODY_SHA256 must be calculated from the raw request body bytes, before JSON parsing or re-serialization.


Signature Algorithm

Algorithm

Encoding

Formula


Header Example


Webhook Payload

The request body sent by AllScale is exactly the following JSON structure.

JSON Field Definitions

Field
Type
Required
Description

all_scale_transaction_id

string

βœ…

AllScale transaction ID for this payment/transfer

all_scale_checkout_intent_id

string

βœ…

AllScale checkout intent ID associated with the payment

webhook_id

string

βœ…

Unique webhook ID (must match X-Webhook-Id)

amount_cents

integer

βœ…

Amount in fiat cents (e.g., $12.34 β†’ 1234)

currency

integer

βœ…

Currency enum value (int). Must be interpreted using AllScale Currency enum mapping

currency_symbol

string

βœ…

Fiat currency symbol (e.g., USD, CAD, CNY)

amount_coins

string

βœ…

Stablecoin amount as a decimal string (to avoid float issues), e.g. "12.340000"

coin_contract_address

string

βœ…

Official ERC-20 token contract address

coin_symbol

string

βœ…

Stablecoin symbol (e.g., USDT, USDC)

chain_id

integer

βœ…

EIP-155 chainId identifying the EVM network (https://chainid.network/)

tx_hash

string

βœ…

On-chain transaction hash

tx_from

string

βœ…

Sender wallet address

payment_method_type

integer

βœ…

Payment method type used for this transaction. Value must correspond to the PaymentMethodType enum: 0=UNKNOWN, 1=WALLET_SCAN, 2=WALLET_CONNECT, 3=ALL_SCALE_PAY.

user_id

string | null

βž–

Optional merchant/user identifier

order_id

string | null

βž–

Optional merchant order identifier

user_name

string | null

βž–

Optional customer/user display name

extra_obj

object | null

βž–

Optional arbitrary JSON object with extra fields

Actual Webhook Body Example (Matches Real Structure)


Verification Flow (Your Server Side)

  1. Extract headers

  2. Validate timestamp (Β±300 seconds)

  3. Validate nonce (store with TTL)

  4. Read raw request body bytes (before parsing JSON)

  5. Compute SHA256 of raw body

  6. Rebuild canonical string

  7. Compute expected signature

  8. Timing-safe compare

  9. Only after verification β†’ process payload


Response Expectations

Your endpoint should respond:

  • 200 OK if processed successfully

  • Non-200 if rejected (signature invalid, timestamp invalid, etc.)

AllScale will log the HTTP status and may retry depending on configured policy.


Best Practices

βœ… Always verify X-Webhook-Signature before processing βœ… Validate timestamp within Β±5 minutes βœ… Cache nonce for replay protection βœ… Use idempotency via webhook_id βœ… Convert amount_coins using Decimal (not float) ❌ Never log secrets or signatures


Troubleshooting

Issue
Cause
Fix

Signature mismatch

Body modified

Use raw bytes exactly as received

Signature mismatch

Wrong path/query

Use the exact request path and query string

Signature mismatch

Wrong secret

Verify correct api_secret

Timestamp rejected

Clock drift

Sync server time (NTP)

Replay rejected

Nonce reused

Generate unique nonce; store with TTL


End of Document

Last updated