Webhooks Reference
Webhooks are essential for PaywallWP Pro to function correctly. They allow payment gateways to notify your site about subscription events in real-time.
Setup Instructions
For step-by-step webhook setup, see the tutorials:
Why Webhooks Are Required
Without webhooks:
- ❌ Subscriptions won't activate after payment
- ❌ Recurring payments won't update status
- ❌ Cancellations won't sync
- ❌ Refunds won't be reflected
- ❌ Failed payments won't be handled
With webhooks:
- ✅ Instant subscription activation
- ✅ Automatic renewal processing
- ✅ Real-time cancellation sync
- ✅ Automatic refund handling
- ✅ Failed payment notifications
Webhook Endpoints
| Gateway | Endpoint URL |
|---|---|
| Stripe | https://yoursite.com/wp-json/paywallwp/v1/stripe-webhook |
| PayPal | https://yoursite.com/wp-json/paywallwp/v1/paypal-webhook |
Replace yoursite.com with your actual domain.
HTTPS Required
Webhook URLs must use HTTPS. Payment gateways will reject HTTP endpoints.
Required Events
Stripe Events
| Event | Purpose |
|---|---|
checkout.session.completed | Initial subscription payment completed |
customer.subscription.created | New subscription created |
customer.subscription.updated | Plan changes, renewals, status updates |
customer.subscription.deleted | Subscription canceled or ended |
invoice.paid | Successful renewal payment |
invoice.payment_failed | Failed renewal payment |
charge.refunded | Refund processed |
PayPal Events
| Event | Purpose |
|---|---|
BILLING.SUBSCRIPTION.ACTIVATED | New subscription started |
BILLING.SUBSCRIPTION.CANCELLED | Subscription canceled |
BILLING.SUBSCRIPTION.EXPIRED | Subscription period ended |
BILLING.SUBSCRIPTION.SUSPENDED | Payment failed, subscription paused |
PAYMENT.SALE.COMPLETED | Payment received |
PAYMENT.SALE.REFUNDED | Refund processed |
Test vs Live Webhooks
You need separate webhooks for each environment:
| Environment | Stripe | PayPal |
|---|---|---|
| Test/Sandbox | Create in Test mode | Create in Sandbox app |
| Live/Production | Create in Live mode | Create in Live app |
Don't Reuse Webhooks
Each environment has different API keys and webhook secrets. Always create new webhooks when switching between test and live modes.
Verifying Webhook Setup
Stripe
- Go to Stripe Webhooks Dashboard
- Click on your webhook endpoint
- View Recent webhook attempts
- ✓ Green checkmark = successful delivery (HTTP 200)
PayPal
- Go to PayPal Developer Dashboard
- Select your app → Webhooks section
- Click your webhook to view event log
- HTTP 200 status = successful delivery
Common Issues
Webhooks Not Being Received
| Cause | Solution |
|---|---|
| Wrong URL | Check for typos, ensure HTTPS |
| Firewall blocking | Whitelist payment gateway IPs |
| REST API disabled | Enable in security plugin settings |
| Plain permalinks | Switch to any other permalink structure |
Webhook Returns Error
| Cause | Solution |
|---|---|
| Invalid signing secret | Re-copy from gateway dashboard |
| PHP errors | Check /wp-content/debug.log |
| Timeout | Increase PHP max execution time |
| Memory limit | Increase PHP memory limit |
Payment Works, Subscription Doesn't Activate
This is always a webhook issue:
- Check webhook delivery status in gateway dashboard
- Verify signing secret/webhook ID is correct
- Enable
WP_DEBUG_LOGand check error logs - Ensure all required events are selected
Local Development
For testing webhooks on localhost:
Stripe CLI
# Install
brew install stripe/stripe-cli/stripe
# Login
stripe login
# Forward webhooks locally
stripe listen --forward-to localhost/wp-json/paywallwp/v1/stripe-webhook
The CLI provides a temporary signing secret for local testing.
ngrok (for PayPal)
# Install
brew install ngrok
# Expose local site
ngrok http 80
# Use the ngrok URL for webhooks
# https://abc123.ngrok.io/wp-json/paywallwp/v1/paypal-webhook
Security Notes
- Never share signing secrets or webhook IDs publicly
- Webhooks are cryptographically verified — don't skip verification
- Monitor webhook logs for unusual activity
- Use HTTPS exclusively