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.
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.
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.
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
- Pasting a test card into a live key. Always confirm you are on a test key before you run anything.
- Reusing the same CVV value across every provider. Read the docs for the one you actually integrate.
- Skipping the decline paths. Success is the easy half of the work.
- 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.