Webhook Interface
Available in API versions | v4 |
---|
About the API
Why is it called “webhook” interface?
Glad that you’ve asked. The core building block of “Webhook Interface” are webhooks, implemented by POS, or whoever takes on the adventure to integrate with “Qerko”.
Comparison with /v2
Websocket API
Compared to websocket API, from POS perspective you don’t need to bother with stateful websocket connection management. Webhook API implementation is easier due to its statelessness. However there are few limitations when it’s not possible to use webhooks, such as when for some reason you cannot have publicly accessible webhook HTTP endpoint. Common reason why that wouldn’t be possible is networking constraint on side on POS, in which case we recommend use of websockets, instead of webhooks.
How it works? - Communication protocol 101
- Full communication is bidirectional - i.e. “Qerko” can request something from POS and POS can request something from “Qerko”
- Whenever POS needs something from “Qerko”, you can call REST API - section “Endpoints” in API reference
- Whenever “Qerko” needs something from POS, we call one of webhooks implemented by POS - section “Webhooks” in API reference
- All communication received by “Qerko” from POS is authorized - requires assigned API key present in
Authorization
HTTP header and Pos-Id, in additionalPos-Id
HTTP header. All authorization failures are treated with401
HTTP status code. - Requests with incorrect data shape, that doesn’t match “Qerko” specs are responded with
400
status code i.e. in example case/get-payment
requirespaymentId
in request body - All webhook communication is signed. “Qerko” performs two kinds of request signatures, from which you can choose to validate webhook invocations - RFC 9421 and HMAC-SHA-256. Reason for two mechanisms is to provide simpler alternative, in case of not having suitable library to address RFC 9421 headers. Your unique API key is used as shared secret.
- For RFC 9421 signature “Qerko” provides 2 additional HTTP Headers -
Signature
andSignature-Input
- For HMAC-SHA-256 signature “Qerko” provides custom
Signature-SHA256
header. - Webhook signature mismatches are treated by POS with
401
HTTP status code, i.e. “Qerko” isn’t authorized. created
andexpires
timestamps are parts of signature input, i.e. tampering with them will result in malformed signature. Bothcreated
andexpires
are present in request body of of every webhook invocation. Reason for that is protection against reply attacks. webhook invocations, that have incorrect timing should be treated with410
HTTP status code- Webhooks can be responded either in “synchronous” or “asynchronous” response. POS controls whether to respond to webhook “synchronously” by returning
200
HTTP status or “asynchronously” by providing202
HTTP status. This notifies “Qerko” to expect response, that POS should provide by calling the/reply
endpoint - Both “synchronous” and “asynchronous” responses are subjected to 15 second timeouts; i.e. webhook calls are considered stale after 15 seconds of not receiving reply
- “Qerko” validates both asynchronous and synchronous webhook responses. If “Qerko” encounters validation errors in your webhook response, “Qerko” responds by invoking the
error
event of your webhook implementation, where the event will contain further error context, that will provide more details. - Server errors from POS webhook calls that are reported with
500
HTTP status are automatically retried, up to 3 times.
Configuring endpoint per merchant
You can configure your webhook per merchant (i.e. restaurant). By calling one-time endpoint, called /configure
, you can associate your webhook endpoint with merchant through corresponding API key. This allows you to have generalized endpoints, such as /webhook/:my-merchant-identifier
Synchronous vs. asynchronous?
Synchronous responses are advised for short methods, that don’t require much processing on the side of POS. Asynchronous responses are viable option for background tasks, that cannot be processed by POS right away, with respect to timeout settings on side of “Qerko”.
Support for asynchronous and synchronous responses is denoted in API reference by their respective status codes, i.e.
202
for asynchronous200
for synchronous.
Communication overview
Setting up your webhook
Synchronous flow
Asynchronous flow
Full integration steps
1. Set up your API key
Reach out to techsupport@qerko.com
to get access to our administration, where you can set up your testing environment along with API keys.
You will start implementing the API in our sandbox environment, to ensure your webhooks work correctly before full production deploy.
In case of any issues encountered from this step onwards, techsupport@qerko.com
will be your primary means of communication.
2. Prepare your authorization headers for sandbox
QERKO_API_KEY="<<YOUR_API_KEY_FROM_PREVIOUS_STEP>>"
# Alternatively use any uuid generator online tool to set up this variable
QERKO_POS_ID=$(which uuidgen >/dev/null && (uuidgen | tr '[:upper:]' '[:lower:]') || echo "59afcffa-6793-407b-9b31-d61652ec0209")
HTTP Header | Value |
---|---|
Authorization | Bearer YOUR_API_KEY_FROM_PREVIOUS_STEP |
Pos-Id | uuidv4 (for production this value is assigned by “Qerko”) |
3. Test your authorization headers against sandbox REST API
Test calling the /api/v4/who-am-i
endpoint
curl --request POST \
--url https://sandbox.qerko.com/api/v4/pos/who-am-i \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$QERKO_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Pos-Id: '"$QERKO_POS_ID"
4. Configure your webhook endpoint for your API key
Calling endpoint /api/v4/configure
will associate your API key with your webhook endpoint
QERKO_WEBHOOK_URL="https://your-unique-webhook-origin.com/merchant-specific-pathname"
curl --request POST \
--url https://sandbox.qerko.com/api/v4/pos/configure \
--header 'Accept: application/json' \
--header 'Authorization: Bearer '"$QERKO_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Pos-Id: '"$QERKO_POS_ID" \
--data '{
"webhookUrl": "'"$QERKO_WEBHOOK_URL"'"
}'
5. Implement your functionalities
5.1. Accessing the debugger
You should be able to access our POS debugging tool in Qerko administration - Screenshot of left-side in-app menu
5.2. Implementing the “middleware” scenarios
In “Qerko Administration” debugger page, you should see a dropdown, where you choose a scenario to test your implementation against. The important scenarios for are the ones prefixed with v4
, where v4
denotes API version.
Start with scenarios that are expected to be implemented in your middleware - i.e. request preprocessing
- Verify unauthorized response for invalid API key
- Verify expired request-response
5.2.1. Verify the request timing
All errors related to request timing should be treated with 410
HTTP status code.
First, validate that req.body.created
and req.body.expires
are within acceptable range. You should expect req.body.expires
to always be a timestamp denoting time in the future, i.e. greater than Date.now()
In case of req.body.created
is timestamp in the future, it could mean one of following
- HTTP request is genuinely out of range
- Time is out-of-sync between “Qerko” and POS
We recommend implementing verification of req.body.created
within acceptable treshold of 1 minute. You can choose different value, but it should be kept in mind that large threshold values could ignore malicious request, while smaller thresholds are more sensitive to timing, and could result in pointless errors.
5.3. Implementing the signature verification
5.3.1. Verify content digest
Start with verifying HTTP header Content-Digest
, which should contain sha256
request.headers['Content-Digest']=SHA256(request.body)
Mismatches in Content-Digest
should be treated with 401
HTTP status code.
5.3.2. Implement the verification
- RFC 9421
- recommended, if you can find suitable library doing the work for you, such as
http-message-signatures
fornodejs
- recommended, if you can find suitable library doing the work for you, such as
- HMAC-SHA-256
5.3.2.1. RFC 9421
For RFC 9421 we recommend following library instructions with API key being shared secret. All the required data should be present under HTTP headers
Signature-Input
Signtaure
5.3.2.2. HMAC-SHA-256
HMAC-SHA-256 Signature is implemented with Signature-SHA256
custom HTTP header. We include this header in our webhook HTTP calls, as an alternative if you run into issues implementing RFC 9421 verification method.
Note - request.body
includes timestamps created
and expires
to prevent timing forgery
5.4. Implementing basic methods
Implement the fundamental webhook methods
- Verify accepting
ping
- Verify accepting
error
(for asynchronous error reporting) - Verify unsupported method response
Note - ping
method isn’t just for testing purposes, it is required for “Qerko” health-checking mechanism periodically executed against POS
5.4.1. Futureproofing your implementation
Motivation behind “unsupported method” is future-proofing your implementation, if “Qerko” were to release a functionality that you might not have implemented at given time, in order to notify the end user that such configuration between “POS” and “Qerko” integration doesn’t work. Since webhook events listed in “Qerko” API Reference are consumed by a single endpoint, you can imagine it as a large switch
-case
statement, where the default
branch (i.e. fallback) should be reserved to return 404
response to “Qerko”.
5.5. Test the basic methods
Before proceeding make sure that the scenarios are functional, namely that ping
and error
reporting works.
5.6. Full POS functionalities
Implement the functionalities that you wish to support. You should be able to test them against the debugger tool.
Note - More testing scenarios are being added at moment
6. Reconfigure for production
Following are final production pre-release steps
- Reach out to
techsupport@qerko.com
- “Qerko” will test your implementation, if it’s ready for production.
- Replace production parameters
- replace
sandbox.qerko.com
hostname withqerko.com
- replace
Pos-Id
with uuidv4 value assigned from “Qerko”
- replace
7. All set
Open up the champagne, all the hard work is done.
Need help? If you get stuck or have questions, email us at techsupport@qerko.com—we’re here for you!