In a sandbox, a test CVV is a placeholder. Nearly every gateway accepts any three digits, and the number you see printed in most docs is 123. A few processors also publish specific values that force a certain response, such as a CVV mismatch decline. Nothing is validated against a real card, because there is no real card behind it.

more on this topic

Why sandbox CVVs are fake by design

A live CVV is a 3-digit code (4 for American Express) that the issuer checks against a real account. In test mode the request never reaches an issuer. The gateway only needs a value that passes schema validation, so a string of three digits is enough. Zero-padded values like 007 work too, but they are worth testing once if your form does any parsing.

related article

Common test CVV values by provider

  • Stripe — 123 for an approved charge. Certain other values return specific decline codes.
  • Adyen — test cards accept any CVC. A small set of chosen values returns refusal responses.
  • Braintree — 123 covers most success cases, with set values for CVV mismatch results.
  • PayPal and Square sandboxes — any 3-digit value passes.

American Express test cards expect 4 digits. If you hardcode 3 everywhere, your Amex path breaks in test and you will not notice until someone tries a real one.

Sandbox Test CVV Code: What It Is and How to Use It

Card number, expiry, and CVV travel as a set

Test card numbers are built to pass the Luhn checksum, and each one carries a fixed expiry month and year in the provider docs. The CVV is the least strict part of that trio. I have seen people spend an hour on a failed test charge when the real problem was an expired test expiry date from a doc they copied two years ago. Check the number first, then the date, then the CVV.

sandbox test cvv example

Testing CVV declines on purpose

You want your checkout to handle a bad CVV gracefully, so trigger one. Stripe, Adyen, and Braintree each publish values that produce a CVV failure, and the pattern is similar across them: use the normal test card number, then swap in the special CVV. Your app should surface a clear message and keep the customer on the payment form, not throw a 500.

Mistakes I see in test setups

  1. Pasting a test card into a live key. Always confirm you are on a test key before you run anything.
  2. Reusing the same CVV value across every provider. Read the docs for the one you actually integrate.
  3. Skipping the decline paths. Success is the easy half of the work.
  4. Leaving test cards in production seed data.

When a test CVV stops working

If a value that worked last month now fails, the provider likely rotated its test card list. Test credentials change without much notice. Bookmark the docs page for your processor and re-check it when you upgrade an SDK.

One last thing: these values exist for test environments only. Using a real card number and CVV that belongs to someone else is card fraud, and no sandbox documentation covers that.