Skip to main content

Webhooks API

123hub sends outgoing webhooks to merchant callback URLs when payment or payout events occur. Merchants can configure callbacks through onboarding/dashboard flows, Backoffice operations, or per-payment webhook_url.

Event Types

Withdrawals use the same payment.* callbacks as deposits and are identified by data.result.payment.destination: "out". payment.processing is a payment status value, not a currently emitted merchant callback event. Some account tooling may also expose balance.updated, merchant.updated, and webhook.test events outside the payment lifecycle. Opt-in public support selectors are ticket.created, ticket.updated, ticket.status_changed, ticket.comment.created, ticket.reopened, refund.requested, refund.status_changed, and chargeback.created. They use the same delivery headers/retries but a minimal public-resource payload; see Support webhooks. Existing subscriptions are not expanded automatically.

Delivery Payload

Outgoing payment webhook deliveries use this envelope:
Internal indexing fields are stripped before delivery. Do not depend on fields prefixed with _.

Delivery Headers

Use X-Webhook-Signature-V3 when present. It binds replay metadata and the raw body. Use X-Webhook-Signature-V2 or X-Data-Hash only for backward-compatible verification. Webhook create/rotation reveals a dedicated webhook-only secret once. Historical API-compatible rows do not deliver until the webhook secret is explicitly rotated; API-key rotation is independent. For a callback auto-created by params.payment.webhook_url, derive the webhook secret as lowercase HMAC-SHA256(apiSecret, "quadpay:merchant-webhook-signing:v1"), using the exact test or production API secret that authenticated that payment create. The URL is bound to that payment and never receives another payment’s events.

Signature Verification

Verify against the exact raw request body bytes. Do not parse and re-serialize JSON before hashing.
Node.js
After verification, read payment data from payload.data.result.payment.

Retry Policy

Webhook delivery succeeds on any HTTP 2xx response. Non-2xx responses, timeouts, network errors, oversized payloads, URL validation failures, or an open circuit breaker are treated as failures. Default webhook retry settings: The retry delay uses exponential backoff with jitter:
Retries are processed by a scheduler. Delivery order is not guaranteed, so handlers must be idempotent.

Idempotency

Use id plus data.result.payment.status.status as a practical deduplication key. data.request_id is unique per generated callback body and should not be used as the business idempotency key.

Webhook Management

Legacy callback configuration routes under /api/v1/webhooks are no longer part of the public API. Configure merchant callback URLs through onboarding or Backoffice operations. Payment-level re-delivery remains available through the signed endpoint below.

Merchant Payment Webhook Resend

For payment-level re-delivery, merchants can also use the signed API endpoint:
This mutation requires X-Data-Application-Id, X-Data-Hash and the webhooks.update scope. X-Data-Timestamp plus X-Data-Nonce are an optional pair; a partial pair is rejected. It is throttled to 10 requests per minute. The JSON body is:
payment_id must equal the path parameter. Reuse operation_id only for an exact retry of the same resend intent. Without replay headers, X-Data-Hash remains SHA512(raw JSON body + API secret). With both optional replay headers, the signature payload is the exact UTF-8 concatenation below, followed by the raw JSON body; X-Data-Hash is SHA512(payload + API secret):

Per-Payment Webhook URL

payment.in and payment.out accept params.payment.webhook_url. In production, use an absolute public HTTPS URL including the protocol. The system validates it at request time and again before delivery to reduce SSRF risk. The first use of a new URL creates a webhook-only derived secret. Compute the same lowercase hex value with HMAC-SHA256(exactAuthenticatedApiSecret, "quadpay:merchant-webhook-signing:v1") and use that derived value for callback verification.