𝗦𝘁𝗼𝗽 𝗥𝗲𝗳𝘂𝗻𝗱𝗶𝗻𝗴 𝗣𝗮𝘆𝗺𝗲𝗻𝘁𝘀 𝗬𝗼𝘂 𝗦𝗵𝗼𝘂𝗹𝗱 𝗡𝗲𝘃𝗲𝗿 𝗛𝗮𝘃𝗲 𝗖𝗵𝗮𝗿𝗴𝗲𝗱

Many developers ship a checkout flow that charges the card immediately. Then, they run order validation like stock checks or fraud checks.

If validation fails, the code issues a refund.

This creates problems for your customers. They see a charge and then a refund days later. They think your company is untrustworthy. They think their money is stuck.

Refunds have real costs:

The solution is to use the authorize and capture model.

Most tutorials teach you to capture money instantly. Instead, you should place a hold on the funds first. A hold sits on the card without moving the money. If your validation fails, you simply cancel the hold. No charge ever hits the customer statement.

In Stripe, you do this by setting the capture_method to manual.

The new flow works like this:

  1. Create a PaymentIntent with manual capture.
  2. The funds are authorized but not moved.
  3. Run your order validation.
  4. If the order is valid, capture the payment.
  5. If the order fails, cancel the intent.

This approach offers several benefits:

Most major payment providers use this same logic.

Use this method if any part of your business logic can fail after a customer hits pay. Move your risky checks between the authorization and the capture. This keeps your money movements clean and your customers happy.

Source: https://dev.to/jguillaumesio/stop-refunding-payments-you-should-never-have-charged-4d7m