Advertisement

Card numbers explained

CVV vs CVC vs CID: card security codes explained

CVV, CVC, CID, CAV2, CVN2 — the three or four digits that every online checkout asks for go by a different name on almost every card network. They all do the same job. This guide explains what the code proves, how issuers create it, how to handle it in a payment form and what PCI DSS says about keeping it.

By the Fakecreditcard teamPublished 8 min read

Advertisement

Key takeaways

  • CVV2 (Visa), CVC2 (Mastercard), CID (American Express, Discover), CAV2 (JCB) and CVN2 (UnionPay) are names for the same thing: a code that shows the payer has the card.
  • American Express prints a 4-digit code on the front; the other major networks print 3 digits on the back.
  • Issuers derive the code with secret keys, so a merchant can only check its length. Whether it is correct is decided by the issuer during authorization.
  • PCI DSS Requirement 3.3.1.2: the code may be collected for authorization but must never be stored afterwards, not even encrypted.
On this page
  1. What a card security code is for
  2. The names used by each network
  3. CVV1, CVV2, iCVV and dynamic codes
  4. Validating the security code in a form
  5. Storage: the PCI DSS rule
  6. What the issuer’s answer looks like
  7. Testing security code failures in a sandbox
  8. Common mistakes
  9. Frequently asked questions

Every card-not-present checkout asks for the same short code, but the label changes with the card: Visa says CVV, Mastercard says CVC, American Express says CID. Developers then have to decide how long the field should be, what to validate and what may be logged. The answers are simpler than the alphabet soup suggests.

What a card security code is for

The card security code is a short value printed on the card but not contained in the card number. When a customer types it into an online checkout, the issuer can compare it with the value it expects for that card. A match is evidence that the payer has the physical card — or at least saw it — rather than just a list of card numbers.

That evidence matters most for card-not-present payments: e-commerce, apps and phone orders, where nobody can inspect the card. It is one layer of fraud prevention alongside address verification (AVS) and 3-D Secure, not a complete defense: a phishing page can steal the code together with the number.

The names used by each network

Every network gives the code its own name, but the function is the same. Generic terms you will also see are CSC (card security code) and CVD (card verification data).

NetworkNameStands forDigitsWhere
VisaCVV2Card Verification Value 23Back
MastercardCVC2Card Validation Code 23Back
American ExpressCID (also 4DBC)Card Identification Data / 4-Digit Banking Code4Front, above the number
DiscoverCIDCard Identification Data3Back
JCBCAV2Card Authentication Value 23Back
UnionPayCVN2Card Validation Number 23Back
Diners ClubSecurity code—3Back

In your UI, a neutral label such as “Security code” plus a small hint (“3 digits on the back, 4 on the front for Amex”) works for every brand. Switch the hint once you have detected the brand from the card number’s prefix — the card number format page lists the prefixes.

Advertisement

CVV1, CVV2, iCVV and dynamic codes

The “2” in CVV2 and CVC2 is there because there is also a version 1. Several related values exist, and each is used in a different channel:

ValueWhere it livesUsed for
CVV1 / CVC1Encoded in the magnetic stripeCard-present swipe transactions, checked by the issuer
CVV2 / CVC2 / CIDPrinted on the cardCard-not-present payments typed by the customer
iCVVChip dataChip and contactless transactions; differs from CVV1, so chip data copied onto a magnetic stripe does not carry a valid stripe code
Dynamic CVVBanking app or, on some cards, a small displayCard-not-present payments with a code that changes over time

The printed code and the stripe value are calculated with different inputs, which is why reading a magnetic stripe does not reveal the code you type online. With dynamic CVV, some issuers no longer print a fixed code at all; the cardholder gets a fresh one in their banking app. For a checkout this changes nothing — you still collect three or four digits and pass them to the gateway.

How issuers generate the code

The code is not computed from the card number with a public formula the way the Luhn check digit is. The issuer derives it cryptographically from the card number, the expiry date and a service code, using secret keys kept in hardware security modules. Different service codes produce the stripe value, the printed value and the chip value from the same card data.

Two practical consequences follow:

  • A merchant cannot tell whether a code is correct. Only the issuer, holding the keys, can verify it during authorization.
  • A random code that a card generator produces is just three or four random digits. It fits the field and nothing more.

With only 1,000 possible three-digit values, the protection depends on issuers and merchants limiting repeated attempts. That is why guessing security codes is a hallmark of card-testing attacks, and why velocity limits belong next to every payment form.

Validating the security code in a form

Client-side validation can only check the shape of the value. Keep it simple and brand-aware:

  • Digits only, as a string. Codes can start with zero (042), so never convert them to a number.
  • Length by brand. Four digits for American Express, three for Visa, Mastercard, Discover, JCB, Diners Club and UnionPay. Before the brand is known, accept three or four.
  • Correct input hints. Use inputmode="numeric" for a numeric keypad and autocomplete="cc-csc" so browsers and password managers can fill it.
  • Don’t mask it as a password field. Customers mistype hidden digits; a plain text field with a short length is enough on the payment page.
HTML + JavaScript
<label for="cc-csc">Security code</label>
<input id="cc-csc" name="cc-csc" inputmode="numeric" autocomplete="cc-csc"
       maxlength="4" pattern="[0-9]{3,4}" required>

<script>
  // brand comes from your card-number detection: 'amex', 'visa', 'mastercard', ...
  function cscError(value, brand) {
    const len = brand === 'amex' ? 4 : brand ? 3 : null;
    if (!/^[0-9]+$/.test(value)) return 'Use digits only';
    if (len && value.length !== len) return `Enter the ${len}-digit security code`;
    if (!len && (value.length < 3 || value.length > 4)) return 'Enter 3 or 4 digits';
    return null;   // well formed; the issuer decides whether it matches
  }
</script>

If you use a hosted payment field from your gateway (Stripe Elements, Braintree Hosted Fields, Adyen Components and similar), the code never touches your page’s JavaScript or your servers. That is the simplest way to keep it out of your systems entirely.

Storage: the PCI DSS rule

The card verification code is sensitive authentication data under PCI DSS. The PCI Security Standards Council states that merchants may request it from cardholders, but PCI DSS Requirement 3.3.1.2 strictly prohibits storing it after authorization — even if it is encrypted.

What that means in practice

  • Collect it only for an authorization and discard it as soon as the authorization completes.
  • Not for card-on-file or recurring payments. The Council’s FAQ says codes are not needed for those transactions and storage for these purposes is prohibited. A customer’s permission does not change this.
  • Watch logs and tooling. Request-body logging, error trackers, analytics, support tickets and database backups are the usual places a code ends up by accident. Filter cvc, cvv and csc fields before anything is written.
  • No “temporary” storage. A process that claims to delete the code but can still retrieve it for later authorizations is storage.

Re-asking is allowed, keeping is not

Some merchants ask returning customers to re-enter the security code for a saved card as an extra risk check. That is fine: the code is collected for that specific authorization and discarded afterwards. Keeping it so customers don’t have to re-enter it is not.

For the wider picture — why real card data, including codes, should never be in development and test systems — see Test data and PCI DSS.

What the issuer’s answer looks like

When you send a code, the issuer returns a separate result for it alongside the approve-or-decline decision. Gateways normalize that result; Stripe, for instance, reports cvc_check as pass, fail, unavailable or unchecked. Depending on the issuer and your gateway settings, a mismatched code can produce an outright decline, or an approval with a failed check that your own rules then reject.

  • Mismatch: ask the customer to check the code, and count the attempt towards your velocity limits.
  • Unavailable: the issuer did not check it. Decide whether to accept based on other signals.
  • Not sent: the check is skipped. Stripe notes that if you omit the code, the check cannot fail — so require the field if your fraud rules depend on it.

Testing security code failures in a sandbox

Most sandboxes accept any code of the correct length, so the happy path is easy. To test the failure path, each gateway documents a specific card or trigger. These come from the official documentation listed on our test card numbers pages:

GatewayHow to simulate a CVC failure
StripeCard 4000 0000 0000 0127 declines with incorrect_cvc; 4000 0000 0000 0101 fails the CVC check (send a CVC value)
Checkout.comCard 4734 8689 5873 3862 returns 200N7, decline for CVV2 failure
PayPalName on card CCREJECT-CVV_F
BraintreeCVV 200 (CID 2000), with CVV rules enabled in the sandbox
AdyenholderName set to CVC_DECLINED
SquareCVV 911
Authorize.netCard code 901

Check that your UI shows a clear message (“The security code doesn’t match. Please check the card.”), that the attempt is logged without the code itself, and that repeated failures trigger your rate limits.

Common mistakes

  • Fixed three-digit fields. They lock out American Express customers. Size the field for four digits and validate per brand.
  • Converting to an integer. 042 becomes 42 and fails at the issuer.
  • Optional field without a reason. If you don’t send a code, you lose the issuer’s check entirely.
  • Leaking it into logs. The most common way codes end up stored against PCI DSS rules.
  • Treating a match as proof of identity. A matching code proves knowledge of the code, not that the payer is the cardholder. Combine it with AVS, 3-D Secure and behavior signals.

Frequently asked questions

Is CVV the same as CVC?

Yes, in practice. CVV2 is Visa’s name and CVC2 is Mastercard’s name for the printed security code. Both are three digits on the back of the card and are checked by the issuer in the same way.

Where is the CID on an American Express card?

On the front, printed above and to the right of the card number. It has four digits, unlike the three-digit codes on the back of most other cards.

Can a website check whether a CVV is correct without the bank?

No. The code is calculated by the issuer with secret keys. A website can only check that it has the right number of digits; correctness is confirmed in the issuer’s authorization response.

Can I store the CVV for recurring payments?

No. The PCI Security Standards Council states that card verification codes are not needed for card-on-file or recurring transactions and must not be stored for those purposes, even if the customer agrees.

Why does my test payment succeed with any CVC?

Most sandboxes accept any code of the right length so you can test the happy path. To simulate a CVC failure, use the gateway’s dedicated test card or trigger value, such as Stripe’s 4000 0000 0000 0127.

Sources

  1. PCI SSC FAQ — Are merchants allowed to request card verification codes from cardholders?
  2. PCI SSC FAQ — Can card verification codes be stored for card-on-file or recurring transactions?
  3. Worldline Direct — CVV (security code names per scheme)
  4. Sipay Developers — CVV
  5. Wikipedia — Card security code
  6. Stripe Docs — Testing (CVC test cards)

Tools used in this guide

Related guides

Written for developers, QA teams and merchants. Generated card numbers are test data: they are not real cards and cannot pay for anything.

Advertisement