iVendNextDevelopers Request a sandbox

S17 — an order board (pp_pge): a partner page

The order board on the till, end to end

A cashier presses Deliveries on a sale, the partner's board opens over the sale in the till's own look, and after Attach to sale the delivery number is on the sale.

Your own screen, shown inside iVendNext: on the till as a sheet over the sale, and in Desk as a page for a record. This sample is for a developer whose service has a screen of its own (here, a delivery board) and who wants cashiers and staff to use it without leaving iVendNext POS.

When to use it: your service needs its own screen in the till or in Desk, and may hand one answer back to the sale.

What happens

On the till (counter and tablet):

  1. The cashier presses the Deliveries key on a sale.
  2. The board opens as a sheet over the sale. It offers a delivery order number.
  3. The cashier presses Attach to sale.
  4. The board's server answers the till once. The till shows its usual confirm sheet, with the sale detail PP PGE Delivery Order.

In Desk, the same board opens as a page for a record (/app/partner-page/<page>?doctype=Sales Order&name=…), for Stock Users and Stock Managers.

The shop opens the page with a signed, one-time context in the address's fragment (#ctx=…): who is looking, at what, for five minutes, once. The board checks it on its own server, and never holds the shop's session.

What it looks like

The names in the pictures are a demo shop's: a cashier selling to a customer on the till, and a stock user opening the board for a Sales Order in Desk (step 5).

Step Frame Screenshot
1. A sale with one item; the Deliveries key sits with the till's other keys the till, /pos?frame=terminal, 1440 wide
2. The board, framed as a sheet over the sale, drawn with the till's own tokens the till, 1440 wide
3. After Attach to sale: the till's own confirm sheet, with the sale detail and the number the till, 1440 wide
4. Applied: the delivery number is on the sale (Sale details) the till, 1440 wide
5. The same board in Desk, as a page for a Sales Order Desk, 1440 wide

The sale detail reads PP PGE Delivery Order because our samples carry placeholder names until their real ones are reserved; a partner's copy shows its own name.

The files

File What
manifest.json the page (extension_subscriptions, extension point page, Till key and Desk page) and the sale detail it answers with, installed switched off
page.py the pure core: read and check the context (signature, expiry), the nonce-once set, the till's answer and its signature
service/app.py the HTTP service (standard library): GET /board/, POST /board/api/open, POST /board/api/answer
service/board.html the page: reads the fragment once and takes it out of the address, never puts context text into markup, and draws with the shop's design tokens the way the till's own sheets do (the till's type, a bold title, muted detail rows, one full-width button)
tests/test_service.py laptop tests: the real service, contexts minted as the shop mints them, a stand-in for the shop's api/page.submit
tests/test_contract.py the answers, and every context our test shop minted, against the published contract (partner_page.v1.schema.json)

The recipe is recipes/partner_page.md.

How to run it

Start the service on your server, under your own process manager: python3 service/app.py service/.env.local. Install the manifest in the shop. It installs switched off: the shop reads what the page will receive, ticks the consent, switches the page on, and places the Deliveries key on the till (the recipe has the steps).

What is refused, and why

When the shop cannot be reached

If the shop cannot be reached when the board answers, the board says so and the cashier presses again. The context's one answer is not used up.

Before you copy it

Technical notes

What was walked, and where

The GIF: frame: the till, /pos?frame=terminal in a 1440-wide window. Walked on our test bench on 2026-10-07, iVendNext POS app at 8dc36aab8. Built from the same screens as the stills, uncropped.

The stills: walked in a real browser on our test bench, 2026-10-07, iVendNext POS app at 8dc36aab8. On the till, the bench's demo cashier (Thabo Nkosi) sells to Naledi Khumalo; in Desk (step 5), a stock user (Nomsa Zulu) opens the board for a Sales Order.

On our test bench the page was opened through the till's own press and pick-up and Desk's own context call, for every case in the recipe. tests/test_contract.py checks every context the bench minted.

Why it is built this way

Option Cost Verdict
Do nothing 0 row 48 (the delivery partner's screen on the till) has no sample to copy
A static page that only shows the context ~40 lines skips the two duties that matter: checking the context on the server, and answering once
A pure core + a standard-library service + one HTML page ~300 lines picked: every duty P-PAGE gives the partner, in code a new developer reads unaided

Two locks on one answer. The board refuses a second answer for one context itself, and the shop refuses it again ("This page has already answered."). Either is enough; the bench proves both.

Bounds, stated

This page in the kit