Appearance
Webhooks
Webhooks let FairShare send split-session events to your backend in near real time.
Use webhooks to:
- update order/payment state in your system
- trigger fulfillment only after a terminal event (for example
split_session.completed) - keep your system in sync without polling
Webhooks are environment-specific:
- Sandbox endpoints receive only sandbox events.
- Live endpoints receive only live events.
If you move to live, create a live webhook endpoint separately. For more details, see Sandbox vs Live.
Endpoint Requirements
Your webhook endpoint should:
- accept
POSTrequests withContent-Type: application/json - be publicly reachable over HTTPS
- return a
2xxresponse quickly after basic validation and enqueueing - avoid long synchronous work in the request thread
FairShare treats these as successful delivery:
- any
2xxstatus 409(useful when your side already processed the event and treats it as duplicate)
Webhook Headers
Each delivery includes:
X-SplitPay-Event: event name (for examplesplit_session.completed)X-SplitPay-Delivery: unique delivery attempt IDX-SplitPay-Timestamp: Unix timestamp (seconds)X-SplitPay-Signature: HMAC signature, formatv1=<hex>
Signature Verification
Verify every webhook before processing.
Signing format:
- Build the signed payload string:
timestamp + "." + rawBody - Compute
HMAC-SHA256using your webhook signing key - Compare against
X-SplitPay-Signaturevalue after removing thev1=prefix
Also enforce a timestamp tolerance window (for example 5 minutes) to reduce replay risk.
Event Payload Shape
All webhook events use this envelope:
json
{
"id": "event_uuid",
"type": "split_session.completed",
"created": "2026-04-08T10:15:30Z",
"data": {
"object": {}
}
}id: unique event ID (stable identifier for dedupe on your side)type: event typedata.object: event-specific object payload
Example (split_session.completed):
json
{
"id": "7f7dfef6-c76a-4ef0-a631-fd8caea3abec",
"type": "split_session.completed",
"created": "2026-04-08T10:15:30Z",
"data": {
"object": {
"id": "9f6e96d3-7b18-4f0e-96b8-e2eb9f6a2a1c",
"merchantId": 123,
"status": "COMPLETED",
"environment": "SANDBOX",
"gateway": "STRIPE",
"currency": "QAR",
"total": 200.00,
"collected": 200.00,
"createdAt": "2026-04-08T10:00:00Z",
"splitType": "EQUAL_COUNT",
"expectedContributors": 4,
"minContribution": null,
"convenienceFeeType": "FIXED_PER_CONTRIBUTION",
"convenienceFeeValue": 2.50,
"splitSessionLink": "https://app.fairsharepay.com/contributor/9f6e96d3-7b18-4f0e-96b8-e2eb9f6a2a1c",
"leadContributorName": "Jane Doe",
"leadContributorEmail": "jane@example.com",
"completedAt": "2026-04-08T10:15:29Z",
"meta": "order-123"
}
}
}Webhook Events
| Event | What it means |
|---|---|
contribution.created | A new contribution was created for a split session. |
split_session.created | A new split session was created. |
split_session.lead_authorized | The lead contributor's payment was successfully authorized. |
split_session.partial | The split session has received some funding but is not complete. |
split_session.completed | The split session is fully completed. |
split_session.expired | The split session expired before completion. |
split_session.canceled | The split session was canceled. |
split_session.refunded | A completed split session was refunded. |
split_session.status_changed | Generic status transition event with fromStatus and toStatus. |
Delivery and Retries
Delivery is asynchronous and at-least-once. You may receive duplicates or out-of-order events.
Retry behavior:
- retried on network failure / timeout
- retried on HTTP
408,429, and5xx - not retried on other
4xxresponses - up to multiple retry cycles with increasing backoff
Because delivery is at-least-once, your handler must be idempotent.
Idempotent Processing Pattern
Recommended server-side flow:
- Verify signature and timestamp.
- Parse JSON and extract
event.id,type, anddata.object.id. - Check if
event.idhas already been processed. - If already processed, return
200(or409) immediately. - Enqueue work or apply state transition transactionally.
- Mark
event.idas processed. - Return
2xx.
Delivery Attempts in Dashboard
In the dashboard, each attempt shows:
- attempt time
- event type
- result
- HTTP status code
- request body
- response body
Use this view to debug signature failures, endpoint timeouts, and non-retryable 4xx responses.
Recommended Integration Flow
- Create webhook endpoint in sandbox.
- Implement signature verification and idempotent processing.
- Test success and failure scenarios and review delivery attempts.
- Promote the same implementation to live.
- Create a separate live webhook endpoint and signing key.