Webhooks

Payr sends webhook notifications to your configured endpoint when payment events occur. Webhooks are signed with HMAC-SHA256 and retried on failure.

Contact [email protected] to configure your webhook URL and receive your webhook secret.

Event Types

Event
Status
Description

payment_success

completed

Payment was completed successfully

payment_failed

failed

Payment was declined or failed

payment_pending

pending

Payment is awaiting confirmation (e.g., 3DS)

Common Payload Fields

All webhook payloads include these fields:

Field
Type
Description

event

string

Event type

student_ref

string

Your external student/tenant reference

payment_id

string

Payr payment ID

amount

integer

Payment amount in minor units (pence). 85000 = £850.00

currency

string

Currency code (e.g., "GBP")

timestamp

string

ISO 8601 timestamp

payment_method

string

Payment method (e.g., "card")

transaction_id

string

Acquirer transaction ID

status

string

"completed", "failed", or "pending"

Full Payload Examples

payment_success:

Extra Field
Type
Description

schedule_activated

boolean

Whether an installment schedule was activated

schedule_id

string

Schedule ID (present when schedule_activated is true)

next_installment_date

string or null

Next installment due date

payment_failed:

Extra Field
Type
Description

error_code

string

Machine-readable error code

error_message

string

Human-readable error description

payment_pending:

Extra Field
Type
Description

pending_reason

string

Reason the payment is pending

Signature Verification

All webhooks include an X-Payr-Signature header containing an HMAC-SHA256 signature. Always verify the signature before processing the payload.

Steps:

  1. Serialize the JSON payload with compact separators (no spaces) and sorted keys

  2. Compute HMAC-SHA256 using your webhook secret

  3. Compare the result with the X-Payr-Signature header value using a timing-safe comparison

Python:

Node.js:

Important for Node.js: The payload must be serialized as compact JSON with sorted keys to match the signature. If possible, verify against the raw request body string rather than re-serializing.

Retry Policy

If your endpoint returns a non-2xx status or is unreachable, Payr retries up to 3 times with increasing backoff:

Attempt
Delay

1

1 second

2

5 seconds

3

15 seconds

Your endpoint should return a 200 status code to acknowledge receipt. All delivery attempts (successful and failed) are logged on Payr's side.


Last updated