Webhooks
Verify signed 0Bit events, handle retries, dedupe event ids, and reconcile payment, swap, liquidity, settlement, and scan activity.
Webhooks are the backend source of truth for asynchronous 0Bit state. Browser callbacks can make the UI feel responsive, but they are not enough to fulfill orders, update balances, release goods, mark invoices paid, or close reconciliation tasks.
Use webhooks to receive signed events from product surfaces such as 0Gate sessions, payment or settlement records, pool trades, mint/burn activity, and scan-visible protocol updates where supported.
Verify before parsing business logic
Signature verification must use the raw request body. Do not parse JSON, mutate whitespace, or reserialize the body before verification.
What this page covers
- Webhook endpoint behavior.
- Signature verification with raw request bodies.
- Event deduplication and durable handling.
- Delivery logs, replay, and test events.
- How webhooks relate to browser callbacks and API reads.
Event ingestion lifecycle
Minimum handler contract
| Step | Requirement |
|---|---|
| Receive raw body | Configure your framework so the webhook route receives bytes, not already-parsed JSON. |
| Verify signature | Use the Gate-Signature or product-specific signature header with your whsec_* secret. |
| Reject invalid or stale events | Return 400 for invalid signatures before any state changes. |
| Dedupe | Store event ids and ignore duplicate deliveries after the first durable handling. |
| Persist first | Update your database or enqueue a durable job before returning 2xx. |
| Return quickly | Long-running fulfillment should be queued after the event is persisted. |
Express example
import express from "express";
import { GateClient } from "@0bit/gate";
const gate = new GateClient({ apiKey: process.env.OBIT_SECRET_KEY! });
const app = express();
app.post("/webhooks/0bit", express.raw({ type: "application/json" }), (req, res) => {
try {
const event = gate.webhooks.constructEvent(
req.body,
req.header("Gate-Signature"),
process.env.OBIT_WEBHOOK_SECRET!,
);
// Store event.id before fulfillment so retries are idempotent.
// Fulfillment should be driven by verified event type + object status.
res.sendStatus(200);
} catch {
res.status(400).send("invalid signature");
}
});Delivery operations
0Gate includes delivery operations that help partners test and recover webhook endpoints.
| Operation | Purpose | Notes |
|---|---|---|
GET /webhooks/deliveries | List your outbound delivery log. | Scoped to your partner; includes delivery status, attempts, response status, and last error. |
POST /webhooks/deliveries/{id}/replay | Requeue a dead-lettered delivery. | Only for your own dead-lettered deliveries. |
POST /webhooks/test | Send a synthetic webhook.test event. | Use it to verify endpoint reachability and signature handling. |
Delivery logs are for operational health. They are not a place to expose raw payloads, PII, provider details, or another partner's events.
Event handling model
| Event input | Use it for | Do not use it for |
|---|---|---|
| Event id | Dedupe retries and audit event handling. | User-facing order ids by itself. |
| Object id | Read the session, quote, trade, payment, settlement, or transaction record. | Inferring product availability. |
| Event type | Route to the correct handler. | Free-form string parsing beyond documented events. |
| Request id | Support and traceability. | Secrets or PII. |
| Metadata / user reference | Join back to your order/account/invoice. | Trusting client-provided data without server records. |
Browser callback vs webhook
| Signal | Trust level | Use it for |
|---|---|---|
Browser onSuccess callback | UX hint | Show a progress screen and tell the user you are confirming. |
| Redirect return URL | UX/navigation hint | Restore app state and show pending/completed status from your server. |
| Verified webhook | Backend source of truth | Fulfillment, balances, invoices, settlement, and reconciliation. |
| Trusted API read | Backend confirmation | Reconcile missed webhooks or support investigations. |
Retry and replay behavior
Your endpoint should be safe to receive the same event more than once. A retry may happen because your endpoint returned a non-2xx status, timed out, or was temporarily unreachable. Replay may happen when an operator requeues a dead-lettered delivery.
| Scenario | Handler behavior |
|---|---|
| First valid delivery | Verify, persist, handle, return 2xx. |
| Duplicate valid delivery | Verify, find existing event id, return 2xx without double-fulfillment. |
| Invalid signature | Return 400; do not parse business logic. |
| Valid event but unknown object | Persist the event and queue investigation or a trusted API read. |
| Downstream service down | Persist event, queue retry internally, return based on whether durable handling succeeded. |
Production checklist
- Webhook URL is HTTPS in live mode.
- Raw body verification is implemented.
- Sandbox and live webhook secrets are separate.
- Event id dedupe table exists.
- Handler is idempotent.
- Durable persistence happens before
2xx. - Browser callbacks do not fulfill orders.
- Delivery logs are monitored.
- Dead-letter replay process is documented.
- Request ids, event ids, object ids, and partner references are logged.
Related pages
Webhook signing
Implement raw-body signature verification.
Webhooks API
Review delivery, replay, and test-event API behavior.
Webhook events
See the public-safe event catalog and handler rules.
0Gate quickstart
Build the hosted session flow with signed webhooks.
Errors and rate limits
Handle retries, failures, and duplicate writes safely.