16. What is possible, what is not, and the limits
This chapter gives a straight answer to "can we do this for the customer?". The answer is one of four: yes; yes, once an extension point we are building ships; not today; or never. Each answer comes with the limit that goes with it. It is for a builder, or a salesperson, before a quote.
The recipe or chapter behind each answer is named in its row.
When to use it
Use it before you quote. If a customer's need is not in these tables, place it on the ladder (chapter 3). If no rung fits, request an extension point (chapter 9).
Possible today
| What | How | Chapter |
|---|---|---|
| Prices, promotions, coupons; receipt and gift-receipt layouts; reprint; workflows; numbering; permissions; reason codes; blind counts (the kit has no recipe yet for blind counts, permissions per till action or gift receipts: chapter 4) | configuration | 4 |
| Your service reading and writing records, in any language | outside app over the API | 5 |
| Reacting to sales, returns and stock moves | outside app on the event feed (a feed scoped to your own app has shipped, chapter 9; the kit's samples still read the older shared feed, chapter 5) | 5 |
| An answer for the cashier during a sale — a message, or details added to the sale | till key answered by your service | 6 |
| Your own records, fields, print formats, notifications and workspaces | manifest | 7 |
| Native screens for your records; your records listed under ours | manifest + configuration | 13a |
| An online shop on WooCommerce; an ERP on Acumatica | our connectors (both in beta) | 10 |
| The customer's own ERP, order system, warehouse system, CRM, loyalty earning or online shop | outside app | 10 |
| A feed of your own events, with business labels | event feed | 5 |
| Field rules enforced when a record is saved | save rules | 7 |
| Buttons on Desk forms and lists answered by your service | Desk action | 13a |
| Your page inside our frame on the till or on Desk | partner page | 13a |
| An outside fiscal service recording its tax result on the sale | fiscal reader | 11 |
Possible after an extension point we are building
| What | Extension point | Chapter |
|---|---|---|
| Refuse a sale, or ask the cashier a question, before payment | check before tender | 9 |
| Your wallet on the till's tender screen, with a cap | wallet tender | 9 |
| Unit barcodes, IMEIs or pharmacy codes recognised at scan | scan resolver | 9 |
| Ask the cashier for something on scan or when a customer is added | capture on an event | 9 |
| Hide, relabel or require fields on the selling screen | field vocabulary | 9 |
| Pricing logic that also works offline | pricing extension point, as a sandboxed function | 8 |
| A QR code or fiscal mark on the receipt (a WhatsApp receipt has no recipe or extension point in the kit yet) | receipt extension point | 4 |
| Labels from the till and from Handheld | labels extension point | 4 |
| A live price or discount from your service before payment — a carrier deal, say — within the shop's limits (a floor, a cap, an approver) | deal extension point | 9 |
| Your own payment connector, on your server, certified with our payments test kit (a terminal wired to the counter comes later) | remote gateway contract | 11 |
The four rules
- Money enters the sale visibly, before payment, and is never changed after the cashier has seen it.
- Don't override or patch iVendNext.
- Your code runs on your server; inside the customer's site you ship data.
- Your screens use our doors — never your JavaScript inside Desk forms or the till.
The reasons and the alternatives are in chapter 3.
Not possible today
These are product decisions on our side. Ask us if a customer needs one.
| What | Instead |
|---|---|
| Your own fiscal or e-invoicing country | we add countries; an outside fiscal service can record its result through a fiscal reader (chapter 11) |
| Your own connector on our integration framework | build an outside app, or ask us to build the connector |
| Extending Handheld | react to what Handheld books, through the API and the event feed |
| Several companies in one site, with connectors | one site per company |
| A store server | — |
| A final receipt while the till is offline | a provisional slip offline; the final receipt once it reconnects |
Limits to state up front
| Limit | What it means for your project |
|---|---|
| No load test has been run yet; the largest live customer runs 18 terminals | run the customer's scale profile on a sandbox before go-live |
| Our Acumatica connector: about 2.75 complete sales a minute per connection | size the busiest hour against it |
| One ERP per company | choose one ERP per company |
| Handheld books online only in its first release, and offers no extension point | receiving and counts need a connection |
| A sandboxed function that runs on a till is compiled from Rust | JavaScript started too slowly on a slowed-down till stand-in; a function that only runs on the server may be JavaScript (chapter 8) |
| Till keys answer online only, and the request carries no money and no serial numbers | read money and serials from the booked sale, after it is booked |
| An API key acts with its user's role; there are no scoped keys and no server-to-server sign-in grant | narrow the role; one user per app |
| The kit's samples read the shared feed, whose key is not limited to one app (a scoped feed has shipped, but the kit has not run it yet); webhooks try three times, then stop | use the feed for anything you must not miss; a webhook is only a nudge |
| Fields made required by a condition are checked in the Desk form only, not on API writes or imports | your service checks its own writes |
| Who may edit a record in a workflow state is checked in the browser only | follow the four safeguards in chapter 13a |
| Permissions hide an action, never a field | field hiding waits for the field vocabulary |
| Member pricing goes through promotions, not pricing rules | one promotion per tier, by customer group |
| Offline: pricing rules are not applied; loyalty, gift cards and store credit wait for a connection | plan offline behaviour per need |
| One company is one country and one currency | several countries, several sites |
| Our WooCommerce connector does not reserve stock, and takes percentage vouchers only | state it to the customer |
| Labels print through a desktop utility today | the labels extension point replaces it |
What is refused, and why
Anything that breaks one of the four rules. The reasons are in chapter 3. What we run on a submission is not covered by the kit yet (chapter 17).
When your service is down, and when the till is offline
Offline, pricing rules are not applied, and loyalty, gift cards and store credit wait for a connection (the offline row in the limits table). Each chapter has its own section on what happens when your service is down.
The tests
Every need in your blueprint has an answer from these tables, and every limit that applies is written into the customer's proposal.
Technical notes
The exact wording behind some rows above, with the evidence for them.
- Event feed row. Outside app on the event feed (the scoped feed has shipped, chapter 9; the kit's samples still read the engine feed, chapter 5).
- Feed limit. The kit's samples read the engine feed, whose key is not scoped to one application (the scoped feed has shipped, chapter 9; the kit has not run it yet); webhooks try three times, then stop.
- Rust on the till. A sandboxed function that runs on a till is compiled from Rust. JavaScript compiled to WebAssembly started too slowly on a slowed-down till stand-in; a function that only runs on the server may be JavaScript (chapter 8).
- Scale bound. No load test has been run yet; the largest live estate is 18 terminals.
- Required-by-condition fields. Conditional mandatory fields are checked in the Desk form only, not on API writes or imports.
- API keys. API keys act with their user's role; there are no scoped keys and no server-to-server sign-in grant.