Skip to main content

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

  1. Go to Settings → API & MCP in your PayRequest dashboard
  2. Scroll down to the Webhooks section
  3. Enter your endpoint URL (must be publicly reachable over HTTPS)
  4. Click Save — a signing secret is generated automatically
  5. 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: