An expiry date test verifies three things: the value is well formed, it falls inside a plausible date range, and it has not already passed. Merchants run the format check in the browser for fast feedback, then repeat the same check on the server, because the server result is the only one that decides whether an order proceeds.

This guide covers expiration date validation on checkout forms you operate. It does not cover testing card credentials you do not own. Card numbers and CVV values belong to the people named on them, and using someone else's credentials is fraud.

Why the check matters

A malformed expiration date produces a failed authorization that looks like a declined card. The customer retries, support gets a ticket, and the real problem is a two-digit year typed into a four-digit field. A range check also stops obviously fabricated input such as month 13 or a year set to 1990.

What a valid expiration date looks like

Physical cards print the expiration as two-digit month and two-digit year, separated by a slash or space. Card networks use the last day of the stated month as the cutoff, so a card marked 09/27 stays valid through September 30, 2027. Internally, store the value as a month and a four-digit year, never as free text.

Prerequisites

  • A checkout form with separate month and year inputs, or a single masked field
  • Server-side validation that runs independently of the browser
  • A trusted clock, ideally UTC on the server, for the comparison

How to run the test

  1. Strip spaces, slashes, and dashes from the submitted value.
  2. Split the remaining digits into a month segment and a year segment.
  3. Confirm the month is an integer from 1 through 12.
  4. Confirm the year has four digits and does not exceed the current year by more than 20.
  5. Build an end-of-month timestamp from the month and year.
  6. Compare that timestamp against the current server time.
  7. Reject the submission if the timestamp is in the past.
  8. Validate the card number separately with the Luhn check digit before you call the processor.

Common failure cases

  • Two-digit years accepted as-is, so 26 becomes year 26
  • Client-side checks treated as authoritative
  • Timezone drift between the browser and the server near midnight on the first of a month
  • Expiration accepted but the card number field left unvalidated

What the test cannot tell you

A passing expiration date test means only that the date is plausible. It says nothing about whether the account is open, funded, or authorized. Only the issuer's response to an authorization request answers that, and merchants should treat any other signal as incomplete. If you store expiration dates, keep them inside your PCI DSS scope and never store the CVV or full track data.