Create Webhook
Learn how to set up your webhooks
Bloc uses webhooks to notify your system when an event occurs. Example of these events are: Customer.created
, transaction.new
, transaction.successful
, etc. When these events occur, we send an HTTP POST request to your configured URL, allowing you to act on it.
1. Configure your Webhook URL
Log into the Dashboard, and go to Developer settings. Scroll down to the Webhooks section. Input your URL and generate an API key.
Important to Note
You need to set up your webhooks for both Test Mode and Live Mode separately. Also, make sure that you are not using the wrong environment's credentials in your application.
2. Verify your Webhook
Setting up your webhook means that it is available on the internet. You want to make sure to verify and make sure that only requests coming from us are able to pass through into your systems and avoid dangerous actors.
Using Convoy as our webhook provider, we’re able to support two methods of verification:
1. IP Whitelisting
IP Whitelisting means you set up your application to only listen for events coming from predefined IPs. This blocks out any other request coming from other IPs, blocking bad actors before hitting your application at all.
Bloc only sends webhook events via these IP addresses:
- 159.223.160.239
- 147.182.169.205
Please note that these IP addresses are subject to change. In the event of a change, we will inform you accordingly.
2. Signature Header Verification
Requests from our systems are always signed with X-Bloc-Webhook;
you can verify this request headers hitting your endpoint:
app.post("/my/webhook/url", function(req, res) {
//validate event
const hash = crypto.createHmac('sha256', webhook_secret).update(JSON.stringify(req.body)).digest('hex');
if (hash == req.headers['X-Bloc-Webhook']) {
// Retrieve the request's body
const event = req.body;
// Do something with event
}
res.send(200);
});
<?php
// only a post with bloc signature header gets our attention
if ((strtoupper($_SERVER['REQUEST_METHOD']) != 'POST' ) || !array_key_exists('x-bloc-webhook', $_SERVER) )
exit();
// Retrieve the request's body
$input = @file_get_contents("php://input");
define('BLOC_SECRET_KEY','SECRET_KEY');
// validate event do all at once to avoid timing attack
if($_SERVER['HTTP_X_BLOC_WEBHOOK'] !== hash_hmac('sha256', $input, BLOC_SECRET_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();
?>
class BlocController < ApplicationController
skip_before_action :authorize_request, only: :webhook
def webhook
bloc_instance = BlocObject.instance
valid_event = bloc_instance.verify_webhook_event?(request)
raise StandardError, 'Phony event - Not Bloc' unless valid_event
render status: 200, plain: "Ok\n"
body = params.permit!
body = body.to_hash
HandleBlocWebhookJob.perform_later(body)
end
end
class BlocObject
include Singleton
WHITELISTED_IPS = ['159.89.231.210', '159.223.166.174', '159.65.239.138'].freeze
def initialize
@secret_key = ENV['BLOC_SECRET_KEY']
end
def verify_webhook_event?(request)
verify_ip_address(request.remote_ip) && verify_header_signature(request)
end
private
def verify_ip_address(ip_address)
WHITELISTED_IPS.include?(ip_address)
end
def verify_header_signature(request)
body = request.body.string
hash = OpenSSL::HMAC.hexdigest('SHA512', @secret_key, body)
hash == request.headers['HTTP_X_BLOC_WEBHOOK']
end
end
3. Listen for events
Build an HTTP handler that listens for events coming from Bloc
const express = require('express');
const app = express();
app.post('/myapp/webhook', express.json({type: 'application/json'}), (request, response) => {
const event = request.body;
console.log(event)
response.json({success: true});
});
Helpful Tip:
If a webhook fails the first time, and you didn't receive it, you can access your Webhook Logs in your Developer settings, and view a list of all failed webhooks.
You can then manually retry it or click to see more information about the event payload.
Updated over 1 year ago