Skip to content

Webhooks

Webhooks notify your server when events occur in your Fyber account. Use them to trigger actions like fulfilling orders, sending emails, or updating your database.

Setup

  1. Go to Fyber Console > Developer > Webhooks
  2. Add your endpoint URL (e.g., https://yoursite.com/webhooks/fyber)
  3. Select the events you want to receive
  4. Copy your webhook secret (whsec_...)

Verify Signatures

Always verify webhook signatures to ensure requests come from Fyber.

JavaScript

javascript
import express from 'express';
import { Fyber } from '@fyber.one/sdk-js';

const app = express();

app.post('/webhooks/fyber', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['fyber-signature'];
  const webhookSecret = 'whsec_your_webhook_secret';

  let event;
  try {
    event = Fyber.webhooks.verify(
      req.body.toString(),
      signature,
      webhookSecret
    );
  } catch (err) {
    console.error('Webhook verification failed:', err.message);
    return res.status(400).send('Invalid signature');
  }

  // Handle the event
  switch (event.type) {
    case 'checkout.session.completed':
      handleCheckoutComplete(event.data.object);
      break;
    case 'payment.succeeded':
      handlePaymentSucceeded(event.data.object);
      break;
    // ... handle other events
  }

  res.json({ received: true });
});

PHP

php
<?php

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_FYBER_SIGNATURE'];
$webhookSecret = 'whsec_your_webhook_secret';

try {
    $event = Fyber::verifyWebhook($payload, $signature, $webhookSecret);

    switch ($event['type']) {
        case 'checkout.session.completed':
            handleCheckoutComplete($event['data']['object']);
            break;
        case 'payment.succeeded':
            handlePaymentSucceeded($event['data']['object']);
            break;
    }

    http_response_code(200);
    echo json_encode(['received' => true]);
} catch (Fyber\Exceptions\FyberException $e) {
    http_response_code(400);
    echo 'Invalid signature';
}

C#

csharp
[HttpPost("webhook")]
public IActionResult HandleWebhook()
{
    var payload = new StreamReader(Request.Body).ReadToEnd();
    var signature = Request.Headers["fyber-signature"].ToString();
    var webhookSecret = "whsec_your_webhook_secret";

    try
    {
        var webhookEvent = FyberClient.VerifyWebhook(payload, signature, webhookSecret);

        switch (webhookEvent.Type)
        {
            case "checkout.session.completed":
                HandleCheckoutComplete(webhookEvent.Data);
                break;
            case "payment.succeeded":
                HandlePaymentSucceeded(webhookEvent.Data);
                break;
        }

        return Ok();
    }
    catch (FyberException)
    {
        return BadRequest("Invalid signature");
    }
}

Flutter

dart
try {
  final event = Fyber.verifyWebhook(
    payload: rawBody,
    signature: request.headers['fyber-signature']!,
    secret: 'whsec_your_webhook_secret',
  );

  switch (event['type']) {
    case 'payment.succeeded':
      handlePaymentSucceeded(event['data']['object']);
      break;
  }
} on FyberException catch (e) {
  print('Invalid webhook: ${e.message}');
}

Event Types

Checkout Events

EventDescription
checkout.session.completedCustomer completed checkout
checkout.session.expiredSession expired without payment

Payment Events

EventDescription
payment.succeededPayment completed successfully
payment.failedPayment was declined
payment.canceledPayment was canceled/voided

Refund Events

EventDescription
refund.createdRefund initiated
refund.succeededRefund completed
refund.failedRefund failed

Token Events

EventDescription
token.createdCard saved successfully
token.deletedSaved card removed

Subscription Events

EventDescription
subscription.createdSubscription started
subscription.payment_succeededRecurring payment successful
subscription.payment_failedRecurring payment failed
subscription.trial_endingTrial ends in 3 days
subscription.canceledSubscription ended

Installment Events

EventDescription
installment.plan_createdPlan activated
installment.payment_succeededScheduled payment completed
installment.payment_failedScheduled payment failed
installment.plan_completedAll payments completed
installment.plan_defaultedCustomer defaulted

Event Object

json
{
  "id": "evt_abc123",
  "object": "event",
  "type": "payment.succeeded",
  "data": {
    "object": {
      "id": "pay_xyz789",
      "amount": 5000,
      "currency": "JMD",
      "status": "succeeded"
    }
  },
  "createdAt": "2024-01-15T10:30:00Z"
}

Best Practices

Respond Quickly

Return a 2xx response immediately, then process the event asynchronously:

javascript
app.post('/webhooks/fyber', async (req, res) => {
  // Verify signature first
  const event = Fyber.webhooks.verify(...);

  // Respond immediately
  res.json({ received: true });

  // Process asynchronously
  await processEventAsync(event);
});

Handle Duplicates

Events may be delivered more than once. Use the event ID to deduplicate:

javascript
const processedEvents = new Set();

function handleEvent(event) {
  if (processedEvents.has(event.id)) {
    return; // Already processed
  }
  processedEvents.add(event.id);
  // Process event...
}

Retry Failed Deliveries

If your endpoint returns a non-2xx response, Fyber retries:

  • 1st retry: 5 minutes
  • 2nd retry: 30 minutes
  • 3rd retry: 2 hours
  • 4th retry: 24 hours

After 4 failed attempts, the webhook is marked as failed.

Test Webhooks Locally

Use a tool like ngrok to expose your local server:

bash
ngrok http 3000
# Use the ngrok URL as your webhook endpoint

Webhook Logs

View webhook delivery history in the Fyber Console under Developer > Webhooks > Logs.

Fyber Payment API