A CVV test in frontend work checks a payment form with sandbox card numbers, fake security codes, and edge cases that real users type. Sandbox CVVs work only inside a processor's test mode, so no live card account is touched. You need three things: test card data from your payment provider, a field that validates before submit, and a list of cases that covers odd input.
Where does CVV test data come from?
Each payment processor publishes its own test card list. Stripe, Adyen, PayPal, and Braintree all ship sandbox numbers with matching CVC rules, plus cards that force a CVC failure on purpose.
A common example is 4242 4242 4242 4242, which Stripe accepts in test mode with any future expiry date and any three-digit CVC. Values change over time, so pull the current list from the docs of the provider you integrate.
- Stripe: test cards plus a CVC check failure card for decline paths.
- PayPal and Braintree: sandbox card sets for hosted fields.
- Adyen: test cards tied to specific result codes.
Test mode keys matter. A sandbox CVV fails when the request hits a live endpoint, and a live card fails in test mode. Keep the two key sets apart in your build config.
What CVV format rules should the frontend enforce?
- Three digits for Visa, Mastercard, Discover, and most debit cards.
- Four digits for American Express.
- Digits only. No spaces, letters, or dashes.
- Leading zeros count, so 012 is valid and must survive validation.
The card brand decides the length. Read the brand from the card number field as the user types, then set the max length on the CVV input. Do not hardcode three digits for every card.
How do you build a CVV field you can test?
Input attributes that help
- Use type="text" with inputmode="numeric" so mobile browsers show a number pad and leading zeros stay intact.
- Set autocomplete="cc-csc" so browsers and password managers fill the field.
- Cap input with maxlength="4" and strip non-digits in the input handler.
- Add an aria-label such as "Card security code" for screen readers.
What to avoid
- type="number", which drops leading zeros and adds spinner controls.
- Trimming the value with parseInt or Number().
- Writing the CVV to console logs, analytics events, or localStorage.
- Putting the value in a URL or a hidden field that posts to a third party.
Which CVV test cases should you run?
- Empty field, then submit.
- One digit and two digits.
- Three digits on a Visa test card.
- Four digits on an Amex test card.
- Five digits, which the field should block.
- A leading-zero value such as 012.
- Letters, symbols, and mixed input.
- Paste with a trailing space or a dash.
- Browser autofill on desktop and on a phone.
- Card brand change after the CVV is typed.
Run each case in the sandbox and read the response. A CVC check failure card should surface your decline message, not a generic error.
How do you test without real card data?
You never need a live card to test a CVV field. Sandbox keys, mock API responses, and provider test cards cover the whole flow.
- Point your frontend at test keys in a staging build.
- Mock the token endpoint so you can force timeouts and 500 responses.
- Throttle the network to see how the field behaves on slow connections.
- Test on a real phone, since mobile keyboards and autofill differ from desktop.
Why the frontend should not store the CVV
PCI DSS treats the card verification code as sensitive authentication data. It cannot be stored after authorization, even in encrypted form, and it should not sit in a database, a session replay tool, or an error tracker. Collect it, pass it to your processor through a token or a hosted field, then drop it.
Hosted fields and iframes keep the value out of your own DOM and JavaScript scope. A frontend test should confirm the CVV never lands in your state store, your logs, or your analytics payloads.
What bugs show up in CVV fields?
- Leading zeros stripped by a number input or a parseInt call.
- Amex four-digit codes cut to three.
- Value kept after the card number changes.
- CVV sent to analytics or written into error reports.
- Paste blocked by a keydown handler that reads single keystrokes.
- Error text that says "invalid card" when the real problem is the code.
FAQ
Does the Luhn check validate a CVV?
No. Luhn is a checksum for the primary account number. The security code has no checksum, so the frontend can check length and digits only.
Can a frontend test prove a CVV is real?
No. Only the issuer, through the processor, can verify a security code. Your form checks shape, then the authorization response tells you if the code matched.
Should the CVV field hide its digits?
Most checkout forms show the three or four digits as plain text. Masking the field can break browser autofill and adds no security, since the value travels over TLS anyway.
Checklist before you ship
- Test mode keys in staging, live keys in production, no crossover.
- Length rules tied to the card brand.
- Leading zeros preserved from input to token.
- No CVV in logs, storage, or analytics.
- Every case above passing on desktop and a real phone.
- Decline messages that name the failed check.