SERVER-TO-SERVER
Use webhooks as a trigger, not as the source of truth.
A merchant-controlled PBE node can watch an exact payment tuple and send HMAC-authenticated state changes to your backend. The merchant order and blockchain state remain authoritative.
Secrets stay server-sideNever place the webhook management token, signing secret, or database credentials in browser JavaScript, wallet URLs, mobile apps, game clients, or downloadable examples.
Receiver checklist
- Read the exact raw request body before decoding JSON.
- Verify
X-Paybyte-Signaturewith HMAC-SHA256 using the node's signing secret. - Reject stale timestamps.
- Store or deduplicate the event ID.
- Load the merchant order by its own reference and re-check recipient, amount, canonical state, and confirmation depth.
- Fulfil in an idempotent transaction.
PHP signature verification
PHP
$raw = file_get_contents('php://input');
$timestamp = (int)($_SERVER['HTTP_X_PAYBYTE_TIMESTAMP'] ?? 0);
$provided = preg_replace('/^v1=/i', '', $_SERVER['HTTP_X_PAYBYTE_SIGNATURE'] ?? '');
$expected = hash_hmac('sha256', $timestamp . '.' . $raw, $signingSecret);
if (abs(time() - $timestamp) > 300 || !hash_equals($expected, strtolower($provided))) {
http_response_code(401);
exit;
}Operational event handling
| Event | Merchant action |
|---|---|
| payment.pending | Display pending state only; do not fulfil. |
| payment.confirming | Track confidence as canonical confirmations increase. |
| payment.confirmed | Re-verify the stored order tuple, then fulfil exactly once if policy is met. |
| payment.reorged | Re-evaluate order state according to your settlement policy. |
| payment.expired | Stop waiting on this watch; leave the merchant order unpaid unless separate verification succeeds. |
Endpoint registration, headers, event payloads and callback-network restrictions are specified in the Commerce webhook developer reference. The complete implementation example is available under Golden Sword.
