Webhooks
Learn how to listen to events whenever certain actions occur on your integration.
What are webhooks?
We trigger events that your application can listen to whenever certain actions occur on your Okra integration. Here's where webhooks come in handy. We deliver payloads for such events to a webhook URL on your server. If you use webhooks, for example, we'll send a balance.success
event to your server as soon as a balance is retrieved. The following is a list of events we can send to your webhook URL.
Helpful Tip
We advise using a webhook instead of a callback to deliver value to your clients. Callbacks can fail if a customer's device's network connection fails or is weak, or if the device turns off after a request, among other things that are beyond our and your control.
You can specify your webhook URL on your dashboard where we would send POST
requests whenever an event occurs.
Here are some things to note when setting up a webhook URL:
- If using
.htaccess
, remember to add the trailing/
to the URL you set. - Do a test post to your URL and ensure the script gets the post body.
- Ensure your webhook URL is publicly available (localhost URLs cannot receive events)
Webhooks Configuration
To set up a new webhook:
- From the Environment Switcher in your Okra dashboard, select the environment you want to create a new webhook.
- Select the Developer tab and click Webhooks.
- Select the Configuration tab and input your webhook URL and bearer token.
- URL: The URL receives the data of an event that occurs in your Okra integrations.
- Token: It's a text string used to authenticate API requests.
Click Save Changes.
✳️ Done! The webhook is now set up and your application will be notified of new events related to any product opted for.
Receiving an event
All you have to do to receive the event is to create an unauthenticated POST
route on your application. The event object is sent as JSON in the request body.
// Using Express
app.post("/your/webhook/url", function(req, res) {
// Retrieve the request's body
const event = req.body;
// Do something with event
res.send(200);
});
<?php
// Retrieve the request's body and parse it as JSON
$input = @file_get_contents("php://input");
$event = json_decode($input);
// Do something with $event
http_response_code(200); // PHP 5.4 or greater
?>
Best practices for setting up webhooks
1. Responding to an event
A 200 OK
should be used to respond to an event. This is considered an acknowledgment by your application. If your application returns a status other than 2xx
, we will consider it unacknowledged and will continue to send it every hour for the next 72 hours. You don't need to provide a request body or any other parameters because they will be ignored - we only care about the status code.
Okra may timeout waiting for a response if your application is likely to start a long-running task in response to the event, in which case the event will be considered unacknowledged and queued to be raised later. You can avoid duplication by having your application respond with a 200 right away before continuing with the rest of the task.
2. Correctly matched keys
All webhook requests are sent with an Okra-Auth header for verification.
It is recommended that you verify and match the webhook secret key you passed when creating this webhook.
Here’s an example of how to verify incoming webhook requests in Node JS:
// Javascript Implementation
const secret = process.env.OKRA_WEBHOOK_KEY;
function verifyWebhook(req, res, next) {
//isVerified is a function that verifies the token
if (!isVerified(req.headers['Okra-Auth'])) {
return res.status(401).json({
message: "Unauthorized request."
});
}
next();
}
router.post('/create', verifyWebhook, (req, res) => {
const webhook = req.body;
switch(webhook.event) {
case "okra.event":
// do something with webhook.data.account;
break;
}
return res.sendStatus(200);
});
Example incoming webhook
If you're using callbacks with any product, you'll receive a callback when Okra finishes processing the product's data for the Record. Once you receive this callback, you can make an API call to retrieve the product's data.
Below you will see an example of an incoming webhook from Okra's servers. The below example is for AUTH
but you will receive webhooks for all products.
Webhook response
If you've set up webhook notifications for your account, we will also send you a response in the format below:
{
method: 'IDENTITY',
callback_type: 'IDENTITY',
callback_code: 'PRODUCT_IS_READY',
type: 'CALLBACK',
code: 'PRODUCT_IS_READY',
callbackURL: 'https://e2c550b71c3f.ngrok.io/v2/data/login/',
env: 'production-sandbox',
status: 'is_success',
started_at: '2021-04-23T07:39:10.133Z',
ended_at: '2021-04-23T07:39:35.376Z',
message: 'Record callback started!',
options: { },
bankName: 'Access Bank',
bankType: 'ind',
bankId: '5d6fe57a4099cc4b210bbec0',
bankSlug: 'access-bank',
record: '6082799e5ad7d31243eb6d43',
login_type: 'bank',
customerId: '602d7a668299304ef0df55v2',
extras: {},
owner: '5d9288ea182d3d000cb7c481'
}
{
"method": "AUTH",
"callback_type": "AUTH",
"callback_code": "AUTH_SUCCESS",
"type": "CALLBACK",
"code": "AUTH_SUCCESS",
"callbackURL": "https://webhook.site/f9feec4c-3b12-4d10-82a6-7da824fb1aaf",
"env": "production-sandbox",
"status": "is_success",
"started_at": "2021-10-14T09:56:30.121Z",
"ended_at": "2021-10-14T09:56:30.474Z",
"message": "Record callback started!",
"meta_responses": null,
"meta": {},
"bankName": "Stanbic IBTC Bank",
"bankType": "ind",
"bankId": "5d6fe57a4099cc4b210bbeb6",
"bankSlug": "stanbic-ibtc-bank",
"record": "6167febb7e0b622d072a3335",
"recordId": "6167febb7e0b622d072a3335",
"callback_url": "http://localhost:5000/v2/callback?record=6167febb7e0b622d072a3335&method=AUTH",
"login_type": "mobile",
"customerId": null,
"customerEmail": [
"[email protected]",
"[email protected]"
],
"customerBvn": null,
"country": "NG",
"extras": {},
"current_project": "6050d01a9306f087a64462cf",
"owner": "5d9288ea182d3d000cb7c486"
}
{
"method":"IDENTITY",
"callback_type":"IDENTITY",
"callback_code":"PRODUCT_IS_READY",
"type":"CALLBACK",
"code":"PRODUCT_IS_READY",
"callbackURL":"https://webhook.site/#!/b9656de5-2803-40e0-8e8b-11bad56a1884",
"env":"production",
"status":"is_success",
"started_at":"2021-10-14T13:01:29.831Z",
"ended_at":"2021-10-14T13:01:30.884Z",
"message":"Record callback started!",
"meta_responses":null,
"options":{
"tester_id":"123"
},
"meta":{
},
"bankName":"Stanbic IBTC Bank",
"bankType":"ind",
"bankId":"5d6fe57a4099cc4b210bbeb6",
"bankSlug":"stanbic-ibtc-bank",
"record":"616829f0aed04439dc016b9e",
"recordId":"616829f0aed04439dc016b9e",
"login_type":"mobile",
"customerId":"613644c21eeb46b178f0d798",
"identityType":"bvn",
"customerEmail":[
""
],
"customerBvn":null,
"country":"NG",
"extras":{
},
"identity":{
"bvn":"22165416979",
"nin":"97340973633",
"firstname":"OLATUNDE",
"lastname":"GARUBA",
"middlename":"MICHAEL",
"email":[
""
],
"name":"OLATUNDE MICHAEL GARUBA",
"fullname":"OLATUNDE MICHAEL GARUBA",
"dob":"1984-04-16",
"gender":"M",
"marital_status":"Single",
"phone":[
"08038603506"
],
"address":[
"JACOB MEWS ADEBISI, STREET, YABA",
"2/4 FUSHO STREET QUEENS COLLEGE LAGOS"
],
"aliases":[
"OLATUNDE GARUBA",
"undefined undefined"
],
"verification_country":"NG",
"photo_id":[
],
"lga_of_origin":"Ogbomosho North",
"lga_of_residence":"Lagos Mainland",
"nationality":"Nigeria",
"state_of_origin":"Oyo State",
"state_of_residence":"Lagos State",
"options":{
"tester_id":"123"
},
"id":"613bb6d194f8133a31591f38",
"details":"https://api.okra.ng/v2/callback?record=616829f0aed04439dc016b9e&method=IDENTITY",
"customer":"613644c21eeb46b178f0d798",
"bank":"5d6fe57a4099cc4b210bbeb6",
"env":"production",
"projects":[
"6050d01a9306f087a64462cf"
]
},
"current_project":"6050d01a9306f087a64462cf",
"owner":"5d9288ea182d3d000cb7c486"
},
"serverResponse":{
"success":false,
"error":{
"message":"The POST method is not supported for this route. Supported methods: GET, HEAD.",
"id":null
}
}
}
{
"method": "ACCOUNTS",
"callback_type": "ACCOUNTS",
"callback_code": "ACCOUNTS_SUCCESS",
"type": "CALLBACK",
"code": "ACCOUNTS_SUCCESS",
"callbackURL": "https://webhook.site/f9feec4c-3b12-4d10-82a6-7da824fb1aaf",
"env": "production-sandbox",
"status": "is_success",
"started_at": "2021-10-14T09:34:37.888Z",
"ended_at": "2021-10-14T09:34:38.538Z",
"message": "Record callback started!",
"accountId": "6167442f2791dde7e1cfeef5",
"meta_responses": null,
"options": {},
"meta": {},
"bankName": "Stanbic IBTC Bank",
"bankType": "ind",
"bankId": "5d6fe57a4099cc4b210bbeb6",
"bankSlug": "stanbic-ibtc-bank",
"record": "6167f8a9dfa6e32b9c8f4ed3",
"recordId": "6167f8a9dfa6e32b9c8f4ed3",
"callback_url": "http://localhost:5000/v2/callback?record=6167f8a9dfa6e32b9c8f4ed3&method=ACCOUNTS",
"login_type": "mobile",
"customerId": null,
"customerEmail": [
"[email protected]",
"[email protected]"
],
"customerBvn": null,
"country": "NG",
"extras": {},
"nuban": "7433275284",
"account": {
"_id": "6167442f2791dde7e1cfeef5",
"bank": "5d6fe57a4099cc4b210bbeb6",
"env": "production-sandbox",
"nuban": "7433275284",
"created_at": "2021-10-13T20:40:14.870Z",
"customer": null,
"last_updated": "2021-10-14T09:34:30.488Z",
"name": "another test",
"type": "Savings",
"currency": "NGN"
},
"current_project": "6050d01a9306f087a64462cf",
"owner": "5d9288ea182d3d000cb7c486"
}
{
"method": "BALANCE",
"callback_type": "BALANCE",
"callback_code": "BALANCE_SUCCESS",
"type": "CALLBACK",
"code": "BALANCE_SUCCESS",
"callbackURL": "https://webhook.site/f9feec4c-3b12-4d10-82a6-7da824fb1aaf",
"env": "production-sandbox",
"status": "is_success",
"started_at": "2021-10-14T10:05:55.441Z",
"ended_at": "2021-10-14T10:06:02.141Z",
"message": "Record callback started!",
"accountId": "6167442f2791dde7e1cfeef5",
"meta_responses": null,
"options": {},
"meta": {},
"bankName": "Stanbic IBTC Bank",
"bankType": "ind",
"bankId": "5d6fe57a4099cc4b210bbeb6",
"bankSlug": "stanbic-ibtc-bank",
"record": "616800e94600fc2d7e6f10a9",
"recordId": "616800e94600fc2d7e6f10a9",
"callback_url": "http://localhost:5000/v2/callback?record=616800e94600fc2d7e6f10a9&method=BALANCE",
"login_type": "mobile",
"customerId": null,
"customerEmail": [
"[email protected]",
"[email protected]"
],
"customerBvn": null,
"country": "NG",
"extras": {},
"nuban": "7433275284",
"balance": {
"_id": "616744312791dde7e1cfef27",
"available_balance": 10134674,
"created_at": "2021-10-13T20:40:17.318Z",
"currency": "NGN",
"customer": null,
"env": "production-sandbox",
"last_updated": "2021-10-14T10:05:55.441Z",
"ledger_balance": 10134674,
"$addToSet": {
"owner": "5d9288ea182d3d000cb7c486"
}
},
"current_project": "6050d01a9306f087a64462cf",
"owner": "5d9288ea182d3d000cb7c486"
}
{
"method": "TRANSACTIONS",
"callback_type": "TRANSACTIONS",
"callback_code": "PRODUCT_IS_READY",
"type": "CALLBACK",
"code": "PRODUCT_IS_READY",
"callbackURL": "https://webhook.site/f9feec4c-3b12-4d10-82a6-7da824fb1aaf",
"env": "production-sandbox",
"status": "is_success",
"started_at": null,
"ended_at": "2021-10-14T09:37:23.060Z",
"message": "Record callback started!",
"accountId": "6167442f2791dde7e1cfeef5",
"meta_responses": null,
"options": {},
"meta": {},
"bankName": "Stanbic IBTC Bank",
"bankType": "ind",
"bankId": "5d6fe57a4099cc4b210bbeb6",
"bankSlug": "stanbic-ibtc-bank",
"record": null,
"recordId": null,
"callback_url": "http://localhost:5000/v2/callback?record=null&method=TRANSACTIONS",
"login_type": "mobile",
"customerBvn": null,
"country": "NG",
"extras": {},
"newTransactions": 0,
"nuban": "7433275284"
}
{
"method":"INCOME",
"callback_type":"INCOME",
"callback_code":"PRODUCT_IS_READY",
"type":"CALLBACK",
"code":"PRODUCT_IS_READY",
"callbackURL":"https://16764cf0511d.ngrok.io/v1/callback",
"env":"production",
"status":"is_success",
"started_at":"2021-10-14T00:33:13.068Z",
"ended_at":"2021-10-14T00:36:44.195Z",
"message":"Record callback started!",
"accountId":"6089ddfba351d4b0d6e7f922",
"options":{},
"meta":{},
}
{
"method":"PAYMENT",
"callback_type":"PAYMENT",
"callback_code":"PAYMENT_SUCCESS",
"type":"CALLBACK",
"code":"PAYMENT_SUCCESS",
"callbackURL":"http://localhost:5000/v2/callback",
"env":"production",
"status":"is_success",
"started_at":"2021-09-13T16:36:46.997Z",
"ended_at":"2021-09-13T16:39:01.346Z",
"message":"Record callback started!",
"accountId":"609aa830dd46hfd2604a518f",
"meta_responses":null,
"options":{},
"meta":{},
"bankName":"Guaranty Trust Bank",
"bankType":"ind",
"bankId":"5d6o9hg4s099cc4b210bbeb3",
"bankSlug":"guaranty-trust-bank",
"record":"613f7c8c37a198uhbv4efce9",
"recordId":"6190ok7627a1679413eefce9",
"callback_url":"https://api.okra.ng/v2/callback?record=613f7c8c37a198uhbv4efce9&method=PAYMENT",
"login_type":"mobile",
"customerId":"608b0098yt5fg42a4989c70c",
"identityType":"bvn",
"customerEmail":[
"[email protected]"
],
"country":"NG",
"extras":{
},
"garnishment":{
"amount_collected":10000
},
"schedule":{
"current_amount":0,
"paymentId":"613f7e0a7a7b6917bee79ef5"
},
"paymentId":"613f7c8c37a198uhbv4efce9",
"link":null,
"payment":{
"_id":"613f7c8c37a198uhbv4efce9",
"record":"613f7c8c37a198uhbv4efce9",
"amount":10000,
"available_balance":null,
"bank":"5d6fe57a4099cc4b210bbeb3",
"bank_response":{
"CODE":"1000",
"MESSAGE":"TRANSACTION SUCCESSFUL",
"SESSIONID":"0000132186543073850000325621364",
"ERROR":null,
"STATUSCODE":null,
"STATUSMESSAGE":null,
"NIBSSRESPONSECODE":" 00",
"BANKDOWNTIMEMESSAGE":"",
"DestAccName":"OKRA WALLET"
},
"created_at":"2021-09-13T16:36:26.652Z",
"credit_account":"5eaaff7741318jh464b964d3",
"currency":"NGN",
"current_project":"6050d01a9307g087a64462cf",
"debit_account":"609aa830dd48gf72604a518f",
"email":null,
"env":"production",
"error":null,
"error_response":null,
"fee":26.88,
"last_updated":"2021-09-13T16:38:58.809Z",
"link":null,
"meta":{
},
"meta_responses":null,
"owner":"5d9288ea182d38v00cb7c486",
"ref":"Okra, Inc via OKR PAY Ref _XbpOiwNX",
"schedule":null,
"source":"link",
"status":"success",
"customer":"608b03b09doj2d2a4989c70c"
},
"current_project":"6050d00o9306f087a64462cf",
"owner":"5d9288ea182d3dho0cb7c486"
},
"serverResponse":{
"status":"error",
"message":"Record does not match this user, please use your correct Bearer Token or record does not exist!",
"data":null
}
Checking a webhook status
curl -X GET https://api.okra.ng/v2/callback?record={RECORD}&method=METHOD
-H 'Content-Type: application/json'
-H 'Authorization: Bearer <secretKey>'
Product callbacks/webhooks
The following are the current events that we have for you. As we hook into more actions in the future, we'll add to this list.
Product | Methods | Endpoint |
---|---|---|
auth | AUTH | GET /v2/callback?record={RECORD ID HERE}&method=AUTH |
identity | IDENTITY | GET /v2/callback?record={RECORD ID HERE}&method=IDENTITY |
balance | BALANCE PERIODIC_BALANCE | GET /v2/callback?record={RECORD ID HERE}&method=BALANCE |
income | INCOME | GET /v2/callback?record={RECORD ID HERE}&method=INCOME |
transactions | TRANSACTIONS PERIODIC_TRANSACTIONS | GET /v2/callback?record={RECORD ID HERE}&method=TRANSACTIONS |
payment | PAYMENT PAYMENT_RECURRING | GET /v2/callback?record={RECORD ID HERE}&method=PAYMENT |
Other webhooks
{
"message": <message about the connection/>,
"event": 'USER_DISCONNECT',
"data": {
"accounts": <id-of-accounts-disconnected/>
"customer": <id-of-user/>
"disconnected_at": <time-of-disconnection/>
}
}
{
"message": <message about the connection/>,
"event": 'USER_REAUTH',
"data": {
"customer": <id-of-user/>
"deauthorized_at": <time-of-disconnection/>
}
}
WebHook trigger
Overview
The webhook trigger can come in very handy if you need to get the webhooks associated with a particular record id(s), in scenarios where the server goes down unexpectedly or you want to send webhooks to a different server.
You can use the webhook trigger to check the status of a webhook by supplying their record id(s) as the payload to the webhook trigger endpoint.
The way this works is by, calling this endpoint <https://api.okra.ng/v2/callback/trigger
>, and passing the record id or an array of record id(s), or maybe a valid URL you'd like to redirect the webhooks to.
payload = {
records: ["60b7be20ca7ce542d906e029", "60b7bc9aca7ce542d906e026"] //array of recordIds
url: "https://yourcompany/webhooks/okra"//callback_url (optional), it default to your saved callback_url
}
{
"status": "success",
"messgae": "webhook trigger successfully initiated",
"data": {}
}
Note that the records array accepts a maximum of 100 record ID's
How to setup Okra JS with webhooks
Webhook logs
The webhook logs on your dashboard, and help track activities on your webhooks, such as successful and failed sessions on what users do on a widget, its search functionality allows you to query customer ID, record ID as well as filter based on date ranges and status.
Search
To monitor the activities on your webhooks, you can use the search feature to query specific keywords, such as code
, status
, record ID
, and customer ID
.

Sample webhook response
Date
You can filter your search based on a certain date range on the calendar or choose from the default options, such as Today
, Yesterday
, Last 7 days
, Last 14 days
, Last 30 days
, This month
and Last month
.

Date Range
Status
You can streamline your search to output logs based on failed and successful status.

Select webhook status
Export
For ease of analysis outside of the Okra dashboard, you can export the logs by selecting some or all of the logs, the format of the export(in JSON), and click the "send to mail" button to download it directly from your mail.
Updated 7 months ago