-
Notifications
You must be signed in to change notification settings - Fork 7
서브스크립션 생성 및 청구 금액 정산 설계서
DROP TABLE IF EXISTS organization_billing_rule;
CREATE TABLE organization_billing_rule (
id VARCHAR(36) NOT NULL,
organization_id VARCHAR(36) NOT NULL,
tenant_id VARCHAR(36) NOT NULL,
rule LONGTEXT DEFAULT NULL,
reg_dt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8;
결제 룰의 종류는 다음과 같다.
- billingAlignment : 결제 주기 정렬
- createAlignment : 구독 생성시 계획 단계 정렬(애드온 만 해당)
- cancelPolicy : 구독 중단 시기 규칙
- changePolicy : 구독 변경 시기 규칙
- changeAlignment : 구독 변경시 계획 단계 정렬
이 규칙은 작성 컨텍스트를 사용하고 구독에 사용되는 청구 정렬 유형을 구성한다. 사용 가능한 정렬에는 세 가지 종류가 있다.
-
ACCOUNT : 가입의 청구주기가 계정의 청구주기 날짜와 일렬로 정렬됨을 의미한다. 첫 번째 청구서 주기가 자동으로 ACCOUNT 의 청구주기로 설정된다.
-
SUBSCRIPTION : 이 정렬을 통해 구독 요금 청구주기가 구독 계획의 첫 번째 청구일과 일치하게된다. 따라서 구독이 1 월 3 일에 시작되어 15 일 무료 평가판을 사용하는 경우 첫 번째 청구일은 18일로 설정된다.
-
BUNDLE : 정렬을 번들로 설정하는 것은 추가 기능에 유용하다. 기본주기 계획(BASE) 이 사용하는 것과 일치하도록 청구서주기 날짜를 설정해준다. 룰 설정 api 및 ui 에서는 ADD_ON 에서만 이 정렬 옵션을 사용가능하도록 코딩하도록 한다.
이 규칙은 애드온 구독이 생성될 때 기존 BASE 구독의 phase 와 애드온의 phase 가 정렬되는 방법을 결정한다.
-
START_OF_BUNDLE : BASE 구독이 처음 생성 된 날짜에 애드온의 phase 를 시작한다. 예를 들어 BASE 플랜의 평가 단계에서만 추가 기능(ADD_ON) 평가판을 허용하려는 경우에 유용하다. 애드온 평가판 phase는 BASE 플랜의 평가판 phase와 동일한 기간을 가져야한다. 이 경우 애드온이 언제 시작하던지와 상관없이 BASE 와 동일한 기간에 평가판이 만료된다.
-
START_OF_SUBSCRIPTION - 애드온 가입이 생성되면 애드온 phase가 시작된. 예를 들어 추가 기능이 기본 계획과 독립적으로 발생하는 평가판을 허용하도록하려는 경우에 유용하다.
이 규칙은 구독 취소가 발생할시기를 지정하는 데 사용된다.
-
END_OF_TERM : 결제 기간이 끝나면 취소가 적용됨을 의미한다. 이 경우는 남은 기간에 의해 산정된 크레딧을 생성되는 것을 피하고자하는 상황에서 전형적으로 쓰인다.
-
IMMEDIATE : 취소가 즉시 적용되고 고객이 지불했지만 아직 사용되지 않은 잔액을 크레딧으로 적립하게 된다.
이 규칙은 구독의 플랜 변경이 발생해야하는 시기를 지정한다.
-
END_OF_TERM : 현재 결제 기간이 끝날 때 변경을 수행하도록 지정한다.
-
IMMEDIATE : 요청시 변경이 발생하도록 지정한다.
-
ILLEGAL - 계획 변경이 허용되지 않는다.
이 규칙은 구독의 플랜이 변경 될 때 새 플랜의 phase를 기존 플랜의 phase에 맞추는 방법을 지정한다.
-
START_OF_SUBSCRIPTION : phase 가 구독의 시작일부터 시작된다. 가장 일반적인 정렬이며 대부분의 상황에 적용된다.
-
START_OF_BUNDLE : phase 가 BASE 구독의 시작일부터 시작된다. 이는 애드온에만 의미가 있다.
-
CHANGE_OF_PLAN : phase 가 플랜의 변경 시점에 새로 시작된다.
-
CHANGE_OF_PRICELIST : phase 가 price list 를 마지막으로 변경 한 시점부터 시작한다. uengine billing 초기 버젼은 price list 기능 제공을 하지 않으므로 이 옵션은 사용하지 않도록 한다.
각 결제 룰의 하위요소는 컨디션 프로퍼티와 Action 프로퍼티로 이루어지도록 한다.
-
컨디션 프로퍼티 요소
- productCategory
- BASE
- ADD_ON
- billingPeriod
- DAILY(Period.days(1)),
- WEEKLY(Period.weeks(1)),
- BIWEEKLY(Period.weeks(2)),
- THIRTY_DAYS(Period.days(30)),
- MONTHLY(Period.months(1)),
- QUARTERLY(Period.months(3)),
- BIANNUAL(Period.months(6)),
- ANNUAL(Period.years(1)),
- BIENNIAL(Period.years(2)),
- NO_BILLING_PERIOD(Period.ZERO);
- phaseType
- TRIAL
- DISCOUNT
- FIXEDTERM
- EVERGREEN
- fromProductCategory
- productCategory 동일
- fromBillingPeriod
- billingPeriod 동일
- toProductCategory
- productCategory 동일
- toBillingPeriod
- billingPeriod 동일
- productCategory
-
액션 프로퍼티 요소
- billingAlignment
- ACCOUNT
- BUNDLE
- SUBSCRIPTION
- planAlignmentCreate
- START_OF_BUNDLE
- START_OF_SUBSCRIPTION
- billingActionPolicy
- START_OF_TERM
- END_OF_TERM
- IMMEDIATE
- ILLEGAL
- planAlignmentChange
- START_OF_BUNDLE
- START_OF_SUBSCRIPTION
- CHANGE_OF_PLAN
- billingAlignment
결제 룰은 아래와 같은 json 으로 표현하도록 한다.
아래의 json 표현은 각 결제 룰이 허용하는 프로퍼티만을 표기한 것이다.
{
"billingAlignment": [
{
productCategory : ""
billingPeriod: ""
phaseType: ""
billingAlignment: ""
}
]
//ADD_ON 만 해당
"createAlignment": [
{
planAlignmentCreate: ""
}
],
"cancelPolicy": [
{
productCategory : "",
billingPeriod: ""
phaseType: ""
billingActionPolicy: ""
}
],
"changePolicy" : [
{
phaseType: ""
fromProductCategory: ""
fromBillingPeriod: ""
toProductCategory: ""
toBillingPeriod: ""
billingActionPolicy: ""
}
],
"changeAlignment" : [
{
phaseType: ""
fromProductCategory: ""
fromBillingPeriod: ""
toProductCategory: ""
toBillingPeriod: ""
planAlignmentChange: ""
}
]
}
각 프로퍼티의 enum 값과 그 의미를 다음의 기술코드로 이해하도록 한다.
package org.killbill.billing.catalog.api;
public enum ProductCategory {
BASE,
ADD_ON,
STANDALONE
}
package org.killbill.billing.catalog.api;
import org.joda.time.Period;
/**
* The {@code BillingPeriod} supported in the system
*/
public enum BillingPeriod {
DAILY(Period.days(1)),
WEEKLY(Period.weeks(1)),
BIWEEKLY(Period.weeks(2)),
THIRTY_DAYS(Period.days(30)),
MONTHLY(Period.months(1)),
QUARTERLY(Period.months(3)),
BIANNUAL(Period.months(6)),
ANNUAL(Period.years(1)),
BIENNIAL(Period.years(2)),
NO_BILLING_PERIOD(Period.ZERO);
private final Period period;
BillingPeriod(final Period period) {
this.period = period;
}
public Period getPeriod() {
return period;
}
}
package org.killbill.billing.catalog.api;
public enum PhaseType {
TRIAL,
DISCOUNT,
FIXEDTERM,
EVERGREEN
}
public enum BillingAlignment {
/**
* All {@code Subscription}s whose {@code Plan} has been configured with this alignment will
* be invoiced using the {@code Account} billCycleDay.
*/
ACCOUNT,
/**
* All {@code Subscription}s whose {@code Plan} has been configured with this alignment will
* be invoiced using the startDate of the first billable {@code PlanPhase} for the {@code ProductCategory.BASE}
* {@code Plan}.
*/
BUNDLE,
/**
* All {@code Subscription}s whose {@code Plan} has been configured with this alignment will
* be invoiced using the startDate of the first billable {@code PlanPhase} for the
* {@code Subscription}.
*/
SUBSCRIPTION
}
package org.killbill.billing.catalog.api;
// TODO private?
/**
* The available alignments for the subscription system
*/
public enum PlanAlignmentCreate {
START_OF_BUNDLE,
START_OF_SUBSCRIPTION,
}
package org.killbill.billing.catalog.api;
/**
* Specifies how {@code Subscription} cancellation or plan change should operate
* <p/>
*/
public enum BillingActionPolicy {
/**
* The cancellation or {@code Plan} change effectiveDate will occur at the start of the current invoiced service
* period and that will trigger a full credit.
*/
START_OF_TERM,
/**
* The cancellation or {@code Plan} change effectiveDate will occur at the end of the current invoiced service
* period, and that will not trigger any proration and credit.
*/
END_OF_TERM,
/**
* The cancellation or {@code Plan} change effectiveDate will occur at the requestedDate
*/
IMMEDIATE,
ILLEGAL
}
package org.killbill.billing.catalog.api;
public enum PlanAlignmentChange {
START_OF_BUNDLE,
START_OF_SUBSCRIPTION,
CHANGE_OF_PLAN,
CHANGE_OF_PRICELIST
}
도메인 | METHOD | URI | 설명 |
---|---|---|---|
bundle | GET | /1.0/kb/bundles | external key 로 번들을 가져온다. |
GET | /1.0/kb/bundles/pagination | 번들을 페이지네이션으로 가져온다 | |
GET | /1.0/kb/bundles/search/{searchKey} | 주어진 검색어에 해당하는 번들을 페이지네이션으로 가져온다. | |
GET | /1.0/kb/bundles/{bundleId} | 번들 한건을 가져온다. | |
PUT | /1.0/kb/bundles/{bundleId} | 번들을 다른 계정으로 이동시킨다. | |
PUT | /1.0/kb/bundles/{bundleId}/block | 번들을 블락 처리한다. | |
GET | /1.0/kb/bundles/{bundleId}/customFields | 번들의 커스텀 필드를 가져온다. | |
POST | /1.0/kb/bundles/{bundleId}/customFields | 번들의 커스텀 필드를 추가한다. | |
DELETE | /1.0/kb/bundles/{bundleId}/customFields | 번들의 커스텀 필드를 삭제한다. | |
PUT | /1.0/kb/bundles/{bundleId}/pause | 번들을 일시정지한다. | |
PUT | /1.0/kb/bundles/{bundleId}/resume | 번들의 일시정지를 해제한다. | |
GET | /1.0/kb/bundles/{bundleId}/tags | 번들의 태그를 가져온다. | |
POST | /1.0/kb/bundles/{bundleId}/tags | 번들의 태그를 생성한다. | |
DELETE | /1.0/kb/bundles/{bundleId}/tags | 번들의 태그를 삭제한다. | |
subscription | POST | /1.0/kb/subscriptions | 구독을 추가한다. |
POST | /1.0/kb/subscriptions/createEntitlementWithAddOns | 구독을 애드온과 함께 추가한다. | |
POST | /1.0/kb/subscriptions/createEntitlementsWithAddOns | 다수의 구독을 애드온과 함께 추가한다. | |
GET | /1.0/kb/subscriptions/{subscriptionId} | 구독 한건을 가져온다. | |
PUT | /1.0/kb/subscriptions/{subscriptionId} | 구독 한건을 다른 플랜으로 변경한다. | |
DELETE | /1.0/kb/subscriptions/{subscriptionId} | 구독 한건을 정지시킨다. | |
PUT | /1.0/kb/subscriptions/{subscriptionId}/bcd | 구독의 결제일을 변경시킨다. | |
PUT | /1.0/kb/subscriptions/{subscriptionId}/block | 구독을 블락처리한다. | |
GET | /1.0/kb/subscriptions/{subscriptionId}/customFields | 구독의 커스텀 필드를 가져온다. | |
POST | /1.0/kb/subscriptions/{subscriptionId}/customFields | 구독의 커스텀 필드를 추가한다. | |
DELETE | /1.0/kb/subscriptions/{subscriptionId}/customFields | 구독의 커스텀 필드를 삭제한다. | |
GET | /1.0/kb/subscriptions/{subscriptionId}/tags | 구독의 태그를 가져온다. | |
POST | /1.0/kb/subscriptions/{subscriptionId}/tags | 구독의 태그를 추가한다. | |
DELETE | /1.0/kb/subscriptions/{subscriptionId}/tags | 구독의 태그를 삭제한다. | |
PUT | /1.0/kb/subscriptions/{subscriptionId}/uncancel | 구독의 정지를 해제한다. |