StableOps
Concepts

Webhooks

Real-time notifications for payment events and system alerts.

Webhooks allow your application to receive real-time notifications when events occur in StableOps, such as when a payment is detected, confirmed, or finalized.

Overview

Instead of polling the API to check payment status, StableOps sends HTTP POST requests to your server when events happen. This enables:

  • Real-time updates: Know immediately when payments arrive
  • Reduced API calls: No need to poll for status changes
  • Reliable delivery: Automatic retries with exponential backoff
  • Event history: All webhook deliveries are logged and can be replayed

How Webhooks Work

┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│  Blockchain │────────▶│  StableOps  │────────▶│  Your App   │
└─────────────┘         └─────────────┘         └─────────────┘
   Payment sent          Event detected         Webhook sent
  1. An event occurs (e.g., payment detected on blockchain)
  2. StableOps creates a webhook delivery
  3. HTTP POST request is sent to your endpoint
  4. Your server processes the event and returns 200 OK
  5. If delivery fails, StableOps retries with exponential backoff

Webhook Events

Payment Events

payment_order.created

Sent when a new payment order is created.

{
  "type": "payment_order.created",
  "data": {
    "id": "po_abc123",
    "merchant_order_id": "order_123",
    "scenario": "checkout",
    "amount": "10.00",
    "settlement_asset": "USDC",
    "status": "created",
    "expires_at": "2024-01-01T12:30:00Z",
    "metadata": {
      "user_id": "user_456"
    },
    "created_at": "2024-01-01T12:00:00Z",
    "accepted_assets": [
      { "chain": "base", "asset": "USDC" }
    ],
    "payment_instructions": [
      { "chain": "base", "asset": "USDC", "address": "0x1234..." }
    ]
  }
}

payment.detected

Sent when a payment transaction is first seen on the blockchain (0 confirmations).

Action: Update UI to show "Payment received, confirming..."

Warning: Do not fulfill the order yet - the transaction could still be reverted.

payment.finalized

Sent when the payment has reached finality and cannot be reverted.

Action: Safe to fulfill the order - payment is guaranteed.

This is the recommended event to trigger order fulfillment.

Setting Up Webhooks

1. Create an Endpoint

In your StableOps dashboard:

  1. Go to DevelopersWebhooks
  2. Click Add Endpoint
  3. Enter your webhook URL (must be HTTPS in production)
  4. Select which events to receive (omit enabled_events on create to subscribe to everything)
  5. Save the webhook secret

The secret field is returned only on create and rotate — store it somewhere durable; the dashboard will not show it again. After you call rotate-secret, the previous secret stays valid alongside the new one for 24 hours, so you can roll out the new value without dropping deliveries.

2. Verify Signatures

Always verify webhook signatures to ensure requests are from StableOps.

import { SIGNATURE_HEADER, verifySignature } from '@stableops/api-sdk/webhooks'

const result = verifySignature({
  secrets: [webhookSecret],
  header: request.headers.get(SIGNATURE_HEADER) ?? undefined,
  rawBody,
})

if (!result.ok) {
  console.error('Invalid signature:', result.reason)
  // Reject the request
}

Delivery, retries, and the dead letter queue

Success criteria

Any 2xx response is treated as success. Any other status code, a network error, or no response within 10 seconds counts as failure.

Retry schedule

Failed deliveries are rescheduled on this curve before moving to the dead letter queue on attempt 6:

AttemptDelay
130 s
260 s
35 min
430 min
52 h
6+DLQ

Delivery log fields

Key fields you'll see on webhook-deliveries:

FieldDescription
attemptsNumber of HTTP attempts performed
response_statusDownstream status code on the most recent attempt
response_duration_msHow long the last attempt took
error_messageShort, log-friendly reason for the most recent failure
next_retry_atWhen the worker will retry — null once delivery is terminal
statuspending, succeeded, failed, dead_letter

Replay

The three replay endpoints (endpoint replay, single-delivery replay, and replay-dead-letters) all enqueue a brand-new delivery row — the original audit log is preserved. The dashboard's "replay" button is just these endpoints under the hood.

Best Practices

1. Always Verify Signatures

2. Return 200 Quickly

3. Process Idempotently

4. Use Raw Body for Verification

5. Handle All Event Types

6. Log Everything

7. Monitor Delivery Health

Next Steps

On this page