Introduction

Webhooks or callback URLs allow you to define URLs on your server that notifications should be sent to when specific events occur in your Onafriq account.

📘

The webhooks api endpoint is:

https://api.mfsafrica.com/api/webhooks

Notes on URLs

  • Non-HTTPS URLs will be rejected. For testing with a self-signed certificate, see the “Testing webhooks” section below.
  • The URL you submit isn’t specific to a specific object. Once submitted, it will receive notifications for all future events of the specific type made in your organization, whether they are made via the API or via the web interface.
  • Therefore, you are encouraged to use one URL for each event type. Since URLs are stored at a per-organization level, using different URLs may result in duplicate notifications being sent to the different URLs.
  • Previously submitted URLs can be deleted via the web browser, or the Webhooks API methods described elsewhere in this reference.

Responding to the webhook

The API implements a 5-second timeout. We wait 5 seconds for a response to each request, and if there isn’t one, or there is an error, we will retry the request a total of 10 times, with an increasing wait period between each attempt.

Because of this timeout, we recommend that your webhook responds immediately with a 200 response, and then you continue processing the request. For example, you could store the event information, respond and then continue with your tasks. A 410 (gone) response will lead to the deletion of the webhook.

Depending on the server and language you are using, there are various mechanisms for achieving this, including flushing() the output in PHP or using a message queue and background tasks in other languages.

Supported Event types

See the Events API for a list of supported event types.

Managing Webhooks

You can create and manage webhooks in two ways:

  • By logging into your account
  • By using the Webhooks API (only create and get functions)

Managing Webhooks from the web browser

To manage webhooks using the web browser:

  1. Log into your account.
  2. Go “Home” > Settings (Cogwheel) > “Organization Settings” > “Advanced Settings” > “Notification Endpoints”.

Managing Webhooks from the API

You can use the Webhooks API described below to create your callback URLs programmatically.

Required permissions

To manage webhooks, either with the API or the web browser, you must have “Manage Users and Organization Settings” permissions for your organization.

The Webhook object

FieldTypeDescription
idlong integerUnique object identifier
userlong integerThe ID of the user who created the webhook
eventstringThe webhook event. See the supported events section
createdstringThe date that the webhook was created, in the UTC timezone. Format: “YYYY-MM-DDTHH:MM:SSZ”
updatedstringThe date that the webhook was last modified, in the UTC timezone. Format: “YYYY-MM-DDTHH:MM:SSZ”
targetstringThe URL that triggered events will be sent to
{
    "id": 53,
    "created": "2015-08-01T16:56:29Z",
    "updated": "2015-08-01T16:56:29Z",
    "event": "payment.status.changed",
    "target": "https://my.callback.url/",
    "user": 42
}

Notification body format

When an event is triggered, a JSON post will be sent to the URL that subscribed to the webhook. The JSON post body will include the following information:

ParameterDescription
hookA JSON representation of a webhook object. See the see webhook section below.
dataA JSON representation of the object that triggered the event. This is different for each event. See the ‘Supported events’ section above.

📘

Note

Sample Response (JSON) - if you use one of the development libraries, this is automatically converted into a native object for you:

{
    "hook": {
                "id": 53,
                "created": "2015-08-01T16:56:29Z",
                "updated": "2015-08-01T16:56:29Z",
                "event": "payment.status.changed",
                "target": "https://my.callback.url/",
                "user": 42
            },
    "data": {
                "id": 2314,
                "organization": 1,
                "amount": "30",
                "currency": "BXC",
                "payment_type": "money",
                "metadata": {"id": 1234, "name": "Lucy"},
                "description": "Per diem payment",
                "phone_nos": ["+80000000001"],
                "state": "completed",
                "last_error": null,
                "rejected_reason": null,
                "rejected_by": null,
                "rejected_time": null,
                "cancelled_reason": null,
                "cancelled_by": null,
                "cancelled_time": null,
                "created": "2014-11-22T20:57:04.017Z",
                "author": 15,
                "modified": "2014-11-22T20:57:04.018Z",
                "updated_by": null,
                "start_date": "2014-11-22T20:57:04.018Z"
            }
}

Creating a new webhook

To create a new webhook, make a POST to the endpoint above, with the attributes below.

Parameter (*required field)TypeDescription
event*String
Ex.
‘payment.status.changed’
Must be a supported event
target*String
Ex. ‘https://my.callback.url/'
Must be an https URL

Responses

If successful, a JSON representation of the new webhook object will be returned.

Sample Request

curl http://api.mfsafrica.com/api/webhooks -H "Authorization: Token ab594c14986612f6167a975e1c369e71edab6900" \
-d "payment.status.changed" \
-d target="https://my.callback.url/"
package com.beyonic.samples;

import com.beyonic.exceptions.BeyonicException;
import com.beyonic.models.*;

Beyonic.API_KEY = "ab594c14986612f6167a975e1c369e71edab6900";

String response = null;

try{
    HashMap<String, Object> data = new HashMap<>();
    data.put("event", "payment.status.changed");
    data.put("target", "https://my.callback.url/");
    response = new Webhook().create(data, null);
    System.out.println(response);
}
catch (Exception e){
    e.printStackTrace();
}
<?php
require_once('./lib/Beyonic.php');
Beyonic::setApiKey("ab594c14986612f6167a975e1c369e71edab6900");

$hook = Beyonic_Webhook::create(array(
  "event" => "payment.status.changed",
  "target" => "https://my.callback.url/"
));
?>
import beyonic
beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hook = beyonic.Webhook.create(event='payment.status.changed',
                              target='https://my.callback.url/'
                              )
require 'beyonic'
Beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hook = Beyonic::Webhook.create(
    event: "payment.status.changed",
    target: "https://my.callback.url/"
)

📘

Note

Sample Response (JSON) - if you use one of the development libraries, this is automatically converted into a native object for you:

Sample Response

{
    "id": 53,
    "created": "2015-08-01T16:56:29Z",
    "updated": "2015-08-01T16:56:29Z",
    "event": "payment.status.changed",
    "target": "https://my.callback.url/",
    "user": 42
}

Retrieving a single webhook

To retrieve a single webhook object, provide the webhook id and a webhook object will be returned.

Parameter (*required field)TypeDescription
id*Integer
Ex. 23
The id of the webhook you want to retrieve

Sample Request

curl https://api.mfsafrica.com/api/webhooks/23 -H "Authorization: Token ab594c14986612f6167a975e1c369e71edab6900"
package com.beyonic.samples;

import com.beyonic.exceptions.BeyonicException;
import com.beyonic.models.*;

Beyonic.API_KEY = "ab594c14986612f6167a975e1c369e71edab6900";

String response = null;

try{

    response = new Webhook().get(123);
    System.out.println(response);
}
catch (Exception e){
    e.printStackTrace();
}
<?php
require_once('./lib/Beyonic.php');
Beyonic::setApiKey("ab594c14986612f6167a975e1c369e71edab6900");

$hook = Beyonic_Webhook::get(23);
?>
import beyonic
beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hook = beyonic.Webhook.get(23)
require 'beyonic'
Beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hook = Beyonic::Webhook.get(23)

Sample Response

📘

Note

Sample Response (JSON) - if you use one of the development libraries, this is automatically converted into a native object for you:

{
    "id": 23,
    "created": "2015-08-01T16:56:29Z",
    "updated": "2015-08-01T16:56:29Z",
    "event": "payment.status.changed",
    "target": "https://my.callback.url/",
    "user": 42
}

Listing all webhooks

To retrieve a list of all webhooks, make a GET request to the webhooks endpoint. This will return a list of webhooks objects.

Sample Request

curl https://api.mfsafrica.com/api/webhooks -H "Authorization: Token ab594c14986612f6167a975e1c369e71edab6900"
package com.beyonic.samples;

import com.beyonic.exceptions.BeyonicException;
import com.beyonic.models.*;

Beyonic.API_KEY = "ab594c14986612f6167a975e1c369e71edab6900";

String response = null;

try{
    response = new Webhook().list(null, null);
    System.out.println(response);
}
catch (Exception e){
    e.printStackTrace();
}
<?php
require_once('./lib/Beyonic.php');
Beyonic::setApiKey("ab594c14986612f6167a975e1c369e71edab6900");

$hooks = Beyonic_Webhook::getAll();
?>
import beyonic
beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hooks = beyonic.Webhook.list()
require 'beyonic'
Beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hooks = Beyonic::Webhook.list

Sample Response

📘

Note

Sample Response (JSON) - if you use one of the development libraries, this is automatically converted into a native object for you:

{
    "count": 4,
    "next": "http://localhost:8000/api/webhooks?offset=10",
    "previous": null,
    "results": [
        {
            "id": 50,
            "created": "2015-08-01T16:43:43Z",
            "updated": "2015-08-01T17:05:38Z",
            "event": "payment.status.changed",
            "target": "https://mysite.com/callbacks/payment/saved/1",
            "user": 42
        },
        {
            "id": 52,
            "created": "2015-08-01T16:43:43Z",
            "updated": "2015-08-01T17:05:38Z",
            "event": "payment.status.changed",
            "target": "https://mysite.com/callbacks/payment/saved",
            "user": 42
        },
        {
            "id": 53,
            "created": "2015-08-01T16:56:29Z",
            "updated": "2015-08-01T16:56:29Z",
            "event": "payment.status.changed",
            "target": "https://my.callback.url/",
            "user": 42
        },
        {
            "id": 55,
            "created": "2015-08-01T16:56:29Z",
            "updated": "2015-08-01T16:56:29Z",
            "event": "payment.status.changed",
            "target": "https://google.com",
            "user": 42
        }
    ]
}

Filtering webhooks

You can search or filter webhooks on the following fields. Simply add them to your request as shown in the examples. You can combine multiple filters. Note that filters return exact matches only.

  • user - the ID of the user who created the webhook. Note that only users within your organization will be matched.
  • event - the webhook event
curl https://api.mfsafrica.com/api/webhooks?user=1 -H "Authorization: Token ab594c14986612f6167a975e1c369e71edab6900"
package com.beyonic.samples;

import com.beyonic.exceptions.BeyonicException;
import com.beyonic.models.*;

Beyonic.API_KEY = "ab594c14986612f6167a975e1c369e71edab6900";

String response = null;

try{
    HashMap<String, String> filterValues = new HashMap<>();
    filterValues.put("user", "1");
    response = new Webook().filter(filterValues, null);
    System.out.println(response);
}
catch (Exception e){
    e.printStackTrace();
}
<?php
require_once('./lib/Beyonic.php');
Beyonic::setApiKey("ab594c14986612f6167a975e1c369e71edab6900");

$hooks = Beyonic_Webhook::getAll(array(
  "user" => 1
));
?>
import beyonic
beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hooks = beyonic.Webhook.list(user=1)
require 'beyonic'
Beyonic.api_key = 'ab594c14986612f6167a975e1c369e71edab6900'

hooks = Beyonic::Webhook.list(
  user: 1
)

Authorization of Webhooks

You can optionally set HTTPBasicAuth authorization for your webhooks to verify that they come from Onafriq. To enable this, privately send the username and password you want to use for the callback verification to [email protected] and we will set this up for you. Once set up we will include an Authorization Header in the requests to your notification endpoint with a value like Basic YWFzZGZhc2RmOmJhc2RmYWRmYXNkZmFzZGY=. You can use this to authenticate the request.

If no Authentication details were provided during creation then no Authorization Header will be sent.