POS API
POS API
Kassen anbinden, Warenkörbe verarbeiten und Kundenguthaben nutzen.
https://pos-playground-eu.qnips.com/api/pos/v3merchants
trackingUnits
baskets
contextIdentifiers
sortiments
/sortiments?thirdPartySortimentIdentifier={string1}&name={string2}POSTsortiments/{qnipsSortimentId}/group}/sortiments/{qnipsSortimentId}/group/{Id}PUTsortiments/{qnipsSortimentId}/group}/sortiments/{qnipsSortimentId}/group/{Id}DELETEsortiments/{qnipsSortimentId}/group/{Id}}/sortiments/{qnipsSortimentId}/group/{Id}POSTsortiments/{qnipsSortimentId}/article}/sortips/{qnipsSortimentId}/article/{PLU}?groupId={groupId}PUTsortiments/{qnipsSortimentId}/article}/sortips/{qnipsSortimentId}/article/{PLU}?groupId={groupId}DELETEsortiments/{qnipsSortimentId}/article/{PLU}?groupId={groupId}/sortips/{qnipsSortimentId}/article/{PLU}?groupId={groupId}POSTsortiments/{qnipsSortimentId}/bulkUpload?changedArticlesOnly={changedArticlesOnly}}/sortiments/{qnipsSortimentId}/bulkUpload?changedArticlesOnly={changedArticlesOnly}tokens
/tokens/{id}GETtokens/{id}/info/tokens/{id}/infoPOSTtokens/{id}/lock/tokens/{id}/lockPOSTtokens/{id}/dispose/tokens/{id}/disposeGETtokens/{id}/balance/tokens/{id}/balancePOSTtokens/{id}/addBalance?balanceToAdd={balanceToAdd}/tokens/{id}/addBalance?balanceToAdd={balanceToAdd}POSTtokens/{id}/withdrawBalance?balanceToWithdraw={balanceToWithdraw}&pin={pin}/tokens/{id}/withdrawBalance?balanceToWithdraw={balanceToWithdraw}&pin={pin}POSTtokens/{id}/Allowances?pin={pin}/tokens/{id}/Allowances?pin={pin}POSTtokens/{id}/ExternalBasket?pin={pin}/tokens/{id}/ExternalBasket?pin={pin}POSTtokens/{id}/UserGroups?pin={pin}/tokens/{id}/UserGroups?pin={pin}Grundlagen & vollständige Einführung
This page describes how you can integrate the menio functions into your software. The API is roughly divided into 5 areas, which can be implemented independently of each other, so that a partial implementation of the menio functionality is also possible.
| Area | Description |
|---|---|
| Registering New API Clients | This describes how a new client registers with the API and automatically joins the virtual organizational structure of a merchant. |
| Basket handling | Real-time calculation and reporting of discount and loyalty campaigns based on a basket are topics in this area. |
| Sortiment maintenance | This allows product data to be imported into the menio system, which enables the following functional areas: product and material group-based loyalty campaigns and customizable immediate discounts, digital menus and menus, ordering functionality. |
| Customer/credit/gift cards | In order not to have to deprive smartphone users exclusively of the advantages of menio functions, they can also be implemented with any type of customer card (magnetic card, NFC/RFID transponder, barcode/QR code cards etc.) as a means of identifying a customer profile and providing the menio offers. Customer cards can be loaded with credit in our system, which can then be used as a means of payment. |
| Mobile Payment | menio allows convenient mobile payments at your POS via various established payment services. |
Let's get started!
Basics
Our API is implemented as REST API. You should therefore use an HTTP client library to create the corresponding GET, POST, PUT and DELETE Perform operations on individual resources of our API. The available resources can be accessed via unique URLs.
Example: GET https://{https://pos-playground-eu.qnips.com}/api/{v3}/{brands}/{123}
Values in curly brackets have the following meaning:
| Code | Description |
|---|---|
{https://pos-playground-eu.qnips.com} This is the main domain of our API. Change this value on productive systems to 'https://pos-live-eu.qnips.com'. |
|
{v3} |
Version of the interface. Currently 'v3' is to be used. |
{brands} |
Name of the resource you want to access. The following resources are available: merchants, trackingUnits, baskets, sortiments, products, tokens |
{123} |
id of the object specified by the resource name to be delivered. |
Requests
Each resource of our API is protected with two special mandatory HTTP headers:
| Header Name | Description |
|---|---|
DevKey |
Here you have to enter your DeveloperKey, which you can get from us. |
trackingUnitId |
Each individual client that wants to call the menio API must first register with the menio system (see Client registration), which gives it a unique trackingUnitId that must be specified here for each subsequent call. |
Optional headers
Furthermore, there are some optional headers with which, for example, the desired format (JSON or XML) for the data exchange can be specified.
| Header Name | Description |
|---|---|
Accept |
Here you specify whether you expect the results of a call in XML or JSON format. Allowed are 'application/xml' and 'application/json'. Default is application/xml. |
Content-Type |
This specifies whether the content in the body of your POST and PUT requests is XML or JSON. Allowed are 'application/xml' and 'application/json'. Default is application/xml. |
Accept-Encoding |
To reduce the traffic and to speed up the interaction with the menio API it supports the zipped transmission of the content. If this header is set in the request with 'gzip', the content is zipped in the response. |
Content-Encoding |
For some POST calls it is useful to also transfer the content of the request body in zipped form. In this case set this header with 'gzip'. This way the backend notices that the request is zipped and unzips it before processing |
SecurityToken |
Some resources are additionally protected with a security token that is to be calculated dynamically in order to protect particularly sensitive parts of the API. The parts of the request from which such a token is to be formed are described directly in the specification of the resource. The calculation algorithm is always the same and is described here. |
Please always place an XML/JSON encoded in 'utf-8' in the body of requests.
Note that certain characters are also not allowed as values for XML tags in XML, so that a URL escaping of the values may have to take place
*Example: <name>Drinks&Food</name> would have to be converted at least to <name>Drinks%26Food</name>.
Responses
API-responses are normal HTTP-responses with an HTTP status code, response headers and, if applicable, a response body
The following HTTP status codes are used:
| Code | Description |
|---|---|
200 |
Success - Marks the successful execution. |
400 |
Bad Request - Request cannot be executed due to failed validations or unfulfilled preconditions. Please process the ErrorId in the response body for such errors, since in some cases it makes sense to repeat the request. |
401 |
Unauthorized - DevKey, trackingUnitId or Security-Token is/are not or incorrectly specified. |
500 |
Server error - Something went wrong during processing. The body usually contains more details about the bug, which are intended for logs and developers, but are not suitable for output to the UI. |
If successful, the response body may contain an XML or JSON (depending on the 'Content-Type'-header) serialized object
Security token
Since parameters of menio WebAPI resources are transmitted in plain text, even sufficient SSL encryption cannot protect completely against man-in-the-middle attacks. Therefore, menio secures the transmission of safety-relevant parameters by means of a so-called 'security token', which is to be dynamically calculated before the request, added to the request as a header and validated in the menio backend before the request is processed. This SecurityToken is secured by:
one, the third unknown, calculation algorithm
an individual secret key for each trackingUnit (checksumSecret), which is assigned to the trackingUnit when it is registered (see GET trackingUnits
Each resource protected with a SecurityToken defines for which parts of the input parameters a 'SecurityToken' is to be formed. The method for calculating the security token therefore takes a string and also returns the token as a string. Here is the algorithm for this method:
form a string with 'input' +
„qPnsS14“+ 'checksumSecret', with:- 'input': the value for which the checksum should be calculated
„qPnsS14“: a constant stringchecksumSecret: key assigned to thetrackingUnitat registration
Example with
input=„123456“ undchecksumSecret=„af87b1“: „123456qPnsS14af87b1“Create an MD5 hash for the result from the first step. For the value from the example shown above, the MD5 hash would be the following „1283ff82ae8e9ace636449a519d99fa9“
This hash is the 'SecurityToken'. Now pack it into the 'SecurityToken' header of the request so that the request can be processed at our backend.
Definition of terms
This API description uses some terms that are understood as follows:
merchant (merchant) - a merchant is a person identified by their unique menio username (e.g. 'max@mustermann.de') differentiable carrier of one or more sales locations (outlet). The outlets can be used in one or more trademark (brand) must be classified.
brand (private label) - a private label is usually a combination of several locations (outlet), which are operated under a uniform brand or corporate identity (e.g. 'Pizza Hut') A merchant can be the owner of several such brands. and manage them as independent units in qnips.
outlet (sales location) - a sales location is usually a branch, which is distinguished from other branches by its unique address stores (or sales locations) is distinguished.
trackingUnit (POS terminal) - are there several places in an outlet where invoices with independent invoice number ranges can be processed, each such location must be registered independently in our system as a so-called tracking unit. Will the Invoicing also centrally processed for several terminals, it is sufficient to register only the central unit as trackingUnit.
sortiment (Product master data) - A product master data is an organizational unit for the products marked as reward-enabled by the merchant. Sales articles that can be booked in a basket at the POS. Such articles must be uploaded to the menio system by an upload so that the merchant can define a reward on these articles.
basket - this is an object containing the data about the items purchased by the consumer, as have been entered in a trackingUnit in the context of an invoice
consumer - this refers to an end customer who purchases a basket in a store of a merchant. and links this purchase event ( purchase ) either via a scan of the QR code or via identification at the POS with his consumer profile in the menio system
consumerIdentToken - this refers to a 'token' of any type stored on any medium, which is uniquely is linked to a consumer profile and is therefore suitable for uniquely identifying the consumer. This token can e.g. be stored in a customer card, or exist in the form of a printed or virtual barcode or QR code, which can be read by the POS system can either be scanned or read in via another carrier medium.
Client registration
Each instance in your system that can independently generate and complete an invoice must have a unique 'trackingUnitId' from the menio system. For this, if the client does not yet have a trackingUnitId, a one-time GET trackingUnits-Call to be executed and the result of the call in to persist permanently in the case of the offending entity.
It is important to make a reference to the `outlet' for each trackingUnit to be registered. To do this, the GET trackingUnits-Call an 'outletId' must be specified. This may are fetched in two ways:
GET merchants-info - Use this call to retrieve the 'outlets' available for a 'merchant' in our system and let the desired Select 'outlet' on the UI
POST outlet - If your system has the address of the location where it is used, an 'outlet' can also be can be newly created via an API call. In the response to this call you will find the required 'outletId'.
If the cash register is moved to another location at some point, the new 'outletId' should be added to our system via
Change of location either via a
POST trackingUnits call.
Basket Handling
Basket Handling defines a real-time calculation of possible discounts and loyalty points defined in the menio system for a specific basket. This process consists of (multiple) calls on two resources of our API:
POST basket - this will create the basket using a unique ID submitted. Possible discounts and loyalty points are then calculated and returned to the POS system in response. A basket can and should be renewed several times and each new submission restarts the calculation of discounts and loyalty points.
POST basket-grant- this will mark a basket as completed. Shopping baskets marked this way cannot be re-calculated.
menio offers the following (and more) types of rewards:
Turnover-based coupons (e.g. 10% discount starting at 20€ turnover)
Product-based coupons (e.g. 20% on all men's boots)
coupons on product combinations (e.g. laces to men's shoes at half price)
quantity coupons (e.g. 3 for the price of 2)
Sales and/or product-based point collection systems with flexibly configurable discounts
The complete process of reward crediting is as follows:
1. enter the basket
2. carry out consumer identification if necessary
To do this, read from a customer card or smartphone presented by the consumer at the POS using a suitable reader (for example imager, magnetic card reader, NFC/RFID reader etc. the customer identifier stored in it and save it as a so-called consumerIdentToken.*3. call POST basket The response to this POST could look like this:
{ "Rewards":[ { "ProductId": "20019", "Name": "30% off large coffee drink and a donut", "GrossRewardValue": 0.72, "CouponId": 683, "RewardTriggeringPositionId": 1, "RewardType": 1 }, { "ProductId": "151" "Name": "30% off large coffee drink and a donut", "GrossRewardValue": 0.53, "CouponId": 683, "RewardTriggeringPositionId": 2, "RewardType": 1 } ], "LoyaltyInfo": [ { "Name": "One point for each hot beverage." "LoyaltyId": 171, "Details": [ { "PreviousPoints": 7, "NewPoints": 2, "PointsInScheme": 10, "GrossRewardValue": 0, "RewardTriggeringPositionId": 1 } ] } ] }4. Process 'rewards' in the response
You can now incorporate the rewards directly into the invoice and reduce the invoice amount accordingly.5. mark basket as completed
As long as a basket is not closed (granted), it can be resubmitted as often as desired. With each new submission the rewards are recalculated and replace the old ones. However, if, from the consumer's point of view, a final status is reached and the invoice amount is paid, the basket must be marked as 'granted' in our system. This way, our system will send a notification about a purchase to the consumer (by email or push). To do this, call POST basket-grant
Sortiment Maintenance
Sortiment Maintenance describes the initial upload and update of product/article data in our system. Sortiment Maintenance is a prerequisite for the following menio features:
product related rewards
For product-related rewards, it is sufficient to transfer only those products (or product groups) to the menio system. for which the merchant wants to set up a Reward. Here it is sufficient, if the articles in your minimum form (only PLU and name, and, if applicable, a product group assignment) must be submitted.
Menu card display in the app incl. allergen/nutritional value/additive information
Especially for gastronomy and communal catering in particular, we offer the function of a comprehensive, LMIV-compliant meal plans with proprietary allergen/additive management at item level. Does your system have such data, they can also be uploaded to our system, so that the allergen/additive management remains in your software and only the composition of the menu can be done by us
*NOTE: Please implement the feature so that the merchant can ultimately decide to what extent an sortiment of menio will be uploaded, for example, by creating a way in your system to mark the items transferred to menio as such.
Sortiments
Article data is organized in the menio system in so-called 'sortiments'. A sortiment can be made up of several 'trackingUnits' which can be used together at one or also at different locations. The only distinguishing feature, whether an article can be maintained by several trackingUnit in the same sortiment, is the uniqueness of its PLU ? If a different article name is recorded under the same PLU on two trackingUnit, these articles must be uploaded into different sortiments.
Call GET sortiments?thirdPartySortimentIdentifier={string1}&name={string2}.
Upload
The article data can be uploaded or updated individually or via bulk upload:
POST / PUT / DELETE sortiments/{qnipsSortimentId}/group
POST / PUT / DELETE sortiments/{qnipsSortimentId}/article
POST sortiments/{qnipsSortimentId}/bulkUpload?changedArticlesOnly={boolean}
Loyalty cards
Loyalty cards are another way of linking a 'basket' to a specific consumer profile, in addition to QR code scans. The procedure is quite simple: at the POS, an identifier of any type is generated by any identifier carrier is read out and sent to our system as a 'consumerIdentToken' together with a 'basket'.
Therefore it is not important for us whether this token is found
on a magnetic strip or NFC chip of a plastic card
in the barcode or QR code of a paper card
in an RFID transponder
as a virtual token on the consumer's smartphone
or via other means
It is just as unimportant by whom such a token has been generated, as long as it is unchangeable and is clear enough to distinguish its owner from other consumers.
Register customer card
A customer card can therefore be as easily implemented by using the card identifier stored in the card as a so-called 'token'. To do this, read the identifier from a card that you send to the consumer as a customer card and execute POST tokens/{id} with this identifier as `{id}'.
Block customer card
Customer cards can be blocked by the merchant either directly in the web portal or, if your software acts as the administration center for customer cards, it can be communicated to us via an API call. To do this, perform one of the two actions:
POST tokens/{id}/lock
This action renders a card completely unusable.
or POST tokens/{id}/dispose
Only releases the card from a consumer profile, but the card itself is still available for a new registration and use by another consumer
Top up card with credit
Loyalty cards can be topped up with a credit balance. The (re-)charge can be carried out by the consumer directly via our apps or consumer portal (e.g. by means of a bank transfer or via PayPal). Or it can be done at the POS. To do this, issue an invoice to a consumer, collect the money and post the credit to his or her customer card by entering the 'token' of his or her customer card and making the following call:
POST tokens/{id}/addBalance?balanceToAdd={balanceToAdd}
Withdraw credit
If there is credit on a customer card and your system sends a 'basket' with the 'token' of this customer card, the response to the POST basket/{basketId}?consumerIdentToken={token1} will contain the amount of credit.
If a portion of this credit is to be offset against the invoice total, you call
POST tokens/{id}/withdrawBalance?balanceToWithdraw={balanceToWithdraw}
Gift cards
A 'gift card' is treated as a 'customer card' as well in our system, with the only difference that the holder of a gift card, unlike the holder of a customer card, does not have public access via the consumer portal to the activities (charging and discharging transactions, 'baskets' purchased and possibly paid for with the card, etc.).
*Implementation-wise, however, a 'gift card' is completely identical to the 'customer card'.