Creating a webhook endpoint is no different than creating any page on your website. The endpoint should expect a POST request with JSON data in the body of the request. We recommend using HTTPS for your callback URLs. myPOS will validate the server certificate before sending the notification. myPOS will include the event name in an X-myPOS-Event header as well as a signature validation in an X-myPOS-Signature header. The signature will be generated with the secret provided when creating the webhook. You will need to validate the signature before processing the request to ensure it comes from myPOS.
Responding to a webhook
To acknowledge receipt of a webhook, the endpoint should return a 2xx HTTP status code. All responses outside this range, including 3xx codes, will indicate to myPOS that the webhook was not received. This means a URL redirection or a “Not Modified” response will be treated as a failure.
myPOS will try to deliver webhooks for up to 3 days. Webhooks cannot be manually retried, though information about them can be gathered using the /events endpoint.
Verifying webhook signature
In order to verify the signature of a webhook, it is required to have the secret used when generating the webhook itself. The signature header contains two parameters:
- t – unix timestamp in seconds of when the signature was generated
- v1 – signature schema version. Anything below this version should be considered as an invalid request.
myPOS generates the signature using a hash-based message authentication code, or HMAC, with SHA-256 digest algorithm.
Extracting timestamp and signature
Split the header value using the , character for separator to get a list of elements. Now split each element, using the = character for separator to get a key-value pair.
Generate the expected signature
This is achieved by concatenating the timestamp(as string), . character and the HMAC SHA256 hash of the request body using the webhook’s secret as the key.
Compare signatures
Compare the expected signature with the one received in the X-myPOS-Signature header. If the signatures match, compute the difference between the current timestamp and the timestamp in the same header, then decide if the difference is within your tolerance. myPOS suggests a tolerance of 5 minutes.
If a webhook is marked as failed and retried to be delivered, the timestamp will be different and therefore a new signature will be generated.
import json
import hmac
import hashlib
from flask import request
def validate_signature():
req_data = request.get_json()
signature_header = request.headers['X-myPOS-Signature']
expected_signature = signature_header.split(',')[1]
expected_signature = hmac.new(
key="myrandomgeneratedsecret".encode('utf-8'),
msg=json.dumps(req_data).encode('utf-8'),
digestmod=hashlib.sha256
).hexdigest()
if req_signature != expected_signature:
print("Signatures don't match")
else:
print("Signatures match)
const crypto = require("crypto");
validateSignature: () => {
const signatureHeader = req.headers["x-mypos-signature"];
const requestSignature = signatureHeader.split(',')[1];
const expectedSignature = crypto.createHmac("sha256", "myrandomgeneratedsecret").update(JSON.stringify(req.body)).digest("hex");
if (requestSignature !== expectedSignature) {
console.log("Signatures don't match");
}
else {
console.log("Signatures match");
}
};