시스템 디자인
사례 연구 / 트랜잭션 / Payment System
학습 로드맵

결제 시스템 설계

결제 요청은 재시도되고, PSP 응답은 늦거나 중복되며, 금전 효과는 되돌리기 어렵습니다. 멱등성·승인 상태·이중 기입 원장·조정을 분리해 "한 번만 청구"와 감사 가능성을 함께 지킵니다.

개념 이해면접 답변운영 관점진도 저장
30초 핵심 요약

결제대행사(PSP) timeout은 승인 실패가 아닙니다. 한 Payment Intent 아래 authorization·capture·void·refund를 연결하고, 같은 구매를 다시 승인하지 않습니다. 금전 효과는 이중 기입 원장과 PSP 정산 파일로 끝까지 대사합니다.

일 결제 시도 (설계 가정)200만 건
보류 예시 (계산 결과)0.1% → 2,000건/일
KRW 금액 예시12,900원 → 12900
DESIGN DECISION · 설계 판단

승인 timeout 뒤 capture·refund까지 어떻게 하나의 거래로 닫을 것인가?

예시 일 결제 시도 200만 건 설계 가정
예시 피크 배수 평균의 5배 설계 가정
예시 일 보류 건수 약 2,000건 계산 결과
최종 선택

Payment Intent + authorization/capture 분리 + 이중 기입 조정

멱등 키로 구매를 식별하고 authorization timeout은 보류로 둡니다. 웹훅·조회로 승인 상태를 확정한 뒤 capture·void·refund를 operation과 이중 기입 원장에 추가 기록합니다.

선택 이유

  • 응답이 없다는 이유로 새 승인을 만들어 이중 청구하는 일을 막습니다.
  • 재고 확정 뒤 필요한 금액만 capture하고 미사용 승인은 void할 수 있습니다.
  • 부분 환불과 정산 차이를 원 거래를 덮어쓰지 않고 분개로 추적할 수 있습니다.
포기한 대안

timeout을 실패 처리하고 즉시 새 승인

첫 승인이 PSP에서 성공했을 수 있어 같은 구매가 두 번 청구됩니다. 기존 외부 참조 ID의 결과를 조회·웹훅으로 확인해야 합니다.

감수한 단점

  • 사용자에게 보류 상태와 후속 갱신을 명확히 안내해야 합니다.
  • 승인 만료·미매입·부분 capture·부분 refund 상태 전이가 늘어납니다.
  • PSP 정산 파일과 내부 원장의 차이를 지속적으로 해소할 운영 큐가 필요합니다.
01 · REQUIREMENTS

승인 결과와 금전 효과를 분리한다

# 요구사항

"요청을 받음", "PSP가 승인", "내부 원장 기록", "고객에게 완료 표시"는 같은 시점에 일어나지 않을 수 있습니다. 상태 머신과 감사 경계를 명확히 둡니다.

F1멱등성

같은 주문·작업의 재시도는 첫 payment intent와 응답을 재사용합니다.

F2상태 전이

processing, succeeded, failed, canceled, refunded를 단조 규칙으로 관리합니다.

F3원장 정합

성공 확정은 균형 잡힌 차변·대변 분개를 남깁니다.

F4조정 가능성

외부 명세와 내부 원장의 차이는 별도 운영 큐에서 해결합니다.

02 · HIGH-LEVEL DESIGN

승인, 웹훅, 원장, 조정

# 아키텍처

PSP 응답이 timeout이더라도 신규 승인 요청을 만들지 않습니다. 동일 payment intent의 상태를 조회·웹훅으로 보강하고, 성공 상태만 원장에 반영합니다.

멱등 결제 승인과 비동기 확정 흐름 SVG DIAGRAM · 금액은 정수·상태는 텍스트로 구분
클라이언트, 결제 API, PSP, 웹훅, 원장과 조정 큐의 결제 흐름멱등 키를 가진 결제 요청이 결제 API와 PSP를 거쳐 원장에 기록되고 서명 웹훅과 조정 큐가 비동기 결과와 불일치를 해소하는 흐름이다.ClientIdempotency-KeyPayment APIintent · state machinePSPapprove / timeoutWebhooksigned eventDouble-entry ledger12900 KRW · debit = creditReconcileexception queuetimeout은 failed가 아니라 processing/unknown으로 보관하고 외부 ID로 결과를 확인한다.
03 · PAYMENT FLOW

재시도 전에 결과를 찾는다

# 처리 흐름
1Intent 생성

주문·금액 정수·통화·멱등 키를 검증해 pending intent를 저장합니다.

2PSP 승인

attempt와 외부 참조 ID를 남기고 PSP 요청을 보냅니다.

3비동기 확정

웹훅·조회 결과의 서명과 외부 ID를 검증해 단조 상태 전이를 적용합니다.

4원장·조정

succeeded만 분개하고 차이는 예외 큐에서 근거 기반으로 정정합니다.

04 · TRADEOFFS

단순 응답보다 복구 가능한 상태

# 트레이드오프

결제에서 "빠른 실패"는 실제 청구 결과와 다를 수 있습니다. 보류 상태와 조정 비용을 감수해도 단일 금전 효과를 지키는 것이 우선입니다.

선택
강점
주의점
권장 상황
동기 승인만
사용자 흐름 단순
timeout 결과 불명 취약
외부 의존성 없음
intent + 웹훅
비동기 결과 복구
상태 머신·운영 복잡도
외부 PSP 연동
단일 잔액 컬럼
초기 구현 빠름
정정·감사 근거 부족
비금전 포인트
이중 기입 원장
균형·감사·정정 추적
계정 규칙 필요
결제·정산
05 · FAILURE MODES

모르는 결과를 실패로 단정하지 않는다

# 장애 대응
?timeout 뒤 결과 불명

PSP 응답은 없지만 고객 결제수단이 실제 승인됐을 수 있습니다.

대응 · 새 승인 대신 외부 ID 조회·웹훅 대기로 processing을 해소합니다.
중복 결제 요청

클라이언트·네트워크 재시도가 같은 구매를 반복합니다.

대응 · idempotency key별 최초 intent·응답을 재사용합니다.
웹훅 재전송·역순

늦은 이벤트가 성공 상태를 과거 상태로 바꾸려 합니다.

대응 · 서명·이벤트 ID dedupe와 단조 상태 전이 규칙을 적용합니다.
!원장 불일치

PSP 명세와 내부 분개 합계가 다르면 회계 보고가 틀어집니다.

대응 · 차이 항목 격리 후 반대 분개와 근거를 남겨 조정합니다.
06 · OPERATIONS

보안·관측·조정

# 운영
영역
확인할 것
판단 기준
주의점
결제수단
토큰화·권한 분리
민감 원문 미보관
웹훅도 서명 검증 필요
관측
성공률, PSP 지연, 보류 체류
상태 수량과 원장 금액을 분리
이벤트 수=금전 효과가 아님
조정
PSP 명세 vs 내부 ledger
차이 잔액 0
원 결제를 덮어쓰지 않음
출처
PSP 멱등·웹훅 문서, PCI DSS
검토일 2026-08-29
공급자별 보장은 일반화하지 않음
면접 모드 · 추가 질문05:00
“PSP가 timeout을 반환했는데 고객은 결제 완료 화면을 기다리고 있습니다. 중복 청구 없이 어떤 상태·조회·조정 흐름을 설계하시겠습니까?”
멱등 키 범위보류 상태이중 기입 조정
답변 구조 보기 4단계
  1. 금전 효과를 한 번만 만들기 위한 멱등 키 범위를 정한다.
  2. 승인 timeout을 실패가 아닌 보류 상태로 분리한다.
  3. PSP 웹훅과 조회 결과의 순서·중복을 상태 전이 규칙으로 제한한다.
  4. 원장과 PSP 명세를 조정하는 운영 경로까지 설명한다. 이번 선택: authorization과 capture를 분리하고 timeout은 보류 상태로 수렴시킨다. 깨지는 신호: 보류 체류 시간, 중복 외부 거래 ID, 승인 후 미매입 건, 정산 차이가 증가한다. 다음 검증: 승인 timeout·웹훅 역순·부분 환불을 연속 주입해 PSP 순액과 내부 원장이 같은 9,000원으로 닫히는지 확인한다.
INTERVIEW ↔ PRACTICE · 면접과 실무의 차이

승인 timeout에서 부분 환불·정산까지 한 lifecycle로 닫기

INTERVIEW · 면접

한 구매의 authorization·capture·void·refund를 순서대로 설명합니다.

  • timeout을 processing authorization으로 남기고 새 승인을 막습니다.
  • 재고 확정 뒤 capture하고 미사용 승인은 void합니다.
  • 부분 refund는 원 capture 아래 별도 operation과 반대 분개로 기록합니다.
PRACTICE · 실무

외부 거래 ID와 내부 원장을 lifecycle 전체에서 대사합니다.

  • 승인 후 미매입 건과 보류 체류 시간을 관측합니다.
  • 웹훅 중복·역순에도 단조 상태 전이가 유지되는지 시험합니다.
  • 12,900원 capture 뒤 3,900원 refund가 순액 9,000원으로 닫히는지 확인합니다.
LEARNING ROADMAP다음 시스템 설계 주제 보기
EDITORIAL NOTES

작성·검토·참고 자료

콘텐츠 원칙
이 문서는 독립적으로 재작성한 한국어 학습 자료입니다. 사실과 학습용 설계 가정을 구분합니다.
작성·기술 검수
프로젝트 운영자가 직접 작성·기술 검토했습니다. 주제별 공식·1차 자료와 명시적인 설계 가정을 확인하며, 독립적인 제3자 검수가 아닙니다. 경력 범위와 검수 원칙 보기
최종 검토
예상 학습 시간
24분

참고 자료

  • Stripe API: Idempotent requests — 결제 API 재시도의 멱등성 경계를 검토했다.
  • Stripe Docs: Webhooks — 비동기 이벤트의 서명 검증·재전송 처리 경계를 검토했다.
  • PCI SSC: PCI DSS v4.0.1 — 결제수단 데이터 보관 범위를 최소화해야 하는 보안 원칙을 검토했다.
  • 본 문서의 금액 예시는 최소 통화 단위 정수이며, 규모·비용 수치는 설계 가정 또는 계산 결과이다.
  • 주제 구성 참고: liquidslr/system-design-notes (독립 재집필, 문장·이미지 미사용)

사실 오류·출처 정정은 문의·정정 페이지로 알려 주세요.