연동 가이드
수시결제 동의로 결제
회원이 동의한 한도 안에서 필요할 때마다 결제를 요청하는 수시결제 동의 API.
수시결제 동의는 회원이 "필요할 때마다 이 카드로 결제해도 된다" 고 미리 동의해 둔 것입니다. 동의할 때 회원은 한 번에 최대 얼마, 한 달에 최대 얼마를 보고 동의하며, 가맹점은 그 한도 안에서 원하는 때에 금액을 정해 결제를 요청합니다. 이용량만큼 받는 요금, 추가 구매처럼 금액과 시점이 정해지지 않은 결제에 씁니다.
| 정기결제 계약 | 수시결제 동의 | |
|---|---|---|
| 금액·시점 | 계약 금액을 청구일에 | 그때그때 · 가맹점이 요청할 때 |
| 결제 실행 | 빌링플러스가 자동으로 | 가맹점이 API(또는 화면)로 요청 |
| 실패하면 | 미납으로 남고 재청구 | 즉시 거절 응답, 청구서는 자동 무효(미납으로 남지 않음) |
| 상한 | 계약 금액 | 1회 한도 · 월 한도(필수) |
동의 받기
API 로 동의를 만드는 경로는 없습니다. 회원 본인의 동의 없이 동의가 생기면 안 되기 때문입니다. 아래 경로에서 회원이 직접 동의합니다.
- 등록창 —
billing_mode: "ON_DEMAND"와limit_once·limit_month를 보내 창을 엽니다. - 가입 링크 — 링크를 수시결제 방식으로 만듭니다.
- 빌링플러스 화면 — 담당자가 보내는 등록 링크, 또는 담당자 대행 등록.
동의가 만들어지면 웹훅 charge_consent.created 가 가고, 본문의 charge_consent.id 가 결제를 요청할 때 쓰는 번호입니다. 등록창이라면 창 조회의 charge_consent_id 로도 받습니다.
한 회원이 동의를 여러 건 가질 수 있지만, 같은 카드 + 같은 품목명의 동의는 하나만 둡니다(한도가 두 배가 되지 않게). 한도를 바꾸려면 해지하고 새로 받습니다.
동의 조회
GET /api/v1/charge-consents/{id} · 목록 GET /api/v1/charge-consents?customer_id=1024&status=ACTIVE
{
"id": 77,
"consent_no": "Q26100001",
"customer_id": 1024,
"customer_code": "M-0001",
"status": "ACTIVE",
"item_name": "이용 요금",
"limit_once": 50000,
"limit_month": 200000,
"month_used": 35000,
"month_remaining": 165000,
"charge_max": 50000,
"payment_method_id": 501,
"card_masked": "123456******3456",
"source": "WINDOW",
"agreed_at": "2026-10-06T14:05:00+09:00",
"revoked_at": null,
"created_at": "2026-10-06T14:05:00+09:00"
}| 필드 | 뜻 |
|---|---|
status | ACTIVE(사용중) · REVOKED(해지) |
month_used | 이번 달(한국 시각) 이 동의로 청구한 합계. 결과를 기다리는 결제와 미수도 포함하고, 거절되어 무효가 된 청구는 빠집니다. |
month_remaining | 이번 달 남은 한도 |
charge_max | 지금 한 번에 요청할 수 있는 최대 금액 = 1회 한도와 남은 월 한도 중 작은 값. 해지된 동의는 0 |
source | 동의 경로 — STAFF(담당자 대행) · INVITE(등록 링크) · WINDOW(등록창) · SIGNUP(가입 링크) |
결제 요청 — POST /api/v1/charge-consents/{id}/charges
청구서(수시결제) 발행 · 확정 · 카드 승인을 한 번에 합니다. Idempotency-Key 가 필수이며, 같은 키로 다시 부르면 다시 결제하지 않고 처음 결과를 돌려줍니다.
| 필드 | 필수 | 설명 |
|---|---|---|
amount | 필수 | 결제 금액(원, 부가세 포함 총액). 1원 이상, 1억 원 이하 정수 |
item_name | 이번 결제의 품목명. 비우면 동의의 품목명 | |
memo | 청구서 항목 메모(200자) |
POST /api/v1/charge-consents/77/charges
Idempotency-Key: order-20261028-0042-7c1e
{"amount": 12000, "item_name": "10월 추가 이용분"}{
"invoice_id": 5531,
"invoice_no": "I-2026-1028-0042",
"invoice_status": "PAID",
"payment": {
"id": 8820,
"payment_no": "P-2026-1028-0015",
"status": "APPROVED",
"amount": 12000,
"channel": "API",
"card_masked": "123456******3456",
"failure_reason": "",
"approved_at": "2026-10-28T15:02:11+09:00",
"...": "결제 객체의 나머지 필드"
}
}결과 처리
| payment.status | invoice_status | 할 일 |
|---|---|---|
APPROVED | PAID | 결제 완료. 이용권을 지급합니다. |
FAILED | VOIDED | 카드사 거절. 청구서는 자동으로 무효가 되어 미수로 남지 않고 한도도 쓰지 않습니다. failure_reason 으로 회원에게 안내합니다. |
UNKNOWN | CONFIRMED | 결제사 응답을 못 받은 미확정입니다. 실패로 처리하지 말고, 다시 요청하지 마세요. 빌링플러스가 확정하면 웹훅(payment.approved / payment.failed)이 가고, GET /api/v1/payments/{id} 로도 확인할 수 있습니다. 확정 전까지 이 금액은 월 한도를 씁니다. |
거절 사유 — 422 · 409
아래 경우에는 결제사에 묻지 않고 바로 거절합니다. error.detail.reason 으로 사유를 가릅니다.
| detail.reason | 뜻 | detail 의 다른 값 |
|---|---|---|
LIMIT_ONCE | 1회 한도를 넘는 금액 | limit_once · amount |
LIMIT_MONTH | 이번 달 한도를 넘음 | limit_month · month_used · month_remaining · amount |
CONSENT_REVOKED | 해지된 동의. 회원에게 동의를 다시 받아야 합니다 | |
CUSTOMER | 해지·휴면 회원 | |
CARD_UNAVAILABLE | 동의에 등록된 카드를 쓸 수 없음. 카드를 다시 등록받고 동의를 새로 받아야 합니다 | |
INVALID_AMOUNT | 금액이 숫자가 아니거나 1원 미만·1억 원 초과 | |
KEY_REUSED | 그 멱등키가 이미 다른 동의의 결제에 쓰였음 | |
INVALID_REQUEST | 요청 값이 비어 있음(멱등키·해지 사유 등) |
{
"error": {
"code": "UNPROCESSABLE",
"message": "이번 달 한도(200,000원)를 넘습니다. 남은 한도 15,000원.",
"detail": {"reason": "LIMIT_MONTH", "limit_month": 200000, "month_used": 185000,
"month_remaining": 15000, "amount": 30000},
"request_id": "req_1a2b3c4d5e6f7a8b9c0d1e2f"
}
}같은 동의로 다른 결제가 처리 중이면 409 REQUEST_IN_PROGRESS + Retry-After: 5 입니다. 기다렸다가 같은 멱등키로 다시 보내세요. 한 동의의 결제는 한 번에 하나씩 처리됩니다.
동의 해지 — POST /api/v1/charge-consents/{id}/revoke
{"reason": "회원 요청으로 해지"}- 사유(
reason, 2자 이상)는 필수입니다. 이미 해지된 동의를 다시 해지하면 그대로 해지 상태를 돌려줍니다. 해지한 동의는 되살리지 않습니다 — 다시 결제하려면 회원에게 동의를 새로 받습니다. - 이미 걷은 결제는 그대로입니다. 환불은
POST /api/v1/payments/{id}/cancel(전체취소)로 따로 합니다. - 카드는 내리지 않습니다. 같은 카드를 쓰는 다른 계약이 있을 수 있기 때문입니다.
- 해지되면 웹훅
charge_consent.revoked가 갑니다.
호출 한도는 결제 경로와 같은 낮은 한도를 씁니다 — 레이트리밋
개발자센터