Skip to main content

Setting up a webhook

Use webhooks when your system needs to react to Radom events without waiting for a user redirect or manually polling the Dashboard. Typical uses include order fulfillment, subscription billing updates, deposit reconciliation, payout operations, refund tracking, and open-banking payment completion.

Radom sends each webhook as a JSON POST request to every active endpoint registered for your organization.

Integration checklist

  1. Create an HTTPS POST endpoint.
  2. Verify the radom-verification-key request header.
  3. Store or process the webhook idempotently using the payload id.
  4. Return a 2xx response after your endpoint has accepted the message.
  5. Handle retries and duplicate deliveries safely.
  6. Use the event-specific pages for payload fields and examples.

Delivery and retries

If your endpoint does not return a successful 2xx response, Radom retries delivery up to 4 additional times, for up to 5 delivery attempts total.

Your handler should be idempotent. Store the webhook message id or the relevant Radom object ID before triggering irreversible work such as fulfillment, ledger posting, or customer notification. If Radom retries a message you have already processed, return 2xx without repeating the side effect.

You can inspect webhook messages and manually retry failed deliveries from the Developer Webhooks page in the Dashboard.

Event model

Each payload includes:

FieldDescription
idUnique webhook message ID.
webhookIdWebhook endpoint ID.
eventTypeEvent name, such as managedPayment, refund, or payout.
eventDataEvent-specific data. The nested property name matches eventType.
radomDataRelated Radom object context when available.

For example, a managedPayment webhook has eventData.managedPayment. A refund webhook has eventData.refund.

Payment fulfillment

For checkout, payment link, invoice, and donation flows, fulfill an order only after receiving the final success event for the payment type you use.

For open banking checkout sessions, do not treat the customer returning from their bank app as proof of payment. Use the final managedPayment webhook as the successful-payment signal. For open-banking payments, eventData.managedPayment.openBankingPaymentData can include final provider details such as status, paymentScheme, and instantPaymentScheme.

Event examples

These examples are shortened to show routing and handling patterns. Use the event-specific pages in the sidebar for complete payload schemas.

{
"id": "f2e4a657-5a8f-4c9a-9a6f-35e5f2bb48fb",
"webhookId": "3a027f31-fc48-49aa-9e5d-a9a984bb41f3",
"eventType": "managedPayment",
"eventData": {
"managedPayment": {
"paymentMethod": {
"network": "Solana",
"token": null
},
"amount": "25.00",
"transactions": [
{
"network": "Solana",
"transactionHash": "5eKc...",
"token": null,
"amount": "0.12",
"blockTimestamp": "2026-07-09T14:22:18Z"
}
],
"openBankingPaymentData": null
}
},
"radomData": {
"checkoutSession": {
"checkoutSessionId": "109d5abf-1f8b-460f-9dd8-3c1486b8feba",
"metadata": []
}
}
}

Create an endpoint

Create a web server route that accepts JSON POST requests and returns a 2xx response after the message has been accepted.

Validate the radom-verification-key request header against the verification key generated for your webhook endpoint.

const express = require('express')

const app = express()
const port = 9999

app.use(express.json())

// Generated when creating the webhook endpoint in the Radom dashboard.
const verificationKey = process.env.RADOM_WEBHOOK_VERIFICATION_KEY

app.post('/webhook', async (req, res) => {
if (req.headers['radom-verification-key'] !== verificationKey) {
return res.sendStatus(401)
}

const event = req.body

// Persist event.id before performing irreversible side effects.
// If event.id was already processed, return 200.
switch (event.eventType) {
case 'managedPayment':
// Fulfill the order or mark the invoice paid.
break
case 'payout':
// Update payout operations.
break
default:
// Store unhandled events for review or ignore safely.
break
}

return res.sendStatus(200)
})

app.listen(port, () => {
console.log(`Webhook receiver listening on port ${port}`)
})

Register the webhook

Use the Developer Webhooks page in the Dashboard to register your webhook endpoint.

You can also create the webhook through the API.

Update or pause a webhook

Use the Developer Webhooks page in the Dashboard to update, pause, resume, inspect, or retry webhook deliveries.

You can also update the webhook through the API.

Next steps