Webhooks deliver notifications of events as HTTP requests whenever important data within your account changes, for example the change in the status of a payment. This mechanism allows you to take additional actions on the occurrence of these events, and eliminates the need for polling or manual checks.

Setting up Webhooks

To start receiving webhook events, reach out to the customer success team to:
  1. Register the URL of an endpoint to receive webhooks
  2. Receive a secret signing key that will be generated and shared with you and is essential for ensuring the authenticity of incoming payloads and preventing malicious requests
Ensure that the URL you specify points to a secure endpoint using HTTPS, and can receive POST requests.
The secret signing key can be rotated on request.
We suggest using a tunneling service such as ngrok to test your webhook implementation.

Using Webhooks

Request Headers

When we send a webhook event, the HTTP request includes three essential headers:
  • webhook-id: An ID that uniquely identifies each message.
  • webhook-timestamp: A Unix timestamp indicating when the event was signed. This timestamp is included in the signature to guard against replay attacks. See Verifying Events for more details.
  • webhook-signature: A list of signatures (HMAC-SHA256) created using a secret signing key and will be used to validate the authenticity of an event. Typically, the signature list consists of only one element, but it can contain any number of signatures. It is formatted as a space delimited list of signatures and their corresponding version identifiers. See Verifying Events for more details. For example:
    v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE= v1,bm9ldHUjKzFob2VudXRob2VodWUzMjRvdWVvdW9ldQo=
    

Processing Events

The endpoint on your server must be capable of receiving HTTPS POST requests, and it’s important to respond with a 2xx status code within a reasonable timeframe. We recommend sending the response within 15 seconds to ensure timely confirmation. This endpoint will be triggered whenever an important event occurs, for example the status of a payment changes, thus enabling you to handle events in real time. It’s important to respond with a 2xx status code within a reasonable timeframe. We recommend sending the response within 15 seconds to ensure timely confirmation. If no 2xx status code is received, the system retries delivery according to this schedule:
  • Immediately
  • 5 seconds
  • 5 minutes
  • 30 minutes
  • 2 hours
  • 5 hours
  • 10 hours
  • Additional 10 hours
After the conclusion of the above attempts the event will be marked as Failed for this endpoint. If all attempts to a specific endpoint fail for a period of 5 days, the endpoint will be disabled.‍

Verifying Events

Webhooks can be vulnerable to security risks, such as malicious actors sending fake events or replaying intercepted requests. To safeguard against these threats, you should prevent replay attacks, verify the origin and authenticity of events, and prevent duplicate processing of events. A replay attack can be prevented by blocking intercepted requests from being reused. Every webhook includes thewebhook-timestamp request header, which provides the Unix timestamp of when the event was signed. Use this timestamp to prevent replay attacks:
  • Ensure the webhook-timestamp is within a valid time window (we recommend up to 3 minutes).
  • Since retries generate a new timestamp for each attempt, you can confidently validate each request.
  • Reject requests with timestamps outside the threshold to block tampered or replayed events.
Verify the origin and authenticity of events by using the secret signing key unique to your account, and the request header, webhook-signature, included as part of the webhook. We sign all webhooks originating from us using the secret signing key. Follow these steps to ensure the event was sent by us:
  • Generate the signed content by concatenating the values of thewebhook-id request header, webhook-timestamp request header, and a string representation of the request body into a single string, separated by periods.
  • Calculate the expected signature, using the secret key and the signed content above to generate a HMAC SHA256 signature. Then, encode this value using a base64 encoding.
  • Verify the signature by comparing the expected signature above above with the signature sent in the webhook-signature header. If the generated signature matches the provided signature, you can proceed with processing the event.
  • Make sure to use the string representation of the request body i.e. the raw request body as any minor modification to the body will generate a completely different signature.
  • Before calculating the expected signature, ensure that you exclude the whsec_ prefix from the secret signing key.
  • Before verifying the signature, make sure to remove the version prefix and delimiter (e.g. v1,).
  • When comparing the signatures, it is recommended to use a constant-time string comparison method to prevent timing attacks.
Duplicate processing of events can be prevented by processing events in an idempotent safe manner by storing the webhook-id request header in a persistent data store and ensuring that an event has not been processed before. Additionally every webhook event sent has a unique event-id in the message body that can be used to prevent duplicate processing.

Structure of an Event

The event payload of a webhook request sent to the registered endpoint will contain:
  • id : An ID that uniquely identifies each event.
  • type: The type of event that triggered the webhook, for example, payment_session.created or payment_session.updated events
  • data: The actual payload, which can be a different object depending on the event type. For example, for payment_session.* events, the payload will always be the payment_session object.

Additional Security Precautions

In addition to the security measures used to verify the origin and authenticity of webhook events described in the Verifying Events section above, all webhook events are sent from a specific set of source static IP addresses. If your webhook endpoint is hosted behind a firewall or a NAT (Network Address Translation) gateway, you’ll need to ensure it can receive incoming requests. To do this, make sure to whitelist the following source static IP addresses in your network configuration so that webhook traffic isn’t blocked or dropped by your security settings.
52.215.16.239
54.216.8.72
63.33.109.123
2a05:d028:17:8000::/56

Sample Code

Our code sample below will help you get started quickly.