Skip to content

Webhooks

Webhooks let your systems receive real-time notifications when events occur in Fynex. Instead of polling the API, Fynex sends an HTTP POST request to your URL whenever a subscribed event fires.

Setting Up a Webhook

  1. Go to Settings > Integrations.
  2. In the Webhooks section, click Add Webhook.
  3. Enter the URL where Fynex should send events (must be HTTPS).
  4. Select the events you want to subscribe to.
  5. Click Save. Fynex generates a signing secret for this webhook — copy and store it securely.

Available Events

EventTriggered When
account.createdA new account is added to the portfolio
account.updatedAccount data is modified (balance, status, metadata)
account.status_changedAccount status transitions (e.g., active → resolved)
contact.createdA new contact is added to an account
contact.updatedContact information is modified
interaction.completedA communication (call, email, SMS, WhatsApp) is completed
promise.createdA payment promise is registered
promise.fulfilledA promise is marked as fulfilled (payment received)
promise.brokenA promise passes its due date without payment
payment.registeredA payment is recorded against an account
dispute.createdA debtor raises a dispute
escalation.createdAn account is escalated (human review, legal, supervisor)

Payload Format

Every webhook request is a JSON POST with this structure:

json
{
  "event_type": "promise.created",
  "timestamp": "2026-03-22T14:30:00.000Z",
  "data": {
    "id": "a1b2c3d4-...",
    "account_id": "e5f6g7h8-...",
    "amount": 15000,
    "due_date": "2026-04-05"
  }
}

The data object contains the full resource that triggered the event. Its shape varies by event type — for example, account.updated includes account fields, while interaction.completed includes interaction details.

Signature Verification

Every webhook request includes an X-Fynex-Signature header containing an HMAC-SHA256 signature of the request body. Always verify this signature to confirm the request came from Fynex.

Verification in Node.js

js
const crypto = require("crypto");

function verifyWebhookSignature(rawBody, secret, signatureHeader) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return expected === signatureHeader;
}

// In your webhook handler:
const isValid = verifyWebhookSignature(
  req.rawBody,
  process.env.FYNEX_WEBHOOK_SECRET,
  req.headers["x-fynex-signature"]
);

if (!isValid) {
  return res.status(401).send("Invalid signature");
}

WARNING

Always verify the signature before processing the payload. Use a constant-time comparison in production to prevent timing attacks.

Retry Policy

If your endpoint returns a non-2xx status code or fails to respond within 10 seconds, Fynex retries with exponential backoff:

AttemptDelay after failure
11 minute
25 minutes
330 minutes
42 hours
512 hours

After 5 consecutive failures, the webhook subscription is automatically disabled. You can re-enable it from Settings > Integrations after fixing the issue.

Testing Webhooks

Each webhook endpoint has a Send Test button in Settings > Integrations. This sends a sample event to your URL so you can verify connectivity and signature validation without waiting for a real event.

TIP

During development, use a tool like webhook.site or ngrok to expose a local server and inspect incoming payloads.

Troubleshooting

  • Not receiving events — Confirm your URL is publicly accessible over HTTPS, returns a 200 status quickly, and the webhook is not disabled.
  • Signature mismatch — Make sure you are verifying against the raw request body (not parsed JSON). Check that you are using the correct signing secret for this webhook.
  • Webhook disabled — After 5 consecutive failures, Fynex disables the subscription. Fix your endpoint, then re-enable the webhook in Settings.
  • Duplicate events — Use the event_type and data.id fields to deduplicate. Retries may deliver the same event more than once.
  • Slow processing — Return 200 immediately and process the payload asynchronously. Fynex times out after 10 seconds.