Skip to main content
Register your merchant endpoint in the dashboard, then verify every signature before you update local state.
Why this page matters Webhooks are the main signal that keeps your app in sync with RampHub. If you get this right, the rest of the trade lifecycle is much easier to trust.

Headers

HeaderDescription
x-ramphub-signatureHMAC-SHA256 signature of the raw request body.
x-ramphub-eventLifecycle event name for the delivery.
x-ramphub-deliveryUnique delivery id for idempotency and retries.

Signing secret

When you register a webhook endpoint in the business dashboard, RampHub generates a signing secret for that endpoint. Treat that secret as a server-side credential for the system that receives the webhook.
  • Store the secret in the receiver’s environment or secret manager.
  • Never put it in a browser bundle or public config file.
  • Copy it when the dashboard reveals it and keep it on the receiving server only.
  • Verify x-ramphub-signature against the raw request body before you trust the payload.
  • Keep using monitor-status as the fallback path when a webhook is delayed or missing.
  • If you rotate the endpoint secret, update the receiving server immediately.

Events

EventDescription
transaction.createdTransaction record created and provider instructions are available.
transaction.updatedNon-terminal lifecycle update from the provider or settlement flow. Dashboard labels this using the current stage, such as Order placed, Awaiting settlement, Forwarded to provider, Awaiting customer payment, Invoice created, Settling with provider, Marked completed, or Marked failed.
transaction.completedTransaction is completed in RampHub.
transaction.failedTransaction moved to a failed terminal state.

Common stage labels

These are the most common labels you will see in the dashboard when a delivery arrives as transaction.updated:
  • Order placed
  • Awaiting settlement
  • Forwarded to provider
  • Awaiting provider funding confirmation
  • Awaiting customer payment
  • Invoice created
  • Settling with provider
  • Ready for settlement
  • Awaiting user payout
  • Marked completed
  • Marked failed

Sample payload

{
  "id": "evt_01hzyx8j3m4w9v0g8s2f6t",
  "type": "transaction.completed",
  "createdAt": "2026-04-20T12:00:00.000Z",
  "livemode": true,
  "data": {
    "transactionId": "RH-TX-AB12CD34",
    "status": "completed",
    "provider": "UseBread",
    "asset": "USDT",
    "chain": "base"
  }
}

Signature verification

const crypto = require("crypto");

function verifyRampHubWebhook(rawBody, signature, secret) {
  const computed = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(computed),
    Buffer.from(signature),
  );
}

Rule

Keep the receiver idempotent and persist the delivery id from the headers.