Webhooks are how Points tells your backend that something happened — an order was approved, a refund was issued, a shipping status changed. You register one or more HTTPS endpoints; Points posts JSON to them whenever an event fires. Webhooks are the source of truth for order state on your side. Poll-based reconciliation is a safety net, not the primary path.Documentation Index
Fetch the complete documentation index at: https://docs.papp.sa/llms.txt
Use this file to discover all available pages before exploring further.
When webhooks fire
| Event | Fired when |
|---|---|
approved | Order completes and points are settled |
authorized | Funds authorised (auth+capture PSPs) |
captured | Previously authorised funds captured |
cancelled | Order cancelled |
completed | Replacing order completed via POST /orders/{uuid}/complete |
refunded | Full or partial refund processed |
auto_refunded | Internal automatic reversal performed by Points |
shipping_status_updated | Shipping status changed via POST /orders/{uuid}/status |
Delivery mechanics
- Transport — HTTPS POST,
Content-Type: application/json. - Timeout — 10 seconds per attempt.
- Retries — up to 3 attempts on transient failure (non-2xx response, network error, timeout).
- Delivery order — not guaranteed. Your handler must be idempotent (see below).
- Headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Webhook-Secret | The secret you registered with the webhook (use this to verify authenticity) |
X-Webhook-Event | Event name (e.g. approved). Same value as event in the body. |
Payload shape
Every event has the same envelope:order (e.g. status + status_label for shipping_status_updated). See Webhook events for per-event fields.
Register a webhook
Use the API, or the dashboard (Settings → Webhooks). Example:Multiple endpoints
You can register more than one webhook per merchant. Common reasons:- Separate environments (staging vs production).
- Separate downstream consumers (fulfilment, analytics, CRM).
- A “dead-letter inspector” endpoint that only logs for audit.
Handling webhooks
The recommended consumer pattern boils down to four rules:- verify
X-Webhook-Secret - acknowledge quickly with
2xx - enqueue work instead of processing inline
- deduplicate on
(order.id, event)
Recommended handling sequence
Verifying the secret
Use a constant-time comparison so you don’t leak timing information.Fast-ack pattern
Your endpoint must respond 2xx within the 10-second timeout budget. Anything slower triggers a retry, which leads to duplicates. Do this:- call slow third-party services before responding
- send email synchronously
- update ERP/WMS inline if it can block the response
Idempotency strategy
Points may deliver the same(order.id, event) pair more than once — retry loops, backend replays, network blips. Design your handler so repeat deliveries are safe.
Recommended database uniqueness rule:
200 and do nothing.
Status codes
| Your response | Meaning |
|---|---|
200 / 204 | Accepted |
401 / 403 | Secret invalid |
5xx | Temporary processing failure; may trigger retry |
Retry expectations
Current backend behavior:- each outbound request uses a
10second timeout - the job retries up to
3times on failure
Local development
Webhooks need a publicly reachable HTTPS URL. In local dev, tunnel your laptop to the internet:- ngrok —
ngrok http 3000 - Cloudflare Tunnel —
cloudflared tunnel --url http://localhost:3000 - localtunnel —
lt --port 3000
Operational tips
Log verification failures separately
Log verification failures separately
A sudden wave of secret mismatches often means the secret was rotated on one side only, or the endpoint was copied incorrectly.
Persist raw payload for audit
Persist raw payload for audit
Store the raw JSON and headers for a limited retention period in staging/production so support can reconcile difficult cases.
Use one secret per environment
Use one secret per environment
Never reuse production webhook secrets in staging or local development.
Next
Webhook events
Per-event payload schemas and sample bodies.
Webhook management
CRUD operations via API or dashboard.

