DocumentationWebhook interface

Webhook Interface

Available in API versionsv4

API Reference

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

  1. Full communication is bidirectional - i.e. “Qerko” can request something from POS and POS can request something from “Qerko”
  2. Whenever POS needs something from “Qerko”, you can call REST API - section “Endpoints” in API reference
  3. Whenever “Qerko” needs something from POS, we call one of webhooks implemented by POS - section “Webhooks” in API reference
  4. All communication received by “Qerko” from POS is authorized - requires assigned API key present in Authorization HTTP header and Pos-Id, in additional Pos-Id HTTP header. All authorization failures are treated with 401 HTTP status code.
  5. Requests with incorrect data shape, that doesn’t match “Qerko” specs are responded with 400 status code i.e. in example case /get-payment requires paymentId in request body
  6. 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.
  7. For RFC 9421 signature “Qerko” provides 2 additional HTTP Headers - Signature and Signature-Input
  8. For HMAC-SHA-256 signature “Qerko” provides custom Signature-SHA256 header.
  9. Webhook signature mismatches are treated by POS with 401 HTTP status code, i.e. “Qerko” isn’t authorized.
  10. created and expires timestamps are parts of signature input, i.e. tampering with them will result in malformed signature. Both created and expires 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 with 410 HTTP status code
  11. 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 providing 202 HTTP status. This notifies “Qerko” to expect response, that POS should provide by calling the /reply endpoint
  12. 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
  13. “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.
  14. 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 asynchronous
  • 200 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 HeaderValue
AuthorizationBearer YOUR_API_KEY_FROM_PREVIOUS_STEP
Pos-Iduuidv4 (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

debugger in 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.

debugger scenarios

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
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

  1. Reach out to techsupport@qerko.com
  2. “Qerko” will test your implementation, if it’s ready for production.
  3. Replace production parameters
    • replace sandbox.qerko.com hostname with qerko.com
    • replace Pos-Id with uuidv4 value assigned from “Qerko”

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!