Zum Hauptinhalt springen

Billing 스키마

개요

Billing 관련 테이블은 두 계층으로 구분됩니다:

계층소유RLS설명
플랫폼 빌링Lumie ↔ 학원없음 (앱 계층 접근 제어)plans, subscriptions, invoices, billing_keys 등
학원 수납학원 ↔ 학부모/학생있음 (tenant_id + RLS)guardians, tuition_invoices, tuition_payments, cash_receipts 등

결제 게이트웨이는 Toss Payments입니다. 직접 수납(direct-Toss tuition payment) 기능은 제거(ff9db43)되었으나 merchant_profiles 테이블은 유지됩니다.

플랫폼 빌링 ERD

플랫폼 빌링 테이블 상세

plans

사전 정의된 구독 플랜 목록입니다. custom_domains 컬럼은 V49에서 제거되었습니다 (모든 플랜에서 커스텀 도메인 지원).

플랜 ID월 가격학생 수OMR/월
FREE0원제한 있음제한 있음
BASIC49,000원제한 있음제한 있음
PRO149,000원제한 있음제한 있음
MAX499,000원제한 있음제한 있음

실제 한도값은 plans 테이블에서 확인하세요. V51에서 ENTERPRISE → MAX 리네임.

billing_keys

Toss 자동결제 토큰 (billingKey)을 저장합니다. 테넌트당 활성 키는 1개만 허용합니다 (partial unique index: status = 'ACTIVE'). pg_billing_key는 PG사 비밀 값이므로 절대 로깅하지 않습니다.

subscriptions

테넌트 구독 상태입니다. 테넌트당 1개(UNIQUE on tenant_id).

  • pending_plan_id + scheduled_change_at: 다운그레이드 예약 지원 (V37)
  • status: ACTIVE / PAUSED / PAST_DUE / CANCELLED / EXPIRED

invoices

Lumie가 학원에 발행하는 구독 청구서입니다. invoice_number는 멱등성 키 역할을 합니다.

alimtalk_credits

카카오 알림톡 크레딧 잔액입니다. balance >= 0 CHECK 제약.

payment_transactions

PG 호출 감사 로그입니다. 불변 테이블로 UPDATE/DELETE를 수행하지 않습니다.

컬럼설명
typeBILLING_CHARGE / TUITION_PAYMENT / REFUND / BILLING_KEY_ISSUE / MERCHANT_REGISTER
directionREQUEST / RESPONSE / WEBHOOK
owner_entityINVOICE / TUITION_INVOICE / BILLING_KEY
pg_payload원본 PG 요청/응답 JSONB

billing_operation_locks

진행 중인 빌링 작업의 테넌트별 뮤텍스입니다 (V38). PK (tenant_id, operation_type)으로 동시 요청을 직렬화합니다. 완료 시 행 삭제, 15분 경과 시 스케줄러가 정리합니다.

tax_invoices

세금계산서 발행 이력입니다. buyer_business_no = 학원 사업자번호.


학원 수납 ERD (테넌트 스코프, RLS 적용)

학원 수납 테이블 상세

guardians / student_guardians

학생의 부모/법정대리인 정보입니다. student_guardians는 학생-보호자 M:N 매핑 테이블로, student_id는 크로스 모듈 경계상 DB FK 없이 소프트 참조합니다.

merchant_profiles

Toss 서브머천트 KYC 레코드입니다. 테넌트당 1개. pg_seller_key는 KYC 승인 후 Toss가 발급합니다. 직접 수납(Direct Toss Tuition) 기능은 제거되었으나 이 테이블은 유지됩니다.

tuition_invoices

학원이 학부모/학생에게 발행하는 수납 청구서입니다. items JSONB는 LineItem {name, quantity, unit_price, amount} 배열입니다.

tuition_payments

수납 청구서에 대한 단일 결제 이벤트입니다. order_id는 Toss orderId 겸 멱등성 키입니다.

cash_receipts

현금영수증 발행 이력입니다. PERSONAL(소득공제) / BUSINESS(지출증빙).

마이그레이션 이력

버전내용
V28플랫폼 빌링 테이블 신설 (plans, billing_keys, subscriptions, invoices, alimtalk_credits, payment_transactions, tax_invoices)
V29학원 수납 테이블 신설 (guardians, student_guardians, merchant_profiles, tuition_invoices, tuition_payments, cash_receipts)
V31billing 누락 컬럼 추가
V32plans.version 추가
V33billing_keys.customer_key 추가
V34plans 시드 데이터
V35FREE 구독 백필
V36billing_keys 카드 메타 nullable
V37subscriptions 예약 변경 컬럼 추가 (pending_plan_id, scheduled_change_at)
V38billing_operation_locks 신설
V49plans.custom_domains 제거 (모든 플랜 커스텀 도메인 지원)
V51ENTERPRISE → MAX 리네임 (plans 시드 데이터 업데이트)