Webhooks in Advanced Billing allow integration with your systems by automatically sending HTTP POST notifications when specific subscription, billing, or payment events occur. This article covers configuration, retry mechanisms, metadata, verification methods, and testing options to help you build reliable, secure SaaS integrations.
Webhooks are sent as HTTP POST requests to your URL with a form-encoded body (content-type: application/x-www-form-urlencoded) for easy parsing in almost any programming language.
All webhooks contain the following keys:
id |
A unique, numeric identifier for the webhook. You can use this value to record which webhooks you’ve already seen, recorded, or acted on. |
event |
An identifier for the type of event that occurred. See the list of events. |
payload |
A “hash” of pertinent data about the event. Keys and sub-keys in the hash are denoted using square bracket notation in the key. For example, the product name would be included as the following form-encoded key/pair value in the content body of a
|
Configuring Webhooks
Configure webhooks on the Settings tab for each site. Enable webhooks, provide a target URL, and subscribe to specific events.
Note: the target URL can only use ports 80 and 443, specified via http or https.
Webhook Limitations
Advanced Billing places two limitations on your site for how webhooks can be used. These limitations include data retention (the amount of time old webhooks are stored) and the number of endpoints allowed per site. For more information, refer to how webhooks are limited.
Webhook Timestamps
Timestamps in webhook payloads are rendered using the site’s configured timezone. Some newer event types (e.g., component_allocation_change, metered_usage) use ISO 8601 format in UTC to standardize payload formatting across systems.
Webhook Acknowledgment and Automatic Retries
Upon receiving a webhook, accept it by returning an HTTP "200 OK" response as quickly as possible. Sending any other response (e.g., "500 Internal Server Error," "404 Not Found") or failing to respond within a short period will trigger automatic retries. While the system aims to retry promptly, timing is managed via a backoff schedule.
Advanced Billing will attempt to send each webhook event up to five times before giving up. The retries follow an approximate backoff schedule:
| Attempt | Approximate timing |
|---|---|
| 1 | As soon as possible after the original event |
| 2 | ~10 seconds after the most recent failure |
| 3 | ~15 seconds after the most recent failure |
| 4 | ~90 seconds after the most recent failure |
| 5 | ~180 seconds after the most recent failure |
If you use the webhook replay feature via the webhook API or the webhook panel, avoid duplicate actions by following these suggestions:
- Use the unique webhook ID to track which webhooks you’ve already processed.
- Do not replay webhooks until the
last_sent_attimestamp is well outside the automatic retry intervals.
Inoperative Endpoints
Merchants often set up temporary webhook endpoints for testing purposes but forget to deactivate them. Inoperative endpoints can cause significant system strain as Advanced Billing attempts to deliver webhooks.
If repeated failures occur, Advanced Billing may pause or disable the endpoint. Below are examples of failure counts and their associated states:
| Failure Count | State | System Behavior |
|---|---|---|
| 1 to 25 | Enabled | Retries proceed automatically |
| 26 to 50 | Paused | Webhooks are generated in a paused state and must be manually sent using the webhooks panel. The endpoint is checked every two hours for responsiveness and re-enabled if functional. |
| 51 and over | Disabled | Webhooks are no longer generated for this endpoint |
If you delete an endpoint from Advanced Billing, any paused webhooks referencing that endpoint cannot be resent and are effectively discarded.
Webhook Metadata
Webhook records include metadata about their acceptance or rejection by your application, as well as details about errors encountered during delivery attempts. Metadata attributes include:
-
id: Unique identifier for the webhook, consistent across retries/replays. -
successful: Boolean indicating whether the webhook was accepted on its last attempt. -
created_at: Timestamp for when the webhook was created. -
accepted_at: Timestamp for when the webhook was successfully accepted. -
last_sent_at: Timestamp for the most recent delivery attempt. -
last_error_at: Timestamp for the last failed delivery attempt. -
last_error: Description of the error from the last failed attempt.
Webhooks retain their event and payload data. Refer to the Webhook API for detailed attribute documentation.
Once a webhook is accepted, the accepted_at timestamp will be filled. This timestamp can be viewed via the webhooks API or in the webhooks panel, if available for your plan.
Population of Webhook Data
Each event in Advanced Billing generates a unique webhook payload containing relevant subscriber data. However, not all values may be populated in the payload. For instance, the reason_code data is not delivered in a signup_success webhook. Use discretion to determine whether the data is available and how to handle missing information.
Webhook Verification
Using your Site shared key and a “signature” (signature_hmac_sha_256) that is calculated and sent with the webhook, you can verify the authenticity and integrity of a webhook.
Webhook Signature
Webhooks are signed using an HMAC-SHA-256 hex digest of the raw HTTP body of the webhook post, with your shared key as the secret. In Ruby:
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), site.shared_key, webhook.body)
For example, if your shared key is 123 and the webhook request body is payload[chargify]=testing&event=test, then the signature_hmac_sha_256 is: 19826d51b9f866b26eda1f154de192593360f8d0bcb63df8a28540a5dcf733f1.
This signature is sent with the webhook in the header X-Chargify-Webhook-Signature-Hmac-Sha-256. Alternatively, it can be appended to your URL as a query parameter using {signature_hmac_sha_256}.
For instance, providing the URL http://example.com/?signature_hmac_sha_256={signature_hmac_sha_256} would result in the following webhook being posted:
http://example.com/?signature_hmac_sha_256=19826d51b9f866b26eda1f154de192593360f8d0bcb63df8a28540a5dcf733f1
When in doubt, verify webhook data by checking the current resource state using the API.
Deprecation
Webhooks previously used an MD5 hex digest for signature verification (signature). While still included for backward compatibility, this method is deprecated. We recommend validating only the HMAC-SHA-256 signature (signature_hmac_sha_256). Removal of the MD5 signature may occur in a future update.
Protect your site’s shared key as you would your password. A compromised shared key could allow malicious actors to generate falsified webhooks that pass signature verification.
Finding Your Site Shared Key
Your site’s shared key is automatically generated when the site is created. You can view or update it by selecting Edit Current Site from the Site dropdown menu in the utility bar.
Webhook Testing
You can use the Webhooks Control Panel to send test webhook data to any configured endpoint. This feature lets you verify the operational status of your endpoint, though the payload may not match production webhooks. Test webhooks include the following payload:
id=123456&event=test&payload[chargify]=testing
For comprehensive testing, use a sandbox account to create test subscriptions and perform actions that trigger live webhooks. Refer to the Payload Examples article for full examples.
Testing Tip: Use a tool like Webhook.site to inspect webhook content and headers during development.
Comments
Article is closed for comments.