Authentication
Every client is configured with one explicit Application ID + API version pair. Merchant API v1 keeps the legacy exact-body SHA512 contract. Merchant API v2 uses a domain-separated HMAC-SHA512 contract with mandatory timestamp/nonce replay protection. The server never chooses a default or falls back between versions.Obtaining Credentials
API credentials and merchant accounts are created by the 123hub team during
onboarding. Self-registration is not available.
- Contact your 123hub account manager
- Or email support@123hub.pro
Authentication Headers
Every request toPOST /public/api/multihub/v1 must include the first two
headers below. For that endpoint the replay headers are optional, but when used
they must be sent together:
For
POST /public/api/multihub/v2, send all four headers below:
The v2 request canonical payload has no trailing newline:
X-Data-Signature = HMAC-SHA512(secretKey, canonicalPayload). The path
is the fixed literal shown above. Redis replay storage is mandatory for v2; the
request fails closed if the nonce cannot be reserved. Do not retry v2 as v1.
Successful v2 responses use X-Data-Signature over:
How Signing Works
1
Prepare the request body
Serialize your request body as a JSON string. This is the exact string that
will be sent as the HTTP body.
2
Compute the hash
Concatenate the JSON string with your
secret_key (no separator), then
compute the SHA512 hash of the result. Output as a lowercase hex string. hash = SHA512(jsonBody + secretKey)3
Send the request
Send the two required headers. You may also include timestamp and nonce as a
pair, as shown below. Webhook resend also accepts the two-header legacy
mode; when you send both replay headers, the route-bound signing rules in
Webhooks apply.
Code Examples
Verifying API Response Signatures
Successful API responses includeX-Data-Hash. Verify it with the same merchant API secret:
Verifying Webhook Signatures
When 123hub sends webhook notifications to your server, the request includes anX-Data-Hash header. New deliveries also include replay-protection metadata in X-Webhook-Id, X-Webhook-Timestamp, X-Webhook-Nonce, X-Webhook-Signature-V2, and X-Webhook-Signature-V3. Prefer X-Webhook-Signature-V3 when present, and fall back to V2 or X-Data-Hash only for legacy deliveries.
X-Webhook-Signature-V3 is HMAC-SHA512(timestamp.nonce.webhookId.rawBody, webhook secret). X-Data-Hash remains SHA512(webhookBody + webhook secret).
Webhook create/rotation reveals a dedicated webhook-only secret once. Store it
separately from the API credential; rotating one does not rotate the other.
Historical API-compatible webhook rows are blocked until explicit webhook secret
rotation. For a callback auto-created through params.payment.webhook_url, derive
the lowercase webhook secret with
HMAC-SHA256(apiSecret, "quadpay:merchant-webhook-signing:v1"), using the exact
API secret that authenticated that payment create. Test and production keys do
not cross; the resulting callback destination is scoped to that payment.
Test Mode vs Production
Test and production requests use the same API endpoint and the same
authentication mechanism. The environment is determined by which credentials
you use.
- Test credentials identify an account-specific test environment and routes confirmed during onboarding
- Production credentials create real transactions with actual money movement
- Credentials whose environment does not match the merchant are rejected. Test payments select sandbox provider credentials only and never fall back to a production provider credential or endpoint.
- Webhooks are delivered in both environments for testing integrations
- All API responses follow the same format in both environments
Rate Limits
API requests may be rate-limited to ensure fair usage. The public public API controller is exempt from the gateway default IP throttler, but authenticated applications have protective per-method buckets forpayment.in, payment.out, payment.status, and balance.get.
When a rate limit is applied, it is counted per authenticated merchant/application context and method.
If you exceed an applied limit, the response returns HTTP
429 with the
standard API error envelope and Retry-After-* headers. Retry with backoff or
contact support if you need a higher production throughput profile.Error Responses
Authentication errors are returned in the standard response envelope with HTTP 400. Credential policy or merchant-ownership denials return HTTP403 with code 3008. An enforced credential daily-request limit returns HTTP 429 with code 3009; its counter resets at UTC day rollover. DTO validation failures, including unknown fields rejected by strict validation, return code 9000 when request validation reaches the DTO layer. During deployments, readiness gating can return a non-envelope HTTP 503 before API handling starts.
Invalid Application ID
Invalid Hash Signature
Best Practices
Use Environment Variables
Store your
application_id and secret_key in environment variables, never
in source codeRotate Keys Regularly
Regenerate your secret key periodically from the dashboard for enhanced
security
Verify Webhooks
Always verify the
X-Data-Hash header on incoming webhooks before
processingMonitor Usage
Track API usage in the dashboard to detect anomalies and stay within rate
limits
