Webhooks
PayRequest can send signed HTTP POST requests when a payment succeeds or a security deposit changes status. Use these events to automate fulfillment, synchronize bookings, or trigger downstream workflows without polling.
Setup
- Go to Settings → API & MCP in your PayRequest dashboard
- Scroll down to the Webhooks section
- Enter your endpoint URL (must be publicly reachable over HTTPS)
- Click Save — a signing secret is generated automatically
- Copy the Signing Secret and store it securely in your environment
Verifying signatures
Every request includes an X-PayRequest-Signature header containing an HMAC-SHA256 signature of the raw request body. Always verify this before processing the event.
Always use a timing-safe comparison (hash_equals, hmac.compare_digest, timingSafeEqual) to prevent timing attacks.
Event: payment.succeeded
Fired when a transaction status changes to paid. Delivered asynchronously via the queue (typically within seconds).
Payload
Fields
Security deposit events
Security deposit integrations can receive:
deposit.created
deposit.authorized
deposit.partially_captured
deposit.captured
deposit.released
deposit.expired
deposit.failed
The request also includes X-PayRequest-Event with the event name. See the Security Deposits API for the payload and integration flow.
Retries
Security deposit webhook delivery uses 5 attempts with increasing backoff intervals. Payment webhook delivery uses the existing payment queue policy.
Return any 2xx status code to acknowledge receipt.
Rotating the secret
If your secret is compromised, go to Settings → API & MCP → Webhooks and click Regenerate. Your old secret stops working immediately — update your environment variable before rotating.
Testing locally
Use a tunnel tool to expose your local server during development: