Skip to main content

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.

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:

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, ExtendOrderLock and DeleteOrderLock 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

POST REST /v1/orders/search

REQUEST
RESPONSE
WS SearchOrdersV1

Main page: 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 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 CreateOrderLock or GetOrderById

Main page: Orders

The next step in the Pay at Table flow is triggered when a user selects an Order. This may materialise as either:

GetOrderById

GET REST /v1/orders/{orderId}

REQUEST
RESPONSE
WS GetOrderByIdV1
  • 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 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

POST REST /v1/orders/{orderId}/lock

  • 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

POST REST /v1/orders/{orderId}/record-payment

Main page: Record Payments

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

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 RecordOrderPayment 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 if using REST, or by registering the HandleEvent:payment_intent.status_updated capability if using Websockets.

In order to get the full information for a payment after receiving a RecordOrderPayment, the POS system can lookup the payment intent via the Dojo API: this can be useful when retrieving receipt data, for example.

To determine which order on the POS system a payment intent belongs to, the POS system should look at the orderDetails.externalId field on the 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.

Step 4: Order is unlocked

DELETE REST /v1/orders/{orderId}/locks/{lockId}

Main page: Orders

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.