Every webhook request contains the following two objects in the payload:
- event Contains metadata about the event.
- sender Contains the details of the workplace that is sending the event.
Most webhooks, with the exception of a few like backgroundPoll, also contain the following object:
- session Contains the details of the current session.
Then there are some objects that only occur with specific webhook events:
- scanCode (only occurs with
scanCode event)
Contains the scanned code’s details. - addSessionLine (only occurs with
addSessionLine event)
Contains the added line’s details. - removeSessionLine (only occurs with
removeSessionLine event)
Contains the removed line’s details. - mergeSession (only occurs with
mergeSession event)
Contains the ID of the session that the current session is merging with. - completeSession (only occurs with
completeSession event)
Contains the payment details of the session. - selectRelation (only occurs with
selectRelation event)
Contains the selected relation details. - printBill (only occurs with
printBill event)
Contains the details of previous payments to the bill. - customAction (only occurs with
customAction event)
Contains the details of the custom action. - course (only occurs with
kitchen...Course event)
Contains the details of the underlying course. - externalPayment (only occurs with
...ExternalPayment event)
Contains the external payment’s details. - cafeteriaOrder
Contains the details of the underlying cafeteria order. - tableOrder
Contains the details of the underlying table order. - order
Contains the details of the underlying order. - table
Contains the details of the underlying table.
Finally, some objects may only occur in certain circumstances.
- dialog (only occurs after a
dialog response)
Contains selected dialog options. - form (only occurs after a
form response)
Contains submitted form values. - openUrl (only occurs when the client supports it)
Contains preferences regarding usage of the openUrl response.
There is also always the possibility that your reply triggers an error, this will cause the following request to be sent to you:
- error
Signify an error in the response that was sent.
When replying to a webhook, you can choose to reply with an empty body, or with one or more of the following objects:
- error
Signify an error in the request that was sent. - scanCode (only works with
scanCode)
Response to the scanCode event. - lineChanges
Request changes to the session’s lines. - lineAdditions
Request additions to the session’s lines. - lineDeletions
Request deletions from the session’s lines. - lockSession
Lock the session from further changes. - lockSessionForAdditions
Lock the session from further additions (deletions/decreases is allowed). - receiptFooter (only works with
completeSession)
Request some extra data to be printed on the footer of the receipt. - billFooter (only works with
printBill)
Request some extra data to be printed on the footer of the bill. - dialog
Request a dialog to show up on screen. - form
Request a form with various input fields to show up on screen. - message
Request messages to show up on the user screen and/or the customer screen. - requestScanCode
Request a code to be scanned in the POS. - displayBarcode
Display a code on the POS customer display. - hideBarcode
Instantly hide a code that is currently displayed. - openUrl
Display or redirect to a website - customActionChange
Change the caption of a customAction button. - vatMethodChange
Change the VAT method of the current session. - externalCardScan
Notify the POS that an external card was scanned, that the POS should know about. - prepayTable
Register payment on a table. - requestCustomAction
Request the POS to execute a specific custom action. - version
A string that represent the version of your external software (or webhook middleware). - externalPayment (only works with
...ExternalPayment)
Influence the currently running external payment.
When you receive a polling webhook (you can recognize this by the property event.eventPolling), you must reply with at least a polling object in the response. Otherwise, MplusKASSA will continue querying your endpoint until the webhook is manually cancelled.
- polling Tell MplusKASSA to continue polling or not, and optionally display some messages.
Request objects
event
1 2 3 4 5 6 7 8 9 |
{ ... "event": { "eventBlocking": true, "eventCounter": 1, "eventTimestamp": "2017-08-09T16:07:33.964+02:00" } ... } |
Property | Type | Explanation |
---|---|---|
event.eventBlocking | boolean | Is the event blocking? When this is true, MplusKASSA is waiting for your response. |
event.eventPolling | boolean | Is the event polling? When this is true, MplusKASSA will continue to query your endpoint until you respond that polling is finished (see polling response). |
event.eventCounter | int | An increasing counter that helps you check if you already processed an event. Please note that the counter may occasionally reset. |
event.eventTimestamp | datetime | The date and time that the event occurred. |
sender
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ ... "sender": { "branchNumber": 1, "browser": { "browserFamily": "Chrome Mobile", "browserVersion": "109.0.5414", "deviceType": "Mobile", "platformFamily": "Android", "platformVersion": "10" }, "hasReceiptPrinter": true, "employeeNumber": 6, "instanceId": "f9fac333-9fa7-45fe-8e9c-2c1e6465942f", "language": "nl", "paymentStarted": false, "productName": "MplusQservice", "versionNumber": "48.0.0", "workplaceNumber": 1 } ... } |
Property | Type | Explanation |
---|---|---|
branchNumber | int | The branch the event was sent from. |
workplaceNumber | int | The workplace the event was sent from. |
instanceId | uuid | Every time the POS is restarted, this UUID is regenerated. |
paymentStarted | boolean | When the POS is in the payment screen, this variable will be true. To detect changes to and from the payment screen, you can listen to the startPayment and cancelPayment events. |
productName | string | Whether the webhooks are triggered from the Desktop POS MplusQ or through the API MplusQservice. |
When webhooks are triggered through one of our web apps, this will contain information about the browser that was used. | ||
browserFamily | string (optional) | The browser used. |
browserVersion | string (optional) | The version of the browser used. |
deviceType | string | Mobile, Tablet, Desktop, or Bot |
platformFamily | string (optional) | The platform (or OS) used. |
platformVersion | string (optional) | The version of the platform used. |
hasReceiptPrinter | boolean (optional) | Whether the workplace has a receipt printer configured. |
overallState | string (optional) | Offline, NotReady, or Ready |
coverState | string (optional) | Unknown, Open, or Closed |
paperState | string (optional) | Unknown, Empty, Low, or Present |
ageInSeconds | int (optional) | How many seconds ago the state was last updated. |
session
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
{ ... "session": { "sessionId": "5eea25d4-4188-43b8-9a66-8086561d590c", "table": { "number": 11, "subNumber": 4 }, "relation": { "relationNumber": 54, "extRelationId": "CST042", "name": "John Doe", "address": "", "zipcode": "", "city": "", "country": "", "deliveryAddress": "", "deliveryZipcode": "", "deliveryCity": "", "deliveryCountry": "", "telephone": "", "mobile": "", "email": "", "cardNumber": "", "bankAccountNumber": "", "vatNumber": "", "commerceNumber": "" }, "lines": [ { "lineId": "c686f63d-46a7-498e-b421-c72e5cb7136b", "extLineId": "External line reference #32424", "articleNumber": 1, "priceIncl": 2.50, "quantity": 1, "text": "Coffee", "discountPercentage": 50, "discountAmount": 1, "barcode": "8712345678901", "supplierArticleNumber": "XR-123", "pluNumber": "9864", "extArticleId": "651", "externalDiscount": { "discountId": "d2091980-7e7d-11e7-bb31-be2e44b06b34", "discountDescription": "Sample Voucher", "discountPercentage": 10, "discountAmount": 2 } } ], "payments": [ { "amount": 1, "description": "With cash", "method": "CONTANT" } ] } ... } |
Property | Type | Explanation |
---|---|---|
session.sessionId | uuid | The session’s unique ID. |
session.table.number | bigint (optional) | The table number that the session is attached to. |
session.table.subNumber | bigint (optional) | The table sub number that the session is placed upon. |
session.lines | array | The session’s lines. |
session.lines[].lineId | uuid | The line’s unique ID. |
session.lines[].articleNumber | bigint (optional) | The line’s article number. |
session.lines[].priceIncl | number (optional) | The line’s price including VAT. |
session.lines[].quantity | number (optional) | The line’s quantity. |
session.lines[].text | string | The line’s textual description. |
session.lines[].discountPercentage | number (optional) | The line’s percentual discount, this stacks with the discount amount. |
session.lines[].discountAmount | number (optional) | The line’s discount amount, this stacks with the discount percentage. |
session.lines[].supplierArticleNumber | string (optional) | Article number from the supplier, if available. |
session.lines[].pluNumber | string (optional) | PLU number, if available. |
session.lines[].extArticleId | string (optional) | External article ID, if available. |
Note that you would normally not be able to have a line with a discount from MplusKASSA and an external discount. It can only be one or the other. | ||
session.lines[].externalDiscount.discountId | uuid (optional) | This is a UUID you generate and store to remember that you applied this discount. |
session.lines[].externalDiscount.discountDescription | string (optional) | A textual description for the external discount. |
session.lines[].externalDiscount.discountPercentage | number (optional) | The line’s external percentual discount, this stacks with the external discount amount. |
session.lines[].externalDiscount.discountAmount | number (optional) | The line’s external discount amount, this stacks with the external discount percentage. |
Note that you would normally not be able to have a line with a discount from MplusKASSA and an external discount. It can only be one or the other. | ||
session.payments[] | payment (optional) | The session’s payments, including any prepayments that were made at any point in its history. |
Look at the completeSession object for a description of the payment’s properties. |
scanCode
1 2 3 4 5 6 7 8 |
{ ... "scanCode": { "scannedCode": "8712345678901", "codeType": "barcode" } ... } |
Property | Type | Explanation |
---|---|---|
scanCode.scannedCode | string | A textual representation of the code that was scanned. |
scanCode.codeType | string | barcode, rfid |
addSessionLine
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ ... "addSessionLine": { "line": { "lineId": "c686f63d-46a7-498e-b421-c72e5cb7136b", "articleNumber": 1, "priceIncl": 2.50, "quantity": 1, "text": "Coffee" } } ... } |
Property | Type | Explanation |
---|---|---|
addSessionLine.line.lineId | string | The added line’s unique ID.< |
addSessionLine.line.articleNumber | bigint (optional) | The added line’s article number. |
addSessionLine.line.priceIncl | number (optional) | The added line’s price including VAT. |
addSessionLine.line.quantity | number (optional) | The added line’s quantity. |
addSessionLine.line.text | string | The added line’s textual description. |
On top of this the added line can also contain all the additional properties a session.lines[] object can contain. |
removeSessionLine
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ ... "removeSessionLine": { "line": { "lineId": "c686f63d-46a7-498e-b421-c72e5cb7136b", "articleNumber": 1, "priceIncl": 2.50, "quantity": 1, "text": "Coffee" } } ... } |
Property | Type | Explanation |
---|---|---|
removeSessionLine.line.lineId | string | The removed line’s unique ID. |
removeSessionLine.line.articleNumber | bigint (optional) | The removed line’s article number. |
removeSessionLine.line.priceIncl | number (optional) | The removed line’s price including VAT. |
removeSessionLine.line.quantity | number (optional) | The removed line’s quantity. |
removeSessionLine.line.text | string | The removed line’s textual description. |
On top of this the added line can also contain all the additional properties a session.lines[] object can contain. |
mergeSession
1 2 3 4 5 6 7 8 9 10 11 |
{ ... "mergeSession": { "mergeWithSessionId": "f232b716-8ab4-419e-b45e-e70720203e57" }, ... "session": { "sessionId": "15a0ea55-3ae8-4191-a7c1-3e93984e23b4" } ... } |
Property | Type | Explanation |
---|---|---|
mergeSession.mergeWithSessionId | string | The session that the current session is merged with. |
session.sessionId | string | The session that is merged. |
completeSession
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ ... "completeSession": { "payments": [ { "amount": 5, "description": "Contant", "method": "CONTANT" }, { "amount": 10, "description": "Cadeaubon", "method": "CADEAUBON" } ] }, ... "session": { "sessionId": "15a0ea55-3ae8-4191-a7c1-3e93984e23b4" } ... } |
Property | Type | Explanation |
---|---|---|
completeSession.payments[].amount | number | The amount that was paid with this specific payment method. |
completeSession.payments[].description | string | The description label of this payment method. |
completeSession.payments[].method | string | The reference id of this payment method. |
The completeSession.payments list only contains the payments that were made in the final transaction, and does not include any previous prepayments that were made to the session. You can find a list of all (pre)payments in the session.payments list. |
selectRelation
1 2 3 4 5 6 7 8 9 10 |
{ ... "selectRelation": { "relation": { "relationNumber": 1, ... } } ... } |
Check the definition of session for possible contents of relation.
When a relation is deselected, the value of relation will be null. |
customAction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ ... "customAction": { "customActionId": "A_CUSTOM_ACTION_ID", "buttonCaption": "The Button Caption", "onStartup": false, "longClick": false, "numpadValue": 1.5 }, ... "session": { "sessionId": "15a0ea55-3ae8-4191-a7c1-3e93984e23b4" } ... } |
Property | Type | Explanation |
---|---|---|
customAction.customActionId | text | The manually configured ID of the customAction button that was clicked. |
customAction.buttonCaption | text | The manually configured caption of the customAction button that was clicked, can be changed through a webhook response. |
customAction.onStartup | boolean | Whether or not the webhook was called during POS startup. You may use this to set initial state. |
customAction.longClick | boolean (optional) | Whether or not the button was held for a long time. You may decide to alternate behaviour based on this. |
customAction.numpadValue | number (optional) | The current value of the POS numpad input. |
course
1 2 3 4 5 6 7 8 9 10 11 12 |
{ ... "customAction": { "customActionId": "A_CUSTOM_ACTION_ID", "numpadValue": 1.5 }, ... "session": { "sessionId": "15a0ea55-3ae8-4191-a7c1-3e93984e23b4" } ... } |
Property | Type | Explanation |
---|---|---|
customAction.customActionId | text | The manually configured ID of the customAction button that was clicked. |
customAction.numpadValue | number (optional) | The current value of the POS numpad input. |
externalPayment
1 2 3 4 5 6 7 8 9 10 |
{ ... "externalPayment": { "externalPaymentId": "7d5b3a3a-9330-11ed-a1eb-0242ac120002", "amount": 3.14, "method": "K_WEBHOOK", "callbackUrl": "https://yourplatform.example.com/callback" } ... } |
Property | Type | Explanation |
---|---|---|
externalPaymentId | string | Each external payment receives a new id. |
amount | number | The amount that has to be paid. |
method | string | The name of the payment method that was configured to trigger the webhook. |
callbackUrl | string (optional) | If this URL is provided, please call it when you have the final status of the external payment. This is an important step in speeding up certain parts of the payment processing. You don’t need to do anything with the result of this request. |
cafeteriaOrder
1 2 3 4 5 6 7 8 9 10 |
{ ... "cafeteriaOrder": { "orderId": "8fdcaa6d-9908-4c16-b594-ee0f1ae10279", "year": 2019, "number": 13465, "ticketNumber": 465 }, ... } |
Property | Type | Explanation |
---|
tableOrder
1 2 3 4 5 6 7 8 9 |
{ ... "tableOrder": { "orderId": "c7ec2390-9333-11ed-a1eb-0242ac120002", "year": 2023 "number": 1 }, ... } |
Property | Type | Explanation |
---|
order
1 2 3 4 5 6 7 8 9 |
{ ... "order": { "orderId": "c7ec2390-9333-11ed-a1eb-0242ac120002", "year": 2023 "number": 1 }, ... } |
Property | Type | Explanation |
---|
table
1 2 3 4 5 6 7 8 9 |
{ ... "table": { "number": 3, "subNumber": 1, "numberOfGuests": 2 }, ... } |
Property | Type | Explanation |
---|
dialog
When you reply with a dialog, the user will be able to select some dialog options. Afterwards, the same event will be sent to you again, but this time including the selected dialog options.
1 2 3 4 5 6 7 |
{ ... "dialog": { "selectedDialogOptionIds": [1,2] }, ... } |
Property | Type | Explanation |
---|---|---|
dialog.selectedDialogOptionIds | int[] | The ID’s of the selected dialog option. Can be zero, one or more. |
On top of this, you also receive all the original data from the event. |
form
When you reply with a form, the user will be able to fill out and submit it. Afterwards, the same event will be sent to you again, but this time including the submitted form values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ ... "form": { "id": "custmer_registration", "cancelled": true/false, "fields": [ { "id": "name", "value": "John Doe" }, { "id": "email", "value": "john@doe.example.com" }, { "id": "allergies", "selected": [ "peanut", "gluten" ] } ] }, ... } |
Property | Type | Explanation |
---|---|---|
form.id | string | Form identifier as specified in the initial form response. |
form.cancelled | boolean (optional) | If the form was explicitly cancelled, this will be true. |
form.fields[].id | string | Field identifier as specified in the initial form response. |
form.fields[].value | string | No matter the original field type, submitted values are always sent as string. |
form.fields[].selected | string[] | Contains the selected options in case of a select field. |
On top of this, you also receive all the original data from the event. |
openUrl
Contains preferences regarding usage of the openUrl response.
1 2 3 4 5 6 7 |
{ ... "openUrl": { "redirectUrl": "https://mpluskassa.online/handheld/webhook/0f2e40a6-9336-11ed-a1eb-0242ac120002" }, ... } |
Property | Type | Explanation |
---|---|---|
redirectUrl | string | If you plan to redirect the client to another URL during webhook interaction, please redirect back to this URL after completion. |
error
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "error": { "code": LINE_ALREADY_HAS_DISCOUNT", "message": "Line ID c686f63d-46a7-498e-b421-c72e5cb7136b already has a discount applied to it." }, "original": { "event": ... "sender": ... "session": ... ... } } |
Property | Type | Explanation |
---|---|---|
error.code | string | One of the Error Codes. |
error.message | string | Additional descriptive explanation of the cause of the error. |
original | object | All of the details of the original event. |
Response objects
error
1 2 3 4 5 6 |
{ "error": { "code": "INVALID_SUBSCRIPTION_ID", "message": "The supplied subscription does not exist in our database. Please contact support at ... to set-up your account." } } |
Property | Type | Explanation |
---|---|---|
error.code | string | One of the Error Codes. |
error.message | string | Additional descriptive explanation of the cause of the error. |
scanCode
1 2 3 4 5 6 |
{ "scanCode": { "recognized": true, "relationNumber": 123 } } |
Property | Type | Explanation |
---|---|---|
scanCode.recognized | boolean | Did you recognize the code or not? If you respond with true, the POS will stop looking for the code in its own data. |
scanCode.relationNumber | int (optional) | A relation to select in the POS. |
lineChanges
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "lineChanges": [ { "lineId": "c686f63d-46a7-498e-b421-c72e5cb7136b", "externalDiscount": { "discountId": "12551430-7ce9-11e7-bb31-be2e44b06b34", "applyToQuantity": 1, "discountPercentage": 50, "discountAmount": 1 "discountDescription": "Sample Voucher", "discountType": "promotional" } } ] } |
Property | Type | Explanation |
---|---|---|
lineChanges[].lineId | uuid | The UUID of the session line that you want to change. |
lineChanges[].externalDiscount | externalDiscount (optional) | The details of an external discount are explained below. |
externalDiscount.discountId | uuid | This is a UUID you generate and store to remember that you applied this discount. |
externalDiscount.discountPercentage | number (optional) | The discount percentage that you want to apply to the line. |
externalDiscount.applyToQuantity | number (optional) | The quantity of this line that you want to apply the discount too. For example, if the quantity of the line is 2, but you want to apply the discount to 1 of these 2. |
externalDiscount.discountAmount | number (optional) | The exact amount of discount percentage that you want to apply to the line. |
externalDiscount.discountDescription | string (optional) | A descriptive label for the discount. |
externalDiscount.discountType | string (optional) | Can be any kind of text, will be usable as a filter in reports |
lineAdditions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "lineAdditions": [ { "lineId": "f1b8a9aa-9875-11e7-abc4-cec278b6b50a", "extLineId": "foobar-123", "articleNumber": 1005, "barcode": "8712345678901", "pluNumber": "9864", "supplierArticleNumber": "XR-123", "extArticleId": "651", "priceIncl": 2.10, "quantity": 3, "text": "Chocolate Milk", "externalDiscount": (...) } ] } |
Property | Type | Explanation |
---|---|---|
lineAdditions[].lineId | uuid (optional) | The UUID of the session line that you want to add. You are allowed to generate this. If you omit this an UUID will be generated automatically, but it will be more difficult for you to know which line you added. |
lineAdditions[].extLine | string (optional) | An identifier so you can recognize this line in a later stage. |
lineAdditions[].articleNumber | bigint (optional) | This number should be present in the MplusKASSA administration. |
lineAdditions[].barcode | string (optional) | This barcode should be present in the MplusKASSA administration. |
lineAdditions[].pluNumber | string (optional) | This PLU number should be present in the MplusKASSA administration. |
lineAdditions[].supplierArticleNumber | string (optional) | This supplier article number should be present in the MplusKASSA administration. |
lineAdditions[].extArticleId | string (optional) | This external article ID should be present in the MplusKASSA administration. |
You can add an article through articleNumber, barcode, pluNumber, supplierArticleNumber, extArticleId, or a combination thereof. | ||
lineAdditions[].priceIncl | number (optional) |
The line’s price including VAT. If you omit this, the default price will be used. |
lineAdditions[].quantity | number (optional) | The line’s quantity (how many). If you omit this, a default quantity of 1 will be used. |
lineAdditions[].text | string (optional) | The line’s text (description). If you omit this, the default article text will be used. |
You can add a simple text line (without any article references) by using only text. | ||
lineAdditions[].externalDiscount | externalDiscount (optional) | See the explanation at session for more details. |
lineDeletions
1 2 3 4 5 6 7 |
{ "lineDeletions": [ { "lineId": "f1b8a9aa-9875-11e7-abc4-cec278b6b50a" } ] } |
Property | Type | Explanation |
---|---|---|
lineDeletions[].lineId | uuid | The UUID of the session line that you want to delete. |
It is possible that your request for deletion will be denied. For example, you can only delete lines that you yourself added. You will receive an error message if this is the case. | ||
lockSession
1 2 3 |
{ "lockSession": true } |
Property | Type | Explanation |
---|---|---|
lockSession | boolean | Locks or unlocks the session from further changes. |
lockSessionForAdditions
1 2 3 |
{ "lockSessionForAdditions": true } |
Property | Type | Explanation |
---|---|---|
lockSessionForAdditions | boolean | Locks or unlocks the session from further additions (deletions/decreases are allowed). |
receiptFooter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "receiptFooter": { "textBefore": line1\nline2\nline3", "textBeforeOptions": { "align": "center", "doubleHeight": true, "doubleWidth": true, "underline": true, "bold": true }, "barcode": { "codeType": "code128", "code": "8712345678901" }, "textAfter": "line1", "textAfterOptions": { "align": "center", "doubleHeight": true, "doubleWidth": true, "underline": true, "bold": true } } } |
Or for multiple footers, use an array:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ "receiptFooter": [ { "textBefore": "line1", "textBeforeOptions": { "align": "center", "doubleHeight": true, "doubleWidth": true, "underline": true, "bold": true }, "barcode": { "codeType": "code128", "code": "8712345678901" }, "textAfter": "line1", "textAfterOptions": { "align": "center", "doubleHeight": true, "doubleWidth": true, "underline": true, "bold": true }, "printSeparate": true }, { "textBefore": "line2", "barcode": { "codeType": "code128", "code": "8712345678902" }, "textAfter": "line2", "printSeparate": true } ] } |
Property | Type | Explanation |
---|---|---|
textBefore | string (optional) | The additional text that you want to print on the receipt footer before the code. New lines ( \n) are supported. |
textBeforeOptions.align | string (optional) | Available alignments are: left (default), center and right. |
textBeforeOptions.doubleHeight | boolean (optional) | Indicate whether the line should have double the normal character height. |
textBeforeOptions.doubleWidth | boolean (optional) | Indicate whether the line should have double the normal character width. |
textBeforeOptions.underline | boolean (optional) | Indicate whether the line should get underlined. |
textBeforeOptions.bold | boolean (optional) | Indicate whether the line should be bold. |
barcode.codeType | string (optional) | The type of barcode you want to print on the receipt footer. Available types are: code128 (default) or qrcode. |
barcode.code | string (optional) | The code that you want to be printed as a barcode on the receipt footer. |
textAfter | string (optional) | The additional text that you want to print on the receipt footer after the code. New lines ( \n) are supported. |
textAfterOptions | (optional) | See textBeforeOptions above for a full explanation. |
printSeparate | boolean (optional) | Set to true if the footer should be printed separately from the receipt. (The receipt printer will make a cut between the receipt and this footer.) |
It is possible that your request for extra data on the footer will be denied. You will receive an error message if this is the case, and the receipt will be printed without your additional data. |
billFooter
The JSON details of billFooter
are identical to receiptFooter
.
dialog
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
{ "dialog": { "required": false, "requireConfirmation": true, "allowMultipleOptions": false, "dialogTitle": "Select the voucher to apply", "columns": 2, "dialogOptions": [ { "optionId": 1, "optionName": "Second cup of coffee for free!", "optionColor": "#00ff00", "articleNumber": 1005, "barcode": "8712345678901", "pluNumber": "9864", "supplierArticleNumber": "XR-123", "extArticleId": "651" }, { "optionId": 2, "optionName": "5% discount over the entire order", }, { "optionId": 3, "optionName": "Coffee + Cake 3,-", } ] } } |
Property | Type | Explanation |
---|---|---|
dialog.required | boolean | Is a choice required? |
dialog.allowMultipleOptions | boolean | Is more than one choice allowed? |
dialog.dialogTitle | string | Which title should the dialog show? |
dialog.columns | int (optional) | How many columns should the dialog use to display the options? |
dialog.dialogOptions[].optionId | int | The option’s ID. |
dialog.dialogOptions[].optionName | string | The option’s textual description. |
dialog.dialogOptions[].optionColor | string | The option’s color in hexadecimal format. |
dialog.requireConfirmation | boolean (optional) | Do you need to click confirm after selecting an option? Useful to prevent misclicks. |
dialogOptions[].articleNumber | string (optional) | Will enrich the option button with article information and imagery from the POS system. |
dialogOptions[].barcode | ||
dialogOptions[].pluNumber | ||
dialogOptions[].supplierArticleNumber | ||
dialogOptions[].extArticleId |
form
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
{ "form": { "id": "customer_registration", "title": "Register New Customer", "enableReset": true, "fields": [ { "id": "name", "type": "text", "required": true, "label": "Your name", "hint": "Use your official name", "value": "John", "minimumLength": 1, "maximumLength": 200 }, { "type": "label", "value": "Just some information", "separator": "below" }, { "id": "email", "type": "email" }, { "id": "card_number", "type": "text", "regex": "^C\\d{8}$" }, { "id": "family_size", "type": "number", "decimals": 0, "minimumValue": 1, "maximumValue": 9 }, { "id": "allergies", "type": "select", "multiple": true, "columns": 3, "options": [ { "id": "peanut", "label": "Peanuts", "color": "brown", "selected": false, "image": "https://mpluskassa.nl/images/peanut.png" }, { "id": "gluten", "label": "Gluten", "color": "#00ff00", "selected": true } ] }, { "id": "welcome_gift", "type": "select", "multiple": false, "columns": 2, "options": [ { "id": "gift_01", "label": "Peanuts", "articleNumber": "2343241" }, { "id": "gift_02", "label": "Gluten", "articleNumber": "2136533", "disabled": true } ] }, { "id": "start_of_contract", "type": "date" }, { "id": "preferred_delivery_time", "type": "time" }, { "id": "accept_terms", "type": "checkbox", "label": "I accept the Terms and Conditions" } ] } } |
Property | Type | Explanation |
---|---|---|
form.id | string | Form identifier that will be included when the form is submitted. |
form.title | string | Title will be displayed above the form. |
form.enableReset | boolean (optional) | Whether to display the button that will reset the form to its original state. |
form.fields[].id | string | Field identifier that will be included when the form is submitted. |
form.fields[].type | string | text, email, number, select, date, time, checkbox, label |
form.fields[].required | boolean | Whether the field is required. |
form.fields[].separator | string (optional) | none, above, below |
form.fields[].label | string | What caption to display with the form field. |
form.fields[].hint | string (optional) | A longer explanation to clarify the requirements. |
form.fields[].value | string (optional) | A default value to populate the field with. |
form.fields[].minimumLength | int (optional) | A minimum required text length. |
form.fields[].maximumLength | int (optional) | A minimum required text length. |
form.fields[].regex | string (optional) | A regex pattern to validate the input. |
form.fields[].decimals | int (optional) | How many decimals to allow on a number field. |
form.fields[].miminumValue | number (optional) | Minimum value of a number field. |
form.fields[].maximumValue | number (optional) | Maximum value of a number field. |
form.fields[].multiple | boolean (optional) | Whether to allow multiple selections on a select field. |
form.fields[].columns | boolean (optional) | How many columns to use to display the select options. |
fields[].options[].id | string | Option identifier that will be included when the form is submitted. |
fields[].options[].label | string | The label that will be display on the option. |
fields[].options[].color | string (optional) | Preset color name or hex code that will be used as background color. |
fields[].options[].selected | boolean (optional) | Whether the option should already be selected. |
fields[].options[].image | string (optional) | This image will be shown on the option. |
fields[].options[].articleNumber | string (optional) | Will enrich the option button with article information and imagery from the POS system. |
fields[].options[].barcode | ||
fields[].options[].pluNumber | ||
fields[].options[].supplierArticleNumber | ||
fields[].options[].extArticleId | ||
fields[].options[].disabled | boolean (optional) | Can be used to show an option that is not selectable. |
message
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "message": [ { "message": "We encountered a situation that requires your attention", "customerMessage": "ATTENTION REQUIRED", "displayTime": 5, "messageDisplayTime": 5, "customerMessageDisplayTime": 15, "hideTimestamp": false, "clearScreen": true, "clearCustomerScreen": true, "monospacedFont": true, "backgroundColor": "#ff0000" } ] } |
Please note that the message property is an array that allows for multiple messages to be returned in a single reply. | ||
Property | Type | Explanation |
---|---|---|
message[].message | text (optional) | Show a message on the POS user’s display.. |
message[].customerMessage | text (optional) | Show a message on the POS customer display. |
message[].displayTime | int (optional) | This will ensure the message and customerMessage are shown for at least this amount of seconds. |
message[].messageDisplayTime | int (optional) | This will ensure the message is shown for at least this amount of seconds. |
message[].customerMessageDisplayTime | int (optional) | This will ensure the customerMessage is shown for at most this amount of seconds. |
message[].hideTimestamp | boolean (optional) | When set to true, this will hide the timestamps that are usually shown in front of the messages. |
message[].clearScreen | boolean (optional) | When set to true, this will clear all previous messages. |
message[].clearCustomerScreen | boolean (optional) | When set to true, this will clear the current customer message. |
message[].monospacedFont | boolean (optional) | When set to true, this will display the messages in a monospaced font so you can better align multiple lines. |
message[].backgroundColor | string (optional) | The background color of the message popup in hexadecimal format. Or preset color names, like “red” and “green”. |
requestScanCode
1 2 3 4 5 6 |
{ "requestScanCode": { "required": true, "requestTitle": "Please scan your code now" } } |
Property | Type | Explanation |
---|---|---|
requestScanCode.required | boolean | Is a scan required? |
requestScanCode.requestTitle | boolean | What would you like the POS screen to display to the user? |
displayBarcode
1 2 3 4 5 6 |
{ "displayBarcode": { "codeType": "qrcode", "code": "https://example.com/loremipsum" } } |
Property | Type | Explanation |
---|---|---|
displayBarcode.codeType | string | barcode, rfid, qrcode |
displayBarcode.code | string | The contents of the barcode |
hideBarcode
1 2 3 |
{ "hideBarcode": true } |
Property | Type | Explanation |
---|---|---|
hideBarcode | boolean | Instantly hide a code that is currently displayed. |
openUrl
1 2 3 4 5 6 7 8 9 10 |
{ "openUrl": { "url": "https://payment-platform.example.com/transaction/123", "autoOpen": false, "urlTitle": "Click here to start payment", "closeOnDomainChange": true, "minimumWidth": 800, "minimumHeight": 500 } } |
Property | Type | Explanation |
---|---|---|
url | text | The actual URL to open. |
autoOpen | boolean (optional) | Whether or not to automatically open the URL. |
urlTitle | text (optional) | The title of the link/button in case the URL is not set to open automatically, or is unable to open automatically. |
closeOnDomainChange | boolean (optional) | Set this if you want the browser component to automatically close when the current domain changes, e.g. from payment-platform.example.com to some-other-domain.com. |
minimumWidth | int (optional) | In case of a browser popup, determines the minimum width the popup should receive. |
minimumHeight | int (optional) | In case of a browser popup, determines the minimum height the popup should receive. |
polling
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "polling": { "finished": false, "message": "The process has been completed for 55%", "customerMessage": "Progress: 55%", "displayTime": 5, "messageDisplayTime": 5, "customerMessageDisplayTime": 15, "hideTimestamp": false, "clearScreen": true, "clearCustomerScreen": true, "monospacedFont": true } } |
Property | Type | Explanation |
---|---|---|
polling.finished | boolean | Tell MplusKASSA whether the polling process is finished or not. When you return false, MplusKASSA will immediately resend the request to your endpoint. |
polling.message | text (optional) | Show a message on the POS user’s display. Use this to update the user on progress made in the polling process. |
polling.customerMessage | text (optional) | Show a message on the POS customer display. Use this to update the customer on progress made in the polling process. |
polling.displayTime | int (optional) | This will ensure the message and customerMessage are shown for at least this amount of seconds. |
polling.messageDisplayTime | int (optional) | This will ensure the message is shown for at least this amount of seconds. |
polling.customerMessageDisplayTime | int (optional) | This will ensure the customerMessage is shown for at most this amount of seconds. |
polling.hideTimestamp | boolean (optional) | When set to true, this will hide the timestamps that are usually shown in front of the messages. |
polling.clearScreen | boolean (optional) | When set to true, this will clear all previous messages. |
polling.clearCustomerScreen | boolean (optional) | When set to true, this will clear the current customer message. |
polling.monospacedFont | boolean (optional) | When set to true, this will display the messages in a monospaced font so you can better align multiple lines. |
customActionChange
1 2 3 4 5 6 |
{ "customActionChange": { "customActionId": "STATUS_BUTTON", "buttonCaption": "Current status: ON" } } |
Property | Type | Explanation |
---|---|---|
customActionChange.customActionId | text | The ID of the customAction button that should be changed. |
customActionChange.buttonCaption | text | The desired new caption for the customAction button. |
vatMethodChange
1 2 3 |
{ "vatMethodChange": "shifted" } |
Property | Type | Explanation |
---|---|---|
vatMethodChange | text | inclusive, exclusive, shifted |
externalCardScan
Notify the POS that an external card was scanned, that the POS should know about.
1 2 3 4 5 6 7 8 9 10 11 |
{ "externalCardScan": { "cardIdentifier": "b4a7689d-4332-4b94-9f97-1dce8dcdca64", "cardDescription": "My Special Card", "cardBalance": 76.50, "cardExpiration": "2019-12-31", "cardBlocked": false, "displayTime": 5, "isNewBalance": false } } |
Property | Type | Explanation |
---|---|---|
externalCardScan.cardIdentifier | text (optional) | Use any kind of string that you use as identifier for this card within your system. Does not need to be present within the POS. |
externalCardScan.cardDescription | text (optional) | Enter the name of the card owner, or a description of the card itself. |
externalCardScan.cardBalance | number (optional) | The card’s current balance. |
externalCardScan.cardExpiration | datetime (optional) | The date and time when the card expires and is no longer usable. Please note that we do not actually do anything with this date, it is only used for informational purposes in the POS. |
externalCardScan.cardBlocked | boolean (optional) | When set to true the POS will indicate on screen that the card is blocked. |
externalCardScan.displayTime | int (optional) | You can use this to influence the time until the card details should be hidden again. This overrides the setting in the POS itself. Set to 0 to keep the details on screen until the next receipt. |
externalCardScan.isNewBalance | boolean (optional) | When set to true the POS will interpret the balance card as being the balance after the transaction and display accordingly. |
Even though all properties are optional, nothing will be displayed on the POS if you omit them all. |
prepayTable
1 2 3 4 5 6 7 8 9 |
{ "prepayTable": { "table": { "number": 20, "subNumber": 1 }, "sessionId": "367ef280-1b67-11ea-978f-2e728ce88125", "payments" [ { "paymentId": "af282ee3-c516-4805-96c1-fd9aed75f330", "amount": 14.99, "method": "MY_PAYMENT_METHOD" } ] } } |
Property | Type | Explanation |
---|---|---|
prepayTable.table.number | int | Designate the table’s number that the payments are meant for. |
prepayTable.table.subNumber | int (optional) | Designate the table’s subnumber that the payments are meant for. |
prepayTable.sessionId | uuid | Provide the session ID of the table. |
prepayTable.payments[].paymentId | uuid | Provide a unique ID, the POS will use to make sure this payment is not registered more than once. |
prepayTable.payments[].amount | number | The amount that was paid. |
prepayTable.payments[].method | text (optional) | The method that you want to register this payment to. If omitted, the POS uses the generic WEBHOOK payment method. |
requestCustomAction
1 2 3 4 5 |
{ "requestCustomAction": { "customActionId": "A_CUSTOM_ACTION_ID" } } |
Property | Type | Explanation |
---|---|---|
requestCustomAction.customActionId | text | The manually configured ID of the customAction button that you would like to trigger. |
It is important to realize that this is a request to trigger the custom action, not a guarantee that it will. Reasons why the custom action may not trigger are: (1) the POS is not running, (2) the POS is currently in an interrupted state (like processing an electronic payment), (3) the POS currently has no logged in user or (4) the POS is currently in a blocked state (like displaying a dialog). |
version
1 2 3 |
{ "version": "2.4" } |
Property | Type | Explanation |
---|---|---|
version | text | A string representing the version of your software (or the version of the Webhook middleware you created). |
This version number will be added to the communication log and can help with debugging version-related problems. |
externalPayment
Influence the currently running external payment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{ "externalPayment": { "externalPaymentId": "7a4d4fe3-....-....-....-5fc2fd596b26", "started": true/false, "confirmed": true/false, "cancelled": true/false, "finalAmount": 20, "externalTransactionReference": "KQUA6JcQ7sW5qgTXpCYXx4Lr", "receiptTexts": [ { "type": "cardholder", "text": "TRANSACTION DETAILS\nTO PRINT\nON THE RECEIPT" }, { "type": "merchant", "text": "COPY FOR THE MERCHANT\nNEEDS CARDHOLDER SIGNATURE", "requiresSignature": true } ], "cardType": "Maestro", "terminalId": "87420312", "method": "My Payment Platform", "requiresReceiptPrinter": true, "messages": [ { "message": "Payment ready to be started", "customerMessage": "Please insert EUR 11.25", "hideTimestamp": true/false, "monospacedFont": true/false, "clearScreen": true/false, "clearCustomerScreen": true/false, "messageDisplayTime": 3, "customerMessageDisplayTime": 3, "backgroundColor": "#ff0000" } ] } } |
Property | Type | Explanation |
---|---|---|
externalPaymentId | uuid | The external payment ID as received from the POS in the first place. So the POS can verify you are talking about the same payment. |
started | boolean (optional) | Has the external payment process been started? The external payment flow won’t progress from the start, to poll stage until you respond TRUE. |
confirmed | boolean (optional) | Has the external payment process been succesfully completed? The payment flow will end and the payment will be registered after you respond TRUE to this. |
cancelled | boolean (optional) | Has the external payment process been cancelled/aborted/failed? The payment flow will end and the payment will be not be registered after you respond TRUE to this. |
finalAmount | number (optional) | When the external payment succeeds, but with a differing amount than requested, you can specify the actual final amount through this variable. This requires activation of the software setting Webhooks > Algemeen > Webhooks mogen het via hen betaalde bedrag aanpassen. |
externalTransactionReference | string (optional) | Use this to assign a reference to the external transaction, which will be stored with the POS payment.. |
receiptTexts[].type | string (optional) | cardholder (default), merchant. Use this to tell the POS for whom the receipt is intended. |
receiptTexts[].text | string | The actual text to print on the receipt. |
receiptTexts[].requiresSignature | boolean (optional) | When this is true, the POS will prompt the merchant to have the cardholder sign this receipt. |
cardType | string (optional) | Use this to store the used card type with the payment, e.g. Maestro or VPAY. This may be used by the POS to group payments.. |
terminalId | string (optional) | Use this to store a terminal ID with the payment, which may be used by the POS to group payments.. |
method | string (optional) | Use this to store which payment method was used externally. |
requiresReceiptPrinter | boolean (optional) | Use this in the startExternalPayment response to let us know a configured printer is a requirement for a successful transaction. |
For an explanation of all the remaining message-related properties, please see message. |