# Dojo Pay at Table Documentation > Guides for integrating Pay at Table (PAT) — searching payable orders, locking/unlocking, recording payments, and printable bills via the EPOS Data REST and WebSocket APIs. API quick reference: - **API base URL**: https://api.dojo.tech - **Environment selection**: Sandbox and production both use `https://api.dojo.tech`; the API key determines which environment receives the request - **Authentication**: `Authorization: Basic ` (literal `Basic ` prefix; do not base64-encode `api_key:`) - **Version header**: `version: 2026-02-27` PAT uses the Payment Intents API for payment lifecycle operations and the EPOS Data REST/WebSocket contracts for the order, lock, payment, and bill messaging the EPOS implements. WebSocket integrators connect to wss://eu.ws.dojo.tech/epos with handshake headers `Authorization: Basic ` (literal `Basic ` prefix; the key is NOT base64-encoded), `software-house-id`, and optional `reseller-id`. The single connection multiplexes every JSON-RPC method. Before any capability is routed to your EPOS, register it with PUT https://api.dojo.tech/epos/integrations/ws (WebSocket) or /epos/integrations/rest (REST). Send the full set you implement on every PUT — capabilities omitted from the body are not routed. Minimal registration body for PAT: `{"capabilities":[{"name":"SearchOrders","version":"v1"},{"name":"GetOrderById","version":"v1"},{"name":"RecordOrderPaymentById","version":"v1"}]}`. Add `CreateOrderLock`, `DeleteOrderLock`, `ExtendOrderLock` to enable the locking flow, and `GetOrderBillById` to enable printable bills. The registration name plus `V1` is the wire-level method Dojo invokes on your EPOS (e.g. registered `RecordOrderPaymentById` -> wire `RecordOrderPaymentByIdV1`). Machine-readable specs: - [Dojo API v3](https://docs.dojo.tech/api/v3/bundled.json) - [EPOS Data API (REST)](https://docs.dojo.tech/epos-data/bundled.json) - [EPOS Data API (AsyncAPI)](https://docs.dojo.tech/epos-data-asyncapi/bundled.yaml) For complete PAT integration, also load: - `llms-payment-intents.txt` — payment lifecycle, refunds, captures, and setup intents - `llms-epos.txt` — capability registration, WebSocket connection setup, and EPOS contract details - `llms-core-concepts.txt` — shared Order, Party, Table, and Area entities referenced by PAT This file contains all documentation content in a single document following the llmstxt.org standard. ## Pay at Table The **["Pay at Table"](https://support.dojo.tech/hc/en-gb/articles/360020950580-Using-Pay-at-Table)** (PAT) integration allows waiters to retrieve and pay for [orders](https://docs.dojo.tech/core-concepts/orders) on a EPOS, via Dojo card machines. This integration communicates with the EPOS system to retrieve open [orders](https://docs.dojo.tech/core-concepts/orders) and notify the EPOS system about payments via the **[EPOS Data API](https://docs.dojo.tech/api-hosting/epos-data)**. We recommend reading our documentation on [Orders](https://docs.dojo.tech/core-concepts/orders) before beginning this integration, as this is the main entity which the Pay at Table integration depends upon: the Dojo card machines will display payable orders which are returned from the EPOS system via the [SearchOrders](https://docs.dojo.tech/core-concepts/orders#search-orders) capability, lock and unlock orders via the [CreateOrderLock](https://docs.dojo.tech/core-concepts/orders#locking) and [DeleteOrderLock](https://docs.dojo.tech/core-concepts/orders#unlocking) capabilities, and provide payments to be recorded via the [RecordOrderPaymentById](https://docs.dojo.tech/core-concepts/orders#record-order-payment) capability. Dojo may also request to extend the length of the table lock by invoking the [ExtendOrderLock](https://docs.dojo.tech/core-concepts/orders#extending) capability. ## Integration You can integrate into the PAT flow using a combination of the [REST API](https://docs.dojo.tech/api-hosting/epos-data#rest), and/or the [WebSockets API](https://docs.dojo.tech/api-hosting/epos-data#websockets) implementation of the EPOS Data API, depending on your EPOS system's architecture. If you're unsure as to which implemenation option would best suit your system please contact your Partnership Development Manager (PDM). >The following **capabilities** are required to be implemented for Pay at Table: ### SearchOrders > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/paths/~1v1~1orders~1search/post > See OpenAPI spec for SearchOrdersV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-SearchOrdersV1_Request This capability enables searching for orders based on various criteria. It supports filtering and pagination to help Dojo products efficiently find orders within the POS system. Each Dojo product has different requirements on what filters must be implemented which can be found on the product documentation page(s). ### GetOrderById > See OpenAPI spec for GET endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-get-orders-orderId > See OpenAPI spec for GetOrderByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-GetOrderByIdV1_Request This capability enables Dojo to retrieve detailed information about a specific order using its unique order ID. This is crucial for order tracking and status updates. ### GetOrderBillById > See OpenAPI spec for GET endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-get-order-bill > See OpenAPI spec for GetOrderBillByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-GetOrderBillByIdV1_Request This capability allows the terminal to request a Bill - a printable version of the Order. The EPOS can customise the fields and layout of the Bill on a per request basis. ### RecordOrderPaymentById > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-post-record-order-payment > See OpenAPI spec for RecordOrderPaymentByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-RecordOrderPaymentByIdV1_Request This capability allows Dojo to record a payment against an order. All payments recorded this way will be sent with their `paymentIntentId` which is unique and can be used for both deduplication and to control the lifecycle of the payment with operations like Get and Reversal. ### Order-locking The following capabilities relate to an optional [order-locking flow](https://docs.dojo.tech/payments/pay-at-table/flows#createorderlock), giving the POS the opportunity to "lock" orders to prevent further changes while payment is being made, and then notifying the POS when an order is ready to be "unlocked". > **Note:** Although implementing an order-locking flow is optional, all capabilities listed below must be registered for order-locking to be supported. ### CreateOrderLock > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-post-order-lock > See OpenAPI spec for CreateOrderLockV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-CreateOrderLockV1_Request This capability allows Dojo to fetch the latest and full state of the order from the POS system. This will include a unique `lockId` and offer the POS the opportunity to "lock" the table to prevent further changes while payment is being made, although this is not mandatory. ### DeleteOrderLock > See OpenAPI spec for DELETE endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-delete-order-lock > See OpenAPI spec for DeleteOrderLockV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-DeleteOrderLockV1_Request This capability, when requested, gives the opportunity for the POS to allow further actions and updates to the order if these were previously disabled by a CreateOrderLock. ### ExtendOrderLock > See OpenAPI spec for PUT endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-put-extend-order-lock > See OpenAPI spec for ExtendOrderLockV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-ExtendOrderLockV1_Request This capability allows Dojo to extend the length of a requested Order lock if required by the card machine. With this implemented Dojo will request locks with shorter expiries and extend them when needed, this reduces the chance of a lock being held on an order for a long period of time when there is a communication breakdown between Dojo and the POS. --- ## Printable Bills > **Info:** The capabilities mentioned on this page must be registered with the **EPOS Capabilities API** prior to initiating a Pay At Table flow, > learn more [here](https://docs.dojo.tech/api-hosting/epos-data#registering-capabilities). ## Capability ### GetOrderBillById > See OpenAPI spec for GET endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-get-order-bill > See OpenAPI spec for GetOrderBillByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-GetOrderBillByIdV1_Request This capability allows the terminal to request a Bill - a printable version of the Order. The EPOS can customise the fields and layout of the Bill on a per request basis. ## Overview If the GetOrderBillById capability has been set for an account, at anytime during the Pay at Table flow, the payment device can request a "printable bill" - a nicely formatted view of an Order, designed to be shown to the merchant, physcially or digitally. Implementing this feature will improve the payment flow for merchants and customers, allowing them to give out itemised bills, with logos, websites, QR codes etc without needing to walk back to the EPOS each time. ## Full Example
```json { "header": { "lines": [ { "logo": { "svgImage": "" }, "lineType": "Logo" }, { "merchantName": { "name": "Dojo" }, "lineType": "MerchantName" }, { "merchantAddress": { "addressLines": [ "Brunel Building", "1 & 2 Canalside Walk" ], "postcode": "London W2 1DG" }, "lineType": "MerchantAddress" }, { "text": { "value": "Welcome to Our Store!", "size": "Header1", "align": "Center", "emphasisBold": true }, "lineType": "Text" }, { "image": { "svgImage": "...", "align": "Left" }, "lineType": "Image" }, { "horizontalLine": { "line": "Single" }, "lineType": "HorizontalLine" }, { "text": { "value": "Table 5", "size": "Header2", "align": "Left" }, "lineType": "Text" }, { "text": { "value": "Becky 15/03/2022 20:08", "size": "Body", "align": "Center" }, "lineType": "Text" }, { "text": { "value": "Transaction:6328", "size": "Body", "align": "Right" }, "lineType": "Text" } ] }, "order": { "id": "ord_12345678", "details": { "orderType": "DineIn", "dineIn": { "tableId": "Table 5", "waiterId": "Becky" } }, "items": [ { "quantity": 2, "name": "Pizza Pepperoni", "plu": "1234", "amountPerItem": { "value": 1235, "currencyCode": "GBP" } }, { "quantity": 2, "name": "Lager", "plu": "1245", "amountPerItem": { "value": 510, "currencyCode": "GBP" } }, { "quantity": 1, "name": "Water Still", "plu": "1", "amountPerItem": { "value": 50, "currencyCode": "GBP" } }, { "quantity": 2, "name": "Coca Cola", "plu": "2", "amountPerItem": { "value": 249, "currencyCode": "GBP" } }, { "quantity": 1, "name": "Burger", "plu": "234", "amountPerItem": { "value": 1090, "currencyCode": "GBP" }, "modifiers": [ { "name": "No Lettuce", "quantity": 1, "amountPerItem": { "value": 0, "currencyCode": "GBP" }, "plu": "74983" } ] }, { "quantity": 1, "name": "Burger", "plu": "234", "amountPerItem": { "value": 1090, "currencyCode": "GBP" }, "modifiers": [ { "name": "Extra Cheese", "quantity": 1, "amountPerItem": { "value": 0, "currencyCode": "GBP" }, "plu": "10987" }, { "name": "Bacon", "quantity": 1, "amountPerItem": { "value": 0, "currencyCode": "GBP" }, "plu": "872" } ] } ], "discounts": [ { "name": "10% discount", "amountTotal": { "value": 6.21, "currencyCode": "GBP" }, "amountPercentage": 1000 } ], "serviceChargeAmount": { "value": 62.95, "currencyCode": "GBP" }, "taxLines": [ { "id": "VAT", "name": "VAT", "amountPercentage": 20, "amountTotal": { "value": 62.95, "currencyCode": "GBP" } } ], "status": "Finalized", "createdAt": "2022-03-15T20:00:00Z", "updatedAt": "2022-03-15T20:05:00Z", "totalAmount": { "value": 6295, "currencyCode": "GBP" }, "payable": true, "paidAmount": { "value": 0, "currencyCode": "GBP" }, "reference": "Table 5" }, "footer": { "lines": [ { "text": { "value": "Thank you", "size": "Header1", "align": "Center" }, "lineType": "Text" }, { "taxNumber": { "name": "VAT", "number": "342 6287 32" }, "lineType": "TaxNumber" }, { "url": { "url": "https://www.website.com", "showQR": true, "showURL": true }, "lineType": "URL" } ] } } ```
## Bill Sections There are several pre-defined bill sections defined in this API, simplifying the design and layout of bills. However if more control is desired, there are more flexible sections that give complete freedom to the EPOS to dictate the design and layout. The `Header` and `Footer` elements in bill wrap the `Order`, which is the same object returned in the [Get Order by ID](https://docs.dojo.tech/core-concepts/orders#get-order-by-id) request. The `Header` and `Footer` are both arrays of `Lines`. In a line ensure you specify the `lineType` and populate the corresponding field in that object. Some examples are below. ### Predefined Sections #### Logo and Image The `Logo` and `Image` line types are similar, both taking an SVG. However a `Logo` will always appear at the top of the bill, whereas an `Image` will be in the order it is defined in, and allows for `Left`, `Right` or `Center` alignment. In the example below the Logo would be placed at the top, and the Image would be left aligned. ```json { "logo": { "svgImage": "" }, "lineType": "Logo" } ``` ```json { "image": { "svgImage": "" "align": "AlignLeft" }, "lineType": "Image" } ``` #### Merchant information We provide predefined fields for merchant information: - `MerchantEmailAddress` - `MerchantName` - `MerchantPhoneNumber` - `MerchantAddress` These will all be preformatted and simply require the fields to be populated. #### URL The `URL` object allows a website to be displayed in multiple forms. Set the `URL` and optionally a description for extra text and then decide if it should be displayed as a QR code (which we will generate) or printed URL. This allows you to link out to surveys, loyalty schemes or a website. For example, this would display this website as a QR code and a description. ```json { "url": { "url": "https://example.com/", "description": "Visit our website!", "showQR": true, "showURL": false }, "lineType": "URL" } ``` #### Tax We allow a tax number to be displayed, however you must set the name of the tax too. It is your responsibility to ensure the bill is a valid tax receipt for the market you're operating in. ```json { "taxNumber": { "name": "VAT", "number": "12345678" }, "lineType": "TaxNumber" } ``` #### Horizontal Lines A horizonal line can be used to create a divider across the width of the bill. There are `Single` and `Double` lines. ### Custom Sections #### Free Text This field allows text to be input, customising the size, weight and alignment. For example, this will be displayed as the largest text size, and aligned in the center. ```json { "text": { "value": "Thank you for your business!", "size": "Header1", "align": "Center" }, "lineType": "Text" } ``` --- ## Flows > **Info:** The capabilities mentioned on this page must be registered with the **EPOS Capabilities API** prior to initiating a Pay At Table flow, > learn more [here](https://docs.dojo.tech/api-hosting/epos-data#registering-capabilities). The following diagram demonstrates how the Pay at Table product will interact with Dojo and the POS system for settling a table when initiated by a **Dojo product**, such as a **Dojo card terminal** or **QR Pay**: ![](https://docs.dojo.tech/images/pat/flow-diagrams/pat-flow-diagram2.jpg) **Flow diagram: Pat Flow Diagram2** ```mermaid sequenceDiagram participant DP as Dojo Product participant B as Dojo Backend participant P as POS DP->>B: List orders B->>P: SearchOrders P-->>B: SearchOrders response DP->>B: Get a specific order to pay B->>P: GetOrderById P-->>B: GetOrderById response DP->>B: Takes payment B->>P: Record Payment Request P-->>B: Record Payment Response ``` The following diagram demonstrates how the Pay at Table product will interact with Dojo and the POS system for settling a table when initiated by a **Dojo card terminal**, and when order locking is enforced by the POS during the payment flow. ![](https://docs.dojo.tech/images/pat/flow-diagrams/pat-flow-diagram1.jpg) **Flow diagram: Pat Flow Diagram1** ```mermaid sequenceDiagram participant T as Dojo Go Terminal participant B as Dojo Backend participant P as POS T->>B: List orders B->>P: SearchOrders P-->>B: SearchOrders response T->>B: Get a specific order to pay B->>P: GetOrderById* P-->>B: GetOrderById response B->>P: Lock an EPOS Order P-->>B: Lock an EPOS Order response T->>B: Takes payment B->>P: Record Payment Request** P-->>B: Record Payment response B->>P: Unlock an EPOS Order P-->>B: Unlock an EPOS Order response Note over T,P: *GetOrderById may be called during flow by certain products, or to print an EPOS bill. Note over T,P: **Multiple Record Payment requests may occur, such as in the instance where a bill is split between several payees. ``` **Note**: Support of the "no locking flow" detailed above is considered mandatory, while support of the "Locking flow" is only considered mandatory if the [CreateOrderLock](https://docs.dojo.tech/core-concepts/orders#locking), [ExtendOrderLock](https://docs.dojo.tech/core-concepts/orders#extending) and [DeleteOrderLock](https://docs.dojo.tech/core-concepts/orders#deleting) capabilities are registered. If these capabilities are registered, the POS is expected to restrict order access and changes while an order lock is requested. ## Step 1: List orders via SearchOrders > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/paths/~1v1~1orders~1search/post > See OpenAPI spec for SearchOrdersV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-SearchOrdersV1_Request **Main page**: [Orders](https://docs.dojo.tech/core-concepts/orders#search-orders) The initial step in the Pay at Table flow involes the waiter opening the "Integration" screen on the payment device, if configured (on the device) the waiter will be asked to input their waiter id which will be included in the SearchOrders request to the POS system. If the user is a customer and initiating via another product, such as **QR to Pay**, the request will include a `tableId` field to filter the orders by. When initiated from a Dojo card machine, the orders returned via the [SearchOrders](https://docs.dojo.tech/core-concepts/orders#search-orders) request are then presented on the payment device in a list for the waiter to select from, the name presented on the device for each order is determined by the following logic (first condition to match): - `displayName` field if populated in the Order - `tableId` field if populated in the Order - The mandatory `id` field of the Order - Otherwise the `id` field of an Order is used **Exceptions** - In cases where the names of orders to be presented on the payment device have duplicates a suffix of `"- $number"` will be added to the name e.g. `Table1 - 1`. - Dojo payment devices have a 24-character limit for order names. Names longer than this limit will be truncated. **Note:** We will only request payable orders, by setting the `payableOnly` parameter to `true`. Therefore only orders which can be paid for will be presented on the payment device, allowing some orders to be hidden if they're being edited on the POS or have already been fully paid off. ## Step 2: Get a specific order to pay via or GetOrderById or CreateOrderLock **Main page**: [Orders](https://docs.dojo.tech/core-concepts/orders) The next step in the Pay at Table flow is triggered when a user selects an Order. This may materialise as either: ### GetOrderById > See OpenAPI spec for GET endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-get-orders-orderId > See OpenAPI spec for GetOrderByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-GetOrderByIdV1_Request - A waiter choosing from the list of orders (from the previous step) or a customer selecting via the **QR to Pay** flow, which will trigger a [GetOrderById](https://docs.dojo.tech/core-concepts/orders#get-order-by-id) to retrieve an up-to-date representation of the order details. This step ensures that the most recent version of the order is presented on the payment screen before any payment is taken. ### CreateOrderLock > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-post-order-lock > See OpenAPI spec for CreateOrderLockV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-CreateOrderLockV1_Request - A waiter choosing from the list of orders (from the previous step), which will trigger a CreateOrderLock (which includes their `waiterId` if given) to fetch the latest and full state of the order from the POS system using the `id` field. This will include a unique `lockId` and expects the POS to "lock" the table to prevent further changes while payment is being made. **Note**: Both methods of retrieving order data may be invoked during the same flow, such as in the instance where an order is locked and then GetOrderById is used to retrieve a POS receipt for printing, so if the POS is enforcing order locking it must still accept and respond to GetOrderById requests. ## Step 3: Takes payment, payment event sent via Record Payment request > See OpenAPI spec for POST endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-post-record-order-payment > See OpenAPI spec for RecordOrderPaymentByIdV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-RecordOrderPaymentByIdV1_Request **Main page**: [Record Payments](https://docs.dojo.tech/core-concepts/orders#record-order-payment) The waiter can now take the payments for this order, and depending on how the customer chooses to pay, there may be a single payment or multiple for the order (split payment or pay by items). As part of the payment process, a RecordOrderPaymentById will be sent to the POS for each individual payment, this will include the `orderId` as well as other information such as the `paymentIntentId` - this ID should be recorded by the POS to facilitate payment tracking and refunds. If a waiter ID was provided on the payment device, an entry with the key `waiterId` will be included in the `metadata` on those created [payment intents](https://docs.dojo.tech/payments/manage-payments/payment-intent). The POS should respond to this request with a 200 response to indicate that the payment has been acknowledged and recorded. The POS should also respond with the current order "status" to show any changes that may have occurred to this attribute. If the payment cannot be recorded, such as in the event of a mismatching value being submitted in the RecordOrderPaymentById request, the POS should reject the request with a `409` error and the relevant `errorType`, in most cases this will be `Conflict`. This will trigger a payment reversal on the payment device or customer app and prompt the user to reattempt the payment. **Note:** If the order is initiated via a Dojo product such as **QR to Pay** then this may be the final step in the payment flow. **Tracking Payment Intents through Events** As an additional measure, the POS can also track the status of Payment Intents by subscribing to the `payment_intent.status_updated` via [Webhook](https://docs.dojo.tech/development-resources/webhooks#payment-intents-webhooks) if using REST, or by registering the [HandleEvent:payment_intent.status_updated](https://docs.dojo.tech/core-concepts/dojo-events#handle-event-payment-intent-status-updated) capability if using Websockets. In order to get the full information for a payment after receiving a RecordOrderPaymentById, the POS system can [lookup the payment intent via the Dojo API](https://docs.dojo.tech/api#tag/Payment-intents/operation/PaymentIntents_Get): this can be useful when retrieving receipt data, for example. To determine which order on the POS system a [payment intent](https://docs.dojo.tech/payments/manage-payments/payment-intent) belongs to, the POS system should look at the `orderDetails.externalId` field on the [payment intent](https://docs.dojo.tech/payments/manage-payments/payment-intent). This field will be set to the `id` field from the order returned by the POS in the previous steps. **Note:** Events are delivered with an **At least once** guarantee, so the POS will need to handle receiving duplicate events for the same [payment intent](https://docs.dojo.tech/payments/manage-payments/payment-intent). ## Step 4: Order is unlocked > See OpenAPI spec for DELETE endpoint details: https://docs.dojo.tech/epos-data/api#tag/Orders/operation/v1-post-order-lock > See OpenAPI spec for DeleteOrderLockV1 endpoint details: https://docs.dojo.tech/epos-data/ws/api#spec-operation-receive-DeleteOrderLockV1_Request **Main page**: [Orders](https://docs.dojo.tech/core-concepts/orders#unlocking) If order locking is enforced, then the final step of the Pay at Table flow is for the order to be unlocked: Dojo will request this by sending a DeleteOrderLock containing the relevant `orderId` and `lockId`. This request expects the POS to allow further actions and updates to the order if it remains open. --- ## Go-live checklist Dojo is committed to providing the best possible experience for our mutual customers. To achieve this, we require that all integrations meet our minimum requirements. As part of this process, our team will conduct UAT testing with you before accrediting your solution to be used with our customers. To facilitate a smooth onboarding experience with our Pay-at-Table integration, Dojo has prepared a comprehensive testing checklist. Please use this checklist as a reference for self-accreditation before Dojo performs UAT. If you're ready to begin UAT testing with us, or require development support, you can reach out to our team using the links at the bottom of this page. Configuration These tests relate to the configuration of the integration on your POS. | Scenario | Steps to Reproduce | Expected Outcome | |-------|-----|----| | Incorrect authorization credentials. | Input an invalid API Key, then attempt to establish a connection with the EPOS Data API. | The POS should display an appropriate error message and / or status code indication authorization was unsuccessful. | |API Version used.| Record the version of the API developed against, this should be hard-coded. | Version header is not able to be manipulated on the POS.| |Minimum version of POS support.| Record the minimum version of the POS that supports the integration.| This must be shared with Dojo during the accreditation process| |Implementation.| Record whether or not you are using our REST, Websocket or a mixture of both interfaces.| This will be recorded by Dojo during the accreditation process.| Registering Capabilities In the Dojo EPOS Data API, [capabilities](https://docs.dojo.tech/api#tag/Capabilities/paths/~1epos~1integrations/get) represent specific actions that the POS system can perform. These capabilities are linked to corresponding API endpoints in the POS system. By defining these capabilities, the POS system communicates to Dojo which features are supported and accessible. | Scenario | Steps to Reproduce | Expected Outcome | |------------|------|---------------------------| | Get all registered capabilities | The POS should have the ability to retrieve all currently registered capabilities | The registered capabilities do not need to be displayed to the user, but should be accessible if needed. This can be used to confirm that the correct capabilities are registered for Pay-At-Table. | | Register a new capability. | All capabilities needed for the integration should be registered. | Capabilities should be based on what a specific customer can support, therefore the POS should be able to support all endpoints for every customer, or register specific capabilities based on requirement. | Orders These tests cover [Orders](https://docs.dojo.tech/core-concepts/orders). The Order entity represents the core component of the Ordering API, containing all relevant information about an order placed by customers at a given location. An order can consist of multiple items, each with details like status, quantity, price, and applied modifiers. If [order locking capabilities](https://docs.dojo.tech/core-concepts/orders#locking) are registered, the POS must be able to respond to payment flows initiated by both `GetOrderById` and `CreateOrderLock` requests. | Scenario | Steps to reproduce | Expected outcome | |----------|-------|---------| | [SearchOrders](https://docs.dojo.tech/core-concepts/orders#search-orders) request with `payableOnly` set to true.| Using the Epos tester tool or the Dojo card machine, initiate a `SearchOrders` request. | The POS should only return tables that are available to be paid. | | GetOrderById. | Using the Epos tester tool or the Dojo card machine, initiate a `GetOrderById` request by selecting an order to pay from the Order list. | The POS should return information about the specific order requested. | | Water ID Validation. | Using a Dojo Card machine, initiate a `SearchOrders` request while entering a waiter ID. | Dojo will record whether or not the POS validates the `waiterId` field and only returns tables available to that waiter. | | `Status` is returned as required.| Using the Epos tester tool or the Dojo card machine, initiate a `SearchOrders` request. | Not all statuses are required to be supported, but a status must be returned in the response for `SearchOrders`. Dojo will record the statuses that are supported by the POS. | | `ItemLines` are supported. | Using the Epos tester tool or the Dojo card machine, initialize a search orders request. Initiate a `GetOrderById` by using the "Print Bill" function to print the POS bill. | ItemLines should be returned in the correct format. This is a pre-requisite to be able to print POS bills from the card machine. | | Order Locking is implemented. | When registered as a capability, initiate a `CreateOrderLock` request by selecting an order using the Dojo Card Machine and pay off the bill; initiate a `DeleteOrderLock` by completing or exiting out of the payment flow. | If supported, the POS should lock the order when requested, preventing further manipulation to the order items or status, and unlock when requested. | Record a Payment These tests cover the [RecordOrderPaymentById](https://docs.dojo.tech/core-concepts/orders#record-order-payment) capability and the different variations of how a guest may choose to pay. | Scenario | Steps to reproduce | Expected outcome | |----------|-------|---------| |Successful payment in full.| Using a Dojo card machine, pay an order in full without splitting the bill. | The POS should record the payment, including its `paymentIntentId`, against the order. | |Payment in full with split bill.| Using a Dojo card machine, pay an order in full by choosing either of the split options and splitting the bill by at least 2 payments. | The POS should record each payment, including its `paymentIntentId`, against the order. | |Payment in full with split bill and Gratuity.| Using a Dojo card machine, pay an order in full by choosing either of the split options and splitting the bill by at least 2 payments; add gratuity to at least one of the payments. | The POS should record each payment, including its `paymentIntentId` and `tipsAmount.value`, against the order. | |Partial Payment with and without gratuity.| Using a Dojo card machine, pay an order by choosing either of the split options and split by at least 2 ways; add gratuity to the first payment; after completing the first payment, exit out of the payment flow by selecting cancel. | The POS should record the payment, including its `paymentIntentId` and `tipsAmount.value`, against the order; the order should then return to a `payable` state and the outstanding balance should reflect the payment(s) taken. | Refunds These tests cover Refunds. Any payments taken via the Epos Data API can be refunded without the cardholder present through the [Dojo API](https://docs.dojo.tech/api)'s [Matched Refund](https://docs.dojo.tech/api#tag/Terminal-sessions/operation/TerminalSession_Create) function. | Scenario | Steps to reproduce | Expected outcome | |----------|-------|---------| |Successful Matched Refund.| Create a terminal session via the Dojo API with a session type of matched refund. | The POS should be able to initiate a Matched Refund and call the Payment Intent endpoint to confirm the refund was successful. | |Unsuccessful Matched Refund.| The POS should store the paymentIntent ID against the orderId, so they can make use of integrated centralized refunds. | In case of the refund not being successful, the POS should display an appropriate error to the user. | Error Handling These tests cover some of the possible ways in which errors can occur and aim to create additional resilience. | Scenario | Steps to reproduce | Expected outcome | |----------|-------|---------| | Websocket disconnection handling. | If the API is hosted by Websocket, the POS should periodically check the connection status of the maintained Websocket to guard against network related incidents. | If the socket disconnects the connection should be re-established as soon as possible. | | GetOrderById - none existent ID. | Using the Epos tester tool, Initiate a `GetOrderById` with an ID that does not exist. | The POS should return an appropriate error to the request. | [![](https://docs.dojo.tech/images/dojo-icons/Headset.svg) **Support** Our Partner Enablement team is always happy to help with any questions you have.](mailto:partnertech@dojo.tech) [![](https://docs.dojo.tech/images/dojo-icons/Message.svg) **Stack Overflow** Find answers to practical questions.](https://stackoverflow.com/tags/dojo.tech)