Transport security
- All Points endpoints are served over HTTPS only. Plain-HTTP requests are rejected at the edge.
- Use a client that validates the TLS certificate chain by default. Never disable certificate verification in production code.
- Minimum TLS version: TLS 1.2. TLS 1.3 is preferred where your HTTP client supports it.
API key handling
See API keys for issuance and rotation. The short version:- Public key — safe in browser/mobile. Used only for the Checkout redirect endpoint.
- Private key — server-side only. Loaded from a secrets manager or environment variable. Never committed to source, never returned to the client, never logged in plaintext.
- Rotate immediately if a key may have been exposed. Old keys are revoked instantly on regeneration.
Webhook security
Points delivers webhook events with a shared secret in the header:What to verify on every webhook
Check the X-Webhook-Secret header
Compare it against the secret you stored when registering the webhook. Reject any request where the header is missing or does not match.
Use constant-time comparison
In PHP use
hash_equals(); in Node use crypto.timingSafeEqual(); in Python use hmac.compare_digest(). A naïve === leaks timing information.Return 2xx quickly, then process asynchronously
Acknowledge within a few seconds. Push the payload to a queue and let a worker handle the business logic. Slow responses cause retries and duplicates.
What NOT to do
Idempotency
Useorder_number as your deduplication key. If you retry a call with the same order_number inside the distributed-lock window, you will receive a 429 — retry after a short back-off rather than issuing parallel calls.
On the webhook side, the same (order.id, event) pair may be delivered more than once. Your handler must tolerate this safely (e.g. by checking whether you’ve already recorded the event in your DB before acting).
Network & infrastructure
- Outbound from your backend — Points API requests are standard HTTPS on port 443. No special firewall holes required.
- Inbound (your webhook endpoint) — must accept HTTPS POST from Points’ egress. IP allow-listing is optional; the primary trust boundary is the
X-Webhook-Secretheader. - Timeout budget — the Points webhook worker times out at 10 seconds and retries up to 3 times. Keep your endpoint response under ~2 seconds.
Logging & redaction
- Never log the Private API key or
x-api-keyheader. Configure request loggers (e.g. axios interceptors, LaravelHttp::fake()transcripts, nginx access logs) to redact it. - Never log the
X-Webhook-Secretheader for the same reason. - PII:
phone_numberis personally identifiable — redact it from logs unless your logging store meets your compliance requirements.
Rate limits & concurrency
- Earning order creation is serialised per merchant with a distributed lock. Concurrent calls for the same merchant receive
429. Design your checkout completion pipeline to be serial, not parallel. - Other endpoints do not currently enforce a hard rate limit, but abusive traffic will be throttled upstream. Keep production traffic well-shaped.
Checklist
✅ Production readiness
✅ Production readiness
- Private key stored in a secrets manager
- No API key in any committed file or client bundle
- HTTPS enforced on your webhook endpoint
-
X-Webhook-Secretverified on every incoming webhook with constant-time comparison - Webhook handler returns 2xx within 2 seconds and processes asynchronously
- Webhook handler is idempotent on
(order.id, event) - Logging redacts
x-api-key,X-Webhook-Secret, and PII - Key rotation runbook documented internally
Next steps
Webhook handling
Verify, acknowledge, and process webhook events safely.
Go-live checklist
Final checks before flipping production traffic.

