On a vehicle rental platform, I had to handle deposits and security holds with Stripe. They both look like a payment, but they're not the same operation.
A deposit is a normal payment: the money is taken right away, for part of the price.
A security hold must not be collected. You block it on the customer's card, then release it when the vehicle comes back in good shape. In Stripe, that's separating authorization from capture:
# example: €500 held, nothing collected
curl https://api.stripe.com/v1/payment_intents \
-u "$STRIPE_SECRET_KEY:" \
-d amount=50000 \
-d currency=eur \
-d "automatic_payment_methods[enabled]=true" \
-d capture_method=manual
Once the card is confirmed, the payment moves to requires_capture. The money is held, not collected.
Three things to know.
-
The authorization expires. For a card paid online, it's usually 7 days. After that, the hold is released and the payment moves to
canceled. For a longer rental, a hold placed at pickup doesn't last: you need an extended authorization (only for certain cases), or save the payment method to charge later if needed. -
You can capture less than the held amount. With
amount_to_capture, the rest is released automatically. But in most cases, you can only capture once. - Releasing means canceling the payment. Nothing more.
One detail on the customer side: some bank statements don't distinguish a held amount from a charged one. Better to say so in the confirmation email.
And not every payment method allows it: SEPA direct debit or iDEAL, for example, don't support this separation.
Amine Affif, full-stack developer in Paris. amineaffif.com













