The "Rage Click" Double Charge
The Reality: If the UI freezes for even two seconds, users will mash the 'Submit Payment' button repeatedly.
How I test it: I use Chrome DevTools to throttle my network down to a slow 3G connection. I click submit five times in a row. I then check the database and the gateway dashboard to verify that the system generated a unique Idempotency Key, strictly enforcing that only one charge processed while the other four were safely ignored.
The 3DS2 Session Killer
The Reality: European banks require 3D Secure (3DS2) authentication. Users have to leave your website, open their banking app, approve the charge, and switch back.
How I test it: I explicitly test this on Mobile Safari and Chrome. Switching apps often causes mobile browsers to drop session cookies or aggressively cache the page. I verify that when the user returns to the success URL, the system accurately remembers who they are and updates their order status without forcing them to log in again.
The Silent Webhook Failure
The Reality: Stripe takes the money successfully, but right as it fires the payment_intent.succeeded webhook, your server restarts or goes down for maintenance.
How I test it: I process a real test payment, but I intentionally kill our local receiving endpoint. The user is charged, but our database says "Pending." I then spin the server back up and verify that the system successfully processes Stripe's automated webhook retries, or that a scheduled cron job catches the discrepancy during nightly reconciliation.
Partial Refunds & Proration
The Reality: Refunding a $100 order is easy. Refunding one item from a $100 order that had a 15% discount code applied is a nightmare.
How I test it: I write scripts to calculate exact percentage breakdowns, ensuring that partial refunds correctly return the prorated tax amounts and don't accidentally refund non-refundable shipping fees.