Skip to content
OneGate documentation
Dashboard
Guides

Webhooks

Signed notifications for every important change.

Event types

payment.created, payment.pending, payment.processing, payment.requires_action, payment.completed, payment.failed, payment.cancelled, payment.expired, payment.partially_refunded, payment.refunded, refund.created, refund.completed, refund.failed, receipt.created, receipt.issued, receipt.failed.

json
{
  "id": "evt_06GD...",
  "object": "event",
  "type": "payment.completed",
  "api_version": "2026-09-01",
  "created": 1790000000,
  "livemode": false,
  "data": { "object": { "id": "pay_...", "object": "payment", "status": "completed", ... } }
}

Verifying signatures

HeaderValue
OneGate-Signaturev1=<hex> (two values during secret rotation)
OneGate-TimestampUnix seconds
OneGate-Event-IdThe event id; use it to de-duplicate

Compute HMAC-SHA256(secret, timestamp + "." + raw_body) in hex and compare in constant time with any v1 value. Reject timestamps more than 5 minutes old.

python
import hmac, hashlib, time

def verify(secret: str, body: bytes, sig_header: str, ts_header: str) -> bool:
    if abs(time.time() - int(ts_header)) > 300:
        return False
    expected = hmac.new(secret.encode(), f"{ts_header}.".encode() + body, hashlib.sha256).hexdigest()
    return any(hmac.compare_digest(expected, p.split("=", 1)[1])
               for p in sig_header.split(",") if p.strip().startswith("v1="))

Test vector: secret whsec_test, timestamp 1700000000, body {"id":"evt_test"} → 14c4f43763339dcb1c15f41a1ff31a94f2f09f8de278f8b4392ca0d7cbcd257e.

Delivery guarantees

Delivery is at least once and ordering is not guaranteed. You may receive payment.pending after payment.completed, or the same event twice. Make handlers idempotent and treat the payment's status (or a fresh GET) as the truth.

Respond with 2xx within 10 seconds. Failed deliveries are retried after 1 minute, 5 minutes, 30 minutes, 2 hours, 8 hours, 24 hours, 48 hours and 72 hours. You can inspect every delivery, replay events, disable endpoints and rotate secrets in the dashboard (the old secret stays valid for 24 hours after rotation).