콘텐츠로 이동

결제 시스템

문서 역할

  • 역할: 설명
  • 문서 종류: architecture
  • 충돌 시 우선 문서: 결제 운영 정책
  • 기준 성격: as-is

키 충전 및 인앱결제 관련 아키텍처를 정리한 문서이다.

논리 데이터 모델

  • 도메인 ID: payment

먼저 보는 그림

이 그림은 데이터가 어디에 속하고 무엇을 참고하는지 먼저 보여준다. 정확한 이름과 조건은 아래 상세 표를 따른다.

flowchart LR
    entity_key_dash_wallet_dot_entry["Key 변동 원장 · 다른 영역<br/>key-wallet.entry"]
    entity_member_dot_member["회원 계정 · 다른 영역<br/>member.member"]
    entity_payment_dot_purchase["인앱결제 거래<br/>payment.purchase"]
    entity_payment_dot_purchase -->|"참고"| entity_member_dot_member
    entity_payment_dot_purchase -->|"참고"| entity_key_dash_wallet_dot_entry

꼭 지킬 규칙:

  • 동일 플랫폼 거래 식별자는 한 번만 지급 처리한다
  • 결제 상태와 Key 지급·회수 원장은 같은 transaction 결론을 가져야 한다
  • 영수증·서명·접속정보 원문은 최소 권한으로만 조회한다
  • 활성 생애주기의 일반회원 이상만 인앱결제를 요청할 수 있다
정확한 값과 조건 보기

논리 엔티티

논리 ID 표시명 생명주기 역할 엔티티 형태 기록 역할 책임 최고 데이터 분류 생명주기
payment.purchase 인앱결제 거래 root entity state 플랫폼 거래 식별자, 검증 결과, 결제 금액과 지급 결과 민감 정산·환불·분쟁 대응 기간 동안 거래를 보존하고 환불 처리 시 상태 갱신

관계

출발 논리 ID 관계 역할 관계 유형 도착 논리 ID 카디널리티 소유·삭제 규칙
payment.purchase buyer references member.member N:1 회원 개인정보 정리 뒤에도 비식별 정산 이력은 보존
payment.purchase key-entries references key-wallet.entry 1:N 성공·환불 결과에 해당하는 Key 변동 원장을 연결

불변조건

규칙 ID 관련 논리 ID 불변조건 기준 문서
PAYMENT-INV-001 payment.purchase 동일 플랫폼 거래 식별자는 한 번만 지급 처리한다 결제 운영 정책
PAYMENT-INV-002 payment.purchase 결제 상태와 Key 지급·회수 원장은 같은 transaction 결론을 가져야 한다 결제 운영 정책
PAYMENT-INV-003 payment.purchase 영수증·서명·접속정보 원문은 최소 권한으로만 조회한다 데이터 거버넌스 정책
PAYMENT-INV-004 payment.purchase 활성 생애주기의 일반회원 이상만 인앱결제를 요청할 수 있다 결제 운영 정책

결제 상품 노출

  • 구체적인 SKU·가격·지급량·플랫폼 허용값은 배포 가능한 구현과 Store 등록 상태에서 관리하며 이 문서에 목록을 복제하지 않는다.
  • Mobile은 현재 플랫폼에 비허용으로 표시된 상품을 노출하지 않는다.

결제 플랫폼

플랫폼 API 보너스 적용
Google Play POST /member/purchase/google O
App Store POST /member/purchase/apple O
OneStore POST /member/purchase/onestore X

구매 회원 자격

구매 자격은 결제 운영 정책에 따라 API가 회원 생애주기와 회원 심사 상태 조회 모델의 회원 레벨을 함께 판정한다.

회원 생애주기 회원 레벨 구매
PENDING, NORMAL GENERAL_MEMBER, SEMI_MEMBER, FULL_MEMBER, SPECIAL_MEMBER 허용
PENDING PRE_MEMBER 차단
REJECTED, HOLD, BLOCK, LEAVE 모든 레벨 차단
모든 생애주기 허용 목록 밖 또는 누락 차단

일반회원·준회원은 소개글 승인 전까지 회원 생애주기가 PENDING일 수 있으므로 생애주기 상태만으로 구매 자격을 판정하지 않는다.

결제 처리 흐름

sequenceDiagram
    participant App as Mobile App
    participant API as coupler-api
    participant DB as MySQL

    App->>API: POST /member/purchase/{platform}
    API->>API: 구매 회원 자격 검증
    API->>API: 파라미터 검증
    API->>DB: 중복 거래 확인 (order_id)
    alt 중복
        API-->>App: 기존 키 반환
    else 신규
        API->>DB: t_iap 거래 기록 저장
        API->>DB: t_member.key 증가
        API->>DB: t_member_key_log 로그 저장
        API-->>App: 현재 보유 키 반환
    end

결제 상태

상태 의미
0 PENDING 대기 (결제 미완료)
1 NORMAL 정상 (결제 완료)

키 로그 타입 (KEY_LOG)

타입 의미
NORMAL 0 일반 결제/사용
FREE_KEY 1 관리자 무료키 지급

환불 처리

flowchart LR
    A[관리자: 결제 상태 변경] --> B{현재 상태}
    B -->|NORMAL| C[PENDING으로 변경]
    B -->|PENDING| D[NORMAL로 변경]
    C --> E[지급한 키 회수]
    E --> F[t_member_key_log 회수 기록]
  • API: POST /admin/iap/change_status
  • 회수 시 회원 보유 키보다 많이 회수하지 않음 (최소값 제한)

결제 통계 API

API 응답
GET /admin/iap/sta 오늘/어제/이번주/이번달 결제액/환불액
GET /admin/iap/log 결제 기록 목록 (페이징, 검색)
GET /admin/iap/free-key-log 무료키 지급 내역

현재 문서화된 검증 범위

항목 상태
구매 회원 자격 ✅ 구현됨
거래 중복성 검증 ✅ 구현됨
파라미터 필수 여부 ✅ 구현됨
상품 존재 여부 ✅ 구현됨
영수증 서명 검증 현재 문서 범위 외
플랫폼 검증 서버 연동 현재 문서 범위 외
  • 위 표는 현재 문서에서 확인한 범위만 적는다.
  • 별도 합의되지 않은 검증 항목은 TODO로 두지 않고, 필요성 확정 전까지 정책/구현 범위 밖으로 본다.