I once shipped a checkout that charged the card the instant the customer hit pay, then ran the order validation afterward. Stock check, address validation, a fraud heuristic, a third-party availability call. When any of those failed, the code did the obvious thing: it refunded the payment

It worked. It also generated a steady trickle of confused, angry emails. "Why did you charge me 89 euros and then refund it three days later?" To the customer, a charge followed by a refund does not read as "we caught a problem". It reads as "this company is sketchy and now my money is stuck in limbo for a week"

The fix was one property I had been ignoring for years: capture_method: manual

The charge-then-refund antipattern

Here is the flow almost every tutorial teaches, and the one I had shipped: