Webhooks
What is a webhook?
A webhook can be considered as an API driven by events rather than requests. Unlike typical APIs, where you would need to poll for data very frequently to get it in real-time, a webhook is a service that allows one program to send automated messages or information to other apps as soon as a particular event takes place. This essentially means that you can get data in real-time without having to poll our events endpoint for it.
Securing your Webhooks
As webhooks deliver data to publicly available URLs in your app, there’s a chance that someone else could find that URL and then provide you with false data. To prevent this from happening, you can employ a number of techniques. The easiest thing to do (and what you should implement before going any further) is to force TLS connections (https). This will ensure that all data sent to your webhook endpoint is encrypted in transit and can’t be intercepted by a third party. You can also verify the webhook’s authenticity by checking the signature header that is sent with each webhook. The signature header is a hash of the payload and a secret key. The secret key is unique to your account and is used to generate the signature. To know more about how to verify the authenticity of a webhook using the signature header, read the signature verification section.
Registering a Webhook
Webhooks are tied to a single application so to register a webhook requires you to have an application on your account. To know more about applications read What is an application?. Once you have an application, you can register a webhook by navigating to the applications tab and clicking on configure button on the application you want to register a webhook for.
Once you have navigated to the application configuration page, you can register a webhook on the webhooks card. The webhook card contains the following fields:
- URL: This is the URL that will be called when the webhook is triggered. The URL must be a valid URL and must be accessible from the internet.
- Mode: This is the mode of the webhook. The mode can be either
Development
orProduction
. - Status: This is the status of the webhook. The status can be either
Active
orInactive
.
Webhook Events
Webhooks are triggered when a transaction:processed
event is fired. The transaction:processed
event is fired when a transaction is processed by our system. The event is fired regardless of whether the transaction was successful or not. This event is fired with the following payload:
{
"event_id": "9346978a-40c0-11ed-84d0-dead0b5d6103",
"event_kind": "transaction:processed",
"created_at": "2022-09-30T13:05:36.707853Z",
"data": {
"ref": "598f7582-ab43-4c90-9575-820806ab9107",
"kind": "CASHIN",
"fee": 2.3,
"merchant": "XXXXX",
"client": "07XXXXXXXX",
"amount": 100,
"provider": "mtn",
"status": "successful",
"created_at": "2022-09-30T12:53:50.880947395Z",
"processed_at": "2022-09-30T13:05:36.706109277Z"
}
},
The data
object contains the details of the transaction that was processed. The data
object contains the following fields:
- ref: This is the reference of the transaction.
- kind: This is the kind of the transaction. The kind can be either
CASHIN
orCASHOUT
. - fee: This is the fee that was charged for the transaction.
- merchant: This is the merchant that the transaction was made for.
- client: This is the client that the transaction was made by.
- amount: This is the amount that was transacted.
- provider: This is the provider that the transaction was made with.
- status: This is the status of the transaction. The status can be either
successful
orfailed
. - created_at: This is the time that the transaction was created.
- processed_at: This is the time that the transaction was processed.
Webhook Status
A webhook can be in one of the following statuses:
- Active: This is the status of a webhook that is currently active.
- Inactive: This is the status of a webhook that is currently inactive.
The status of a webhook can be changed by navigating to the Webhooks tab on your dashboard and clicking on the Edit button on the webhook that you want to edit. You can then toggle the switch under the Active column to change the status of the webhook.
Deleting a Webhook
You can delete a webhook by navigating to the Webhooks tab on your dashboard and clicking on the Delete button on the webhook that you want to delete.
Testing Webhooks
You can test your webhooks by navigating to the Webhook Tester and copying the URL that is generated. To test your webhooks, you can create a transaction using the Create a Transaction guide. Once you have created a transaction, you can navigate to the Webhook Tester and view the data that was sent to your webhook.
X-Webhook-Mode
header in your request. The value of the header should be either development or production. This will ensure that the webhook is triggered.Testing on localhost
If you are testing your webhooks on localhost, you can use localhost.run to expose your localhost to the internet. To use localhost.run run the following command:
ssh -R 80:localhost:8080 nokey@localhost.run
This will generate a URL that you can use to test your webhooks. You can then use the URL to test your webhooks. localhost.run is not a service that we recommend for production use. It is only meant for testing purposes.
If you wish to use another service to expose your localhost to the internet, you can read more about it here.
Signature Verification
Webhooks sent by Paypack are verified by calculating a digital signature of the request body using the webhook secret key. Each webhook request includes a x-paypack-signature
header, generated using the webhook's secret along with the data sent in the request. To verify the request, you need compute the HMAC digest of the request body using the webhook secret key and compare it with the value of the x-paypack-signature
header.
The x-paypack-signature
header is a SHA-256 HMAC digest of the request body calculated using the webhook secret key as the key and the request body as the value. The HMAC digest is then
converted to a base64 string.
copy webhook secret
link under the webhook URL field to copy the webhook secret key.Examples
app.use(
express.json({
// Store the rawBody buffer on the request
verify: (req, res, buf) => {
req.rawBody = buf;
},
})
);
app.post('/webhook', async (req, res) => {
//Extract X-Paypack-Signature headers from the request
const requestHash = req.get('X-Paypack-Signature');
//secret which you can find on your registered webhook
const secret = os.GetEnv("PAYPACK_WEBHOOK_SIGN_KEY");
//Create a hash based on the parsed body
const hash = crypto.createHmac('sha256', secret).update(req.rawBody).digest('base64');
// Compare the created hash with the value of the X-Paypack-Signature headers
if (hash === requestHash || req.Method != "HEAD") {
//Do your work here!
console.log('Webhook is originating from Paypack');
} else {
console.log('Signature is invalid, rejected');
}
});
Troubleshooting
Webhooks not being triggered
If you are not receiving any webhooks, the first thing to check is the URL that you are using. Ensure that the URL is accessible from the internet and that it is a valid URL. If the URL is valid and accessible from the internet, the next thing to check is the application that the webhook is tied to. Ensure that the webhook status is active. If the webhook status is active, the next thing to check is the mode of the webhook. Ensure that the mode used while making requests to our API is set to the same mode on your dashboard.
Our SDKs come pre-configured with the correct mode. If you are using our SDKs on a server the mode will be automatically set to Production
while if you are on a localhost the mode will be automatically set to Development
.