Staying up-to-date with Webhooks

A webhook is a request that Collect sends to your server to alert you of an event. Adding support for webhooks allows you to receive real-time notifications from Collect when things happen in your account, so you can take automated actions in response, for example:

  • When a payment fails due to lack of funds, retry it automatically
  • When a customer bank account is disconnected, notify the customer
  • When a customer’s subscription generates a new payment, record that payment against their account.

Building a webhook handler

Webhooks are HTTP POST requests made to the URL you provided, with a JSON body.

The first step to take when you receive a webhook is to check its signature - this makes sure that is genuinely from Collect and hasn’t been forged. A signature is provided in the X-Collect-Signature header of the request. You just need to compute the signature on your end using the POSTed JSON and your business secret key, and compare it to the one in the header.

If they match, the webhook is genuine, because only you and Collect know the secret. It’s important that you keep the secret safe.

We can compute the signature like this:

var crypto = require('crypto');

function calculateHash(payload, secret){
crypto
      .createHmac('sha512', secret)
      .update(JSON.stringify(payload))
      .digest('hex');
}
<?php 
  
function calculateHash($payload, $secret){
	return hash_hmac('sha512', $payload, $secret)
}

Supported Events

{
  "event": "payment.success",
  "payment": {
    "id": 25,
    "ip": "::1",
    "fee": 1500,
    "amount": 150000,
    "status": "success",
    "channel": "direct-debit",
    "country": "NG",
    "paid_at": "2021-05-18T20:57:26.905Z",
    "currency": "NGN",
    "metadata": null,
    "initiator": "plan",
    "reference": "TX_QX661E6JEYTRLW9",
    "charged_at": "2021-05-18T20:57:26.905Z",
    "created_at": "2021-05-18T19:56:35.432Z",
    "updated_at": "2021-05-18T19:57:26.803Z",
    "description": "Payment for string"
  },
  "customer": {
    "id": 16,
    "code": "CUS_grhjxngq1v",
    "email": "[email protected]",
    "country": "NG",
    "metadata": null,
    "last_name": "Test",
    "created_at": "2021-04-18T17:38:13.341Z",
    "first_name": "Customer",
    "updated_at": "2021-04-18T17:38:13.341Z",
    "middle_name": "null",
    "phone_number": null
  },
  "bank_account": {
    "id": 15,
    "country": "NG",
    "currency": "NGN",
    "bank_name": "Ecobank Nigeria",
    "is_active": true,
    "is_reusable": true,
    "signature": "SIG_cbf12b91eb70bbfe487f597ad0c70e5abe2cc427bff9180530ff27acff4e6a165bcb50720d506b5443e684add0757f88ef3b85a7c7c45e2f625d72f00df269b6",
    "created_at": "2021-05-18T19:33:27.213Z",
    "is_default": false,
    "updated_at": "2021-05-18T19:57:26.842Z",
    "account_name": "Test Customer",
    "authorization_code": "BA_m5qsj85sue7d9ux",
    "masked_account_number": "******1603"
  }
}
{
  "event": "payment.failed",
  "payment": {
    "id": 25,
    "ip": "::1",
    "fee": 1500,
    "amount": 150000,
    "status": "failed",
    "channel": "direct-debit",
    "country": "NG",
    "paid_at": "2021-05-18T20:57:26.905Z",
    "currency": "NGN",
    "metadata": null,
    "initiator": "plan",
    "reference": "TX_QX661E6JEYTRLW9",
    "charged_at": "2021-05-18T20:57:26.905Z",
    "created_at": "2021-05-18T19:56:35.432Z",
    "updated_at": "2021-05-18T19:57:26.803Z",
    "description": "Payment for string"
  },
  "customer": {
    "id": 16,
    "code": "CUS_grhjxngq1v",
    "email": "[email protected]",
    "country": "NG",
    "metadata": null,
    "last_name": "Test",
    "created_at": "2021-04-18T17:38:13.341Z",
    "first_name": "Customer",
    "updated_at": "2021-04-18T17:38:13.341Z",
    "middle_name": "null",
    "phone_number": null
  },
  "bank_account": {
    "id": 15,
    "country": "NG",
    "currency": "NGN",
    "bank_name": "Ecobank Nigeria",
    "is_active": false,
    "is_reusable": false,
    "signature": "SIG_cbf12b91eb70bbfe487f597ad0c70e5abe2cc427bff9180530ff27acff4e6a165bcb50720d506b5443e684add0757f88ef3b85a7c7c45e2f625d72f00df269b6",
    "created_at": "2021-05-18T19:33:27.213Z",
    "is_default": false,
    "updated_at": "2021-05-18T19:57:26.842Z",
    "account_name": "Test Customer",
    "authorization_code": "BA_m5qsj85sue7d9ux",
    "masked_account_number": "******1603"
  }
}
{
  "event": "mandate.connected",
  "customer": {
    "id": 16,
    "code": "CUS_grhjxngq1v",
    "email": "[email protected]",
    "country": "NG",
    "metadata": null,
    "last_name": "Customer",
    "created_at": "2021-04-18T17:38:13.341Z",
    "first_name": "Test",
    "updated_at": "2021-04-18T17:38:13.341Z",
    "middle_name": null,
    "phone_number": null
  },
  "bank_account": {
    "id": 15,
    "country": "NG",
    "currency": "NGN",
    "bank_name": "Ecobank Nigeria",
    "is_active": true,
    "is_reusable": false,
    "signature": "SIG_cbf12b91eb70bbfe487f597ad0c70e5abe2cc427bff9180530ff27acff4e6a165bcb50720d506b5443e684add0757f88ef3b85a7c7c45e2f625d72f00df269b6",
    "created_at": "2021-05-18T19:33:27.213Z",
    "is_default": false,
    "updated_at": "2021-05-18T19:57:26.042Z",
    "account_name": "Wale Kslkasl",
    "authorization_code": "BA_m5qsj85sue7d9ux",
    "masked_account_number": "******1603"
  }
}
{
  "event": "transfer.sucess",
  "transfer": {
    "id": 17,
    "fee": 5000,
    "amount": 22200,
    "source": "balance",
    "status": "success",
    "country": "NG",
    "currency": "NGN",
    "metadata": {},
    "narration": "string",
    "reference": "stg1118901",
    "created_at": "2021-05-23T09:01:50.273Z",
    "short_code": "TRF_2r52ppbhzo",
    "updated_at": "2021-05-24T07:22:08.795Z",
    "transferred_at": "2021-05-24T06:51:43.067Z"
  }
}
{
  "event": "transfer.failed",
  "transfer": {
    "id": 17,
    "fee": 5000,
    "amount": 22200,
    "source": "balance",
    "status": "failed",
    "country": "NG",
    "currency": "NGN",
    "metadata": {},
    "narration": "string",
    "reference": "stg1118901",
    "created_at": "2021-05-23T09:01:50.273Z",
    "short_code": "TRF_2r52ppbhzo",
    "updated_at": "2021-05-24T07:22:08.795Z",
    "transferred_at": "2021-05-24T06:51:43.067Z"
  }
}