Skip to content

Receiving Events

Receive the request

Provide an HTTPS endpoint that accepts HTTP POST requests with a UTF-8 JSON body (Content-Type: application/json; charset=utf-8). Validate authentication before acting on the payload, and keep credentials out of application logs.

Authentication by payload version

Payload Authentication Credential lifetime
v1 Legacy static x-signature credential; preserve the existing JWT and expiration contract. The JWT retains its configured exp; the sender and delivery verifier do not enforce it as a delivery-credential expiry. It does not deactivate the subscription.
v2 HMAC-SHA256 signature calculated for each delivery; static-signature authentication is not supported. Cryptographically random opaque secret with a whsec_ prefix and no JWT claims, exp, or expiration date. It remains valid until manually regenerated.

Payload v2 is a voluntary subscription choice. Payload versions and signature versions describe separate parts of the protocol: x-signature-version: v1 identifies the HMAC algorithm format, not payload v1.

Verify a payload v2 delivery

Read these headers and preserve the exact request body bytes before JSON parsing:

Header Meaning
x-signature-version v1, the cryptographic wire format.
x-signature v1= followed by the lowercase hexadecimal HMAC-SHA256 digest. The secret is never sent in this header.
x-signature-timestamp Unix timestamp in seconds used in the signature.
x-webhook-delivery-id Delivery identifier, a canonical lowercase UUID. Automated retries retain this identifier.
  1. Require all four headers and the supported signature version. Reject malformed values.
  2. Derive the binary signing key as SHA256(UTF8(secret)). Hash the opaque secret text exactly as provided; do not decode it or interpret it as a JWT.
  3. Build the signing input as UTF8(timestamp + "." + deliveryId + ".") followed by the original body bytes. Do not reserialize JSON or change whitespace, line endings, or Unicode encoding.
  4. Calculate HMAC-SHA256(key, signingInput), encode the digest as lowercase hexadecimal, and prepend v1=. Compare against x-signature using a constant-time comparison.
  5. Check the signed timestamp against your receiver's current UTC time using a bounded tolerance for both past and future timestamps. Choose the tolerance for your integration's clock skew and network delay.
  6. Persist accepted deliveries and enforce idempotency before performing business actions. A correctly authenticated retry of an already accepted delivery should receive a successful acknowledgment without repeating the action.

The timestamp tolerance limits replay of a captured request. It is independent of the secret's lifetime: a request can become too old while its secret remains valid. A new attempt can carry a fresh timestamp and signature for the same delivery identifier; timestamp checking alone does not prevent duplicate processing.

Replace a payload v2 secret

Manual regeneration replaces the secret immediately. There is no automatic rotation and no period during which both old and new secrets are supported. Coordinate the replacement with the receiving application and store the new secret securely before resuming processing. Do not expect a JWT expiration date or an expiration form for payload v2.

Process safely

Validate the payload and store enough information to reconcile the transaction with your own records. Design processing so receiving the same notification again does not repeat a business action, such as issuing goods or updating an invoice twice. Do not assume notifications arrive in transaction order.

After accepting the notification, return a successful HTTP status in the 2xx range. The response body is ignored. If you queue work for later processing, persist it before acknowledging receipt.

A webhook HTTP acknowledgment confirms receipt by your application. Determine the payment outcome from the transaction information, and reconcile uncertain outcomes against the API before taking further action.

Test your endpoint

Use the synthetic examples in the reference to test payload handling locally. Test valid signatures, modified raw body bytes, incorrect secrets, missing or malformed headers, timestamps outside tolerance, and repeated receipt. Confirm that manual regeneration requires the replacement secret. These examples do not initiate payments.

Coordinate an integration test and the applicable delivery policy with Blackstone support before enabling the endpoint for your merchant account.