Definition
A webhook is a server-to-server notification: when an event happens at one service (payment gateway, third-party API), that service sends an HTTP POST request to a URL you specify, containing details about the event. Webhooks enable real-time, asynchronous integration between systems without constant polling.
For subscription billing, webhooks are essential: gateways notify your store when charges succeed, fail, or are refunded — and many of these events happen outside any user action (renewals, retry attempts, asynchronous bank decisions).
Why It Matters for WooCommerce Stores
Without webhooks, your subscription state desyncs from the payment gateway state. A renewal charge succeeds at 2:00 AM but your store doesn't know until tomorrow when you check the gateway dashboard manually.
A customer's card is updated via the gateway's self-service portal but your store still shows the old card. Webhooks make all of this real-time and automatic.
For WooCommerce subscription stores, properly configured webhooks are the difference between automated billing operations and manual reconciliation nightmares. Misconfigured webhooks cause the most common subscription bugs — silent failures where the gateway charged but your store doesn't reflect it.
How It Works
You register a webhook URL in your gateway dashboard (e.g., yoursite.com/wc-api/wc_stripe). When an event happens at the gateway (payment_intent.succeeded, customer.subscription.updated), the gateway sends an HTTP POST to your URL with a JSON payload describing the event.
Your store validates the request signature (proving it came from the gateway, not a malicious actor), processes the event (extends subscription, sends email, updates database), and returns 200 OK. If the gateway gets an error or no response, it retries with exponential backoff for hours or days.
Real-World Example
A Stripe subscription renewal fires at 2:00 AM Friday. Stripe processes the $39 charge — success.
Stripe sends a `invoice.payment_succeeded` webhook to `https://store.com/wc-api/wc_stripe` with payload including subscription ID, amount, and timestamp. WPSubscription receives it, validates the signature against the Stripe webhook secret, extends the subscription by 30 days, creates a renewal order in WooCommerce, and queues a receipt email.
The customer wakes up Friday morning to find a receipt — all from the webhook firing while they slept.
Best Practices
- Always verify webhook signatures — unsigned webhook handling is a security vulnerability
- Make webhook handlers idempotent — receiving the same event twice should be safe
- Respond within 5 seconds — long-running handlers cause timeouts and retries
- Log every webhook for debugging — gateway retries can mask issues
- Use webhook test events from gateway dashboards to verify integration
Common Mistakes
- Not verifying webhook signatures — security risk and source of integration bugs
- Long-running webhook handlers that timeout — gateways retry, causing duplicate processing
- Not handling retry events — webhook may fire multiple times for the same event
- Hard-coding production webhook URLs in test mode — events go to wrong environment
- Ignoring webhook delivery failures in gateway dashboards — silent failures destroy data integrity
In WooCommerce with WPSubscription
WPSubscription receives gateway webhooks at standardized WooCommerce endpoints (/wc-api/wc_stripe, /wc-api/wc_paypal, etc.). The plugin handles signature verification, event processing, and retry logic for each supported gateway automatically.
Misconfigured webhooks are the #1 source of subscription bugs — always verify webhook setup during initial gateway integration.