충전금 모델

Book Print API의 충전금 결제 모델을 안내합니다. 환경 분리, 차감·환불 규칙, 거래 사유 코드, 잔액 부족 처리 등 충전금 도메인의 핵심 개념을 다룹니다.

엔드포인트 호출 방법은 Credits API를, 운영 절차(충전·모니터링·402 처리 패턴)는 충전금 운영 절차를 참고하세요.

모델 개요

SweetBook은 선불 충전금 방식으로 도서 제작 비용을 결제합니다. 파트너 포털에서 충전금을 선충전(Sandbox는 API 충전도 가능)한 뒤, 주문 생성 시 충전금이 자동으로 차감됩니다. 주문 취소 시에는 차감된 금액이 즉시 환불됩니다.

  • 차감 시점: 주문 생성(POST /orders) 직후 즉시
  • 환불 시점: 주문 취소 직후 즉시 (전체 취소 POST /orders/{orderUid}/cancel · 부분 취소 POST /orders/{orderUid}/items/{itemUid}/cancel 둘 다 해당). 자세한 동작은 Orders API 참고
  • 통화: KRW (원). currency 필드는 항상 "KRW"
  • 환경 분리: Sandbox와 Live 충전금은 독립된 잔액으로 관리됩니다 (아래 환경 분리 섹션 참조)

환경 분리

Sandbox 환경과 Live 환경의 충전금은 완전히 분리되어 있습니다. 잔액이 어느 환경의 것인지는 사용한 API Key에 의해 자동 결정되며, GET /credits 응답 본문의 env 필드("test" 또는 "live")로 식별할 수 있습니다.

환경env충전 방법차감/환불 동작
Sandbox"test"파트너 포털에서 직접 입력 (가상 충전금)실제 비용 발생 없음. 테스트용 차감/환불
Live"live"파트너 포털 PG 결제실제 결제·환불 처리
Sandbox 잔액과 Live 잔액은 서로 영향을 주지 않습니다. Sandbox에서 사용한 충전금이 Live 잔액을 차감하거나, 그 반대 경우도 발생하지 않습니다.

차감·환불 규칙

차감 공식

주문 생성 시 차감되는 충전금(paidCreditAmount)은 다음 규칙으로 계산됩니다.

  1. 주문 총액 계산: totalAmount = productAmount + shippingFee + packagingFee
  2. 주문 총액에 부가세 10%를 가산: totalAmount × 1.1
  3. 10원 단위로 절삭(10원 미만은 버림): 최종 paidCreditAmount

예시(Sandbox 실 응답): productAmount 200원 + shippingFee 3,000원 + packagingFee 0원 = totalAmount 3,200원. 부가세 10% 가산 후 3,520원 → 10원 단위 절삭으로 paidCreditAmount 3,520원이 차감됩니다 (이 케이스는 결과가 이미 10의 배수라 절삭이 적용되지 않음).productAmount·shippingFee·packagingFee·totalAmount·paidCreditAmount 모두 POST /orders·POST /orders/estimate 응답에 포함됩니다.

환불 규칙

주문 취소 시 차감된 충전금이 즉시 환불됩니다. 환불 가능 여부는 주문 상태에 따라 결정됩니다.

주문 상태파트너 취소 가능환불 동작
PAIDO전액 환불 (즉시)
PDF_READYO전액 환불 (즉시)
CONFIRMED 이후X파트너가 직접 취소 불가 (제작 확정 이후 단계 — 부분 취소도 동일 조건)

전체 취소 외에 주문 항목별 부분 취소도 지원됩니다. 환불액은 남은 항목 기준으로 재계산한 차액이며(포장비·배송비·부가세 재배분 포함), 단순 항목 차감액과 다를 수 있습니다. 상세 동작과 응답 예시는 Orders API의 부분 취소 섹션을 참고하세요.

차감 공식
paidCreditAmount = floor((productAmount + shippingFee + packagingFee) × 1.1 / 10) × 10

거래 사유 코드 (reasonCode)

GET /credits/transactions 응답의 각 거래 항목에는 reasonCode(거래 사유 코드)와 reasonDisplay(한글 사유)가 포함됩니다.reasonCode는 거래 발생 시점·종류를 식별할 때 사용하고, reasonDisplay는 사용자 표시용 한글 라벨입니다.

코드의미발생 시점방향
1CREDIT_RECHARGE결제 완료 후 충전 (Live PG 결제)+
3ORDER_PAYMENT주문 생성 시 결제 차감-
4ORDER_REFUND주문 환불 (일반)+
7ORDER_CANCEL_REFUND파트너 전체 취소 환불+
8ADMIN_CANCEL_REFUND관리자 전체 취소 환불+
9SANDBOX_CHARGESandbox 테스트 충전 (POST /credits/sandbox/charge)+
10SANDBOX_DEDUCTSandbox 테스트 차감 (POST /credits/sandbox/deduct)-
11ORDER_RESTORE_DEDUCT주문 복원 시 재차감-
13ORDER_MODIFY_REFUND주문 항목 부분 취소 환불+

클라이언트가 사용자에게 거래 사유를 표시할 때는 reasonDisplay 한글 라벨을 그대로 사용하는 것을 권장합니다. reasonCode는 거래 분류·필터링 용도로 사용하세요.

잔액 부족 (402 Payment Required)

충전금 잔액이 차감 예정 금액(paidCreditAmount)보다 적은 상태에서 주문을 생성하면 402 Payment Required 응답이 반환되며, 주문은 생성되지 않습니다.

발생 조건

  • balance(현재 잔액) < required(필요 금액 = 차감 예정 paidCreditAmount)
  • errorCode: ERR_INSUFFICIENT_CREDIT

응답 본문

data 객체에 진단 정보가 포함되어, 클라이언트가 부족 금액을 계산해 사용자에게 안내할 수 있습니다.

  • required: 결제에 필요한 금액 (원)
  • balance: 현재 잔액 (원)
  • currency: 통화 (항상 "KRW")

잔액 부족 시 클라이언트 측 처리 패턴(사전 잔액 확인 + 충전 안내 + 재시도)은 충전금 운영 절차402 에러 처리 패턴 섹션을 참고하세요. errorCode 분기와 공통 에러 응답 구조는 에러 코드 & 트러블슈팅을 참고하세요.

402 응답 예시
{
  "success": false,
  "errorCode": "ERR_INSUFFICIENT_CREDIT",
  "message": "Insufficient Credit",
  "data": {
    "required": 14300,
    "balance": 3220.00,
    "currency": "KRW"
  },
  "errors": ["잔액이 부족합니다. 필요: 14300, 잔액: 3220.00"],
  "fieldErrors": []
}