본문 바로가기
빌링플러스개발자센터
홈 로그인 도입 상담

연동 가이드

수시결제 동의로 결제

회원이 동의한 한도 안에서 필요할 때마다 결제를 요청하는 수시결제 동의 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

응답 200
{
  "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"
}
필드뜻
statusACTIVE(사용중) · 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월 추가 이용분"}
응답 200
{
  "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.statusinvoice_status할 일
APPROVEDPAID결제 완료. 이용권을 지급합니다.
FAILEDVOIDED카드사 거절. 청구서는 자동으로 무효가 되어 미수로 남지 않고 한도도 쓰지 않습니다. failure_reason 으로 회원에게 안내합니다.
UNKNOWNCONFIRMED결제사 응답을 못 받은 미확정입니다. 실패로 처리하지 말고, 다시 요청하지 마세요. 빌링플러스가 확정하면 웹훅(payment.approved / payment.failed)이 가고, GET /api/v1/payments/{id} 로도 확인할 수 있습니다. 확정 전까지 이 금액은 월 한도를 씁니다.

거절 사유 — 422 · 409

아래 경우에는 결제사에 묻지 않고 바로 거절합니다. error.detail.reason 으로 사유를 가릅니다.

detail.reason뜻detail 의 다른 값
LIMIT_ONCE1회 한도를 넘는 금액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요청 값이 비어 있음(멱등키·해지 사유 등)
422 — 월 한도 초과
{
  "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 가 갑니다.

호출 한도는 결제 경로와 같은 낮은 한도를 씁니다 — 레이트리밋