Documentation
Webhooks
Verify and consume WRNexus webhook events — including Stripe billing events forwarded through the WRNexus API.
WRNexus forwards billing lifecycle events from Stripe so your application can react to subscription changes without polling. All webhook endpoints follow the same conventions:
- Transport:
POSTrequests with a JSON body. - Verification: an HMAC signature in the
Stripe-Signatureheader (for Stripe) or anX-WRNexus-Signatureheader (for first-party events, planned). - Idempotency: every delivery includes a stable event ID. Re-deliveries carry the same ID so handlers can no-op safely.
- Acknowledgement: respond with
2xxwithin 10 seconds. Anything else triggers retries with exponential back-off for up to 24 hours.
Stripe billing events
POST https://api.wrnexus.com/api/webhooks/stripe
Configure the endpoint URL above in your Stripe dashboard, then set the
matching signing secret in your WRNexus environment as STRIPE_WEBHOOK_SECRET.
The API validates every request with stripe.Webhook.construct_event and
rejects unsigned or tampered payloads with 400 Bad Request.
Supported event types
| Stripe event | Effect inside WRNexus |
|---|---|
customer.subscription.created | Activates the subscription, upgrades the workspace plan. |
customer.subscription.updated | Syncs status (active, past_due, canceled) to the workspace. |
customer.subscription.deleted | Downgrades the workspace to the free plan. |
customer.subscription.paused | Soft-locks workspace writes pending payment resolution. |
invoice.payment_succeeded | Records the invoice and emails the receipt PDF to the payer. |
invoice.payment_failed | Marks the subscription past_due and starts the dunning loop. |
Events that are not in this list are acknowledged with 200 OK and logged so
they can be enabled later without redelivery.
Example payload
{
"id": "evt_1NXXyyZZ",
"object": "event",
"type": "customer.subscription.updated",
"data": {
"object": {
"id": "sub_1NaaBBCC",
"customer": "cus_1NaaCCDD",
"status": "active"
}
}
}
Example response
{
"received": true,
"eventId": "evt_1NXXyyZZ"
}
Error responses
| Code | HTTP | When |
|---|---|---|
BILLING_NOT_CONFIGURED | 503 | STRIPE_SECRET_KEY is missing on the API server. |
MISSING_SIGNATURE | 400 | The Stripe-Signature header is absent. |
INVALID_SIGNATURE | 400 | The signature failed verification against the signing secret. |
INVALID_PAYLOAD | 400 | The body could not be parsed as a Stripe event. |
Verifying signatures locally
When developing against a local API, forward Stripe events through the Stripe CLI:
stripe listen --forward-to http://localhost:9001/api/webhooks/stripe
The CLI prints a temporary whsec_… signing secret — set it as
STRIPE_WEBHOOK_SECRET in your .env and restart the API service.
Next steps
- API reference — REST endpoints for sessions, workspaces, and account data.
- Authentication — set up MFA, magic links, or OAuth before wiring billing into production.