A salon, tutor or repair shop can ask for a deposit before confirming a time slot. The payment checkout and the booking calendar are separate systems, however. A customer reaching a return page does not prove the deposit was received, and a successful payment does not automatically reserve the slot. Your booking backend must join those events deliberately.
Hold the slot before opening checkout
When a customer selects a time, create a short-lived hold in your own database. The hold should identify the service, date, time, customer and quoted price. Protect it with a database uniqueness rule or transaction so two requests cannot hold the same capacity. If your service allows several bookings at once, use a capacity counter under the same transaction.
Show the customer when the hold ends and explain whether the deposit is refundable. Those are your business terms; Trust Gateway does not manage a calendar, cancellation policy or refunds for you.
Create a payment tied to that hold
Calculate the deposit on the server, then create a Trust Gateway order with the private API key. Save its returned order ID, requested amount, exact payable amount, checkout URL and expiry alongside your hold. The exact payable amount may include a small matching adjustment. Display that returned total to the buyer and compare against it during verification. See the amounts guide for the difference between the quoted and payable figures.
Give each new attempt its own local attempt record. If creating an order times out, mark the outcome uncertain and investigate instead of blindly creating another payment link for the same booking.
Confirm only after authenticated status
When the buyer returns or clicks “I paid”, your server should read the saved order reference and call the authenticated status endpoint. Require a paid result with the expected order ID and exact payable amount before marking the deposit confirmed. A screenshot, URL parameter or customer-entered UTR is a clue for support, not proof by itself. The status verification guide covers a flow that works without relying on webhooks.
In one database transaction, lock the booking, record the verified payment reference and convert the held slot to confirmed. Add a uniqueness constraint on that payment reference so a repeated callback or refresh cannot create a second booking. Send a confirmation only after that transaction commits.
Handle a paid deposit after a hold expires
A visible countdown expiring is not proof that no payment is in flight. Before releasing a hold, check the saved payment state and preserve an uncertain payment for review. If another customer has since booked the time and the first deposit later verifies, place the paid booking into an exception queue. Contact the buyer with available alternatives and follow your published cancellation or refund policy. Never silently mark the payment unpaid or promise an automatic reversal.
Test the awkward cases
- Two people select the final available slot at the same time.
- The buyer pays but closes checkout before returning.
- The booking hold expires while payment verification is pending.
- The buyer refreshes the confirmation page repeatedly.
- Payment verifies after the slot has been assigned elsewhere.
Keep separate states for the slot, payment and customer communication. That separation makes a support investigation possible without changing payment history to fit the calendar. Use the order evidence checklist when a customer reports a missing booking.
