Card test cases are predefined checks that verify how a payment system handles card numbers, expiry dates, security codes, and the responses returned by the processor. A solid set covers valid inputs, invalid inputs, and boundary values so the form accepts legitimate cards and rejects malformed ones. They belong in every release cycle, not only at launch.

What card test cases should cover

Payment flows have more moving parts than a plain text field. Each layer needs its own checks.

  • Number formatting, length, and spacing rules per card brand
  • Check digit validation through the Luhn algorithm
  • Issuer and brand detection from the leading digits
  • Expiry date validation, including the current-month boundary
  • Security code format, which differs between brands
  • Authorization outcomes: approval, decline, review, and error
  • 3-D Secure step-up, challenge, and timeout behavior
  • Retries, idempotency keys, and duplicate submission handling

Field level validation cases

Card number

  1. Valid number for each supported brand
  2. Number that fails the check digit
  3. Digits entered with spaces or dashes
  4. Input with leading or trailing whitespace
  5. Non-numeric characters in the field
  6. String far longer than the maximum length
  7. Empty field and single-digit field
  8. Paste and browser autofill behavior

Expiry and security code

  1. Expired month and year
  2. Current month, which should still pass
  3. Two-digit and four-digit year entry
  4. Month values outside 01 through 12
  5. Security code with too few or too many digits
  6. Letters or symbols in a numeric-only field

Rules for test data

Test cases must never use live cardholder data. Sandbox numbers published by the processor, or synthetic numbers generated for internal testing, keep the suite safe and repeatable. Cardholder data standards require that live account numbers stay protected wherever they are stored, and that includes development and QA environments. Tokenized sandbox values are the cleanest option because they mimic real responses without carrying real account data. A check digit confirms only that a number is well formed. It says nothing about whether the account exists or is funded, so it should never be treated as a security control.

Edge cases teams often miss

  • Decline responses that map to vague or misleading customer messages
  • Partial authorization and void sequences
  • Double submission that could create two authorizations
  • Network timeout after the processor already approved the charge
  • Refunds, partial refunds, and refunds on a settled transaction
  • Currency mismatch and zero-decimal currencies
  • Concurrent requests from the same session
  • Address verification mismatches in each combination of responses

Writing test cases that stay readable

Use a consistent structure so any tester can run the suite without extra context. Give each case an ID, a one-line title, preconditions, steps, expected result, and actual result. A given-when-then format works well for payment flows because the trigger and the expected processor response are both explicit. Keep one assertion per case. When several checks share the same setup, move the shared data into a fixture instead of repeating it.

Automating card test cases

Split the suite in two. Run fast validation cases against a mocked processor on every commit, then run a smaller smoke set against the sandbox before release. Mask card data in logs and test reports, and fail the build if a live-looking number appears in test fixtures.

Quick checklist

  • Every supported brand has at least one valid and one invalid case
  • Boundary values are tested on both sides
  • Decline, error, and timeout paths have expected messages
  • Test data contains no real account numbers
  • Cases are traceable to a requirement or risk