Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.revtain.com/llms.txt

Use this file to discover all available pages before exploring further.

Revtain sends webhook notifications to the URL you registered during onboarding when a recovery attempt reaches a final state. Every webhook is signed for verification.

Webhook Security

Every outbound webhook includes an X-Revtain-Signature header containing an HMAC-SHA256 signature computed using your webhookSigningSecret.
Always verify signatures before processing webhook events. Unsigned or invalid requests should return 401 Unauthorized.

Step-by-Step Verification

1

Set up your webhook endpoint

HTTPS endpoint that accepts POST with JSON body and returns 200 OK.
2

Store your webhook signing secret

Save webhookSigningSecret securely. This is different from your API key.
3

Verify every incoming request

Compute HMAC-SHA256 using your secret, compare with X-Revtain-Signature.
4

Process the event and respond 200

Always respond within 10 seconds. Slow endpoints trigger retries.

Code Examples

const crypto = require('crypto');
const express = require('express');
const app = express();

app.post('/webhooks/revtain', express.json(), (req, res) => {
  const signature = req.headers['x-revtain-signature'];
  const webhookSecret = process.env.REVTAIN_WEBHOOK_SIGNING_SECRET;

  // Compute the expected signature
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(JSON.stringify(req.body))
    .digest('hex');

  // Timing-safe comparison
  if (signature !== expectedSignature) {
    console.error('Invalid webhook signature — rejecting');
    return res.status(401).send('Invalid signature');
  }

  // Signature valid — process the event
  const { event } = req.body;
  console.log(`Received verified webhook: ${event}`);

  res.status(200).send('OK');
});
Always respond with 200 within 10 seconds. If your endpoint is down or slow, Revtain retries up to 3 times with exponential backoff (0s, 2s, 8s). After 3 failures, the event is logged for manual review.

Event Reference

recovery.success

Sent when a previously failed payment has been successfully recovered.
{
  "event": "recovery.success",
  "revtainTransactionId": "da646dba-ce56-4483-ad0a-2a4fac54a5e2",
  "gatewayTransactionToken": "O52A2R2QoQeB2L9i3QG4yBf9pQ8",
  "amount": 5000,
  "currency": "USD",
  "message": "Succeeded!",
  "strategyUsed": "backup1"
}
Action: Mark the customer’s invoice as paid in your billing system.

recovery.failed

Sent when all retry strategies have been exhausted.
{
  "event": "recovery.failed",
  "revtainTransactionId": "da646dba-ce56-4483-ad0a-2a4fac54a5e2",
  "gatewayTransactionToken": "FAILED_API_1773792234011",
  "amount": 5000,
  "currency": "USD",
  "message": "Card declined",
  "strategyUsed": "all_failed"
}
Action: If dunningEnabled is true, Revtain will automatically start a dunning sequence. Otherwise, trigger your own dunning email or send the customer a card update link.

recovery.blocked

Sent when the Risk Engine blocks a transaction (fraud, lost card, etc.).
{
  "event": "recovery.blocked",
  "declineCode": "fraudulent",
  "reason": "Transaction blocked by Revtain Risk Engine to protect Merchant Health.",
  "paymentMethodToken": "01KKZ10AD66A3VX260WKM0YFPG",
  "amount": 5000,
  "currency": "USD",
  "timestamp": "2026-03-17T23:15:21.000Z"
}
Action: Flag the account for review. Do NOT retry this payment.

card.updated

Sent when a customer updates their payment method via a hosted card update link.
{
  "event": "card.updated",
  "oldPaymentMethodToken": "01KKZ10AD66A3VX260WKM0YFPG",
  "newPaymentMethodToken": "02LLZ20BE77B4WY371XLN1ZGQH",
  "clientId": "da646dba-ce56-4483-ad0a-2a4fac54a5e2",
  "timestamp": "2026-04-20T14:30:00.000Z"
}
Action: Update the customer’s stored payment method in your system with the new token. Use the new token for future recovery requests.

predict.risk.high

Sent when the pre-failure risk prediction engine detects a high-risk payment before it fails. Enables proactive intervention.
{
  "event": "predict.risk.high",
  "paymentMethodToken": "01KKZ10AD66A3VX260WKM0YFPG",
  "riskScore": 82.5,
  "reasoning": "Card has 3 prior declines in last 30 days. High-risk pattern detected.",
  "amount": 5000,
  "timestamp": "2026-04-20T14:30:00.000Z"
}
Action: Consider reaching out to the customer to update their payment method before the next billing cycle. Generate a card update link via /api/recovery/update-card/generate.