Webhooks
Source of truth: The webhook is the only source of truth for marking orders paid and triggering fulfilment. Success and cancel URLs are for user experience only.
Configure a Webhook URL and Signing secret in PayShare Admin (per integration). When a session completes (or is cancelled/expired), PayShare POSTs a JSON payload to your URL. You must verify the signature before trusting the event.
Header: X-PayShare-Signature: <hmac-hex> (or signature in body for legacy).
Verification: HMAC-SHA256 of the canonical JSON (keys sorted alphabetically, no extra whitespace), using your signing secret. Compare result with the received signature using a constant-time compare.
Payload (canonical keys, alphabetical): completedAt, currency, eventId, eventType, expiresAt, integrationId, livemode, orderReference, participantsRequired, sessionId, totalAmount.
Example (logical shape):
{
"eventType": "PAYSHARE_SESSION_COMPLETED",
"eventId": "unique-event-id",
"sessionId": "session-uuid",
"orderReference": "your-order-ref",
"totalAmount": 50.00,
"currency": "NZD",
"participantsRequired": 2,
"completedAt": "2026-01-15T12:00:00Z",
"livemode": true,
"integrationId": "integration-uuid",
"expiresAt": "2026-01-16T12:00:00Z"
}Event types
- PAYSHARE_SESSION_COMPLETED – All participants have paid. Use this as the only event that triggers fulfilment (mark order paid, send confirmation email).
- PAYSHARE_SESSION_CANCELLED – User or host cancelled. Use to update order state (e.g. pending → cancelled); do not trigger fulfilment.
- PAYSHARE_SESSION_EXPIRED – Session timed out. Use to update order state; do not trigger fulfilment.
Handler steps
- Parse JSON.
- Build canonical payload (same key order as above).
- Compute HMAC-SHA256(canonical, signing_secret).
- Compare with
X-PayShare-Signature(constant-time). - If invalid, respond 401.
- Use
eventIdfor idempotency (ignore duplicate events). - For COMPLETED only, mark order/booking as paid. Look up your order by
orderReferenceorsessionId.
Redirect: Completion also sends the user to your successUrl with the same data as signed query params. Use that only for the thank-you page; the webhook is the source of truth. Verify the redirect signature too (same algorithm) if you use it.
Retries: We may retry webhooks on 5xx or timeout. Respond with 200 for already-processed events (use eventId) so duplicate deliveries do not cause double fulfilment.
See: Integration reference · Error codes