Webhooks

Configure and listen to webhook events produced by Chargeflow to automatically notify your system of changes and trigger reactions.

Why Use Webhooks

When building an integration with Chargeflow, you might want your applications to receive certain events immediately as they occur. For example, get notified when a new dispute event is received.

Webhooks enable you to register an HTTP call to an endpoint of your choice, performed every time an event occurs. The endpoint must be publicly available and reachable from Chargeflow's APIs.

Enabling Webhooks

Chargeflow allows registration of webhook events through the Chargeflow UI Settings page, in the Developers section.

Please ensure to generate API Access Keys by clicking on Generate Keys button, and use them to make API calls back to Chargeflow.

Upon registration, Chargeflow sends an HTTP POST message to the specified URL. Successful reception of the webhook event is confirmed by receiving a 2XX response (preferably 200). In the event of any other response, Chargeflow will attempt to resend the event until either a 2XX response or the maximum retry count or time is reached.

Each webhook carries essential details such as the webhook ID, creation date and time, event type, and its associated data payload.

Event Authentication

Each Webhook POST request coming from Chargeflow includes an HMAC signature in the X-Chargeflow-Hmac-Sha256 based on the body, path, and method of the request.

You can use this signature to verify the authenticity and integrity of the request on your side. This way, you can avoid reacting to unauthorized third-party calls to your public Webhook endpoint.

We highly recommend implementing this verification in production systems.

The Secret Key used to sign (and verify) the Webhook requests is available in the Chargeflow's Settings page together with other Webhooks configurations.

The API Secret Key used is currently the same as the primary API Access Keys generated


Example HMAC Verification Code

const crypto = require('crypto')

// Function to generate HMAC-SHA256 signature
function generateHmacSignature(data, secretKey) {
  const hmac = crypto.createHmac('sha256', secretKey);
  hmac.update(data);
  return hmac.digest('hex');
}

function verifySignature(req) {
    const receivedSig = req.headers['x-chargeflow-hmac-sha256'];

    const method = req.method
    const path = req.originalUrl
    const body = JSON.stringify(req.body) 

    const dataToSign = `${method}\n${path}\n${body}`;
    const secret = 'your_secret_key'; // Obtain from Chargeflow admin panel
    const hash = generateHmacSignature(dataToSign, secret);
    return receivedSig === hash;
}

Configuring Webhooks

Enable Webhooks

As mentioned above, first, make sure to register the web-hook event through the Chargeflow Admin console.

Create a Handler

To handle the webhook call, you need to create a simple URL endpoint that:

  1. Handles POST requests with a JSON payload consisting of an event object.
  2. Quickly returns a successful status code (2xx) before any complex logic that could cause a timeout.

Example Endpoint

Below is an example NodeJS endpoint to handle a Chargeflow webhook. The actual implementation will depend on your system's language and chosen framework.

// This example uses Express to receive webhooks
const express = require('express');
const app = express();

// Match the raw body to content type application/json
// If you are using Express v4 - v4.16 you need to use body-parser, not express, to retrieve the request body
app.post('/webhook', express.json({type: 'application/json'}), (request, response) => {
  const event = request.body;

  // Optionally validate request signature against body from x-chargeflow-hmac-sha256 header
  
  // Handle the event
  switch (event.type) {
    case 'dispute.ingested':
      const disputeIngested = event.data;
      // Then define and call a method to handle the dispute ingested event data.
      // handleDisputeIngested(disputeIngested);
      break;
    // ... handle other event types
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});

app.listen(8000, () => console.log('Running on port 8000'));