Store Builder

Booking app

Take appointments or room bookings through a form — slots, capacity and closed days are checked on the server, every booker becomes a customer, and an appointment book lets you confirm, cancel and mark no-shows.

Manage → Apps has a Booking card on the Built-in shelf:

"Take appointment bookings through a form — dates and time slots are checked on the server, and the booker is saved as a customer."

What separates this from a Contact form with a date box is the second half of that sentence. A booking page is a web page: anyone can edit it in their own browser, type a date that has passed, a slot that does not exist, or send the same thing twice. So every rule an appointment book lives by — seats left or not, closed days, duplicates — lives on the server, not on the page, and is re-checked on every submission, including one sent from a tampered page.

A booking form is still a form

There is no separate builder. Drag Form onto a page as usual (see Forms); under Ready-made two templates belong to this app:

Book an appointment"A date and a time slot with a phone number — the visitor picks, you confirm."

Book a stay"Check-in / check-out, room type and guest count — availability counted per night."

Pick either before the store has the app and the builder asks "Install the Booking app?", installing it on the spot when you press Agree and install — once per store, not once per form.

Book an appointment comes with a name and a phone number (both required), a calendar box for the appointment date that only accepts today onwards, a time slot select with three wide bands, and a notes box. The template is seeded in Vietnamese whatever language you edit in — the bands read Sáng (8:00–12:00), Chiều (13:00–17:00), Tối (18:00–21:00) (morning, afternoon, evening) — and they are a starting vocabulary, not anybody's opening hours: rewrite them as your real sittings, in your own language, add or remove as you like. The server counts seats against exactly the list you leave, and a slot that is not on it is refused ("This time slot is not available") — a visitor cannot invent a sitting.

How the server finds the date box and the slot box

Rebuild the form freely; keep one shape: the first calendar box is the date, the first select (or radio) is the slot. That is what both templates seed, and the order a hand-built form naturally takes.

Two useful variants fall out of that shape:

  • No slot box → capacity is counted per day. A photo studio that takes two sessions a day does not need to invent time slots: drop the select, set Max bookings per time slot to 2, and that number becomes the day's capacity.
  • Two calendar boxes → the form reads a range, which is the stay template: the first calendar is check-in, the second check-out, and the select is the room type — each room type is a "slot" with its own capacity. A room counts as taken per night, from check-in up to but not including check-out: the morning a guest leaves, that room is free for someone else that night.

With no calendar box at all there is no rule to apply — the form behaves like a Contact form.

Booking rules

Open the form in the builder, Settings tab, Booking rules group. Every box at 0 means no rule, so an untouched form accepts everything.

  • Max bookings per time slot — that many on one date and slot and it is full. The visitor sees "This time slot is fully booked — please pick another". On the stay template this is the number of rooms of each type, counted per night.
  • Max bookings per day — a ceiling across the whole day, all slots combined. A restaurant that seats ten per sitting but serves forty a night is this box; it only means something alongside a slot box.
  • Minimum notice (days) — 1 is "not today", 2 is "the day after tomorrow at the earliest". Days, not hours, because the date box has no clock.
  • Accept bookings up to (days ahead) — 30 means visitors can book within the next 30 days only.
  • Max open bookings per visitor — counts today-onwards bookings from one phone number (email when there is none). Stops one number from holding seats all month.
  • Allow repeat bookingsoff by default: the same phone booking the exact same date + slot a second time is refused ("You already have this booking"), which is nearly always a double click or a re-submit. Two different slots on the same day are fine. Turn it on when one number really needs several seats in one sitting — two haircuts for a parent and child.
  • Closed dates — specific days: public holidays, Tết, a renovation week. The visitor sees "We are closed on this date — please pick another day". A fixed weekly closing day does not go here but on the date box itself, under its Accepted dates group — two places, two different questions. On the stay template a closed date refuses any stay that sleeps through it; checking out that morning is still fine.
  • Minimum / maximum stay (nights) — read only by a two-calendar form: the homestay that takes weekends from two nights up, and the mirror for a place that will not hold a room for half a year.

Two things the server does with no box to switch on:

  • Past dates are refused at the calendar box — the templates seed it as today onwards, and that rule is checked on the server like every other.
  • A submission classified as spam holds no seat. It is still stored for you to look at, but it never makes a slot "full" and is never told which rule it tripped.

The appointment book

Manage → Apps → Booking is the book. It builds nothing and configures nothing — it answers one question every morning: who is coming up?

At the top, three numbers: Today, Awaiting confirmation, Next 7 days. The middle one is the work — every new booking enters the book as Complete, and Awaiting confirmation counts the ones nobody has called back; it stands out while it is not zero and goes quiet when it is.

Below, the book runs day by day, with Today and Tomorrow named. Each row: the slot (or the check-out date), the customer's name, the phone number — tappable to call on a phone, since that is the next move on almost every row. With more than one booking form there is a filter by form, and the numbers follow it.

The life of a booking, read from the buttons on its row:

  • Confirm — you called and they are coming. The row wears a Confirmed badge; a glance down the day shows who has been called.
  • Cancel booking — asks first, because it opens that seat to other visitors. The record stays, labelled Cancelled.
  • No-show — appears only once the appointment day has arrived, since "did not come" is a fact about the past and a future booking should not be branded with it by mistake. This is why the book has a Last 7 days section: you learn a customer did not turn up after the row has left the upcoming list.
  • Restore — on a cancelled or no-show row. No confirmation, since it only takes back what already existed, but the server re-counts before giving the seat back: if someone else booked that slot while it was cancelled, the restore is refused and the book says so — "Could not restore — another customer took this slot while the booking was cancelled."

The rule behind those four buttons is one sentence: Complete and Confirmed hold a seat; Cancelled and No-show do not. Every capacity count above counts exactly the first two.

The same data sits in the form's Submissions and under Manage → Forms — the Status column carries those four values, filterable and exportable to Excel — so this book is not a copy but another reading of the same table.

The booker is a customer

The Contact group on the form (name, phone, email) maps onto the customer record like on every other form: each booking creates or joins a person under Manage → Customers (see Customers). That is also the "one visitor" the rules above refer to: identified by the digits of the phone number, so "090 123 4567" and "0901234567" are one person.

Removing the app

Uninstalling is refused while the store still has booking forms — a form that keeps taking bookings behind a screen saying the app is gone is not a state worth having. Delete or repurpose those forms first, then uninstall.

Updated 05/09/2026