This is the reference guide to get started with Kill Bill Subscription Billing.
Kill Bill, as a system, is composed of several components:
The core billing platform itself, which is embedded in a web server and offers a REST api. When we refer to Kill Bill in the documentation, this is what we are referring to, unless explicitly specified
KAUI, the Kill Bill Admin UI, which is a Rails mountable engine, and communicates with the core billing platform using the REST api
A set of client libraries (Java, Ruby, PHP, Node.js, …)
Let’s consider some common web-based use cases for Kill Bill. Each of these cases combines Kill Bill with custom code to implement the specific business logic required. Kill Bill solves the billing problem but not the custom flow required around the billing platform. This must be handled by the custom code, which should support the following functions:
Offer a way for customers to select a plan from the Kill Bill catalog, which would result in the creation of a subscription
Offer a form for customers to enter their payment information, using a credit card or any other payment method. The flow will differ depending on the payment gateway and PCI compliance needs
Offer a way for customers to review and change their subscriptions
Offer a way for customers to review and change their payment methods
The first option is to create a custom web app, containing the application-specific business logic, that interacts with Kill Bill using the REST API.
The second option is to embed the application-specific code inside Kill Bill. In this case no separate app is required.
The final option would be to create a custom web app and embed Kill Bill into it. Kill Bill offers a set of Java APIs below the REST API, so it is possible to use Kill Bill as a billing library.
Before beginning this guide, you should perform the following preliminary steps:
Review the Getting started tutorial.
Using the tutorial, get MySQL, Kill Bill and Kaui set up and running in Docker containers.
Set up a tenant configured with API key
boband API secret
Ensure that you have cURL installed. This is only to be able to run the setup steps and examples from this documentation. In practice, your application will use one of our client libraries. If you are on Windows, we recommend that you use Git Bash to run the
The catalog is the central configuration object of Kill Bill for all of your Business rules. It contains what the customer buys (products), how the customer pays for a product (plans), change rules, prices, etc.
Please refer to the Catalog Configuration documentation to make Kill Bill use your own catalog.
The catalog is one of the most complex yet powerful tools provided by Kill Bill.
If you want to validate your catalog, you can use the catalog load-tool (where x.y.z is your current Kill Bill version):
# Download the tool from maven central: curl -L -O 'http://search.maven.org/remotecontent?filepath=org/kill-bill/billing/killbill-catalog/x.y.z/killbill-catalog-x.y.z-load-tool.jar' # Run the command java -jar killbill-catalog-*-load-tool.jar /path/to/catalog.xml
If you see "Success: Catalog loads!", the catalog is valid.
Also, if you need an xsd file, you can find one here or generate one using the catalog xsd-tool:
# Download the tool from maven central: curl -L -O 'http://search.maven.org/remotecontent?filepath=org/kill-bill/billing/killbill-catalog/x.y.z/killbill-catalog-x.y.z-xsd-tool.jar' # Run the command java -jar killbill-catalog-*-xsd-tool.jar schema.xsd
The Catalog is a data model that captures the core configuration of the billing system. This model is at the heart of the billing system. It is very important that all the business logic associated with the billing behaviour of your system is captured in the billing system. If your billing system is not capable of capturing all of the business logic it ends up being put in multiple places such as your purchase flow, Admin UI, human process etc. It becomes very difficult to keep all these places consistent, and very difficult to make changes when they are needed.
Kill Bill provides a very powerful catalog that, unlike other billing systems, allows the administrator to set up sophisticated business rules around cancellation and plan changes. For example, Kill Bill can just be told to “Cancel” a plan and it will know when to perform the cancel, based on things like the type of plan, or whether it is in trial.
The things you can configure with the Kill Bill catalog include:
Trials and discount phases - plans can be configured with trial and discount phases so that they move automatically between different pricing schemes
Cancellation - business rules to determine when a cancellation should happen.
Plan Change - business rules to determine when to apply upgrades and downgrades.
Which add-ons are available with which product types, so that when the customer upgrades or downgrades, add-ons that are not available are automatically cancelled
Billing Alignment - rules to determine if a Plan should be billed independently or on the account billing date.
Catalog change - ways to specify how and when catalog changes apply to new and existing subscriptions
Kill Bill also supports the concept of a Price List, which is a grouping of (usually discounted) plans that can be offered to a customer.
Of course, any catalog can only support a limited number of options. When you need to go further, and many people do, you can write plugins to implement pretty much anything you need.
In this section we outline some key pieces of terminology that you will need to understand. A complete Glossary is given at the end of this document. Different billing systems use these same words to mean subtly different things so, even if you are familiar with the language, it is worth looking through exactly how we use the terms in Kill Bill.
Customer – someone who buys your product
Administrator (or Admin) – the person who can use the Kill Bill UI to view and modify customer accounts
Kill Bill Administrator (or Kill Bill Admin) - the person responsible for installing or configuring Kill Bill
Account – a customer account. It represents what Kill Bill knows about a customer.
Subscription – a contract between you and a customer to purchase a particular product with particular terms. In the system it associates a Plan (see below) with an Account and a start date.
Subscription Bundle (or just Bundle) – a collection of subscriptions that are associated with a particular instance of a product. For example, you might have a voice plan, a data plan and a text plan for your mobile phone. In Kill Bill each plan would have its own subscription and we would represent the fact that they are associated with a single phone by grouping them in a Subscription Bundle. Of course an account might have multiple phones associated with it and a Kill Bill Account can have multiple Bundles associated with it.
What’s in a Catalog?
A Kill Bill Catalog includes the following sections:
Products - The things that the customer actually buys (or rents). In the example depicted at the start of the chapter, the product available for rent is a Spy Car, which is available in three different versions:
Plans - Specifications for the terms of the Subscription contract. In particular, plans define how much a customer pays for a product, and how often they pay it. For example, we could offer the Standard Spy Car product at $100 per month.
Plan Phases (or just Phases) - Time periods within a subscription during which certain rules apply. Kill Bill plans can have multiple phases and each phase can have a different price and payment term. In this way, we can have plans with built in trials or discount phases. Kill Bill automatically handles the transitions between phases. In our example above the plans have two phases: they start with a 30 day trial which is free, and then move to a recurring phase at $100 per month.
Price List - A collection of plans. Price Lists are normally used to group discount plans that are associated with a particular customer group. For example, MI6 might have special rental terms for their Spy Cars with the CIA. In this case they would create a CIA Price List that grouped plans with those special terms together. When CIA agents would come to the rental site, they would see plans from that price list. More importantly, if they change plans (for example, if they upgrade from Sports to Super to meet the needs of a particularly difficult mission), they will upgrade to the Sports plan within the CIA Price List.
Billing Period - The period for which the customer is billed (e.g
Rules - The rules that determine how Kill Bill should behave when a plan is created, cancelled or changed.
How is the Catalog Used Inside Kill Bill?
Kill Bill first uses the catalog when the user creates a subscription, then subsequently if there is a change of
Plan (upgrade or downgrade), and then finally when the user cancels the subscription. During such operations, catalog information is retrieved to make sure the system builds the right subscription (e.g. maybe there is a
TRIAL phase to start). Information about how to perform such operations is configured in the catalog through the Subscription Alignment Rules. Examples of these rules include:
Plan Cancellation Timing - Should the customer get a pro-ration credit when the subscription is cancelled before its next renewal date?
Plan Change Timing - Should a customer downgrading to a lower (paid) plan be active immediately or should the system wait for the next renewal date?
The catalog is also used by the invoicing system to make sure each customer is billed at the right time and for the right amount. Information about how the customer is billed and when the customer is billed is also defined in the catalog using alignments and their associated rules.
Catalog configuration allows the Kill Bill Administrator to define whether all subscriptions attached to a customer should be invoiced at the same time, or if they should be billed separately on their own schedule. There could also be a mix of both where some are grouped together on the same invoice and others are invoiced independently. In the simplest case, the customer gets one invoice per billing period. Note that grouping subscriptions together may by default lead to some proration for a new subscription, to align it with the billing period. For further discussion of this topic see Billing Alignment Rules.
Creating the Catalog
Most Kill Bill catalogs have the form of XML documents. Complex catalogs may need to be created by Java programs using a custom plugin (see Developing a Catalog Plugin), while simple catalogs can be generated directly by the Kaui interface (see the Kaui Catalog Interface). This section describes how to create a catalog configured to your particular needs. For this discussion we assume the catalog is an XML document.
The XML document starts in a standard way. The main tag is
<catalog>. Within the
catalog tag you should specify the schema location.
You can use the standard schema location, as shown in the example. This schema can be found at XSD schema.
In most cases this schema will meet your needs. If not you can have the code generate the current schema by executing the tool killbill-catalog-x.y.z-xsd-tool.jar, where
x.y.z is replaced by the appropriate version of Kill Bill. The tool for version
0.22.0 can be found here. After downloading this tool, the schema can be generated by the following command:
java -jar killbill-catalog-x.y.z-xsd-tool.jar <output_filename>
The order of content information in the catalog is important. The first tag should be the “effectiveDate” (when the catalog becomes effective), then “catalogName” and then “currencies”, as shown below. Further, the catalog requires all attribute strings to be unique, and those strings cannot contain spaces.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://docs.killbill.io/latest/catalog.xsd"> <effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate> <catalogName>SpyCarBasic</catalogName> <currencies> <currency>USD</currency> <currency>GBP</currency> </currencies> ... </catalog>
We have now described the heading information for the catalog. The following discussions explain in depth the catalog sections that correspond to the concepts described above.
The Product is a representation of the thing the customer is actually buying. Specifying a Product is very straightforward. The product is described by the following parameters:
Name - a string that is used to refer to the Product elsewhere in the catalog. For example "Super".
Category - a descriptor that determines how Kill Bill allows the combining of this product with others within a bundle. The options are BASE, ADD_ON and STANDALONE. These options are explained below.
Inclusion/Exclusion lists (optional) - Lists that determine which addons can be purchased with a given base plan.
Plans specify the terms of a subscription contract. Each Plan has a name and refers to the purchase of a single product. The details of a Plan are arranged by phase. In the illustration (right) we are showing a Plan with a 30 day Trial followed by an unlimited recurring or "evergreen" phase.
For each phase of the Plan we need to specify:
Phase Type - can be one of TRIAL, DISCOUNT, FIXEDTERM, EVERGREEN
Duration - the length of the phase in days, months, years or UNLIMITED
Billing Period - how frequently do we want to invoice for this phase. Can be DAILY, WEEKLY, BIWEEKLY, THIRTY_DAYS, MONTHLY, QUARTERLY, BIANNUAL, ANNUAL, BIENNIAL or NO_BILLING_PERIOD
Recurring Price - the recurring price that needs to be paid every billing period (unless no billing period was specified). The price needs to specify numeric values for every currency that the catalog supports.
Fixed Price - a fixed price charged at the beginning of the period in addition to the recurring price. This is also a multi currency price and must be specified for all currencies.
Usage Sections - these are optional and outside the scope of this tutorial.
Plan, Phase and Usage sections can have a
prettyName element which would correspond to the display name (such information is subsequently available on invoice items). This is useful for instance if a product is rebranded to a new name in a subsequent version. Plan names don’t need to be updated.
Note that unlike
name elements need to be globally unique in the catalog and must conform to the XML
NCName definition. This means that they cannot contain symbol characters like
:, @, $, %, &, /, +, ,, ;,, whitespace characters or parentheses, and they cannot begin with a number, dot or minus character.
For our Spy Car catalog example we specify three plans with two phases:
The first phase is of type TRIAL and it has a duration of 30 days and a Billing Period set to "NO_BILLING_PERIOD". There is no recurring price specified, and the fixed price is given as Â£0/$0.
The second phase is of type EVERGREEN. It has a Duration of UNLIMITED, a Billing Period of MONTHLY, and a recurring price of Â£75/$100 (or whatever is appropriate for the Product).
<plans> <plan name="standard-monthly"> <product>Standard</product> <initialPhases> <phase type="TRIAL"> <duration> <unit>DAYS</unit> <number>30</number> </duration> <billingPeriod>NO_BILLING_PERIOD</billingPeriod> <fixedPrice> <!-- empty price implies $0 --> </fixedPrice> </phase> </initialPhases> <finalPhase type="EVERGREEN"> <duration> <unit>UNLIMITED</unit> </duration> <billingPeriod>MONTHLY</billingPeriod> <recurringPrice> <price> <currency>GBP</currency> <value>75.00</value> </price> <price> <currency>USD</currency> <value>100.00</value> </price> </recurringPrice> </finalPhase> </plan> ... </plans>
As noted above, Kill Bill supports three categories of products:
Base Products - Products that can have one or more addons
Add-On Products - Products that can be bundled with a base product
Standalone Products - Products that cannot have any addons
The terms BASE, ADD_ON, and STANDALONE represent plans that are associated with these three types of product respectively. Having an explicit representation of Add-On products allows Kill Bill to be configured to only allow purchases of add-ons with particular base plans, and to trigger appropriate cancellations automatically when the base plan changes or is cancelled.
A Subscription Bundle is a collection of subscriptions that correspond to an individual product instance, such as all the subscriptions associated with a single cell phone, or, in our example catalog, all the subscriptions associated with the rental of a Spy Car. Subscription Bundles can either consist of a collection of subscriptions to stand-alone plans or a single Base Plan subscription with zero or more Add-On Plan subscriptions.
The Kill Bill catalog allows you to specify the inclusion and availability of Add-On Products with associated Base Products. For example, suppose that we create some add-on products for our example catalog. Let’s add an
OilSlick Product and a
RemoteControl Product. Now, let’s discuss the availability and inclusion of these:
Neither product is available in the
StandardPlan, meaning that you can’t purchase either of these add-ons if you are on
Both products are available on the
RemoteControl is available on the
SuperPlan, but as we can see from the original Plan definition,
OilSlickis already included in the
If we have this specified in the catalog then Kill Bill knows to disallow certain purchases, e.g. it will not allow the purchase of an
OilSlick add-on in a Bundle with a
Standard Base Plan.
Similarly if the Base Plan in a Bundle containing
RemoteControl is downgraded to
Standard, Kill Bill knows to automatically cancel the
RemoteControl Add-On since it is no longer available.
Finally, if the Base Plan of a Bundle containing
OilSlick is upgraded to
Super, Kill Bill knows to cancel the
OilSlick Plan because its features are already included, by default, in the new Base Plan.
<products> <product name="Standard"> <category>BASE</category> </product> <product name="Sports"> <category>BASE</category> <available> <addonProduct>OilSlick</addonProduct> <addonProduct>RemoteControl</addonProduct> </available> </product> <product name="Super"> <category>BASE</category> <included> <addonProduct>OilSlick</addonProduct> </included> <available> <addonProduct>RemoteControl</addonProduct> </available> </product> <product name="OilSlick"> <category>ADD_ON</category> </product> <product name="RemoteControl"> <category>ADD_ON</category> </product> </products>
Price Lists are collections of Plans, usually associated with a promotion or discount package. For example, we might offer special rates on our Spy Car rental package for CIA Agents, which offers 33% off for the first 3 months of hire.
To do this, we create plans similar to the ones we have already. They should have the same trial phase and the same evergreen phase, but we insert a new discount phase which, for 3 months, charges the appropriate discount.
In this example we consider only the first of the three additional plans.
<plan name="discount-standard-monthly"> <product>Standard</product> <initialPhases> <phase type="TRIAL"> <duration> <unit>DAYS</unit> <number>30</number> </duration> <billingPeriod>NO_BILLING_PERIOD</billingPeriod> <fixedPrice> <!-- empty price implies $0 --> </fixedPrice> </phase> <phase type="DISCOUNT"> <duration> <unit>MONTHS</unit> <number>3</number> </duration> <billingPeriod>MONTHLY</billingPeriod> <recurringPrice> <price> <currency>GBP</currency> <value>50.00</value> </price> <price> <currency>USD</currency> <value>66.00</value> </price> </recurringPrice> </phase> </initialPhases> <finalPhase type="EVERGREEN"> <duration> <unit>UNLIMITED</unit> </duration> <billingPeriod>MONTHLY</billingPeriod> <recurringPrice> <price> <currency>GBP</currency> <value>75.00</value> </price> <price> <currency>USD</currency> <value>100.00</value> </price> </recurringPrice> </finalPhase> </plan>
Once our additional plans have been created, we can add the new pricelist, after the default price list:
<priceLists> <defaultPriceList name="DEFAULT"> <plans> <plan>standard-monthly</plan> <plan>sports-monthly</plan> <plan>super-monthly</plan> </plans> </defaultPriceList> <childPriceList name="CIA"> <plans> <plan>discount-standard-monthly</plan> <plan>discount-sports-monthly</plan> <plan>discount-super-monthly</plan> </plans> </childPriceList> </priceLists>
The alignment and price list change rules can be used to specify the behaviour to use when changing pricelists. In the example above, we would expect customers to be able to upgrade and downgrade within the discount phase of the subscription and stay in the discounted price list. We refer to this as a "sticky" price list. Kill Bill can also support "non-sticky" price lists, in which plan changes cause the customer to drop out of the pricelist that they are in and move to a different one (usually the Default). In the section on rules we explain how to configure these properties.
There are several different Rules that can be configured in the Kill Bill Catalog. Each Rule answers a specific question. For example, one of the Rules answers the question "When should this plan change be applied?". Suppose Kill Bill receives a request for a subscription to have its plan upgraded, Kill Bill will check the rules, and based on the current plan, the phase it is in, the new plan etc. Kill Bill can determine whether the transition should happen immediately, or be deferred until later.
Rules consist of a series of Cases. Each Case is represented by a Predicate and a Result. Rules are evaluated against a Context. Each Case is examined in order, and the Predicate for that Case is compared to the Context. If the Context satisfies the Predicate, then Kill Bill applies the Result of that Case.
For example, consider the following rule for the timing of applying a plan change:
Predicate: phaseType=TRIAL ; Result: IMMEDIATE
Predicate: phaseType=Evergreen AND fromProduct=Sports AND toProduct=Standard ; Result: END_OF_TERM
Predicate: ; Result: END_OF_TERM
In this example there are three cases. The cases are evaluated from first to last and the first case for which the predicate matches the context is the one that is successful.
Consider the following Context:
To evaluate the Rule against this Context, we start by considering Case 1. The predicate in Case 1 requires that PhaseType=TRIAL, but the first line of our context has phaseType set to EVERGREEN, so Case 1 fails. However, when we consider Case 2, all the predicate clauses are satisfied by the above context: phaseType=Evergreen, fromProduct=Sports and toProduct=Standard. So, Case 2 succeeds and the Rule evaluates to "END_OF_TERM".
Notice that the predicates only need to specify the values of some of the fields in the context. Fields that are omitted in a predicate can take any value. For this reason Case 3 is a catch-all Case. It always succeeds because the predicate has no clauses so it will succeed with any Context.
The XML for the above rules is given below:
<rules> ... <changePolicy> <changePolicyCase> <phaseType>TRIAL</phaseType> <policy>IMMEDIATE</policy> </changePolicyCase> <changePolicyCase> <phaseType>EVERGREEN</phaseType> <fromProduct>Sports</fromProduct> <toProduct>Standard</toProduct> <policy>END_OF_TERM</policy> </changePolicyCase> <changePolicyCase> <policy>END_OF_TERM</policy> </changePolicyCase> </changePolicy> ... </rules>
There are three types of Context:
Creation Context - provides the context for a new subscription
Subscription Context - provides the context of an existing subscription, including details of the plan, phase, pricelist, product etc.
Change Context - provides the context not only about the phase of the current subscription but also details of the new target plan. This is used in the event of a plan change.
|Creation Context||Subscription Context||Change Context|
In the remainder of this section we illustrate each type of rule supported by the system.
Billing Alignment Rules
Billing alignment is concerned with specifying the day on which a particular subscription is to be billed. If an account has multiple subscriptions it is often desirable that they be billed on the same day.
If the billing period for a subscription is MONTHLY or a multiple of MONTHLY (such as QUARTERLY, ANNUAL, etc.) then we define the Bill Cycle Day (BCD). This is the date on which the billing occurs for that subscription each month. If multiple subscriptions have the same BCD, they may be billed on the same invoice. However, if the BCD for a new subscription differs from its start date, then the initial bill will have to be prorated. This will also occur anytime the BCD for a subscription is changed.
If a BCD falls on a date past the end of a given month, such as April 31, it will be set to the last day of that month.
The Billing Alignment Rules specify the policy for billing alignment for the current subscription. There are three kinds of alignment available:
ACCOUNT - this alignment means that the billing cycle of the subscription will be lined up with the BCD of the account. If a day value is not specified, the system will generate one using the first recurring bill date of all subscriptions with an
ACCOUNTbilling alignment. In some cases this is undesirable, because it means that the bill amount will need to be prorated on the first billing to line up the cycles.
SUBSCRIPTION - this alignment will cause the subscription’s bill cycle to line up with the first bill day of the subscription plan. For example, if the subscription starts on January 3rd and has a 15 day free trial, the first billed day will be January 18th, and the BCD for the subscription will be set to 18.
BUNDLE - this alignment sets the BCD to the same day the base plan is using. This may be useful for add-ons.
For example, suppose we have a MONTHLY subscription, billed on the 15th of the month, and we add an ANNUAL subscription. If we start the ANNUAL on the 8th, we have 2 choices:
We can use an ACCOUNT alignment, so everything gets invoiced on the 15th. This would require an initial proration for the ANNUAL subscription from the 8th to the 15th, to align it with the MONTHLY subscription.
We can use a SUBSCRIPTION alignment and keep the ANNUAL on its own invoice, once a year on the 8th. This avoids any leading proration, but requires separate invoices.
The next example will align addons with the base plan, monthlies to the Account bill cycle day and annuals to their first billed day. Anything else is aligned with the Account.
<billingAlignment> <billingAlignmentCase> <productCategory>ADD_ON</productCategory> <alignment>BUNDLE</alignment> </billingAlignmentCase> <billingAlignmentCase> <billingPeriod>MONTHLY</billingPeriod> <alignment>ACCOUNT</alignment> </billingAlignmentCase> <billingAlignmentCase> <billingPeriod>ANNUAL</billingPeriod> <alignment>SUBSCRIPTION</alignment> </billingAlignmentCase> <billingAlignmentCase> <alignment>ACCOUNT</alignment> </billingAlignmentCase> </billingAlignment>
Subscription Alignment Rules
Plan Creation Add-On Phase Alignment
This rule also uses the Creation Context and determines how the phases of an Add-On plan align with an existing subscription.
There are two choices (illustrated below):
START_OF_BUNDLE - causes the phases of the add-on to start on the date when the base plan was first created. This is useful, for instance, if you want to allow add-on trials during the trial phase of the base plan only. The add-on plans must have a trial of the same length as the base plan, so the trials will expire at the same time whenever the add-on is created.
START_OF_SUBSCRIPTION - this causes the phases of the add-on to start when the add-on subscription is created. This is useful, for instance, if you want to allow add-ons to have trials that occur independently of the base plan.
Predicate: product=OilSlick ; Result: START_OF_BUNDLE
Predicate: product=RemoteControl ; Result: START_OF_SUBSCRIPTION
Predicate: ; Result: START_OF_BUNDLE
In this example the product
OilSlick is aligned to the START_OF_BUNDLE and the product
RemoteControl is aligned to START_OF_SUBSCRIPTION. The default for anything else is START_OF_BUNDLE.
<createAlignment> <createAlignmentCase> <product>OilSlick</product> <alignment>START_OF_BUNDLE</alignment> </createAlignmentCase> <createAlignmentCase> <product>RemoteControl</product> <alignment>START_OF_SUBSCRIPTION</alignment> </createAlignmentCase> <createAlignmentCase> <alignment>START_OF_BUNDLE</alignment> </createAlignmentCase> </createAlignment>
For more information on
Plan Creation Phase Alignment, and in particular to understand how that works with apis (Subscription Create or Subscription Change Plan) that specify a target
PhaseType, you can also refer to this documentation.
Plan Cancellation Timing
This rule uses the Phase Context and is used to specify when a cancellation should occur.
There are two options (illustrated below):
END_OF_TERM - means that the cancellation will be applied at the end of the billed period. This is typical in a situation where we want to avoid generating credits.
IMMEDIATE - means that the cancellation will be applied immediately and the customer credited with the balance of the subscription that they have paid for but not yet used.
Predicate: productCategory=BASE ; Result: END_OF_TERM
Predicate: productCategory=ADD_ON ; Result: IMMEDIATE
Predicate: ; Result: END_OF_TERM
In this example base plans are cancelled at the end of their term, while add-on plans are cancelled immediately.
<cancelPolicy> <cancelPolicyCase> <productCategory>BASE</productCategory> <policy>END_OF_TERM</policy> </cancelPolicyCase> <cancelPolicyCase> <productCategory>ADD_ON</productCategory> <policy>IMMEDIATE</policy> </cancelPolicyCase> <cancelPolicyCase> <policy>END_OF_TERM</policy> </cancelPolicyCase> </cancelPolicy>
Plan Change Timing
This rule uses the Change Context and, like the cancellation rule above, specifies when a plan change should occur.
There are three options (two of which are illustrated above):
END_OF_TERM - specifies that the change should happen at the end of the current billed period.
IMMEDIATE - specifies that the change should happen when requested.
ILLEGAL - plan change is not allowed (not illustrated).
Predicate: phaseType=TRIAL ; Result: IMMEDIATE
Predicate: fromProduct=Standard AND toProduct=Sports ; Result: IMMEDIATE
Predicate: toProduct=Super ; Result: IMMEDIATE
Predicate: ; Result: END_OF_TERM
In this example we specify that trials and upgrades occur immediately, anything else is to occur at end of term.
<changePolicy> <changePolicyCase> <phaseType>TRIAL</phaseType> <policy>IMMEDIATE</policy> </changePolicyCase> <changePolicyCase> <fromProduct>Standard</fromProduct> <toProduct>Sports</toProduct> <policy>IMMEDIATE</policy> </changePolicyCase> <changePolicyCase> <toProduct>Super</toProduct> <policy>IMMEDIATE</policy> </changePolicyCase> <changePolicyCase> <policy>END_OF_TERM</policy> </changePolicyCase> </changePolicy>
Plan Change Phase Alignment
In the section "Plan Creation Add-on Phase Alignment" above, we specified how to align the phases of an add-on with a base plan. This rule, which uses the Change Context, specifies how the phases of a new plan should align with the phases of the existing plan when a plan is changed.
There are four options:
START_OF_SUBSCRIPTION - The plan phases start with the start of the subscription. This is the most common alignment and applies in most situations.
START_OF_BUNDLE - The plan phases align with the start of the base subscription. This is only meaningful for addons.
CHANGE_OF_PLAN - The plan phases start at the time of the change
CHANGE_OF_PRICELIST - The plan phases start at the time of the price list’s last change
Predicate: toProductCategory=ADD_ON ; Result: START_OF_BUNDLE
Predicate: toPriceList=SpecialDiscount ; Result: CHANGE_OF_PRICELIST
Predicate: ; Result: START_OF_SUBSCRIPTION
<changeAlignment> <changeAlignmentCase> <toProductCategory>ADD_ON</toProductCategory> <alignment>START_OF_BUNDLE</alignment> </changeAlignmentCase> <changeAlignmentCase> <fromPriceList>SpecialDiscount</fromPriceList> <toPriceList>SpecialDiscount</toPriceList> <alignment>CHANGE_OF_PRICELIST</alignment> </changeAlignmentCase> <changeAlignmentCase> <alignment>START_OF_SUBSCRIPTION</alignment> </changeAlignmentCase> </changeAlignment>
In this example, add-on changes are aligned to the start of the bundle, changes to the
SpecialDiscount price list are aligned to that change, and everything else aligns to the start of the subscription.
For more information on
Plan Change Phase Alignment, and in particular to understand how that works with apis (Subscription create or Subscription Change Plan) that specify a target
PhaseType, you can also refer to this documentation.
Plan Change Price List Choice
This rule uses the Change Context and specifies which pricelist should be chosen for specific changes. The rule allows us to configure whether a price list is "sticky" or not.
For example, suppose we have an affiliate pricelist with special prices for members of the CIA for Spy Car rental. Let’s say that this price list offers a 30% discount for the first 3 months of rental.
Now, Special Agent Mills from the CIA subscribes to a
Sports product on that price list. However, 1 month after renting the car his daughter is kidnapped and he needs additional capabilities and decides to upgrade to a
Since he bought the original subscription on a special offer that still has two months to run we would expect the upgrade to put him into the corresponding 30% off
Super plan and give him a further 2 months at that price. This is a "sticky" price list.
Alternatively, consider long term customer 003 who has been renting the
Super for the last 4 years but decides that she wants to save money and calls to downgrade her plan. Our representative offers her a special Rescue Pricing plan that gives her 40% off for the next year and she decides to take it.
However, a month later she changes her mind and decides to downgrade anyway. In this situation we want her to downgrade to the default price plan. This is a "non-sticky" price list.
Predicate: fromPriceList=CIA ; Result: CIA
Predicate: fromPriceList=SpecialDiscount ; Result: DEFAULT
Predicate: ; Result: DEFAULT
<priceList> <priceListCase> <fromPriceList>SpecialDiscount</fromPriceList> <toPriceList>DEFAULT</toPriceList> </priceListCase> <priceListCase> <fromPriceList>CIA</fromPriceList> <toPriceList>CIA</toPriceList> </priceListCase> <priceListCase> <toPriceList>DEFAULT</toPriceList> </priceListCase> </priceList>
This far in the discussion we have been considering single stand-alone catalogs, but Kill Bill allows you to modify the catalog over time. You can do this by creating a set of catalogs, one XML file for each version; the system will rank such files based on their
effectiveDate to create the various versions. There is no version number proper; the
effectiveDate associated with each catalog XML constitutes the version and the next catalog supersedes the previous one. In this way we can change prices, add new Plans, Products, Price Lists etc, retire Plans, Products, Price Lists, etc.
Note that it is possible to remove entries in subsequent catalog versions. For example, removing a
Plan in a new catalog version would prevent future customers from subscribing to that
Plan. However existing subscriptions may still refer to it.
Deferred Price Change
Kill Bill supports the ability to make a price change to a plan that applies based on the catalog effective date for new purchases, but which is deferred for existing subscriptions. It is often the case that existing customers will need a notice period before prices are changed but you need to deliver the new prices to new purchases as soon as the change is announced.
This feature uses the field
effectiveDateForExistingSubscriptions that is included on Plans.
The semantics is simply that the changes to that plan will only take effect for existing subscriptions, after that date, but new subscription would use the new price immediately.
The drawing below summarizes how the system would apply the change for an existing subscription:
Kill Bill supports billing customers based on their usage data, and the pricing schemes for this billing are defined in the Kill Bill catalog.
Plan section of the catalog can contain one or several
usage section(s) to define how customers will be billed.
These sections can be defined in addition to other, non usage based, billing schemes, such as fixed or recurring price.
Each usage section will need to specify a
The only billing mode supported today is the
IN_ARREAR mode, which allows customers to be billed based on usage data from previous periods.
We plan to add the
IN_ADVANCE mode in the future to support prepaid scenarios such as toll bridge pass, where the customer purchases a
certain number of units in advance and such units are decremented as the customer uses the service.
Each usage section will also need to specify a
usageType and along with it, specify the
unit (types) for which the customer is being billed, such as cell phone/minutes.
The usage type can be one of the following:
CONSUMABLE: This is used for defining prices that are based on the number of units (for a certain type) being consumed — e.g., water consumed in the last period.
CAPACITY: This is used for defining prices that are based on rates or upper bound values. In this scheme, we bill based on the maximum value that was seen over the period — e.g MBytes/sec
The following blog post provides additional context about these use cases.
For each usage section, we support defining pricing tiers, allowing customers to be billed differently based on their usage.
These tiers work differently depending on the usage type,
Each usage section also needs to define the
billingPeriod — e.g
MONTHLY — to define how often and for which period consumers are being billed.
Consumable In Arrear Mode
In this mode, each
tier definition contains a
tieredBlock that defines the limits and price associated with a particular
unit type. We support two
ALL_TIER: This policy charges users across each tier based on their usage. Higher prices are charged to the less preferred tier. This may be a lower tier, e.g for cloud usage where we want to reward users who consume more, or a higher tier, e.g for an electric bill where we want to encourage users to consume less.
TOP_TIER: With this policy we still go through each tier, but everything is charged at the top tier pricing. Here it makes sense to offer lower pricing for the top tier, since this is a rewarding model.
Consumable In Arrear Mode:
To demonstate the
ALL_TIER policy, let’s start with an example of a
tieredBlock definition. The following tier block section defines the pricing for the
cell-phone-minutes unit, and can be understood the following way:
<tieredBlock> <unit>cell-phone-minutes</unit> <size>10</size> <prices> <price> <currency>EUR</currency> <value>1.00</value> </price> </prices> <max>100</max> </tieredBlock>
This defines a block of size
10, where each block is priced at 1.00 EUR
100blocks of this size will be priced at 1.00 EUR
If a consumer uses more than
100blocks of this size, he will be charged at the price of the next tier.
As mentioned previously, each usage section can contain multiple tiers and also charge for multiple unit types.
The following section shows the defintion for 2 units, cell-phone-minutes and Mbytes, and defines two tiers.
max value for the last tier is defined with -1 which represents an unbounded value:
<tiers> <tier> <blocks> <tieredBlock> <unit>cell-phone-minutes</unit> <size>10</size> <prices> <price> <currency>EUR</currency> <value>1.00</value> </price> </prices> <max>100</max> </tieredBlock> <tieredBlock> <unit>Mbytes</unit> <size>1</size> <prices> <price> <currency>EUR</currency> <value>0.5</value> </price> </prices> <max>1024</max> </tieredBlock> </blocks> </tier> <tier> <blocks> <tieredBlock> <unit>cell-phone-minutes</unit> <size>10</size> <prices> <price> <currency>EUR</currency> <value>0.50</value> </price> </prices> <max>-1</max> </tieredBlock> <tieredBlock> <unit>Mbytes</unit> <size>1</size> <prices> <price> <currency>EUR</currency> <value>0.1</value> </price> </prices> <max>-1</max> </tieredBlock> </blocks> </tier> </tiers>
CONSUMABLE mode, when defining a usage section with multiple unit (types), it is important to realize that the consumer is charged independently
for each unit. For example, with the definition provided above, and given the following usage data for the period:
The total amount would be 739.4. This is calculated as follows:
Tier 1: 100 blocks of size 10 at 1 EUR ⇒ 100 EUR
Tier 2: 50 blocks of size 10 at 0.5 EUR ⇒ 25 EUR
Tier 1: 1024 blocks of size 1 at 0.5 EUR ⇒ 512
Tier 2: 1024 blocks of size 1 at 0.1 EUR ⇒ 102.4
Total: 100 + 25 + 512 + 102.4 = 739.4
For more information on this model, see our tutorial.
Consumable In Arrear Mode:
Using the same example from the previous section with the
TOP_TIER policy would lead to a different result, since all charges would be calculated at the higher tier:
cell-phone-minutes: 150 blocks of size 10 at 0.50 EUR = 150 * 0.5 = 75
Mbytes: 2048 blocks of size 1 at 0.10 EUR = 2048 * 0.1 = 204.8
So the total amount would be 279.8.
Capacity In Arrear Mode
CAPACITY mode, each
tier definition contains a list of
limit, specifying the maximum value for this tier for each
unit (type). In contrast to the
CONSUMABLE mode, the billing happens across the units. Let’s assume the following definition for one tier, with 2 different types of units,
<tier> <limits> <limit> <unit>bandwith-meg-sec</unit> <max>100</max> </limit> <limit> <unit>members</unit> <max>500</max> </limit> </limits> <recurringPrice> <price> <currency>EUR</currency> <value>5.00</value> </price> </recurringPrice> </tier>
Given the following usage data for the period:
bandwith-meg-sec: A peak of 50 in the period
members: A peak of 350 active members in the period
The user would be charged 5.00 EUR.
However if the
members peak data was 501, this would move to the next tier — not shown for simplicity.
So, in this model, the peak data for each unit is used to define which tier to use, and based on the tier we simply apply the pricing defined.
Subscription and Entitlement
The Kill Bill entitlement system offers an API for users to manage their subscriptions. The API allows a user to subscribe to a new product, change to a different product, pause, resume or cancel a subscription. Upon each of those API calls, there are two distinct sets of operations that occur in the system:
When an entitlement change occurs, for instance upon creation, the user gains access to what she subscribed for. The primary goal of that API is to give great flexibility through the use of dates or entitlement policies as to when things should start or stop.
As a consequence of the entitlement operation, the system will also compute the changes that should occur on the billing side. It is important to understand that the entitlement operation has an impact on billing, so the two are connected, but they are not necessarily aligned.
The philosophy behind that API is that the user (of the API) should be able to configure the entitlement so that it matches their needs exactly, and let the system compute the billing aspect based on the policies that were configured in the catalog.
First an administrator sets up Kill Bill to always perform the cancellation END_OF_TERM, which will result in never generating a credit for a particular product 'P'.
A customer comes in, subscribes to that product 'P', and gets invoiced.
At a later date the customer decides that he no longer wants to use the product 'P', and decides to cancel that subscription immediately. From an entitlement point of view, the end date is now. So as soon as the call returns, the customer loses access to the product.
From a billing point of view, however, because the administrator decided to configure the system that way, the system will compute the end date to match the end date of the last period invoiced, also referred to as "charged through date" (CTD). Thus there is no generated credit for that cancellation.
As a general rule, then, the administrator deals with the billing policies, and the user of the API controls the details of its entitlement(s). The entitlement system exposes abstractions that reflect that model:
Entitlement: An entitlement is an abstraction which provides the answer to the following question: Is the user allowed (entitled) to use this service or product at a given time? It provides information about the dates when that service started, ended, or was paused and resumed, along with the specifics about the type of service or product.
Subscription: A Subscription is an abstraction that encapsulates the information contained in the entitlement but also adds additional billing information, such as the dates at which the billing started and ended. When the system is configured to bill in advance, it also provides the date up to which the customer was invoiced (ChargeThroughDate).
SubscriptionBundle: Subscriptions are always part of a SubscriptionBundle. This allows Subscriptions to be grouped together so that specific operations — cancellation, change of plan-- on one Subscription may have an impact on the other Subscriptions in the same SubscriptionBundle. There can be at most one Subscription attached to a BASE Category in a SubscriptionBundle but there can be multiple ADD_ON Subscriptions in that same SubscriptionBundle. Typically, a BASE Category is used to make sure that any operation on the BASE Subscription will be reflected on the ADD_ON Susbcriptions in the same SubscriptionBundle.
Previously we laid out the general case where the user of the API controls the entitlement and Kill Bill manages the billing aspect based on configuration policies. Some specific entitlement APIs also allow you to override the billing policies on a per call basis.
The table below shows the possible combinations that the API supports. The columns represent the various entitlement (ENT) policies: Immediate, End of Term, or specific date. The rows represent the possible billing policies, which have the same three choices.
The diagrams below illustrate each entry in the table, for the case when a cancellation occurs on a subscription that was billed in advance:
The green line shows the entitlement, and the red cross on that line shows the cancellation as seen by the customer; that is, once we hit the red cross the customer loses access to its entitlement.
The red portion below shows the current invoice; by default the customer was invoiced from the start of the period to the end of the period, also referred to as the charged through date (CTD).
We can see that in all cases, cancelling a subscription has both an impact on the entitlement and the billing side, but we also see that those two are not necessarily aligned: