Webhooks

This page will help you understand how to receive real-time notification

What are webhooks?

A webhook is a URL on your server where we send payloads for events. For example, When you run payroll using eazipay, the payroll is being executed within myeazipay system and may take a while before every employee is fully processed. You can implement a webhook on your server that listens to the payroll status as it executes. Your server is notified each time a payroll transaction completes successfully or fails.

Receiving an event

All you have to do to receive the event is to create an unauthenticated POST route on your application. The event object is sent as JSON in the request body.

// ExpressJs
app.post("/my/server/webhook/url", function(req, res) {
    // Retrieve the request's body
    var event = req.body;
    // Do something with event
    res.send(200);
});
<?php
// The request's body is parsed as JSON
$input = @file_get_contents("php://input");
$event = json_decode($input);
// Use the $event...
http_response_code(200); // PHP 5.4 or greater
?>
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/my/server/webhook/url', methods=['POST'])
def handle_webhook():
    try:
        # Retrieve the request's JSON body
        event = request.json

        # Do something with the event

        return jsonify({'status': 'success'}), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(port=5000)  # Change the port as needed

Verifying events

It is important to verify that events originate from myeazipay to avoid delivering value based on a counterfeit event.
Valid events are raised with an header x-eazipay-signature which is essentially a HMAC SHA512 signature of the event payload signed using your webhook_hash_key.
The webhook_hash_key is a SHA256 hash of your API token.

var crypto = require('crypto');
var secret = process.env.SECRET_KEY;
var webhookHashKey = crypto.createHash("sha256").update(secret).digest("hex");
// Using Express
app.post("/my/webhook/url", function(req, res) {
    //validate event
    var hash = crypto.createHmac('sha512', webhookHashKey).update(JSON.stringify(req.body)).digest('hex');
    if (hash === req.headers['x-eazipay-signature']) {
        // Retrieve the request's body
        var event = req.body;
        // Do something with event  
    }
    res.send(200);
});
<?php
// only a post with lenco signature header gets our attention
if ((strtoupper($_SERVER['REQUEST_METHOD']) != 'POST' ) || !array_key_exists('HTTP_X_LENCO_SIGNATURE', $_SERVER) ) 
    exit();
// Retrieve the request's body
$input = @file_get_contents("php://input");
define('LENCO_SECRET_KEY','SECRET_KEY');
$webhook_hash_key = hash("sha256", LENCO_SECRET_KEY);
// validate event do all at once to avoid timing attack
if($_SERVER['HTTP_X_EAZIPAY_SIGNATURE'] !== hash_hmac('sha512', $input, $webhook_hash_key))
    exit();
http_response_code(200);
// parse event (which is json string) as object
// Do something - that will not take long - with $event
$event = json_decode($input);
exit();
?>
from flask import Flask, request, jsonify
import hashlib
import hmac
import os

app = Flask(__name__)

# Replace 'YOUR_SECRET_KEY' with your actual secret key
SECRET_KEY = os.getenv('SECRET_KEY', 'YOUR_SECRET_KEY')

# Calculate webhook hash key using SHA256
webhook_hash_key = hashlib.sha256(SECRET_KEY.encode()).hexdigest()

@app.route('/my/webhook/url', methods=['POST'])
def handle_webhook():
    try:
        # Validate event
        received_signature = request.headers.get('x-eazipay-signature', '')
        computed_hash = hmac.new(webhook_hash_key.encode(), request.data, hashlib.sha512).hexdigest()

        if computed_hash == received_signature:
            # Retrieve the request's JSON body
            event = request.get_json()

            # Do something with the event

            return jsonify({'status': 'success'}), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500

    return jsonify({'status': 'unauthorized'}), 401

if __name__ == '__main__':
    app.run(port=5000)  # Change the port as needed

Responding to an event

You should respond to an event with a 200 OK. We consider this an acknowledgement by your application. If your application responds with any status outside of either 200, 201, or 202, we will consider it unacknowledged and thus, continue to send it every hour for 12 hours. You don't need to send a request body or some other parameter as it would be discarded - we only pay attention to the status code.

If your application is likely to start a long running task in response to the event, Eazipay may timeout waiting for the response and would ultimately consider the event unacknowledged and queue to be raised later. You can mitigate duplicity by having your application respond immediately with a 200 before it goes on to perform the rest of the task.