Custom Webhook
Use the custom webhook when your store is not Tebex. Your backend posts signed events to ShardAnalytics, and the platform treats them like any other store integration: revenue, declines, refunds, player matching, and campaign attribution.
Endpoint
Section titled “Endpoint”POST https://api.shardanalytics.com/v1/webhooks/<tenantId>/customThe endpoint is deterministic. You do not call an API to create it; configure it in Organization Settings → Payments → Custom.
Signature
Section titled “Signature”Every request must include an X-Signature header computed with HMAC-SHA256 over the raw request body:
bodyHash = SHA256(rawBody)signature = HMAC-SHA256(bodyHash, secret)Send the lowercase hex digest in X-Signature. Compute it against the exact bytes you send, before any re-serialisation. The secret is set in the dashboard and stored encrypted.
Payload
Section titled “Payload”{ "type": "payment.completed", "transaction_id": "order-10231", "timestamp": "2026-10-04T18:22:11Z", "amount": 14.99, "currency": "USD", "player": { "id": "00000000-0000-0000-0000-000000000000", "username": "Steve_" }, "packages": [{ "id": "vip-plus", "name": "VIP+ Rank Upgrade", "quantity": 1 }], "country": "GB", "creator_code": "stevebuilds"}| Field | Required | Notes |
|---|---|---|
type | Yes | payment.completed, payment.declined, or payment.refunded. |
transaction_id | Yes | Unique identity for the event. Use your own order or event ID. |
timestamp | No | ISO-8601 event time. |
amount | No | Numeric amount in the store currency. |
currency | No | Three-letter code; defaults to USD when omitted. |
player.id / player.username | No | Used to match the purchase to a player. |
packages[] | No | Item identifiers and names for package reporting. |
country | No | Buyer country. |
creator_code | No | Creator code for campaign attribution. |
Validation event
Section titled “Validation event”When you set up the integration, ShardAnalytics may send a validation payload. Reply with the echoed ID:
// request{ "type": "validation.webhook", "transaction_id": "test-validation" }
// response{ "id": "test-validation" }Delivery semantics
Section titled “Delivery semantics”- Retries can deliver the same event more than once. Make your sender and the platform tolerant of duplicates by keeping
transaction_idstable per event. - Events may arrive out of order. Use
timestampfor event time andtransaction_idfor identity. - Replay protection is limited to signature verification; there is no documented timestamp tolerance window, so keep your signing secret private and rotate it if exposed.
Setup checklist
Section titled “Setup checklist”- Choose Custom in Organization Settings → Payments.
- Generate and store a secret in your backend.
- Set the same secret in the dashboard.
- Send a validation event and confirm the integration becomes active.
- Map your store to servers if you want per-server revenue.