UsageMetering — 소비자 사용량 과금
외부 API(음성 합성, 문자 발송, LLM 등) 사용료를 회원 크레딧에서 차감하고, 회원이 자기가 지불한 단가를 직접 확인할 수 있게 하는 플러그인입니다. (ADR-119)
무엇을 해결하나
API를 대신 호출해 주는 서비스는 과금이 두 층입니다.
API 공급자 ─── 우리에게 원가 청구 → 우리가 지불 (도매)
▲
우리 서비스 ─── 회원에게 청구 → 회원이 지불 (소매)
아랫층이 없으면 "이 기능은 100크레딧" 같은 값을 코드에 박아 넣게 되고, 공급자 단가가 바뀌면 조용히 틀린 금액을 청구하게 됩니다.
이 플러그인은 그 값을 계산합니다.
회원 단가 = 공급자 도매단가 × (1 + 마진율 / 100)
운영자가 관리하는 것은 마진율 숫자 하나입니다. 0이면 도매가가 그대로 회원 가격이 됩니다.
운영자 가이드
1. 활성화
플러그인 관리 화면에서 사이트별로 켭니다. 켜지 않으면 아무 것도 동작하지 않습니다.
php artisan migrate # plg_metering_rates / plg_metering_usages
2. 요금표 등록 — 회원 관리 › 사용 요금표
| 항목 | 설명 |
|---|---|
| 상품 코드 | 과금 단위 식별자. 공급자 연동 시 apis.{서비스}.{공급자코드} 규약을 쓰면 매핑이 자동입니다 |
| 출처 | 업스트림(도매단가 × 마진) / 고정(자체 기능 — 단가 직접 입력) |
| 마진율(%) | 여기가 핵심입니다. 0 = 도매가 그대로, 50 = 50% 추가 |
| 단위 | characters / messages / tokens … 회원 화면에 그대로 표시됩니다 |
| 최소 과금 | 아주 짧은 호출도 최소 금액은 받고 싶을 때 |
요금표를 바꿔도 과거 사용 내역의 단가는 바뀌지 않습니다. 각 내역은 그 시점 단가를 스냅샷으로 갖고 있어, 회원이 나중에 봐도 당시 계산이 그대로 맞습니다.
3. 사이트 과금 정책 — 사이트 설정 › 사용 과금
| 설정 | 선택지 | 의미 |
|---|---|---|
| 단위 방식 | 정수 크레딧 (권장) / 통화 소수 | 정수 크레딧은 단가 × 수량 = 금액 검산이 항상 맞습니다 |
| 잔액 부족 시 | 차단(기본) / 여유 허용 | 여유 허용은 작업 시작만 허용합니다 — 실제 차감은 잔액을 넘지 않습니다 |
| 마진 하한 | 숫자 | 실비가 견적보다 커질 때 손해를 막습니다 |
4. 회원이 보는 것
- 호출 직후: 응답에 단가·수량·금액·잔액이 함께 옵니다
- 나중에:
/user/usage에서 과거 내역과 그때 단가를 확인합니다
5. 운영자만 보는 것
회원 관리 › 사용 내역 에서는 회원 화면에 없는 값을 봅니다.
| 값 | 회원 | 운영자 |
|---|---|---|
| 회원 단가·금액 | ✅ | ✅ |
| 공급자 실비 | ❌ | ✅ |
| 마진율·마진액 | ❌ | ✅ |
원가와 마진은 코드 차원에서 회원 화면에 들어갈 수 없게 막혀 있습니다(허용 항목 목록 방식). 실수로 노출되는 경로가 없습니다.
또한 관리자 사용분과 회원 사용분이 분리 집계됩니다. 관리자도 차감 대상이므로, 분리하지 않으면 "얼마가 진짜 매출 원가인지" 알 수 없기 때문입니다.
자주 묻는 것
Q. 예약(홀드)이 잡혔는데 잔액이 그대로입니다. 정상입니다. 예약은 가용 잔액에서만 제외하고 지갑은 건드리지 않습니다. 실제 차감은 사용량이 확정될 때 한 번만 일어납니다. 그래서 되돌리는 거래가 생기지 않습니다.
Q. 상태가 "예약됨"에서 안 넘어갑니다. 일부 공급자는 사용량 보고가 비동기라 확정까지 시간이 걸립니다. 자동 정산 배치가 처리하며, 오래 방치된 예약은 자동으로 해제되어 잔액이 잠기지 않습니다.
php artisan metering:settle-pending # 확정 실비 조회 후 정산
php artisan metering:release-stale # 방치된 예약 해제
Q. 마진율을 0으로 두면 무슨 일이 생기나요? 공급자 단가가 그대로 회원에게 청구됩니다. 재판매 없이 원가 그대로 전달할 때 쓰는 설정입니다.
관련
- Wallet (지갑) — 차감 대상 원장
- WalletAutoRecharge (자동 충전) — 잔액 소진 방지