
Introduction to our powerful webhook free app feature
Introduction
The barKoder demo application, available on the iOS App Store and Google Play Store for Android, includes a feature that allows users to set up a webhook that triggers with each scan.
This free feature enables users to transmit scanned data to their server quickly, ensuring fast transfer of barcode information to their server-based application. It comes built into our demo application.
General settings
The webhook section is located at the top of the Settings page. It's disabled by default, but once enabled, configuration options become available. Enabling and setting the webhook feature is pretty straight forward. The most important step in it is the webhook configuration that is handling the actual payload to the webhook. The other setting are how we deal with the payload (should we send it encoded) and the feedback (should we wait for the feedback).
First let's look at how we can enable the webhook

Enable Webhook Feature
Note: To enable the webhook, you must first configure it by tapping on webhook configuration.
Once you enable the webhook the configuration options become available. Enabling the webhook also means that each scanned barcode (if the webhook is configured properly) will be sent to the webhook endpoint automatically. Your next step would be to actually configure the webhook configuration.
Webhook configuration
After tapping on webhook configuration, a dialog screen will ask for two parameters:

Webhook endpoint (enter webhook URL)
A URL that will receive requests sent by the barKoder app. The backend server can use any technology (Node.js, PHP, Python, etc.) as long as it handles POST requests. You can select which protocol will be used for the communication to the server. So your webhook endpoint will look something like this:
example.com/web-hook
The app packages the scan result and sends a POST request to this endpoint.
Secret word (enter secret word)
A secret key used as a passkey to generate a token called security_hash
. The server uses this token to authenticate requests. This is explained in the SERVER SECTION, for now just know that this will be a random word that will be used to “encrypt” the data.
Webhook Confirmation Feedback
You can wait for confirmation from the server about the request status. The app expects a JSON formatted response with the following structure and will show a Toast notification after the scan if this option is enabled and if the return response is valid.
The message structure from the server should be formatted like this:
{
status:Boolean //(true or false if the actions succeeded)
message:String // String message describing the response
}

If you disable this option, data will still be sent, but the app won't wait for confirmation.
Encode webhook data
When enabled, the barcode data sent to the server will be base64 encoded, this will help if you are scanning barcodes that contain unprintable characters and similar data that might get deformed via the transport. It's arguable if you really need this feature, but it's available as an option.

Pre-send procedure (or how does the app prepare the payload)
Before sending data to the webhook, the app prepares the request with three main variables:
security_data
(Int) Unix Timestamp in seconds (10 digits)security_hash
(String) A hash created using the MD5 algorithm, derived from combiningsecurity_data
andsecret_word
data
(String) A JSON formatted string containing the barcode information (type, value)
If "encode data" is enabled, the data will be base64 encoded before sending.
As noted earlier, the security_hash
variable is crucial. It's created by combining security_data
and the secret_word
.
In summary, the app generates security_data
as a UNIX timestamp, concatenates it with the secret word, and then hashes the resulting string using the MD5 algorithm.
Pseudo code:
let security_word = "VERY-SECRET-WORD"
let security_data = UNIX_TIMESTAMP
let security_hash = md5(security_data+security_word)
Swift example:
let securityData = String(format: "%.0f", Date().timeIntervalSince1970)
let securityHash = WebhookService.md5(string: "(securityData)(secretWord)")
let parameters: Parameters = [
"security_data": securityData,
"security_hash": securityHash,
"data": jsonData
]
let request = AF.request(
url,
method: .post,
parameters: parameters,
encoding: JSONEncoding.default
)
request
.validate()
.responseDecodable(of: WebhookResponse.self, completionHandler: { response in
switch response.result {
case .success(let response):
completion(.success(response))
case .failure(let error):
completion(.failure(error))
}
}
})
Server setup
We extract the security_data
, security_hash
, and data
parameters from the incoming JSON request body.
To verify the integrity of the request, we generate an MD5 hash by concatenating security_data
with your secret word and comparing it to the provided security_hash
.
If the computed hash matches the one received, we proceed with processing the data
payload (this is where your custom logic goes). If the hashes do not match, we return a 400 Bad Request
response with an appropriate error message.
Make sure to replace "your_secret_word"
with your actual secret key used for hashing, and ensure the request body includes all required fields in proper JSON format.
NodeJS example
main : async function(req,res){
let post_data = req.body;
let query_data = req.query;
//here we grab both parameters sent by the APPlet security_data = post_data?.security_data ?? false;
let security_hash = post_data?.security_hash ?? false;
let data = post_data?.data ?? false
//if security_data is missing in the post, there is no point to continue
if(!security_data){
res.writeHead(403, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({ status:false,message:'Missing security_data!' }))
return;
}
//same for security_hash, if it's missing why go on?
if(!security_hash){
res.writeHead(403, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({ status:false,message:'Missing security_hash!' }))
return;
}
//now here we can do a basic comparation of the data being sent.
//what we want to achieve is the combination of the security_data that we receive
//and the secret_word that was inputted in the app.
//let's use crypto to create the hash
let crypto = require('crypto')
//ideally you'd have the secret key in an .env file away so the line would look something like this:
//let hash = crypto.createHash('md5').update(security_data + process.env.SECRET_WORD).digest("hex")
//however since this is just a simple showcase and not inteded to be used on a production server we can do:
let secret_word = 'this-is-my-very-secret-word";
let hash = crypto.createHash('md5').update(security_data + secret_word).digest("hex");
//this value of hash needs to match the value that we are being sent by the app stored in security_hash
if(security_hash === hash){
console.log('This is a valid request and we can do something with the data');
//here DO SOMETHING WITH THE DATA
res.writeHead(200, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({ status:true,message:'All good with the data, thanks!' }))
}
else{
console.log('The hash check failed to match, so we might want to deny this request');
res.writeHead(403, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({ status:false,message:'Forbidden for you!' }))
}
},
Final words
This feature should be enough for small sized projects to just use the powerful barcode scanning capabilities of the barKoder SDK in a real production setting without having to create a custom app that would require purchasing a license.