Delivery API | SHiiP
  • Home
  • The Guide
  • Getting Started
    • Authentication
    • Request Format & Responses
    • Errors & Status Codes
    • Rate Limits
    • Wallet Funding
    • Webhook
  • API references
    • Get User Profile
    • International HsCode
    • Get Shipment Rates
    • Get Single Rate
    • Get Available Couriers
    • Book Shipment
    • Assign Shipment
    • Get All Shipments
    • Cancel Shipment
    • Track Shipment
  • Extras
    • Promotions & Discount
Powered by GitBook
On this page
  • What are Webhooks?
  • Rules to Know
  • Listening to Events
  • Webhook Event Sample
  • Status & Description
  1. Getting Started

Webhook

Learn how to listen to events when certain actions occur in your integration with Shiip API.

PreviousWallet FundingNextGet User Profile

Last updated 8 months ago

What are Webhooks?

Webhooks provide a mechanism for automated communication between applications. When specific events are triggered within your integration with our API, we send a notification containing an event payload with the relevant data.

For example, when a shipment status is updated for one of your users, our system will send an event that includes the shipment details and its new status. This allows you to deliver real-time updates to your users or process the payload as needed.

To enable event notifications, you must configure a webhook URL in your application settings. This can be done through our business web app by navigating to Settings > API Settings and updating your webhook URL. Proper configuration ensures your system receives event data promptly for further processing or integration with your workflow.

Rules to Know

When setting up a webhook for your application, keep the following considerations in mind:

  • Ensure that the endpoint is configured to accept POST requests.

  • The timeout for our webhook is 30 seconds. If your webhook processing is resource-intensive, consider handling it asynchronously to avoid timeouts.

  • Perform a test request on your endpoint to confirm it can successfully receive and process the payload.

Additionally, in production, webhooks are sent every 30 minutes, whereas in the Sandbox/Staging environment, webhooks are dispatched every 5 minutes.

Listening to Events

const crypto = require('crypto');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.raw({ type: 'application/json' }));

const secret = "your_secret_key";

app.post('/webhook', (req, res) => {
    const payload = req.body; // Raw body
    const receivedSignature = req.headers['x-signature'];

    // Generate the HMAC signature using the secret key
    const calculatedSignature = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');

    // Compare the calculated signature with the received one
    if (crypto.timingSafeEqual(Buffer.from(calculatedSignature), Buffer.from(receivedSignature))) {
        // Signature is valid
        res.status(200).send('Valid signature');
    } else {
        // Invalid signature
        res.status(403).send('Invalid signature');
    }
});

app.listen(3000, () => {
    console.log('Server is listening on port 3000');
});
import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
secret = b'your_secret_key'

@app.route('/webhook', methods=['POST'])
def webhook():
    payload = request.data
    received_signature = request.headers.get('X-Signature')

    # Generate the HMAC signature using the secret key
    calculated_signature = hmac.new(secret, payload, hashlib.sha256).hexdigest()

    # Compare the calculated signature with the received one
    if hmac.compare_digest(calculated_signature, received_signature):
        return 'Valid signature', 200
    else:
        abort(403, 'Invalid signature')

if __name__ == '__main__':
    app.run(port=3000)
require 'sinatra'
require 'openssl'

secret = "your_secret_key"

post '/webhook' do
  request.body.rewind
  payload = request.body.read
  received_signature = request.env['HTTP_X_SIGNATURE']

  # Generate the HMAC signature using the secret key
  calculated_signature = OpenSSL::HMAC.hexdigest('sha256', secret, payload)

  # Compare the calculated signature with the received one
  if calculated_signature == received_signature
    status 200
    body 'Valid signature'
  else
    status 403
    body 'Invalid signature'
  end
end
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"net/http"
)

const secret = "your_secret_key"

func main() {
	http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
		// Get the raw POST body (payload)
		payload, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "Cannot read payload", http.StatusBadRequest)
			return
		}

		// Get the signature from the headers
		receivedSignature := r.Header.Get("X-Signature")

		// Generate the HMAC signature using the secret key
		h := hmac.New(sha256.New, []byte(secret))
		h.Write(payload)
		calculatedSignature := hex.EncodeToString(h.Sum(nil))

		// Compare the calculated signature with the received one
		if hmac.Equal([]byte(calculatedSignature), []byte(receivedSignature)) {
			w.WriteHeader(http.StatusOK)
			fmt.Fprintf(w, "Valid signature")
		} else {
			w.WriteHeader(http.StatusForbidden)
			fmt.Fprintf(w, "Invalid signature")
		}
	})

	http.ListenAndServe(":3000", nil)
}
<?php
// Receiver side

// The secret key (shared between the sender and receiver)
$secret = "your_secret_key";

// Get the signature from the headers
$receivedSignature = $_SERVER['HTTP_X_SIGNATURE'];

// Get the raw POST data (payload)
$payload = file_get_contents('php://input');

// Generate the hash using the same secret key
$calculatedSignature = hash_hmac('sha256', $payload, $secret);

// Compare the calculated signature with the received one
if (hash_equals($calculatedSignature, $receivedSignature)) {
    // Signature is valid, proceed with processing the webhook event
} else {
    // Invalid signature, reject the request
    http_response_code(403);
    exit('Invalid signature');
}
?>

Webhook Event Sample

{
  "shipment": {
    "data": {
      "destination": "David Ola Ojeniyi St, Ibadan, Nigeria",
      "origin": "1 Kayode Otitoju St, Lekki Phase I 106104, Lekki, Nigeria",
      "reference": "5lqijs7rm9n0",
      "id": "565",
      "status": "Delivered",
      "extra": "pending,In progress,picked up,delivered."
    },
    "carrier": "DHL"
  }
}

Status & Description

Here’s a breakdown of the shipment statuses in a tabular form:

Status

Description

Pending

The shipment has been created, but the pickup process has not yet started. Awaiting confirmation.

In Progress

The shipment is currently being processed, and preparations are being made for pickup or transit.

Picked Up

The shipment has been collected by the courier and is in transit to the destination.

Delivered

The shipment has been successfully delivered to the recipient at the specified location.

Add Your Webhook Url Here