What "Holding a Payment" Really Means — Card-on-File and Auto-Charge at D-14

Authorizations expire. Why we chose saving the card over an auth hold, and how the auto-charge works

payment holdautomatic chargecard on file3-D Securecancellation policy
6 min read

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.

Two kinds of "hold"
BEFORE
Authorization hold (auth)

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

AFTER
Card on file

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.

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.

How the automatic charge job runs
Find candidates

Look for bookings whose scheduled charge date is today or earlier and that haven't been billed yet

Confirm the amount

Fetch the current outstanding balance from the reservation management system

Safety checks

Verify the booking hasn't been cancelled and the amount isn't abnormal

Charge

Bill the stored card and record the result

Report

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."

  1. Authorizations expire — 30 days at most in JPY, so they can't cover far-off dates
  2. Card on file plus cardholder authentication — running 3-D Secure at save time is what makes the later charge go through
  3. 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."