What a CVV test case actually is

A CVV test case is a scripted scenario you run against a payment sandbox to see how your checkout handles the card verification value. You send the gateway a test card number, a specific CVV, and a set of expected outcomes. If the response matches what you predicted, the case passes. If it doesn't, you have a bug in the integration or a gap in your validation. The goal isn't proving the CVV works. It's proving your code reacts correctly when it doesn't.

more on this topic

Cases worth covering

Most teams test the happy path and stop there. I'd rather see a matrix. This is the checklist I keep coming back to:

read more

  • Correct 3-digit CVV on a Visa, Mastercard, or Discover test number.
  • Correct 4-digit CID on an American Express test number.
  • Wrong CVV with an otherwise valid card number. This should surface as a mismatch, not a generic decline.
  • Missing field, sent as null or an empty string.
  • Letters, symbols, or a hyphen mixed into the value.
  • Two digits. Five digits. Six digits.
  • Leading zeros, like 007.
  • A trailing space, or a stray mask character pasted in from a screenshot.
  • Non-ASCII or full-width digits from an international input method.

Each one should map to a distinct, logged result. A bare "declined" tells you nothing when a customer emails support three hours later.

cvv test test case

Where test values come from

Every processor publishes its own set of sandbox card numbers, including dedicated PANs that always trigger a CVV failure and others that always pass. Stripe, Adyen, Braintree, and the rest document them openly. Use those and nothing else. Never run a live card number through a test environment, not even your own card. Sandboxes exist so you don't create real authorizations or real dispute records, and a live PAN sitting in test data is a good way to get a merchant account flagged during review.

related article

Read the raw response, not your UI

Gateways return the verification result separately from the authorization decision. You'll see values along the lines of pass, fail, unchecked, or unavailable. Unchecked is the one people ignore, and it usually means your integration never sent the value at all. That's a silent failure that looks like a success in your own dashboard.

You also want to confirm the account is configured to reject on mismatch rather than just report it. Plenty of processor accounts default to report-only, which means a failed CVV check still authorizes the charge.

What you must not store

After authorization, the CVV should be gone. PCI DSS classifies the CVV, full magnetic stripe data, and the PIN block as sensitive authentication data, and requirement 3.2 prohibits retaining them post-authorization even when encrypted. So a complete test suite also verifies the value never lands in your database, your application logs, or a third-party analytics event. I have seen debug logging dump full request bodies into an observability tool with the CVV included. That turns a routine test pass into an incident report.

Mistakes that make results meaningless

  • Stubbing the gateway so every case returns the answer you wanted to see.
  • Testing CVV in isolation while ignoring AVS, then wondering why fraud rules fire on clean cards.
  • Running the suite against production keys.
  • Skipping the client-side check, where a max length of 3 quietly blocks every Amex CID.

Fix the input handling first. Then let the sandbox tell you the truth.