Skip to content
easeweb
Search topics

Checkout timers that release held seats

A ticket checkout holds the seats for 10 minutes while people type their details, then releases them and empties the form, however far they have got.

WCAG 2.2
SC 2.2.3AAA
Required by
Not required by Section 508 or EN 301 549
Broken seats.hold(seats, { minutes: 10 })
The accessibility problem illustrated: Motor:I was nearly done. Where are my seats?
01

The problem

People who type, read or decide more slowly lose their seats and everything they typed when the checkout's timer runs out

02

Try it

Book the two seats, then skip ahead as if the form took you longer, and see what is left of your order

The demo clock above the window stands in for the minutes; it is not part of the theatre. Press Continue to start the checkout, then skip ahead. When the hold runs out, choose the seats again and look at the form.

Apply the fix, skip ahead an hour and press Pay.

Broken Can you fix this?

BrokenSeats held on a timer
Demo clock: 0:00 since you pressed Continue
Riverside Playhouse

The Lighthouse Keeper

Sat 14 Nov, 7:30 pm

Row F, seats 7 and 8 · $48.00

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Reserve the seats when people pay, not while they type

Before
BrokenSeats held on a timer
<p id="hold" data-expires="2026-11-14T18:40:00Z">We're holding your seats for <span id="hold-time">10:00</span></p><form method="post" action="/orders">  <input type="hidden" name="hold" value="h_81f2">  <label for="name">Full name</label>  <input id="name" name="name" autocomplete="name">  <label for="email">Email</label>  <input id="email" name="email" type="email" autocomplete="email">  <label for="access">Access requirements (optional)</label>  <textarea id="access" name="access"></textarea>  …  <button>Pay $48.00</button></form>
What is wrong3 points
  • The seats are held for 10 minutes from the moment they are chosen, however long the form takes.
  • At zero, the page goes back to the seat plan and the seats go back on sale.
  • Everything typed into the form is lost with the page.
After
FixSeats reserved when people pay
<p>Your seats are booked when you pay.</p><form method="post" action="/orders">  <input type="hidden" name="seats" value="F7,F8">  <label for="name">Full name</label>  <input id="name" name="name" autocomplete="name">  <label for="email">Email</label>  <input id="email" name="email" type="email" autocomplete="email">  <label for="access">Access requirements (optional)</label>  <textarea id="access" name="access"></textarea>  …  <p id="seats-gone" tabindex="-1" hidden></p>  <button>Pay $48.00</button></form>
How it is fixed4 steps
  1. Delete the hold, its expiry and the countdown. Choosing seats now only fills in the form's seats field, so nothing on the page or the server runs out.
  2. Check and reserve the seats in the same request that takes the payment, so the only moment that matters is the moment people press Pay.
  3. Send the form with fetch() and stay on the page. If the seats have gone, no payment is taken and every field still holds what was typed.
  4. Write what happened beside the Pay button, with the nearest free seats, and move focus to it, so people hear it, see it and only have to press Pay again.

This fixes the Before and passes 2.2.3: no step of the checkout depends on time. The seats can still be sold to someone else while people type, and the message is how the checkout says so without costing them the form.

04

Verify the fix

5 checks, no mouse.

Test with: Keyboard, Screen reader, Zoom

0 of 5 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the reservation code or the checkout changes.

Limits

This covers a checkout that holds seats or stock on a timer, the common form of 2.2.3 on shops and booking sites. A quiz or a test with a timer is the other: W3C's answer there is to score it without a time limit, calibrated on how people do when nobody is timed. A session that signs people out, and a warning that lets them extend it, are 2.2.1: session timeouts with no warning or way to extend. Live events, such as an auction with people bidding at the same time, and video or audio that only plays, are outside 2.2.3. Whether a ticket sale can go without a hold is for the people who run it to decide, with what they know about how fast it sells.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

EaseWeb service

Fixed it? Keep it from coming back.

I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.

See the service