카드 유효기간 형식은 카드 앞면에 인쇄된 짧은 숫자 조합입니다. 월을 나타내는 두 자리와 연도를 나타내는 두 자리를 나란히 두고, 그 사이에 구분 기호를 넣습니다. 짧아 보이는 항목이지만 언제 만료로 처리할지, 저장할 때 어떤 형태로 둘지를 잘못 정하면 정상 카드가 거부되거나 만료 카드가 통과합니다. 이 글에서는 인쇄 규칙과 유효 기간의 경계, 그리고 입력 칸에서 자주 생기는 문제를 정리합니다.
카드 앞면의 네 자리는 무엇을 뜻할까?
앞의 두 자리는 달이고, 뒤의 두 자리는 연도입니다. 연도를 네 자리로 쓰지 않고 두 자리만 쓰는 관행이 오래되어서, 화면에서도 두 자리로 받는 경우가 많습니다. 다만 두 자리만 저장해 두면 세기가 사라지므로, 내부적으로 다룰 때는 네 자리 연도로 펼쳐 두는 편이 안전합니다.
인쇄된 순서와 시스템이 다루는 순서가 다르다는 점도 기억할 만합니다. 사람은 달을 먼저 읽지만, 날짜를 비교하는 계산은 연도를 먼저 봅니다.
카드는 그 달 내내 유효한가?
가장 많이 오해되는 지점입니다. 카드에 3월이라고 인쇄되어 있으면 3월 1일에 만료되는 것이 아니라, 3월의 마지막 날까지 유효합니다. 즉 3월 31일까지는 정상 카드이고, 4월 1일이 되는 순간 만료됩니다.
그래서 만료 판단은 달 단위로 해야 합니다. 현재 연도와 달을 기준으로, 카드에 적힌 연도와 달이 그보다 앞서는지 비교하는 방식이 정확합니다. 일 단위로 비교하면 그 달 안에서 하루 차이로 잘못 판정합니다.
| 카드에 인쇄된 값 | 실제 유효 기간 |
|---|---|
| 1월 | 1월 1일부터 1월 31일까지 |
| 2월 | 2월 1일부터 그해 2월의 마지막 날까지 |
| 12월 | 12월 1일부터 12월 31일까지 |
윤년이 있는 달도 있으므로, 그달의 마지막 날을 직접 계산해 두는 편이 안전합니다.
표시 형식과 저장 형식은 어떻게 다를까?
카드에 인쇄된 형태는 사람이 읽기 좋게 만든 것입니다. 시스템이 비교하고 정렬하기 좋은 형태는 연도 네 자리와 월 두 자리를 이어 붙인 값입니다. 이 둘을 같은 것으로 착각하면 화면에는 잘 보이는데 정렬이 뒤섞이거나, 반대로 저장은 멀쩡한데 화면에 두 자리 연도가 그대로 노출되는 일이 생깁니다.
두 형식을 오갈 때는 변환 지점을 한 곳으로 모으는 것이 좋습니다. 화면과 저장소 사이에서 여러 곳이 각자 변환하면, 언젠가 한 곳이 규칙에서 벗어납니다.
두 자리 연도는 어떻게 네 자리로 펼칠까?
두 자리 연도를 다룰 때 가장 조심할 지점은 세기입니다. 27이라는 값이 2027년인지 1927년인지는 값 자체에 들어 있지 않습니다. 대부분의 경우 카드 유효기간은 가까운 미래이므로, 현재 연도를 기준으로 가장 가까운 미래가 되도록 펼치는 규칙이 실용적입니다.
다만 이 규칙은 세기 경계에서 조용히 틀릴 수 있습니다. 펼치는 규칙을 코드에 한 곳만 두고, 경계에 해당하는 값을 테스트에 넣어 두는 편이 안전합니다. 저장소에는 처음부터 네 자리로 넣어 두면 이 문제 자체가 사라집니다.
카드 앞면을 읽을 때 주의할 점
카드에 인쇄된 순서와 시스템이 다루는 순서가 달라서, 사람이 읽는 값을 그대로 옮겨 적으면 순서를 뒤집기 쉽습니다. 화면에서 입력을 받을 때는 달과 연도를 각각의 칸으로 나누어 순서를 명확히 하는 편이 좋고, 저장할 때는 연도를 먼저 두어 정렬과 비교가 자연스럽게 되도록 합니다.
또 하나, 카드에 인쇄된 값을 그대로 읽어 주는 자동 인식이나 음성 입력을 붙일 때는 구분 기호가 섞여 들어옵니다. 값이 두 칸으로 나뉘어 있는 화면이라면 구분 기호를 걷어내는 처리가 한 곳에 모여 있어야 합니다.
이렇게 읽어 낸 값을 입력 단계로 옮길 때 사람들이 자주 하는 실수도 함께 짚어 두겠습니다.
- 연도를 네 자리로 입력하는 경우: 두 자리만 받는 칸에서는 입력이 잘리거나 거부됩니다.
- 달과 연도를 바꿔 넣는 경우: 12월과 27년을 뒤집어 넣으면 미래 카드가 과거 카드로 처리됩니다.
- 한 자리 달을 그대로 두는 경우: 1월을 한 자리로 보내면 두 자리 형식을 기대하는 검증에서 걸립니다.
- 만료된 카드의 오류 문구가 없는 경우: 사용자는 왜 막혔는지 알 수 없습니다.
- 붙여넣기로 들어온 구분 기호를 처리하지 않는 경우: 값이 통째로 비어 버립니다.
경계 조건을 어떻게 시험할까?
만료 판단은 경계에서 틀리기 쉬우므로 시험 항목을 미리 정해 두는 것이 좋습니다.
- 이번 달 카드: 유효해야 합니다.
- 지난달 카드: 만료로 처리되어야 합니다.
- 다음 달 카드: 유효해야 합니다.
- 먼 미래 카드: 유효해야 합니다.
- 두 자리 연도와 네 자리 연도를 섞어 넣은 경우: 같은 결과가 나와야 합니다.
- 시간대가 다른 환경에서 같은 판단이 나오는지
마지막 항목이 특히 자주 빠집니다. 서버 시간대와 사용자 시간대가 다르면 월이 바뀌는 시점에 판정이 갈릴 수 있습니다.
개발자를 위한 메모: 만료 판단을 한 곳에 모아라
만료 여부를 판단하는 곳이 화면과 서버에 흩어져 있으면, 두 곳의 기준이 조금씩 달라집니다. 판단 규칙을 한 곳에 두고 양쪽이 같은 값을 쓰게 하는 편이 좋습니다.
입력 칸은 두 개로 나누는 방식이 가장 무난합니다. 달과 연도를 따로 받고, 두 값이 모두 채워졌을 때 하나의 값으로 합칩니다. 한 칸에 슬래시까지 입력받는 방식은 지우기 동작과 붙여넣기에서 예외가 많이 생깁니다.
또 하나, 만료된 카드의 판단을 검증 실패와 같은 오류로 묶지 않는 것이 좋습니다. 사용자가 해야 할 일이 다르기 때문입니다. 형식이 틀린 것은 다시 입력하면 되지만, 만료는 다른 카드를 써야 합니다. 카드 번호 검증의 다른 단계는 코드로 카드 번호 검증하기에서 이어지고, 입력 칸이 받아야 할 자릿수 규칙은 카드 번호 형식에 정리해 두었습니다.
다음 단계
현재 만료 판단이 일 단위로 되어 있다면 월 단위 비교로 바꾸고, 위 경계 조건을 테스트에 넣어 보세요. 생성기에서 여러 카드를 만들면 유효기간이 함께 표시되므로, 입력 칸과 저장 형식이 기대대로 동작하는지 빠르게 확인할 수 있습니다. 생성기에서 나오는 유효기간과 카드 번호는 구조적으로 유효하지만 실제로 발급된 적이 없어 결제에 사용할 수 없습니다.