Store checkout
Your store’s checkout is one page at /checkout, hosted by Tuppence. You don’t build it or
handle card details: it uses your products, delivery and payment methods, and every paid checkout
becomes a store order. Your code sets a few options and listens for
store.order_placed.
What the shopper sees
Section titled “What the shopper sees”| Part | What it does |
|---|---|
| Summary | First on the page, sticky on a phone: lines, discount, delivery, tax and the total |
| Express | Apple Pay, Google Pay and Link at the top. The wallet sheet fills the contact and address and shows your delivery choices |
| Contact | One field: an email or a phone number |
| Address | Name, then the address with autocomplete |
| Delivery | Your delivery and collection choices for that address, with their prices and dates |
| Payment | The secure card fields and your other payment methods |
| Have a code or gift card? | Collapsed. A discount code applies to the basket |
| Note | Only if you turn it on (below) |
| Marketing | Unticked. Your words, or your country’s default |
The card path asks for at most eight typed fields. The total shown before Pay is the product page’s price plus the chosen delivery.
Includes VAT of).Tax) and is in the total.Methods that take days to settle (Direct Debit and other bank debits) are never offered: an order
is made only once its payment has succeeded. A method that sends the shopper to their bank or
provider brings them back to /checkout/return, which reads the payment and moves on to the order.
1. Set the checkout’s options
Section titled “1. Set the checkout’s options”Two options, in the site’s settings.checkout. They apply to the next checkout, with no publish.
| Setting | Default | Does |
|---|---|---|
note_enabled | false | Shows a collapsed note field. The note reaches the order as fulfilment.instructions |
marketing_text | null (your country’s wording) | The marketing box’s words, up to 300 characters. The box is never ticked for the shopper |
curl -sS https://api.tuppence.ai/v1/sites/site_… \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"settings": {"checkout": {"note_enabled": true, "marketing_text": "Send me news and offers by email."}}}'import { Tuppence } from "@tuppence/node";
const tuppence = new Tuppence(process.env.TUPPENCE_SECRET_KEY);const { data: [site] } = await tuppence.request("GET", "/v1/sites");await tuppence.request("POST", `/v1/sites/${site.id}`, { body: { settings: { checkout: { note_enabled: true, marketing_text: "Send me news and offers by email." } } },});import osfrom tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])site = tuppence.request("GET", "/v1/sites")["data"][0]tuppence.request("POST", f"/v1/sites/{site['id']}", body={ "settings": {"checkout": {"note_enabled": True, "marketing_text": "Send me news and offers by email."}},})Delivery choices come from Store › Settings › Delivery in the dashboard, and the payment methods from those your account takes.
2. Hear about orders
Section titled “2. Hear about orders”Add store.order_placed to a webhook endpoint. It is sent once per order.
curl https://api.tuppence.ai/v1/webhook_endpoints \ -H "Authorization: Bearer $TUPPENCE_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/tuppence", "enabled_events": ["store.order_placed"]}'const endpoint = await tuppence.webhookEndpoints.create({ url: "https://example.com/tuppence", enabled_events: ["store.order_placed"],});console.log(endpoint.secret); // whsec_…, shown onceendpoint = tuppence.webhook_endpoints.create( url="https://example.com/tuppence", enabled_events=["store.order_placed"],)print(endpoint.secret) # whsec_…, shown onceThe event’s object is the store order:
| Field | |
|---|---|
id | The order (ord_…) |
number | The number the shopper sees: Order 1042 |
site, checkout | Where it was placed |
fulfilment | kind (delivery or collection), address, delivery (key, name, amount, earliest, latest) and instructions |
fulfilment_status | unfulfilled until you send it |
order | The order as GET /v1/orders/{id} returns it, with its lines and tenders |
3. Try it in test mode
Section titled “3. Try it in test mode”Your test store is under /test/<your-slug> on the store’s address. It says “Test store: use a
test card. No real card works and no money moves.” and lists the test cards
to pick from. The order, its confirmation email and store.order_placed follow as they would live,
in test mode.
What Tuppence checks
Section titled “What Tuppence checks”| When | Check | The shopper sees |
|---|---|---|
| The checkout opens | Each item’s stock, held for 10 minutes (once more while paying) | “Only 1 Blue mug is left. We’ve changed your basket.” |
| An address is given | You deliver there | “Sorry, we don’t deliver to Jersey.” In your test store, a link to fix it |
| Pay | The basket priced again matches the total shown | The new total, to pay again |
| The payment | The card or method is accepted | “Your card was declined. Try another card or Apple Pay.” |
At the till, a sale is never stopped by an online hold. A payment that succeeds after its hold ran out still makes the order, so a paying shopper is never turned away; the stock may go below zero, and you see it.
When it is paid
Section titled “When it is paid”One payment makes one order, whether the payment’s success arrives first or the shopper’s return.
- The order:
source: online, totals from what the shopper was shown (never worked out again), numbered from 1001 for the shopper. - What the shopper was shown when they pressed Pay is kept with the order: lines, delivery and
its dates, discounts, tax, total, your trader details and the cancellation terms. Read it as
snapshotonGET /v1/orders/{id}/details. - The confirmation email goes in your business’s name, and replies come to you. It links to the order’s status page and to the store’s cancellation form.
- The payment has
source: storeand is priced like any card payment (pricing).
Events
Section titled “Events”| Event | When |
|---|---|
store.order_placed | A checkout was paid and its order made |
order.created, order.paid, order.completed | The same order, as for any order |
payment.succeeded | Its payment |
store.checkout_abandoned | A checkout with a contact and no payment was left for an hour. It carries marketing_consent, so you email only shoppers who agreed |