Short answer
A card test that returns "successful payment" means one thing: the authorization request came back with an approval and your system stored it. In a sandbox no money moves and no real card is involved. On a live account with a real card, an approval means funds are held, not collected. Capture, settlement, webhooks and refunds are separate steps, and that is where most passing tests quietly fall apart.
Know which test you ran
Three different things get called a card test. Mixing them up causes most of the confusion I see.
- Gateway sandbox test. You use the test card numbers the processor publishes. The gateway simulates approvals and declines. Nothing reaches an issuer.
- Acquirer certification. You run a fixed script against the acquirer's test host before go-live. The cases are prescribed and the results get signed off.
- Live micro-charge. A small real charge on a card you own, then refunded. This is the only version where an issuer actually responds.
The first two are safe to repeat. The third costs money and can open a dispute if you fumble it, so run it once and reconcile carefully.
Read the response, not the green checkmark
Most dashboards show a tick for anything that returns HTTP 200. The payload is where the truth sits.
- Authorization result. An approval code plus a response code. Approval values differ by network and by ISO 8583 field mapping.
- CVV and AVS results. These return as separate match, no-match or not-checked values. An approved charge can still carry a CVV result of "not verified."
- Transaction state. Authorized, captured, settled. Success at authorization is not success at settlement.
- Idempotency key. Replaying the same request should return the same result, not a second charge.
What a passing test still hides
A sim approval tells you the plumbing works. It does not tell you the money side works. Four things to probe before you trust the result.
3-D Secure and step-up
Sandbox test cards usually skip the challenge. Force a challenge card, complete the flow, and confirm your code handles the redirect back, the failure case, and the customer abandoning the challenge.
Webhook delivery and ordering
Payment events arrive out of order more often than people expect. Send a capture before an authorization in your test harness and make sure your handler does not downgrade state. Also test a duplicate delivery.
Amount edges
Zero-decimal currencies, minimum amounts, and the difference between 10.00 and 1000 in minor units. A test at 1.00 passes while a production order at 0.50 fails validation upstream.
Declines and refunds
A successful payment is the easy path. Run an insufficient-funds card, an expired card, a partial refund and a full refund. Confirm the ledger matches after each.
Checklist before you call it done
- Authorization approved and the response code logged.
- CVV and AVS results captured and mapped to your risk rules.
- Capture or auto-capture confirmed, with the settled state visible.
- Webhook received, verified by signature, and idempotent on replay.
- Order state in your database matches the gateway state.
- Refund tested end to end, including the partial case.
- Decline path tested and the customer sees a useful message.
- Credentials swapped from test keys to live keys, and the test key path removed from production config.
Common false positives
The most frequent one is a browser redirect that fires before the webhook. The customer sees a thank-you page, your app marks the order paid, and the gateway later reports a decline. Treat the server-to-server event as the source of truth and the redirect as decoration. The second is a test card number left in a production config, which produces approvals that never settle. Both look like success until finance reconciles.