Ghala webhook
Ghala delivers real-time event updates, keeping you informed as they happen. By prioritizing automation, it removes the need for manual effort, streamlining workflows and boosting efficiency.
Super charge your Ghala shop by getting latest updates on certain events as they occur on the system. Its simple to listen for specific event and make updates accordingly. This enables shop owners to tap into the power of Ghala webhook to connect with any external service.
Ghala, now lets you listen to some event happens on your shop. Do you have a system that you like to receive event. This feature comes in handy with some security measures to ensure events are easily verified on the receiving end.
You might ask why have this while i can all do it on the platform, i just need to navigate to the dashboard and get all latest details? Its correct, the platform is already packed with all you need. Ghala already hands you with notifications via either email or SMS only on successful payment but notifications do not provide a way for you/your dev team to automate other tasks such connecting with Logistics handler,
Ohh, this is the developer looking like feature right? I guess so but whoever has the ability to connect and listen to events from Ghala should benefit from the feature.
Much of the talk lets get a bit a gist of what it means to have and connect to the webhook service. Lets get into developer mode...
About Webhook
I'm not good at story telling but will try to get the about of webhook in a story fashion, just a short one.
Ghala Wehbook, works like an alarm. You would set to ring at 0500 to wake you up. When alarm goes off at 0500, you can either snooze or dismiss it [options in my Alarm]. With snoozed alarm, you will keep getting alarms after a particular interval. In case you dismiss it, the alarm never goes off again..
The same way Ghala webhook works, when. you decide to listen for a particular event, you will get notified almost immediately then you will have to acknowledge(dismiss). In case you do not acknowledge,(snooze), you will get a request after a defined intervals.
Webhook Events
Currently, we support only 4 kind of events namely order creation, order cancelled, order updated and successful payment.
Lets explore sample request that will be sent to the configured URL.
- Order Created
Enum: order.created
Sample Request:
{
"event": "order.created",
"data": {
"customer": {
"name": "Sarufi Ghala",
"phone": "255757294146",
"email": "info@ghala.io"
},
"order": {
"id": 1,
"total": 1000,
"currency": "TZS",
"products": [{ "name": "Product 1", "price": 500, "quantity": 2 }]
}
}
}
- Order Cancelled
Enum: order.cancelled
Sample Data
{
"event": "order.cancelled",
"data": {
"customer": {
"name": "Sarufi Ghala",
"phone": "255757294146",
"email": "info@ghala.io"
},
"order": {
"id": 1,
"total": 1000,
"currency": "TZS",
"products": [{ "name": "Product 1", "price": 500, "quantity": 2 }]
}
}
}
- Order Updated
Enum: order.updated
Sample Data:
{
"event": "order.updated",
"data": { "order_id": 1, "old_status": "paid", "new_status": "picked up" }
}
- Sucessful payment
Enum:
Sample Data:
{
"event": "payment.success",
"daata": {
"customer": {
"name": "Sarufi Ghala",
"email": "info@ghala.io",
"phone_number": "255757294146"
},
"amount": 1000,
"payment_number": "255757294146",
"transaction_id": 1,
"order_id": 1
}
}
With Ghala, the events are gracefully retried after the following intervals 2 minutes, 5 minutes, 30 minutes, 2 hours, 5 hours and 12 hours. This is when the receiving system snoozes the request from Ghala.
Setting Webhook
The first thing required is to have a live API that will receive events. Login into your Ghala shop, then navigate to setting then on integration tab. Then fill in all required fields > Save or Test the event
Keep in mind that only active webhooks will be triggered. After saving you will have a secret key, keep it as it will be used to create signature that will be part of request headers.
Webhook Security
With webhook set, webhook secret key provided. Lets take a look on how to verify webhook events from Ghala. Taking into consideration of concerning nature of events and possible consequences that may occur, Ghala has provided a way to verify events against common attacks.
To ensure the authenticity of received events from Ghala, the following verification have been put in place:
- Avoiding replay attacks
- Signature validation
Avoid Replay Attacks
Inside the webhook header there is an additional field X-Ghala-timestamp to indicate the Unix timestamp when the webhook was signed. This can be used to timestamp to reduce the chance of a replay attack.
Signature Validation
Events sent from our Ghala contain the X-Ghala-Signature header. To ensure the webhook's authenticity and confirm its origin from our service, we recommend following the following steps to compare a generated signature with the signature from the header.
- Construct the signed content
To generate the signed content, concatenate the X-Ghala-timestamp and the raw request body. The raw request body is the JSON payload sent in the request. Use `.` as the separator between the timestamp and the raw request body as string.
headers = request.headers
# 1. Get headers [signature and timestamp]
signature = headers.get("X-Ghala-Signature")
timestamp = headers.get("X-Ghala-timestamp")
# 2. Get the body
body = await request.body()
# 3. Decode the body
decoded_body = body.decode()
# 4. create a signed payload [do not alter the order]
content = f"{timestamp}.{decoded_body}"
# 5. Encode the payload
content = content.encode("utf-8")
Make sure to use a raw body as any modification to the body will result in a different signature
- Generate the expected signature
Lets calculate, expected signature you will need use secret key obtained during registration of webhook. You will need to use the secret key and signed content, to generate a HMAC SHA256 signature as bytes.
import hmac
import hashlib
import base64
secret_key="your_secret_key" # Obtained when registering the webhook
secret_key = secret_key.encode('utf-8')
# Create a new signature from content
new_signature = hmac.new(secret, content, hashlib.sha256).digest()
# Create a base64 encoded signature
expected = base64.b64encode(new_signature).decode("utf-8").strip()
- Compare the generated signature with the signature from the header
As highlighted above the header will have the signature that was used to sign the request. Compare the generated signature with the signature from the header.
If the two signatures match, the request is valid then you can proceed with processing the event.
Any response status code other than 200, 201 or 202 will be considered as a snoozed alarm so there will be a retry.
It is recommended to use a constant-time string comparison to prevent any possibility of timing attack.
Sample Code
Starter code to get you started with webhook data verification. More eamples will be updated on official ghala docs. Other sample codes will be update as fast as possible to fuel the integration with other systems.
import base64
import hashlib
import hmac
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook(request: Request):
# 1. Construct the signed content
headers = request.headers
request_body = request.get_data(as_text=True)
webhook_timestamp = headers.get('X-Ghala-timestamp')
signed_content = f"{str(webhook_timestamp)}.{str(request_body)}".encode()
# 2. Generate the expected signature
secret_key="your_secret_key" # Obtained when registering the webhook
secret_key = secret_key.encode('utf-8')
# New hmac signature
signature = hmac.new(secret_key, signed_content, hashlib.sha256).digest()
# Encode the signature to base64
signature = base64.b64encode(signature).decode()
# 3. Compare the generated signature with the signature from the header
gahala_signature = headers.get("X-Ghala-Signature")
if not hmac.compare_digest(gahala_signature, signature):
# Return any status code that is not among [200,201,202]
return "Invalid request", 400
# Perform your actions with data provided then return status code among [200,201,202]
# It can be a background task as the request timeout is about 10s
return "Processed",200
Its getting that developer vibe , so get ready for a lot of integration support that are currently on the way. We start by the beta realise of Webhook support..
Wrap up
With Webhook, Ghala intends to bring developer close to integration with existing systems. More features to come stay alert.