판단의 출발점
다음은 설계 예시입니다. 월정액 서비스를 개발하면서 카드 등록과 첫 결제까지 확인했습니다. 그런데 다음 달 결제가 실패하자 질문이 생깁니다. 지금 이용을 막아야 할까요? 사흘 더 기다려도 될까요? 그사이 해지를 신청한 고객에게 다시 결제를 시도해도 될까요?
정기결제 API를 연결한 것만으로 구독 서비스가 완성되지는 않습니다. 결제수단을 등록하고 돈을 받는 기능에 더해, 누구에게 어느 기간의 얼마를 청구하고 어떤 기능을 언제까지 제공할지 연결해야 합니다. 다만 이 책임을 나누는 것과 별도의 대형 빌링 플랫폼을 도입하는 것은 다른 결정입니다.
토스페이먼츠는 자동결제 가이드에서 구독 서비스를 API로 직접 구축하고 결제 주기에 맞춰 승인 요청을 직접 스케줄링해야 한다고 안내합니다. 빌링키를 발급받는 단계와 그 키로 금액을 결제하는 단계도 구분합니다.[1] 개발 범위를 정할 때는 ‘정기결제 연동’이라는 한 줄보다 그다음에 남는 책임을 먼저 살펴봐야 합니다.
결제수단에서 이용 권한까지, 여섯 가지를 나눠 봅니다
아래는 구축 범위를 정하기 위한 내부 개념도입니다. 특정 공급자의 API 구조나 반드시 만들어야 할 데이터베이스 테이블 여섯 개를 뜻하지 않습니다.
고객 ── 등록 ── 결제수단 참조(예: 빌링키)
│ │
└─ 체결 ── 구독 계약 │ 결제에 사용
│ ▼
요금제·버전·기간 → 청구 → 결제 시도·거래
│ │ 성공 / 실패 / 취소
└──────┬───────┘
▼
유예·변경·종료 정책 적용
▼
이용 권한: 기능·범위·만료 시점| 내부 개념 | 답해야 하는 질문 | 다른 개념과 구분할 점 |
|---|---|---|
| 고객 | 누가 계약하고 누가 비용을 내는가? | 로그인 사용자와 비용을 부담하는 회사가 다를 수 있습니다. |
| 결제수단 | 무엇으로 결제할 수 있는가? | 결제수단 등록 자체는 이번 청구의 수납 완료가 아닙니다. |
| 구독 계약·요금제 | 어떤 조건을 어느 기간에 적용하는가? | 요금제 이름 외에 가격·적용 시점·변경 이력을 구분합니다. |
| 청구 | 어느 이용 기간에 대해 얼마를 받아야 하는가? | 결제에 실패해도 청구할 금액과 근거는 남습니다. |
| 결제 시도·거래 | 실제 결제 요청과 결과는 무엇인가? | 같은 청구의 재시도와 다음 회차의 청구는 다릅니다. |
| 이용 권한 | 지금 어떤 기능을 사용할 수 있는가? | 결제 결과와 함께 유예·무료 체험·종료 정책을 반영합니다. |
이 글에서 ‘청구’는 받을 금액과 대상 기간을 관리하는 기술적 개념입니다. 그 자체를 세금계산서나 특정 회계 처리와 동일하게 보지 않습니다. 표 역시 정해진 정답 스키마가 아니라, 놓친 업무를 찾는 데 쓰는 설계표입니다.
공급자의 이름을 이 내부 모델에 그대로 덮어쓰면 혼동하기 쉽습니다. 토스페이먼츠의 customerKey, billingKey, paymentKey는 각각 고객 식별에 사용하는 값, 자동결제에 사용하는 키, 결제 식별자입니다. 빌링키 발급은 Billing 객체를, 자동결제 승인 성공은 Payment 객체를 반환합니다. 이 키들만으로 애플리케이션의 구독 계약이나 이용 권한이 생기지는 않습니다.[2]
반면 Stripe Billing은 Customer, Product, Price, Subscription, Invoice 등의 객체를 제공하고 구독에 따른 청구와 결제 수집을 연결합니다. Subscription의 active 상태가 모든 청구서의 결제 완료를 뜻하지는 않습니다.[3] 일반 구조를 먼저 정하고 선택한 제품의 객체가 어느 책임을 맡는지 대응시키는 순서가 좋습니다.
구독 조건에서 청구와 재시도까지 — 요금제와 계약 조건을 분리하고 청구 계산과 실패 사유별 재시도를 같은 수명주기로 구현합니다.
구독에는 ‘성공’과 ‘실패’보다 많은 변화가 있습니다
다음 표는 구독 기능을 인수할 때 구분할 상태 변화입니다. 마지막 열은 공급자의 기본 동작이 아니라 서비스가 정해야 할 정책입니다.
| 사건 | 따로 기록해야 할 변화 | 먼저 정할 정책 |
|---|---|---|
| 첫 결제 성공 | 첫 청구의 수납 결과와 최초 이용 기간 | 결제 확인 후 언제 권한을 열 것인가? |
| 다음 청구 도래 | 새 회차의 기간·금액과 결제 결과 | 기준 시간대, 월말 처리, 청구 담당 작업은 무엇인가? |
| 결제 실패 | 해당 시도의 실패 사유와 미수납 상태 | 첫 결제 실패와 갱신 실패를 같은 방식으로 다룰 것인가? |
| 재시도 | 기존 청구에 대한 추가 결제 시도 | 어떤 사유를 언제까지 재시도할 것인가? |
| 유예 기간 | 미수납 상태에서도 허용하는 이용 범위·기한 | 모든 기능을 유지할지, 일부 기능만 허용할지 정했는가? |
| 일시 정지 | 청구·수금·이용 중 무엇이 멈추는지 | 재개일과 정지 중 발생한 청구를 어떻게 처리할 것인가? |
| 해지 예약 | 미래의 종료 시점과 다음 갱신 중단 | 이미 결제한 기간의 이용은 언제 끝나는가? |
| 즉시 해지 | 계약 종료와 권한 종료, 잔여 청구의 처리 | 환불이나 마지막 사용량 청구가 별도로 필요한가? |
| 요금제 변경 | 새 조건의 적용 시점과 추가·차감 청구 | 즉시 변경인지 다음 회차 변경인지, 일할 계산이 필요한가? |
| 환불 | 기존 결제의 금액 조정과 처리 결과 | 구독도 끝낼지, 특정 기간이나 항목만 조정할지 정했는가? |
특히 구독 해지, 결제 취소·환불, 이용 권한 종료를 하나의 작업으로 취급하지 않는 것이 중요합니다. Stripe도 구독의 즉시 해지와 기간 말 해지를 구분하고 환불 여부와 방식은 별도로 다룹니다.[4] 어떤 고객이 해지를 신청했다는 이유만으로 기존 결제 기록을 없애거나 권한을 즉시 끊어서는 서비스가 선택한 정책을 설명할 수 없습니다.
‘일시 정지’도 이름만으로는 부족합니다. Stripe의 pause_collection은 수금 일시 정지이며 구독 상태를 바꾸지 않고 청구서가 계속 생성될 수 있습니다. 서비스 이용 자체의 정지와는 구분해야 합니다.[5] 기획서에 ‘정지 버튼’만 적기보다 무엇을 멈추고 무엇을 계속하는지 적어야 합니다.
API를 고르기 전에 결정할 세 가지
실패한 고객을 언제까지 이용하게 할 것인가
갱신 결제가 실패했을 때 즉시 이용을 제한할 수도 있고, 일정 기간 유예할 수도 있습니다. 이것은 결제사의 오류 코드가 대신 결정하는 문제가 아닙니다.
설계 예시로, 무료 체험이 없는 월정액 서비스가 ‘첫 결제 실패 시 권한을 열지 않고, 갱신 실패 시에는 72시간 유예한다’고 정했다고 합시다. 이 서비스에는 결제 실패 기록뿐 아니라 유예 종료 시각, 그동안 허용할 기능, 유예 종료 후 제한 작업, 결제 회복 후 권한 복원까지 필요합니다. 72시간은 이 예시의 선택일 뿐 권장 표준이나 법정 기간이 아닙니다.
재시도도 오류 사유에 따라 달라집니다. 토스페이먼츠는 카드·계좌 재발급이나 유효기간 만료 시 새로운 정보로 빌링키를 다시 발급받도록 안내합니다.[1] Stripe Smart Retries 역시 일부 강한 거절 사유에서는 새 결제수단 없이는 실제 재결제를 실행하지 않습니다.[6] 모든 실패에 같은 간격으로 승인 요청을 반복하는 정책은 피해야 합니다.
해지 신청일과 이용 종료일을 같게 할 것인가
기간 말 해지를 선택한 설계에서는 오늘 해지 신청을 받아도 이미 허용한 이용 기간은 유지하면서 다음 회차의 청구를 막아야 합니다. 즉시 해지를 지원한다면 계약 종료, 권한 회수, 환불 검토를 각각 처리해야 합니다.
또한 다음 회차를 갱신하지 않는 결정과 이미 발생한 미수납 청구를 어떻게 처리할지는 별도입니다. 해지 예약이 들어왔는데 이전 청구의 재시도까지 모두 중단할지, 확정된 청구만 처리할지 정하지 않으면 운영자마다 다른 행동을 하게 됩니다. 여기서 제시하는 것은 상태 설계의 질문입니다. 특정 해지·환불 정책이 법적으로 허용된다는 판단은 아니며, 실제 상품과 계약에 대한 별도 검토가 필요합니다.
요금제 변경을 언제 반영할 것인가
모든 변경을 다음 청구 주기부터 적용한다면 중간 기간의 차액 계산을 줄일 수 있습니다. 반대로 월 중간에 상위 요금제의 기능을 바로 열어 주려면 추가 요금, 적용 시점, 추가 결제 실패 시 권한 처리를 함께 정해야 합니다.
일할 계산과 환불도 같은 뜻이 아닙니다. Stripe의 일할 계산에서는 차감액이 생겨도 자동으로 환불되는 것은 아니며, 추가액이 생겨도 설정에 따라 즉시 청구되지 않을 수 있습니다. 미납 청구가 있는 상태의 요금제 변경에는 아직 내지 않은 금액을 기준으로 크레딧이 계산되는 경우도 설명되어 있습니다.[7] 계산 기능의 존재보다 어떤 금액을 어떤 시점에 실제로 받거나 돌려줄지가 먼저입니다.
PG, 빌링 도구, 애플리케이션, 운영자의 책임
구독 시스템을 전부 직접 만들 필요는 없습니다. 다만 외부 도구를 사용하더라도 누가 무엇을 처리하는지는 남겨야 합니다. 아래는 토스페이먼츠 자동결제 API와 Stripe Billing 문서에서 확인한 경계를 바탕으로 한 책임 분담 제안이며 모든 PG의 공통 기능표는 아닙니다.[1][2][3][6][8]
| 담당 | 맡길 수 있는 일 | 서비스 쪽에서 여전히 결정·연결할 일 |
|---|---|---|
| PG·결제 API | 계약한 결제수단의 등록·승인·조회·취소, 제공되는 상태 통지 | 요금제 정책, 청구 시점, 실패 후 이용 허용 여부 |
| 상용 빌링 도구 — 선택 사항 | 지원 범위 내 구독·청구서·요금제 변경·재시도 관리 | 상품 규칙 설정, 기존 시스템과의 연결, 지원하지 않는 예외 |
| 애플리케이션 | 고객·계약 연결, 상품 기능과 이용 기간 관리, 외부 결과 반영 | 이용 권한을 실제 요청에 적용하고 어긋난 상태를 복구하는 일 |
| 사업·운영 담당자 | 요금·유예·변경·종료 정책 승인, 고객 안내, 예외 처리 | 담당자·승인 범위·처리 이력을 유지하고 정책 변경을 검증하는 일 |
상용 도구가 이용 권한 정보를 제공해도 애플리케이션의 접근 통제를 대신 완성하는 것은 아닙니다. Stripe Entitlements 문서도 제품에 연결한 기능 정보를 이벤트나 API로 확인한 뒤 서비스에서 권한을 부여·회수하는 흐름을 설명합니다.[8]
자동화의 실행 담당자는 겹치지 않게 정하는 편이 안전합니다. 자체 스케줄러가 청구하는지 상용 빌링 도구가 청구하는지, 실패한 청구를 어느 쪽이 다시 실행하는지 하나씩 정합니다. 운영자가 수동 처리할 때도 근거 거래와 변경 사유를 남기도록 설계합니다.
이때 ‘재시도’라는 표현도 구분해야 합니다. 웹훅 재전송은 결과 통지를 다시 보내는 일이고 결제 재시도는 돈을 받는 요청을 다시 실행하는 일입니다. 토스페이먼츠 웹훅 가이드의 전송 실패 재처리와 Stripe의 결제 재시도 기능은 서로 다른 책임을 다룹니다.[9][6] 웹훅을 받았다는 사실만으로 미수납 청구를 다시 결제하도록 연결해서는 안 됩니다.
도입 가능 여부 역시 개발과 별개입니다. 토스페이먼츠 자동결제는 공식 안내상 리스크 검토와 추가 계약이 필요합니다.[1] 여기서 소개한 빌링 도구가 특정 국내 PG와 바로 연결된다거나 모든 사업자가 같은 조건으로 사용할 수 있다는 뜻은 아닙니다. 실제 계약 주체, 지원 결제수단·통화, 연동 방식을 확인해야 합니다.
두 서비스의 최소 구축 범위는 다릅니다
다음은 실제 고객 사례가 아닌 설계 예시입니다. 고객 수나 매출이 아니라, 선택한 과금 규칙 때문에 필요한 기능이 어떻게 달라지는지 비교합니다.
| 판단 항목 | A: 요금제 하나인 콘텐츠 멤버십 | B: 좌석·사용량을 과금하는 업무용 SaaS |
|---|---|---|
| 기본 조건 | 월 선결제, 단일 요금제, 사용량 과금·쿠폰 없음 | 회사 단위 계약, 여러 요금제, 좌석 수와 사용량에 따른 금액, 프로모션 |
| 변경 정책 | 가격 변경은 다음 회차부터 적용 | 좌석·요금제별 적용 시점과 차액 정책 필요 |
| 청구에 필요한 근거 | 계약 버전, 이용 기간, 고정 금액 | 계약 버전, 좌석 변경 이력, 사용량 집계 기간·마감 기준, 할인 적용 근거 |
| 실패 처리 | 사유별 안내, 허용된 재시도, 유예 만료와 권한 복원 | 청구 항목 확인, 결제수단 변경, 조직별 허용 범위와 예외 승인 |
| 최소 구현 후보 | 기존 앱 안의 구독·청구 모듈, 결제 API, 스케줄러, 권한 검사, 운영 조회 화면 | 사용량 수집·검증, 청구 계산·미리보기, 변경 이력, 권한 연결, 운영 검토 기능 |
| 도구 선택 | 위 범위를 유지·검증할 수 있다면 별도 빌링 플랫폼 없이 시작 가능 | 상용 빌링 도구와 직접 구현을 비교할 이유가 큼. 미지원 규칙과 연동 비용도 확인 |
A에는 복잡한 프로모션 엔진이나 사용량 집계 시스템이 필요하지 않습니다. 기존 애플리케이션에 작은 모듈로 구현할 수도 있습니다. 그러나 청구 누락을 찾는 방법, 결제수단을 다시 등록하는 경로, 해지 후 다음 갱신을 막는 기능까지 빼도 된다는 뜻은 아닙니다. 환불 빈도가 낮다면 운영자 승인 후 처리하는 방식을 택할 수 있지만 금액·거래·권한의 변경 기록은 남겨야 합니다.
B에서는 ‘사용량’의 정의만으로도 범위가 커집니다. 어떤 이벤트를 언제까지 집계할지, 늦게 들어온 사용량은 어느 청구에 반영할지, 청구 마감 뒤 수정은 누가 승인할지 정해야 합니다. 상용 도구를 쓰는 이유는 이 가운데 반복되는 기능을 맡기기 위해서이지, 사업 정책을 생략하기 위해서가 아닙니다.
직접 구축이 적합한 조건은 규칙이 제한적이고 팀이 청구 작업과 예외를 운영할 수 있는 경우입니다. 외부 지원을 검토할 조건은 계산 자체보다 정책·구현·검증·운영의 담당자가 갈라져 책임이 비는 경우입니다. 어느 쪽을 택하든 도입 범위에 포함할 기능과 남겨 둘 업무를 같은 표에 적어 비교하는 편이 낫습니다.
주문에서 승인과 환불까지 상태를 연결 — 결제수단을 주문 흐름에 붙이고 응답 지연과 재시도, 취소와 환불의 예외를 검증합니다.
인수할 때는 ‘결제 성공 화면’ 다음을 확인합니다
아래는 위 설계에 추가할 인수 시나리오의 예시입니다. 실제 테스트 결과가 아니라 합의한 정책을 검증하기 위한 기대 결과입니다.
| 인수 시나리오 | 확인해야 할 결과 |
|---|---|
| 빌링키 발급은 성공했지만 첫 결제는 실패 | 무료 체험 등 별도 근거가 없는 유료 권한은 열리지 않고, 실패 사유와 다음 행동을 확인할 수 있습니다. |
| PG에서는 결제가 성공했지만 내부 결과 반영은 실패 | 이미 결제된 건을 확인해 청구·권한 반영을 복구하는 경로가 있습니다. 복구가 새 결제나 중복 이용 기간 부여를 만들지 않아야 합니다. |
| 갱신 실패 뒤 유예 기간이 끝나거나 결제가 회복 | 선택한 정책에 맞춰 제한·복원이 이루어집니다. 결제 상태만 바뀌고 권한이 그대로 남는지 확인합니다. |
| 기간 말 해지를 예약 | 다음 회차 갱신은 중단하되 약속한 기존 이용 기간은 유지합니다. 이미 발생한 청구의 처리도 합의한 정책과 일치해야 합니다. |
| 요금제 변경의 추가 결제가 실패 | 새 기능을 바로 열지, 변경을 보류할지 정한 결과와 일치합니다. 청구 조건과 실제 권한이 다른 요금제에 머물지 않아야 합니다. |
| 일시 정지·재개 또는 환불을 처리 | 무엇이 멈추고 다시 시작되는지, 어느 결제를 조정했는지, 구독·권한에 어떤 영향을 주었는지 설명합니다. |
범위가 작은 서비스라면 복잡한 운영 콘솔 대신 제한된 조회·처리 화면으로 시작해도 됩니다. 대신 운영자가 왜 이 고객이 청구 대상이며 왜 지금 서비스를 사용할 수 있는지 근거를 확인할 수 있어야 합니다. 실패 재처리의 구체적인 구현이나 부분 환불 금액 계산은 별도 설계로 내려가더라도, 그 기능의 담당자와 인수 조건은 빠뜨리지 않아야 합니다.
결제정보를 직접 보관하는 범위도 줄입니다
카드 자동결제는 공급자가 제공하는 결제창을 활용하고 서비스에서는 결제수단 참조와 필요한 거래 식별자를 관리하는 방향부터 검토합니다. 토스페이먼츠도 결제창을 통한 빌링키 발급 방식을 제공합니다.[1] 빌링키와 API 인증정보는 일반 고객 식별자처럼 취급하지 말고 접근 권한과 로그 노출을 제한하는 것이 좋습니다.
정기결제에 다시 쓰겠다는 이유로 카드 보안코드인 CVV·CVC를 승인 이후 저장하는 구현은 피해야 합니다. PCI SSC는 카드 보안코드의 승인 후 저장을 암호화 여부나 고객 동의와 무관하게 금지한다고 설명합니다.[10] 결제 처리를 외부에 맡겨도 PCI DSS 관련 책임이 전부 사라지는 것은 아니므로, 실제 연동 구조에 적용되는 범위를 확인해야 합니다.[11]
정기결제의 완성 기준은 다음 달에도 설명 가능한가입니다
단순한 월정액 서비스는 작은 빌링 모듈로 충분할 수 있습니다. 여러 요금제·좌석·사용량·할인이 얽히면 상용 빌링 도구가 더 적합할 수 있습니다. 판단의 출발점은 도구의 기능 수가 아니라 요금제, 청구, 결제, 이용 권한을 일치시키기 위해 우리 서비스에 필요한 책임입니다.
먼저 최소 구축 범위를 정한 뒤, 각 규칙의 적용 시점과 기대 결과는 구독 과금 규칙·검증 시나리오 설계서에 구체화합니다. 정책을 적는 양식과 구축 범위를 결정하는 일은 역할이 다릅니다.
요금제·청구·권한·실패 처리 중 외부에 맡길 범위를 검토하고 있다면 IXC 정기 결제·빌링 서비스의 제공 범위를 함께 검토합니다.


