Introduction
"Can we just put the payment on hold?" comes up constantly — in hospitality and in retail alike. You don't want to bill yet, but you do want to know the customer can pay. It's a completely reasonable instinct.
The catch is that there's more than one way to make that "hold" happen. This article walks through what we ran into when we tried to build a hold for lodging bookings, and how we ultimately solved it.
"Hold" means two different things
Auth holds versus saving the card
In payments, "holding" can mean two things with very different characteristics.
Reserve room on the card now, capture it later. The available credit drops, so there's comfort in knowing it can't be spent twice
Simply store the card securely. No credit is reserved, but you can bill it any time later
Intuitively the auth hold looks safer, and it's what I assumed we'd use when we started looking into this. But the more I read, the clearer it became that it doesn't work for lodging bookings.
Authorizations expire
The biggest constraint on an auth hold is that the reserved credit doesn't last forever. For JPY payments on a Japanese account it's 30 days at most, and on some card brands it expires after 7.
Once it expires the hold is released automatically and that authorization can no longer be captured. You end up with "we got the authorization but we can't bill it," and your only recourse is asking the guest to enter their card details all over again.
Unusable for bookings a year out
This property accepts bookings up to 365 days in advance. Holding an authorization from the booking date until 14 days before check-in would mean keeping the credit reserved for roughly 350 days at the extreme. Thirty days doesn't come close.
We looked into the extension mechanisms too, but they only let you top up the amount — they don't extend the expiry itself — and JPY payments and certain card brands are excluded anyway. That's where we abandoned the authorization approach for good.
Card on file as the solution
At booking, all we do is save the card and authenticate
So we went with storing the card securely and billing it on the day we need to. On the payment provider's side, that means using the "save a card" mode rather than the "take a payment" mode.
The crucial part is that we always run cardholder authentication (3-D Secure) at the point the card is saved. That leaves a record with the card issuer that the cardholder personally consented to future recurring charges, so a later charge made while the customer isn't at a screen is treated as legitimate.
Skip that small extra step and the automatic charge at D-14 can be declined on the grounds that the cardholder can't be verified.
All we keep is the last four digits
The card number itself lives with the payment provider and never reaches our database. What we store is an identifier for which card it is, plus the brand name (VISA and so on) and last four digits to show the guest.
Not holding card data ourselves doesn't just make the build easier — it fundamentally limits the damage if there's ever a breach.
How the auto-charge works
It goes looking for candidates every night at midnight
Charging is handled by a scheduled job that runs at midnight each day. It finds the bookings whose charge date is today and bills them one by one.
Look for bookings whose scheduled charge date is today or earlier and that haven't been billed yet
Fetch the current outstanding balance from the reservation management system
Verify the booking hasn't been cancelled and the amount isn't abnormal
Bill the stored card and record the result
Send the guest a receipt email and the operator a daily report
There's a subtlety in how we pick candidates. We look for a charge date of today or earlier, not one that exactly matches today. If the scheduled job fails to run for a day for any reason, an exact-match query would strand that day's bookings forever.
Re-fetch the amount from the reservation system
Do we bill the amount the guest agreed to at booking? Not quite. The operator may have added options or adjusted the rate after the booking was made.
So immediately before charging, we pull the current outstanding balance from the reservation management system and bill that. The rule that the reservation system is the source of truth for money holds here too.
If the amount looks wrong, don't charge — call a human
Any time you pull an amount from an external system, there's a non-zero chance a bug returns a figure that's off by an order of magnitude. If 300,000 yen came back as 3,000,000 yen, that's a disaster.
So we added a check: if a charge exceeds three times the amount at booking, or comes back as zero or negative, we abort and email an alert to the operator. When in doubt, stop and call a human. For any automation that touches money, that safety net is non-negotiable.
No automatic retries on failure
When a charge fails — insufficient funds, say — we don't retry automatically. Repeated attempts can get flagged as fraud by the issuer, and hammering away without fixing the underlying cause won't get it through anyway.
On failure we send the operator exactly one alert, and from there a person decides and re-runs it via the "Charge now" button in the admin screen. One notification per failure, retries by human judgment. Drawing that line makes operations much easier to live with.
Wrapping up
Three things mattered most in building a payment "hold."
- Authorizations expire — 30 days at most in JPY, so they can't cover far-off dates
- Card on file plus cardholder authentication — running 3-D Secure at save time is what makes the later charge go through
- Stop and call a human when something's off — abnormal-amount detection, and no automatic retries after a failure
Payment state management is covered in "An Unbreakable Payment Flow with Webhooks and Status Management," and protecting amounts in "Payment Security Against Price Tampering and Double Charges."
An Unbreakable Payment Flow with Webhooks and Status Management
How we manage the state transitions of bookings and payments.
Payment Security Against Price Tampering and Double Charges
The essentials of protecting amounts on the server.
Stripe Payment Design for Lodging — Choosing Not to Charge at Booking
For the full picture of the payment design, start with the hub article.