OpenSettle
ProductDevelopersPricingCustomersBlogDocs
Sign inStart building
Getting started
  • Overview
  • Quickstart
  • Core concepts
  • Supported chains
Billing
  • Checkouts
  • Subscriptions
  • Invoices
  • Refunds
Developer
  • API reference
  • SDKs
  • Webhooks
  • Errors
  • CLI
Operations
  • Reconciliation
  • Analytics
  • Security posture
OpenSettle

Stablecoin billing infrastructure. Non-custodial by design.

OpenSettle is not a money transmitter, custodian, or exchange. Funds settle directly to merchant wallets.

Get the changelog in your inbox

Product news and deep engineering notes. Unsubscribe in one click.

Product
  • Overview
  • Pricing
  • Integrations
  • vs. Stripe
  • Roadmap
  • Changelog
Developers
  • Documentation
  • API reference
  • Quickstart
  • Webhooks
  • System status
Company
  • About
  • Customers
  • Partners
  • Blog
  • Careers
  • Press
  • Brand
  • Contact sales
Legal
  • Security
  • Trust center
  • Terms
  • Privacy
  • Compliance
  • DPA
  • Subprocessors
  • Cookies
© 2026 OpenSettle Labs, Inc. All rights reserved.security.txt
All systems operational
Developer›Webhooks

Webhooks.

Every state change in your account can be delivered to your server as a signed, idempotent webhook. Retries use exponential backoff up to 24 hours. All events are available via replay from the dashboard or CLI.

Event shape

All events share the same envelope. The data field contains the resource shape you'd get from the GET endpoint for the same object.

payment.confirmed
{
  "id": "evt_01HGKM4Z7WQ4X",
  "type": "payment.confirmed",
  "created": 1728567890,
  "livemode": true,
  "api_version": "2026-04-01",
  "data": {
    "object": "payment",
    "id": "pay_9fX0a2E1",
    "amount": 199.00,
    "currency": "USD",
    "token": "USDC",
    "chain": "base",
    "status": "confirmed",
    "tx_hash": "0x9a2f…3bc1",
    "block": 24822413,
    "confirmations": 4,
    "customer": "cus_9fX0a2E1",
    "fee": 2.985,
    "net": 196.015
  },
  "request": { "id": "req_01HGKM4Z7WQ4X" }
}

Verifying signatures

Every webhook request includes an Opensettle-Signature header with a timestamp and HMAC-SHA256 signature over the raw request body.

verify.ts
import crypto from "node:crypto";

export function verify(body: string, header: string, secret: string) {
  const [ts, sig] = header.split(",").map((s) => s.split("=")[1]);
  const payload = `${ts}.${body}`;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    throw new Error("Invalid signature");
  }
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
    throw new Error("Timestamp outside tolerance");
  }
  return JSON.parse(body);
}

Retries

We retry with exponential backoff for up to 24 hours if your endpoint doesn't return a 2xx within 15 seconds. The full schedule is: 30s, 2m, 10m, 30m, 1h, 3h, 6h, 12h, 24h. After 24 hours of failures, the event goes to a dead-letter state and is replayable from the dashboard.

Idempotency

Webhook delivery can send the same event twice — for example, if your server took 14 seconds to respond. Use the event id as your dedup key; storing processed event IDs for 30 days is sufficient.

Core conceptsAPI reference