PlatformFeaturesPricingHelpVerify Passport
NEXPURA
AboutBook a DemoLoginStart Free Trial
PlatformFeaturesPricingHelpVerify PassportAboutBook a DemoLogin
Start Free Trial
NEXPURA

The operating system for modern jewellers.

Product

  • Platform
  • Features
  • Pricing
  • Security

Resources

  • Blog
  • The Problem
  • Help

Company

  • About
  • Contact
  • Book a Guided Demo
  • Start Free Trial

For Customers

  • Verify Passport

Legal

  • Terms
  • Privacy

© 2026 Nexpura. All rights reserved.

Built for jewellers.

Back to Sales & POS
Docs · Sales & POS

Processing a sale at the POS

End-to-end checkout walkthrough — build the cart, pick the customer, split payment if needed, complete the sale, send the receipt.

Quick reference

  • Open /pos — add items by clicking tiles or scanning barcodes, optionally attach a customer, apply a discount, click Charge $X.XX to open the payment modal.
  • Six payment paths: card, cash, store credit, split, voucher, layby. The selected tab's primary button completes the sale.
  • On success: the page swaps to a confirmation screen with sale number, total, change due (for cash), and action buttons for receipt + invoice.
  • Stock is decremented atomically — sold-out detection is whole-cart-or-nothing; no partial deductions if a piece slips out from under you mid-checkout.
  • Every completed POS sale also creates an invoice automatically, linked back to the sale. Find both at /sales and /invoices.

Walkthrough

1. Open the POS and pick your location

Visit /pos. If you have more than one location and haven't selected one this session, the page prompts you to pick — the selection is held in a cookie and persists across page loads, so you only do this once per session per till.

The location matters because (a) the product grid only shows inventory at the picked location, (b) the completed sale stamps that location on the sale record so dashboard per-location numbers stay accurate, and (c) refunds initiated later through this sale are scoped to the original location for restock.

2. Build the cart

Click product tiles to add items. The first click adds at quantity 1; subsequent clicks of the same tile increment. Alternatively scan a barcode with a keyboard-wedge scanner (just scan; no special focus needed) or tap the camera-scan button on a tablet.

Adjust quantities on each cart line with the − / + buttons. The + button is capped at the item's on-hand quantity, so you can't oversell a piece you're holding 3 of by clicking + four times. Remove a line with the x on the right.

Screenshot pending

Cart pane with three items added — a $1,200 ring, a $450 chain, and a $200 earring pair — quantity steppers visible on each row, subtotal $1,850 building in the footer.

3. Attach a customer (optional — required for some payment types)

The customer field sits at the bottom of the cart, above the discount selector. Start typing — the dropdown surfaces matching customers; click to attach. The chosen customer appears in the field and the store-credit balance becomes available as a payment method.

You can skip this for a basic cash/card walk-in. You need a customer attached if you'll pay with Store credit or use the Layby flow, or if you want the receipt emailed.

If the customer isn't on file yet, open /customers/new in a separate tab, save them, return — they appear in the dropdown on the next keystroke.

Screenshot pending

Customer search dropdown surfacing two matches for the typed 'sm', with name on the left and email on the right of each row.

4. Apply a discount (optional)

The discount control is two inputs: a selector for $ off or % off, and the numeric value. Type the value; the footer updates the running totals immediately. Discount applies to the subtotal; tax is calculated on the discounted amount.

A few guard rails: a percent discount is capped at 100%, a dollar discount is capped at the subtotal — so the total can't go negative no matter what you type. Negative values are clamped to zero — there's no way to add a surcharge through this field.

5. Open the payment modal and pick a method

Click the green Charge $X.XX button at the bottom of the cart. The payment modal opens with the total at the top and six tabs across — Card, Cash, Store credit, Split, Voucher, Layby.

For the standard motion, pick Card or Cash:

  • Card — if Stripe is connected, click Record card payment after the customer's terminal-tap completes. If Stripe isn't connected, the tab shows a Connect Stripe prompt with a link to /settings/payments and a fallback Record as manual card payment button for sales taken on a stand-alone terminal.
  • Cash — type the amount tendered; the modal shows the change in green. The button stays disabled until tendered ≥ total.

Screenshot pending

Payment modal on the Cash tab — $1,850.00 due, $2,000 tendered, $150.00 change shown in a green box, Complete cash sale button active.

6. Or split the payment across two methods

Click the Split tab. Three modes are available along a pill toggle: Cash + Card, Voucher + Card, Voucher + Cash.

For cash + card: type both amounts; they must sum to the total (the modal shows the current shortfall live in amber until they match). Click Complete split payment.

For voucher + cash or voucher + card: type the voucher code, click Look up, the modal pulls the balance and pre-fills the remaining amount field with (total − min(voucher balance, total)). Voucher amount is auto-clamped to balance — a $500 voucher on a $300 sale covers the $300 and the remaining $200 is the leftover voucher balance, untouched.

7. Submit — the saga runs

Click the primary button on whichever tab you picked. A few things happen server-side in one atomic saga: stock is decremented for every cart line, store-credit and voucher amounts are debited if applicable, the sale row is written, sale-item rows are inserted, an invoice is auto-created and linked back.

If any step fails — most often, a sold-out detection on stock — the entire saga compensates: stock restores, debits reverse, the sale row never lands. The cashier sees the error message and the cart stays intact; no half-finished sale to clean up manually.

Submit is also protected by an idempotency key generated client-side: double-clicking the charge button doesn't create two sales — the second click sees an in-flight submission with the same key and returns the existing result.

8. Confirm + send the receipt

On success, the page swaps to a confirmation screen — sale number in monospace, total, change due (for cash), and a stack of action buttons.

Print receipt opens a thermal-receipt PDF in a new window, formatted for 80mm receipt printers. If your default browser printer is set to the receipt printer, this is a one-click motion.

Email to customer only shows if the attached customer has an email on file. It sends a PDF receipt via email; the button updates with a confirmation toast (✓ Receipt emailed to …) when the send completes.

View invoice jumps to the auto-created invoice page. The invoice and sale are linked both ways — the sale detail page shows a “Invoice auto-created” banner with a link, and the invoice page shows the originating sale reference.

Issue passport only appears if the cart included a finished piece (an item with item_type = 'finished_piece'); clicking it jumps to the verify-passport flow pre-filled with the inventory ID. Useful for jewellers who issue passports at the point of sale.

Screenshot pending

Sale success screen — green check, sale number S-0042, total $1,850.00, change $150.00, primary New sale button followed by Print receipt, Email to customer, View invoice, Issue passport, View sales history.

9. Back to an empty cart

Click New sale — the workspace resets to an empty cart, the customer detaches, the discount clears, and the product grid re-fetches its inventory in the background so subsequent sales see the freshly-decremented quantities. The next customer can be rung up immediately.

Common questions

Can I sell at a price different from the listed retail price?

Not by editing the line price directly — every cart line uses the inventory row's retail_price as the unit price. To bring the total down for this customer, apply a discount on the cart (dollar or percent off). The audit trail then shows the original retail and the discount applied, which is cleaner than editing the unit price and losing that history. If you genuinely need to change the listed retail price, edit the inventory item at /inventory first.

Why is the customer-display option not in this flow?

The customer-facing display surface — the screen behind the counter that shows the customer their running cart and total — isn't built yet. The cashier-side workspace is complete; pairing it with a customer-side screen is on the backlog. For now, most stores spin the tablet around at the moment of payment.

What payment method should I pick for a Stripe Terminal tap?

Card. If Stripe is connected and a card-reader is paired, the Card tab's primary button initiates the terminal-side prompt for the customer to tap. The cashier waits for the terminal to indicate success, then the modal confirms. Without a paired reader, the Card tab records the payment as “card (manual)” — i.e. the cashier ran the card on a separate terminal and the POS just records the result.

Can I undo a sale right after completing it?

Not as a direct undo — the sale row is committed and stock is deducted. The clean motion is to issue a refund against the just-completed sale: open the sale at /sales (it's at the top of the list), click into it, and Process refund — that's the inverse motion that restocks inventory and reverses the payment. The refund and the original sale stay linked so the audit trail reads honestly.

What happens to the receipt if I forget to email it then?

You can email any sale's receipt later from the sale detail page, or from the linked invoice page. Both pages have an Email receipt / Email invoice action that re-sends to whatever email is on the customer record. Useful when the cashier didn't attach the customer at the till but the customer asks for the receipt later — attach the customer first, then send.

What does “auto-created invoice” actually mean?

The same saga that writes the sale also writes a matching row in invoices with the next sequential invoice number, the customer, the line items, and a link back to the sale. The invoice renders the proper tax-invoice format (your business name, ABN, customer details, GST breakdown) — it's the tax-compliant version of the thermal receipt. Customers who ask for a tax invoice already have one ready; you don't need a separate “create an invoice for this sale” step.

Troubleshooting

Sale completed but the success screen shows $0.00

Symptom: the charge went through, server confirms a sale row exists, but the success screen renders with a $0.00 total. Cause:stale page state from a long-running session — the success screen normally snapshots the cart's total at submit time, but a stale tab can lose that snapshot. Fix: click View invoice — the invoice has the correct total. Or open /sales and find the sale at the top of the list. The data is right server-side; only the success-screen render was wrong, and a hard-reload of the POS clears it for subsequent sales.

Payment modal won't close after a failed charge

Symptom:the charge errored, the error banner shows inside the modal, and the button is stuck in “Processing…”. Cause:usually a transient network blip during the saga — the client didn't hear back whether the sale committed or not. Fix:close the modal with the X. Don't re-click charge yet — open /sales in a new tab and check the top of the list. If the sale is there, the charge succeeded and you can just confirm with the customer + close out. If it isn't, re-build the payment and retry — the idempotency key on submit prevents accidental duplicates.

Email receipt button doesn't appear

Symptom: after completing a sale, the action stack shows print and view invoice, but no email option. Cause:the email button only renders when there's both an invoice ID and a customer email on file. Walk-in sales (no customer attached) skip it; customers without an email address also skip it. Fix: attach the customer with an email on file BEFORE clicking Charge; or after the sale, open /sales, attach a customer to the sale record (Edit), and email from the invoice page instead.

Sale charged twice

Symptom: the same cart appears as two sales in /sales with the same customer and amount. Cause: two terminals shared the same browser session (very rare), or the idempotency-key window expired between two genuinely separate retries of a hung request. Fix: issue a refund against the duplicate sale row. The refund will restock inventory and reverse the payment; the original sale stays. Reference the duplicate refund and the source sale in the refund notes for the audit trail.

Related

  • POS overview — the surface this walkthrough operates on
  • Processing a refund — the inverse motion when a sale needs reversing
  • Layby — the variant flow off the Layby payment tab
  • Vouchers and gift cards — voucher redemption inside the payment modal
  • Invoices — the auto-created invoice every POS sale produces