Webhooks

In this guide, we will look at how to register and consume webhooks to integrate your app with Felloh. With webhooks, your app can know when something happens in Felloh, such as someone making a payment or a refund being processed.

To register a new webhook, you need to have a URL in your app that Felloh can call. You can configure a new webhook from the Felloh dashboard under Developer Configuration. Add your URL, pick the events you want to listen for, and optionally include child organisations. A signing key is generated when the webhook is created and shown only once, so store it securely.

Now, whenever something of interest happens in your app, a webhook is fired off by Felloh. In the next section, we'll look at how to consume webhooks.


Webhook Signing

To ensure secure communication and verify the authenticity of incoming webhook requests, Felloh signs all webhook payloads using an HMAC-SHA256 signature (available when creating webhooks in dashboard).

The signature is generated by hashing the full JSON payload with a shared secret key (the signing key shown when the webhook was created), and it is sent in the X-Signature HTTP header of each request. This allows recipients to confirm that the payload has not been tampered with in transit and that it originated from Felloh.

To verify the signature on your end, compute the HMAC-SHA256 hash of the raw request body using your shared secret key. Then compare the result to the value in the X-Signature header. A matching signature confirms that the payload is valid

Webhook Verification

const crypto = require('crypto');

function verifySignature(rawBody, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Delivery and Retries

  • Events are delivered as HTTP POST requests with a JSON body and a Content-Type of application/json.
  • Transaction status events are sent whenever a transaction reaches a final status, including declined payments, so always check the status field.
  • Any response other than a 2xx status is treated as a failed delivery. Transaction status events are retried up to 5 times, roughly a minute apart. Refund status events are sent once and are not retried.
  • Respond quickly: a delivery that has not completed within 30 seconds is abandoned.
  • Delivery logs are available in the dashboard for 30 days. See the debugging webhooks guide.

Transaction Status Event

  • Name
    amount
    Type
    integer
    Description

    The total value of the transaction in the lowest denomination of the currency (e.g., pence for GBX, cents for USX).

  • Name
    booking.id
    Type
    uuid
    Description

    The booking ID the transaction is linked to.

  • Name
    booking.booking_reference
    Type
    string
    Description

    Your unique reference for the customer's booking.

  • Name
    completed_at
    Type
    datetime
    Description

    The datetime at which the transaction was completed by the customer.

  • Name
    currency
    Type
    string
    Description

    The currency of the transaction. See currency documentation.

  • Name
    payment_link.id
    Type
    uuid
    Description

    The payment link ID that was used to create the transaction, if any.

  • Name
    ecommerce.id
    Type
    uuid
    Description

    The ecommerce session ID that was used to create the transaction, if any.

  • Name
    provider.name
    Type
    string
    Description

    The provider or merchant acquirer name.

  • Name
    provider.reference
    Type
    string
    Description

    The provider or merchant acquirer reference for the transaction.

  • Name
    status
    Type
    string
    Description

    The status of the transaction.

  • Name
    transaction.id
    Type
    uuid
    Description

    The transaction ID.

  • Name
    transaction.narrative
    Type
    object
    Description

    An object with reason and description explaining the outcome of the transaction, for example why a payment was declined.

  • Name
    surcharge.surcharge_applied
    Type
    bool
    Description

    Whether a surcharge has been applied to the transaction

  • Name
    surcharge.amount
    Type
    integer
    Description

    The total value of the surcharge on the transaction in the lowest denomination of the currency (e.g., pence for GBX, cents for USX), or null when no surcharge was applied.

  • Name
    surcharge.currency
    Type
    string
    Description

    The currency of the surcharge, or null when no surcharge was applied.

Example Event Payload

{

  "amount": 10000,
  "booking": {
    "id": "3d38e53b-867a-43bd-ad5d-4af786dd1b33",
    "booking_reference": "test-123"
  },
  "completed_at": "2021-11-03T11:04:27.000Z",
  "currency": "GBX",
  "payment_link": { "id": "2cc9b939-d2fa-41e5-abae-39c377236978" },
  "ecommerce": { "id": null },
  "provider": {
    "name": "nuvei",
    "reference": "93216A82FBDD1696203B7FC6099A9B66.prod02-vm-tx94"
  },
  "status": "COMPLETE",
  "transaction": { "id": "2cc9b939-d3fa-41e5-acae-39c377236978" },
  "surcharge": {
    "surcharge_applied": true,
    "amount": 100,
    "currency": "GBX"
  }
}

Refund Status Event

  • Name
    authorisation_code
    Type
    string
    Description

    A unique code used to identify a refund.

  • Name
    actioned_at
    Type
    datetime
    Description

    The datetime at which the refund status change was actioned.

  • Name
    amount
    Type
    integer
    Description

    The amount that the refund was for

  • Name
    metadata
    Type
    object
    Description

    User defined metadata attached to the refund

  • Name
    status.id
    Type
    string
    Description

    The status of the refund. All statuses can be retrieved using the enums endpoint.

  • Name
    transaction.id
    Type
    uuid
    Description

    The transaction ID.

  • Name
    transaction.amount
    Type
    integer
    Description

    The amount that the transaction was for (customer was charged)

  • Name
    transaction.currency
    Type
    string
    Description

    The currency of the transaction | see currency documentation.

  • Name
    transaction.booking.booking_reference
    Type
    string
    Description

    The booking reference assigned to the booking (attached to the transaction)

  • Name
    transaction.booking.customer_name
    Type
    string
    Description

    The customer name assigned to the booking (attached to the transaction)

Example Event Payload

{

  "authorisation_code": "3d38e53b-867a-43bd-ad5d-4af786dd1b33",
  "actioned_at": "2021-11-03T11:04:27.000Z",
  "amount": 100,
  "metadata": { "internal_id": "abc-1234" },
  "status": {
    "id": "PENDING_AUTHORISATION"
  },
  "transaction": { 
    "id": "2cc9b939-d3fa-41e5-acae-39c377236978",
    "amount": 100,
    "currency": "GBX",
    "booking": {
      "booking_reference": "FE123456",
      "customer_name": "Caroline Rennie"
    }
  }
}