Hold now, charge later

For when the final amount is not known until the service is delivered.

Place the hold

A hold reserves the money on the card without taking it. Ask for the most you might charge — you can capture less, and the rest is released.

ts
const intent = await sp.paymentIntents.create({
  amount: 20000,               // the most you might charge
  currency: "usd",
  capture_method: "manual",
});

Once the customer has paid, the payment reaches requires_capture and amount_capturable tells you what is held.

Take the money

ts
await sp.paymentIntents.capture(intent.id, {
  amount_to_capture: 17500,    // capture less; the rest is released
});

Or let it go

ts
await sp.paymentIntents.cancel(intent.id);
A hold does not last forever. The card issuer decides how long, and it is typically two weeks to a month — after that the money is released whether or not you captured it. Capture as soon as you know the amount, and do not treat a hold as a long-term reservation.

Which events to expect

payment_intent.amount_capturable_updated when the hold is placed, then payment_intent.succeeded when you capture. A cancelled hold gives you payment_intent.canceled.