구독 기본

금액 조정

할인·설치비 같은 조정 항목을 회차 금액에 그대로 얹어요.

구독 계약에 조정 항목을 추가해 금액을 조정하는 API예요. 설치비, 할인, 추가 요금 같은 항목을 회차에 반영할 때 사용해요. 한 회차만, 여러 회차 범위, 특정 회차부터 끝까지 세 가지 방식으로 걸 수 있어요.

API 엔드포인트

POSThttps://api.bootapi.com/v1/order_subscriptions/:id/adjustmentsBasic Auth (supervisor 권한 필요)

회차를 지정하는 세 가지 방법

방법 보내는 값 결과
한 회차 duration: 5 5회차에만 조정 1건
범위 duration_from: 3, duration_to: 7 3·4·5·6·7회차에 각각 1건씩 (총 5건)
무제한 duration_from: 3, is_unlimited: true 3회차부터 계약이 끝날 때까지 계속 적용 (레코드는 1건​)
무제한은 왜 1건인가요

범위로 걸면 회차 수만큼 조정 레코드가 생겨서, 나중에 빼려면 하나씩 지워야 해요. 무제한은 "3회차 이후 전부"라는 규칙 하나만 저장해두고 청구서를 만들 때마다 적용해요. 그래서 계약이 몇 회차든 레코드는 하나고, 지우면 한 번에 사라져요.

이미 결제가 끝난 회차에는 그 시점 금액이 그대로 남아야 하니, 무제한 조정을 지울 때 결제 완료 회차에는 같은 금액의 개별 조정을 자동으로 만들어둬요.

요청 파라미터

파라미터 타입 필수 설명
id String 필수 구독 계약 ID (URL 경로)
name String 필수 조정 항목명 (예: 설치비, 할인)
price Number 필수 조정 금액. 0은 보낼 수 없어요 (음수는 할인)
tax_free_price Number 선택 면세 금액 (기본 0)
type Number 선택 조정 타입. 생략하면 price > 0이면 2(추가금액), 아니면 1(회차별 할인)로 자동 판정돼요
duration Number 선택 적용 회차 (기본 1). duration_from을 보내면 무시돼요
duration_from Number 선택 범위 시작 회차. 생략하면 duration 값을 써요
duration_to Number 선택 범위 끝 회차. 생략하면 duration_from과 같아요. is_unlimited가 true면 무시돼요
is_unlimited Boolean 선택 true면 duration_from 회차부터 계약이 끝날 때까지 적용해요 (기본 false)

코드 예제

const { BootpayCommerce } = require('@bootpay/backend-js')

const commerce = new BootpayCommerce({
    client_key: '{client_key}',
    secret_key: '{secret_key}'
})

const response = await commerce.orderSubscriptionBill.adjustment.create('687a1b2c3d4e5f6789012345', {
    name: '3개월 할인',
    price: -5000,
    tax_free_price: 0,
    type: 1,
    duration_from: 3,
    duration_to: 7
})
console.log(response)javascript

응답

구독 계약 상세 전체​​를 돌려줘요. 내용 변경 응답과 같은 형태라서 상품·회차·수령인 정보가 모두 들어 있어요. 아래는 조정과 관련된 부분만 추린 예시예요.

{
  "order_subscription_id": "687a1b2c3d4e5f6789012345",
  "price": 45000,
  "order_subscription_adjustments": [
    {
      "order_subscription_adjustment_id": "6965fc104cb8149d07712533",
      "name": "3개월 할인",
      "price": -5000,
      "tax_free_price": 0,
      "type": 1,
      "duration": 3,
      "is_unlimited": false
    }
  ],
  "order_subscription_bills": [
    { "duration": 3, "price": 40000, "status": 1 }
  ]
}json

is_unlimited가 true인 항목은 duration이 시작 회차​​를 뜻해요. 그 회차 이후 모든 청구서에 적용돼요.

조정 타입

값 설명
1 회차별 할인 적용
2 추가금액 (설치비 등)
3 주기 할인 적용
4 추가 비용 적용
5 매회차 추가비용 (모든 할인 적용 후)
10 구독 상품 금액 쿠폰
11 배송비 쿠폰

적용 규칙

조정할 수 있는 회차의 상한이 있어요. 총 회차가 정해진 계약은 그 총 회차까지만 조정할 수 있어요. 계약 밖 회차에 조정을 걸어도 청구서가 만들어지지 않기 때문이에요. 총 회차가 무제한인 계약은 60회차​​까지 걸 수 있어요.

이미 결제가 끝난 회차는 조정할 수 없어요. 그 회차는 청구가 확정된 상태라 금액이 바뀌지 않아요. duration_from을 결제 완료 회차보다 뒤로 잡아주세요.

범위 조정은 전부 되거나 전부 안 돼요. 3~7회차를 요청했는데 6회차에서 최종 금액이 음수가 되면, 3·4·5회차도 저장되지 않고 요청 전체가 거절돼요. 최종 금액은 기준금액 + 배송비 + 그 회차에 적용되는 모든 조정으로 계산하는데, 이때 먼저 걸어둔 무제한 조정도 함께 더해져요​.

이미 생성된 회차에 조정 항목이 추가되면 기존 회차가 삭제 후 재생성될 수 있어요. 결제 예정·결제 실패·지연 대기·재시도 대기·일시정지 상태의 청구서는 금액이 즉시 다시 계산돼요.

에러 코드

공통 에러

인증·권한 관련 에러는 에러 코드표를 참고해요.

코드 메시지 대처 방법
ORDER_SUBSCRIPTION_INVALID 구독결제 건을 찾을 수 없어요. order_subscription_id를 확인해요
ORDER_SUBSCRIPTION_ADJUST_PRICE_INVALID 유효하지 않은 조정 금액이에요. price에 0이 아닌 값을 보내요
SUBSCRIPTION_ADJUSTMENT_DURATION_INVALID 유효하지 않은 회차예요. 1 이상이면서 계약 총 회차(무제한 계약은 60) 이하로 보내요
SUBSCRIPTION_ADJUSTMENT_DUPLICATE 같은 조정 항목이 이미 있어요. 같은 회차에 같은 이름·타입의 조정이 있는지 확인해요
SUBSCRIPTION_ADJUSTMENT_PAYMENT_COMPLETED 이미 결제가 완료된 회차예요. duration_from을 결제 완료 회차 다음으로 잡아요
SUBSCRIPTION_ADJUSTMENT_NEGATIVE_PRICE 결제 금액이 음수가 돼요. 할인 폭을 줄이거나 기존 조정을 먼저 정리해요
SUBSCRIPTION_ADJUSTMENT_NEGATIVE_TAX_FREE 비과세 금액이 음수가 돼요. tax_free_price를 확인해요
SUBSCRIPTION_ADJUSTMENT_TAX_FREE_OVER_PRICE 비과세 금액이 결제 금액을 넘어요. tax_free_price를 결제 금액 이하로 보내요
SUBSCRIPTION_ADJUSTMENT_NOT_FOUND 조정 항목을 찾을 수 없어요. 삭제 시 order_subscription_adjustment_id를 확인해요