Webhooks
PWP delivers webhook notifications to your application's IPN URL when subscription events occur.
Configuration
Set an IPN URL and secret on your application via the admin dashboard. The URL receives POST requests with JSON payloads.
Events
| Event | Trigger |
|---|---|
subscription.activated | Subscription activated |
subscription.created | New subscription activated or renewed via payment |
subscription.expired | Subscription period ended |
Payload
{
"event": "subscription.created",
"account": {
"id": "external_user_id",
"email": "user@example.com"
},
"product": {
"sku": "prod_ABC123"
},
"purchase": {
"id": "456"
},
"subscription": {
"status": "ACTIVE",
"expired": "2026-03-15 00:00:00"
},
"timestamp": "2026-02-15T12:00:00.000Z"
}
Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-PWP-Event | Event name (e.g. subscription.created) |
X-PWP-Delivery | Unique delivery ID |
X-PWP-Signature | HMAC-SHA512 hex digest (if IPN secret is set) |
Signature Verification
If your application has an IPN secret configured, each delivery includes an X-PWP-Signature header containing an HMAC-SHA512 hex digest of the raw JSON body, signed with your secret.
To verify:
- Read the raw request body (do not parse then re-serialize)
- Compute HMAC-SHA512 of the body using your IPN secret
- Compare the hex digest with the
X-PWP-Signatureheader
Retry Schedule
Failed deliveries are retried up to 5 times:
| Attempt | Delay | Total Time |
|---|---|---|
| 1 | Immediate | 0 |
| 2 | +1 minute | 1 min |
| 3 | +5 minutes | 6 min |
| 4 | +30 minutes | 36 min |
| 5 | +200 minutes | ~4 hours |
A delivery is considered successful when your endpoint responds with an HTTP 2xx status code. After all retries are exhausted, the webhook is marked as FAILED.