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.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:


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:"/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  
// only a post with bloc signature header gets our attention
if ((strtoupper($_SERVER['REQUEST_METHOD']) != 'POST' ) || !array_key_exists('x-bloc-webhook', $_SERVER) ) 

// Retrieve the request's body
$input = @file_get_contents("php://input");

// validate event do all at once to avoid timing attack
if($_SERVER['HTTP_X_BLOC_WEBHOOK'] !== hash_hmac('sha256', $input, BLOC_SECRET_KEY))


// parse event (which is json string) as object
// Do something - that will not take long - with $event
$event = json_decode($input);

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

class BlocObject
  include Singleton

  WHITELISTED_IPS = ['', '', ''].freeze

  def initialize
    @secret_key = ENV['BLOC_SECRET_KEY']

  def verify_webhook_event?(request)
    verify_ip_address(request.remote_ip) && verify_header_signature(request)


  def verify_ip_address(ip_address)

  def verify_header_signature(request)
    body = request.body.string
    hash = OpenSSL::HMAC.hexdigest('SHA512', @secret_key, body)
    hash == request.headers['HTTP_X_BLOC_WEBHOOK']

3. Listen for events

Build an HTTP handler that listens for events coming from Bloc

const express = require('express');
const app = express();'/myapp/webhook', express.json({type: 'application/json'}), (request, response) => {
  const event = request.body;


  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.