This is the reference guide to get started with Kill Bill Subscription Billing. Make sure to also check our list of manuals here.
Introduction
Kill Bill as a system, is composed of several components:
-
The core billing platform itself, which is embedded in a web server to offer a REST api. When we refer to Kill Bill in that 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 to the core billing platform using the REST api
-
A set of client libraries (Java, Ruby, PHP, Node.js, …)
Let’s go through a common (web) use case of Kill Bill. One would create a custom webapp, which would contain the application’s specific business logic, and have that webapp interact with Kill Bill using the REST API. In that use case, the custom webapp would:
-
Offer a way for customers to select a plan from the Kill Bill catalog, which would result in the creation a Subscription in Kill Bill
-
Offer a form for customers to enter their CC information — or any other payment method. Here depending on the payment gateway, and also on PCI compliance, the flow would differ
-
Offer a way for customers to review/change their subscriptions
-
Offer a way for customers to review/change their payment methods
It is important to understand that Kill Bill solves the billing problem but not the custom flow required around the billing platform Besides the main use case described above, there are other possible options if one requires going that path:
-
One could embed its webapp specific code inside Kill Bill, and therefore avoid having a separate web app.
-
Another use use case would be to embed Kill Bill into the custom web app: Below the REST API, Kill Bill offers a set of java APIs, and so it is possible to use Kill Bill as a billing library.
Kill Bill Subscription Billing in 5 minutes
Download the latest jetty-console.war from Maven Central (download the jetty-console.war artifact).
To start Kill Bill, either double click on the war file, or run the following in a terminal (recommended to check logs):
java -jar killbill-*-jetty-console.war
This will start Kill Bill with an embedded H2 database (data is persisted in a local killbill.h2.db file, so changes are preserved across restarts).
After the system has started, you can experiment by following the simple scenario below. Note that each call creating an object in the system returns its URI, and so the curls below are using the UUID that was returned at the time the demo was created. You would need to replace the UUID with the one returned in each call if you were to follow that demo.
If you get an error like the following at startup:
16:12:23,432 |-ERROR in ch.qos.logback.core.util.ContextUtil@7a0c1f5f - Failed to get local hostname java.net.UnknownHostException: HOSTNAME: HOSTNAME: nodename nor servname provided, or not known
at java.net.UnknownHostException: HOSTNAME: HOSTNAME: nodename nor servname provided, or not known
you may have an invalid hostname set. To work around it, add the following line in /etc/hosts:
127.0.0.1 HOSTNAME localhost
and restart Kill Bill.
Create your own tenant
The default behavior of Kill Bill is to run with multi-tenancy enabled. In that mode, one needs to first create a tenant and specify the credentials that will be required subsequently on each call. Each call requires a default username and password that is used in the system for role base access control (RBAC). By default we are using the username 'admin' and its default password 'password'. The first operation is to create the tenant specifying the api key and secret that will need to be provided in each subsequent call:
curl -v \
-X POST \
-u admin:password \
-H 'Content-Type: application/json' \
-H 'X-Killbill-CreatedBy: admin' \
-d '{"apiKey": "bob", "apiSecret": "lazar"}' \
"http://127.0.0.1:8080/1.0/kb/tenants"
At this point, test your setup by making sure you can retrieve the default tag definitions:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
"http://127.0.0.1:8080/1.0/kb/tagDefinitions"
Create an account
The next step will be to create an account:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"name":"John Doe","email":"[email protected]","currency":"USD"}' \
"http://127.0.0.1:8080/1.0/kb/accounts"
Now, let’s attach a payment method to that account. Since that demo does not have any real payment plugin attached to it, we will choose the default external payment method plugin that comes configured with the system (used to process checks for example). That default payment plugin does not require any payment method details such as Credit Card info, and so the pluginInfo parameter is an empty map:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"pluginName":"__EXTERNAL_PAYMENT__","pluginInfo":{}}' \
"http://127.0.0.1:8080/1.0/kb/accounts/268983f2-5443-47e4-a967-b8962fc699c5/paymentMethods?isDefault=true"
{"uri":"http://127.0.0.1:8080/1.0/kb/paymentMethods/eef35072-f70e-43da-a614-3215dbc1e28a"}
Note: the payment plugin associated with this payment method will mock all calls, so all payment calls will succeed.
Create a subscription
At this point we can create a subscription based on the default demo catalog:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"accountId":"268983f2-5443-47e4-a967-b8962fc699c5","externalKey":"myBundleName","productName":"Standard","productCategory":"BASE","billingPeriod":"MONTHLY","priceList":"DEFAULT"}' \
"http://127.0.0.1:8080/1.0/kb/subscriptions"
{"uri":"/1.0/kb/subscriptions/b623e0bd-45fd-4636-b177-6528228c5f35"}
It is interesting to verify that the system immediately invoiced for the subscription that was created. Because the subscription is using a Plan with trial phase of $0, there is no associated payment:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
"http://127.0.0.1:8080/1.0/kb/accounts/268983f2-5443-47e4-a967-b8962fc699c5/invoices"
[{"amount":0.00,"currency":"USD","creditAdj":0.00,"refundAdj":0.00,"invoiceId":"15a0abc7-2489-493c-b098-7460afc21203","invoiceDate":"2013-08-25","targetDate":"2013-08-25","invoiceNumber":"1","balance":0.00,"accountId":"268983f2-5443-47e4-a967-b8962fc699c5","auditLogs":null}]
Upgrade/Cancel the plan for the subscription
We will now upgrade the plan from the 'Standard' to the 'Sports' product:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X PUT \
--data-binary '{"accountId":"268983f2-5443-47e4-a967-b8962fc699c5","productName":"Sports","productCategory":"BASE","billingPeriod":"MONTHLY","priceList":"DEFAULT"}' \
"http://127.0.0.1:8080/1.0/kb/subscriptions/b623e0bd-45fd-4636-b177-6528228c5f35"
At then finally, we will cancel the subscription.
Retrieving the invoices like we did in the previous step would show that a new invoice was automatically created after each change on the subscription. By default Kill Bill reacts to any change happening in the system automatically, creating invoices to match new state and trigerring payments when needed.
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X DELETE \
"http://127.0.0.1:8080/1.0/kb/subscriptions/b623e0bd-45fd-4636-b177-6528228c5f35"
Catalog
Overview
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.
In practice, the catalog is an XML file (see an example here). 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
Introduction
The Catalog is at the heart of the billing system. It is a data model that captures the core configuration 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 that 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 Kill Bill can 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 products 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 finite number of options. When you need to go further, and many people do, you can write plugins to implement pretty much anything you need.
Concepts
In this section we outline some key pieces of terminology that you will need to understand. 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 though exactly how we use the terms in Kill Bill.
Background Concepts
-
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 Subscription is 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) – Is 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?
Writing a Kill Bill Catalog involves defining of the following pieces:
-
Products - the product is the thing 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. There are actually three different products available,
Standard
,Sports
andSuper
. -
Plans - Plans specify the terms of the Subscription contract. In particular, they 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 Phase (or just Phase) - 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 price list is 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 a special rental terms for their Spy Cars with the C.I.A. In which case they would create a C.I.A. Price List that grouped plans with those special terms together. When C.I.A. Agents come to the rental site, they will 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 C.I.A. Price List.
-
Billing Period - The periodicity for when the customer is billed (e.g
MONTHLY
,ANNUAL
, …) -
BillCycleDay (BCD) - The day in the month when the invoicing for a particular subscription happens. This only makes sense for recurring subscriptions whose
Billing Period
is a multiple of the month. For other schemes (e.g.WEEKLY
). the day will vary for each invoice, in which case there is noBCD
defined. -
Rules - The catalog rules determine the behaviour that Kill Bill should display when a plan is created, cancelled or changed.
How is the Catalog Used Inside Kill Bill?
The catalog is first used by Kill Bill at the time the user creates a subscription, then subsequently if there is change of Plan
(upgrade, 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. An overview of some of these rules:
-
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 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 to define if different subscriptions attached to a customer should be invoiced at the same time, or at the opposite if they should be billed separately on their own schedule (or a mix of both where some are grouped together on the same invoice and others are invoiced independently). In the simplest case, where all subscriptions are grouped together and there is a BCD
defined (Billing Period
is a multiple of the month), the customer gets one invoice per Billing Period
on that (BCD
) day. Note that grouping subscriptions together may by default lead to some leading pro-ration when the subscription is started on a different date than the BCD
(as the system needs to realign invoicing on that particular date). This behavior is configured in the catalog through the Billing Alignment Rules.
Catalog Documentation
Where do you go from here to learn more:
-
Basic Catalog Tutorial - how to create a simple three tier catalog with simple rules
-
Advanced Catalog Tutorial - enhancing the Basic Catalog Example with add-ons, discount plans, complex rules and catalog changes
Basic Catalog Tutorial
In this tutorial we set about creating a catalog to represent the Spy Car products illustrated above. The tutorial will go through the creation of the following:
-
Products
-
Plans
-
Rules
Someday Kill Bill will have a slick UI for creating and editing Catalogs, but today, Catalogs are represented as XML documents. As we go through the tutorial we will explain the various settings that need to be configured and then give examples and specifics of the XML syntax for representing them.
The XML example for this tutorial can be downloaded in its entirety.
Creating the Catalog
In this section we look at getting the top level catalog created and configured. Note that the catalog currently requires all attribute strings to be unique, and those strings cannot have space.
The XML document starts in a standard way. The main tag is “catalog”. Within the catalog opening tag you can specify the schema location.
You can use the standard schema location (above) or you can have the code generate the current schema by executing:
As an example, the killbill-catalog-x.y.z-xsd-tool.jar for the version 0.13.7
can be found here.
java -jar catalog/target/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.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CatalogSchema.xsd">
<effectiveDate>2013-02-08T00:00:00+00:00</effectiveDate>
<catalogName>SpyCarBasic</catalogName>
<currencies>
<currency>USD</currency>
<currency>GBP</currency>
</currencies>
...
</catalog>
Products
The Product is a representation of the thing the customer is actually buying. Specifying a Product is very straightforward it has the following parameters:
-
Name - this is a string that is used to refer to the Product elsewhere in the catalog. For example “Super”
-
Category - The Product Category determines how Kill Bill allows the combining of products within a bundle. Kill Bill supports three categories of product: BASE, ADD_ON and STANDALONE.
-
Inclusion/Exclusion lists (optional) - these determine which addons can be purchased with a given base plan.
Plans
Each Plan has a name and refers to the purchase of a single product. Beyond that the Plans parameters are arranged by phase. In the illustration above 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 - outside the scope of that tutorial, which is focused on pure recurring subscriptions
For our example Spy Car catalog we specify three plans with two phases:
-
The first phase is of type Trial and it has a duration of 30 days a Billing Period set to “NO_BILLING_PERIOD”. There is no recurring price specified, and a Fixed Price of £0/$0.
-
The second phase is of type Evergreen and it has a Duration of UNLIMITED, a Billing Period of MONTHLY and 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>
Price list
Price Lists are collections of Plans that are grouped for selection or interchange. They are used for identifying discount pricing for presentation to a particular customer group. In the example illustrated above we are supposing that MI6 is providing rental Spy Cars at special pricing levels for C.I.A. agents and former K.G.B. agents.
Kill Bill requires at least one special Price List to be defined, called the default price list. In our example, it contains all three example Plans.
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>standard-monthly</plan>
<plan>sports-monthly</plan>
<plan>super-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
Rules
The rules section of the catalog allows the definition of different Kill Bill behaviours for the creation, cancellation and changing of Plans. Here we provide the most simple rule set possible.
Kill Bill requires that there is a defined default rule for each rule type. The rules are applied by matching cases, if there are no case matching a particular situation then the default rule is applied. It is important to have a default rule even if you don’t expect to use it just to ensure that you cover all possible cases.
In this example we specify the following default for the following rule types:
-
Change Policy [IMMEDIATE] - this is the policy used to determine when to apply a plan change. The policy IMMEDIATE, states that all plan changes will be applied exactly at the time the plan change is requested.
-
Change Alignment [START_OF_BUNDLE] - the change alignment determines how the new plan phases should line up against the old plan phases. This policy says that plan phases should always line up with the start of the bundle. This would mean, for example, that if you have a 30 day trial on all your plans, the customer can move back and forth between different plans many times but since the start of the phases always aligns to the start of the bundle all the trial phases will end at the same time, 30 days from the original start.
-
Cancel Policy [IMMEDIATE] - this determines when a plan is cancelled. The policy chosen here means that it is always cancelled at the time Kill Bill receives the request.
-
Create Alignment [START_OF_BUNDLE] - this determines the way phase of a newly created add-on plan should be aligned. Our choice of START_OF_BUNDLE means that any trials associated with the add on plans would align with the trials of the base plans. Of course, in this example we don’t have any add-ons yet so the choice is irrelevant.
-
Billing Alignment [ACCOUNT] - different plans can be billed on different cycles. The billing alignment ACCOUNT means that the billing will always line up with the Bill Cycle Day of the customer Account.
-
Price List [DEFAULT] - as customers change plan there may be business rules about which Price List should be used to determine the new plan. This rule set allows us to express those rules. In this case we say that every change takes us to the DEFAULT Price List.
<rules>
<changePolicy>
<changePolicyCase>
<policy>IMMEDIATE</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
Also, note that those rules define the default behavior, but the APIs also allow to override those behavior on a per call basis.
Advanced Catalog Tutorial
Overview
This tutorial builds on the Basic Tutorial to illustrate the more advanced features of the Kill Bill Catalog. The XML example for this tutorial can be found here.
Add-ons
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.
Kill Bill supports three categories of products:
-
Base Products
-
Add-On Products
-
Standalone Products
The terms Base Plan, Add-on Plan and Standalone Plan represent plans that are associated with these three types of product respectively.
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 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 of the products is available in the
Standard
Plan, meaning that you can’t purchase either of these add-ons if you are onStandard
. -
Both products are available on the
Sport
Plan. -
RemoteControl is available on the
Super
Plan, but as we can see from the original Plan definition,OilSlick
is already included in theSuper
Plan.
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 Super
and 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 Sports
and 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
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 C.I.A. 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 the are in and move to a different one (usually the Default). In the section on rules we explain how to configure these properties.
Rules
There 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 Predicate is satisfied by the context, then the Result of that Case is applied.
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 following Context:
phaseType |
EVERGREEN |
fromProduct |
Sports |
fromProductCategory |
BASE |
fromBillingPeriod |
MONTHLY |
fromPriceList |
DEFAULT |
toProduct |
Standard |
toProductCategory |
BASE |
toBillingPeriod |
MONTHLY |
toPriceList |
DEFAULT |
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 - this provides the context of an existing subscription, including details of the plan, phase, pricelist, product etc.
-
Change Context - this is used in the event of a plan change provides context not only about the phase of the correct subscription but also details of the new target plan.
Creation Context | Subscription Context | Change Context |
---|---|---|
product |
product |
phaseType |
productCategory |
productCategory |
fromProduct |
billingPeriod |
billingPeriod |
fromProductCategory |
priceList |
priceList |
fromBillingPeriod |
phaseType |
fromPriceList |
|
toProduct |
||
toProductCategory |
||
toBillingPeriod |
||
toPriceList |
In the remainder of this section we illustrate each type of rule supported by the system.
Billing Alignment Rules
This rule uses the Creation Context and configures type of billing alignment used with a subscription. There are three kinds of alignment available:
-
ACCOUNT - this means that the billing cycle of the subscription will be lined up with the bill cycle day of the account. In some cases this is undesirable because it means that a proration charge will be applied on first billing to line up the cycles.
-
SUBSCRIPTION - this alignment will cause the subscriptions bill cycle to line up with the first bill day of the subscription plan. So, if the subscription starts on January 3rd and has a 15 day free trial, the first billed day with be January 18th and the bill cycle day for the subscription will be set to 18.
-
BUNDLE - setting the alignment to bundle is useful for add-ons because it sets the bill cycle day to be aligned with whatever the base plan is using.
Example:
-
Predicate: productCategory=ADD_ON ; Result: BUNDLE
-
Predicate: billingPeriod=MONTH ; Result: ACCOUNT
-
Predicate: billingPeriod=ANNUAL ; Result: SUBSCRIPTION
-
Predicate: ; Result: ACCOUNT
This 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>ANNUAL</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 aligns with an existing subscription.
There are two choices (illustrated above):
-
START_OF_BUNDLE - causes the phases of the addon to start on the date when the base plan was first created. This is for instance useful if you want to allow add-on trials during the trial phase of the base plan only. The addon plans must have a trial of the same length as the base plan and then 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 for instance useful if you want to allow add-ons to have trials that are occur independently of the base plan.
Example:
-
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>
Plan Cancellation Timing
This rule uses the Phase Context and is used to specify when a cancellation should occur.
There are two options (illustrated above):
-
END_OF_TERM - meaning 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 - meaning 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.
Example:
-
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, 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).
Example:
-
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 should 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 last change of price list
Example:
-
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, addon 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.
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 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 Super
.
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.
Example:
-
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>
Catalog Versions
This far in the discussion we have been considering single stand-alone catalogs, but Kill Bill allows the catalog to be modified over time. This is done by creating a set of catalogs with effectiveDates through time. Each catalog is superseded by the next. In this way we can change prices, add new Plans, Products, Price Lists etc, retire Plans, Products, Price Lists etc.
Note that the catalog does not allow the removal of objects. Only additions and certain modifications are allowed. Objects can be retired which means that they cannot be applied to new subscriptions. However existing subscriptions will still refer to them.
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:
Subscription and Entitlement
Overview
The Kill Bill entitlement system primarily 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 its subscription. Upon each of those API calls there are really two distinct set 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/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 drive the entitlement so that it matches exactly its needs and let the system computes the billing aspect based on the policies that were configured in the catalog. Example:
-
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 so he decides to cancel that subscription immediately. From an entitlement point of view, the end date is now and so, as soon as the call returns, the customer loses access to its product 'P'.
-
However from a billing point of view, and because the administrator decided to configure the system that way, the end date will be computed by the system to match the end date of the last period invoiced, also referred to as charged through date (CTD), and that way there is no generated credit for that cancellation.
So, as a general rule, the administrator deals with the billing policies, and the user of the API controls the detail of its entitlement(s). The entitlement system exposes abstractions that reflect that model:
-
Entitlement: An entitlement is an abstraction which helps answer the following question: Is the user allowed (entitled) to use this service/product at a given time? So as such, it provides information about the dates where that service started, ended, was paused/resumed along with the specifics about the type of service/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, 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.
Alignments
The API allows you to provide the following matrix of combinations:
On the horizontal line, we have the various entitlement (ENT) policies or requested cancel date; on the vertical we have the same policies/requested cancel date for the billing side (BILL):
The diagrams below summarize what happens 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 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:
Invoicing
Overview
Most (all?) billing system are batch oriented: Invoice calculation occurs at certain specific times (often configurable), and the system goes through all accounts and generate the missing invoices. Kill Bill, on the other hand, generates new invoices as soon as there is a change in the system that requires such a new invoice:
-
there is a change for a subscription (creation, change of plan, cancellation, etc.)
-
on a recurring phase of a subscription, the system detects a recurring charge is due (e.g. monthly recurring subscriptions)
-
an operator either creates an external charge, adjusts a past invoice or triggers a future invoice
After an invoice has been generated, its balance is positive or zero. If it’s positive, the customer needs owes money and need to pay its balance. Each time an invoice would become negative, the system automatically inserts a special item, called credit balance adjustment (CBA), to bring back the balance to zero. That credit is automatically added to the account and used on future invoices. If the invoice is paid, a payment is added against that invoice. If that invoice is adjusted later on, a CBA item will be automatically generated and appear on the invoice. Kill Bill invoices are for the most part static, with the exceptions of manual changes (manual credit, charge added on a specific invoice after the generation)
An invoice is made of invoice items and the various types of invoice items are:
-
RECURRING: Recurring charge. Used for items with a billing period. This item is always positive or zero
-
FIXED: Fixed (one-time) charge. Used for items without a billing period (non recurring phase, e.g. trials). This item is always positive or zero
-
EXTERNAL_CHARGE: Fixed (one-time) external charge, for items not in the catalog. This item is always positive
-
ITEM_ADJ: Invoice item adjustment, generated by an operator (often associated with a refund). This item is always negative
-
REFUND_ADJ: Invoice level adjustment (against a posted payment). This item is always negative
-
CREDIT_ADJ: Invoice level adjustment (credits), either at the account level (on its own invoice) or against an existing invoice. This item is always negative
-
REPAIR_ADJ: Internal adjustment, generated automatically by the system for an invoice on which the subscription was modified (immediate cancellation or change). The items is always negative
-
CBA_ADJ: Internal adjustment, generated automatically by the system for an invoice which became negative (account level credits). Positive when generating credits, negative when consuming account level credits. The sum of CBA items for an account should always be positive or zero
Recurring invoice items start and end on the same day of the month. For example, a monthly subscription starting on the 21st will have items for the service period 2012-08-21 to 2012-09-21, 2012-09-21 to 2012-10-21, etc. Fixed items only have a start date and never get pro-rated.
Invoice Items
Fixed Item
An invoice for a subscription on a fixed phase of $0 (trial phase for example) would look like:
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1028 |
FIXED |
Silver trial |
$0 |
2013-03-10 |
Recurring Item
An invoice for a subscription on a recurring phase of $20 would look like:
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1029 |
RECURRING |
Silver monthly |
$20 |
2013-04-11 |
2013-05-11 |
Plan Changes
In a case where invoicing occurs in advance, a user gets charged for the upcoming period. For instance a user that subscribed to a monthly plan on 2013-04-11, would get a first invoice, charging for that month. Assuming he paid his invoice, his balance is now 0. Let’s assume he decides to upgrade on 2013-04-26:
Previous invoice:
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1029 |
RECURRING |
Silver monthly |
$20 |
2013-04-11 |
2013-05-11 |
On the new invoice, the system will generate a REPAIR_ADJ item for the part of the subscription on the old plan that was not used, and a new RECURRING item for the new plan on the remaining period.
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1030 |
RECURRING |
Gold monthly |
$15 |
2013-04-26 |
2013-05-11 |
1029 |
REPAIR_ADJ |
Silver monthly |
$-10 |
2013-04-26 |
2013-05-11 |
Note that if the absolute value of the amount of the REPAIR_ADJ had been greater than the amount of the new RECURRING item, the system would have generated a CBA_ADJ item whose purpose would have been to bring the balance to 0, and provide the customer some credit that would have been used on subsequent invoices.
Invoice Item Adjustment
An invoice item adjustment would look like (assuming the invoice wasn’t paid, otherwise a CBA_ADJ item would be added):
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1029 |
RECURRING |
Silver monthly |
$20 |
2013-04-11 |
2013-05-11 |
1029 |
ITEM_ADJ |
$-20 |
2013-04-20 |
2013-04-20 |
Invoice Adjustment
An invoice adjustment would look similar (assuming again the invoice wasn’t paid, otherwise a CBA_ADJ item would be added):
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1029 |
RECURRING |
Silver monthly |
$20 |
2013-04-11 |
2013-05-11 |
1029 |
CREDIT_ADJ |
$-20 |
2013-04-20 |
2013-04-20 |
A REFUND_ADJ item would be used instead of CREDIT_ADJ if the invoice was paid and a refund had been issued.
Credit
Note that CREDIT_ADJ items are also used to represent credits created by the user (via APIs). In this case, a dummy invoice is created with a negative amount for the CREDIT_ADJ item. This makes the system generate a CBA_ADJ automatically, which in turn can be used as account credits. For example, here is how a $20 credit would be represented:
Invoice # | Type | Description | Amount | Start date | End date |
---|---|---|---|---|---|
1029 |
CREDIT_ADJ |
$-20 |
2013-04-20 |
2013-04-20 |
Invoice Payments
The invoice payment table is the bridge between the invoice and payment subsystems, and is used to compute invoice balances. It will contain the payments, refunds and chargebacks made against an invoice.
If an invoice doesn’t have any corresponding row in invoice payment, this means the invoice isn’t paid (either because no payment was ever attempted, or the payment attempts weren’t successful).
A successful payment against an invoice would have a single row (of type ATTEMPT):
Invoice # | Type | Payment date | Amount |
---|---|---|---|
1029 |
ATTEMPT |
2013-04-12 22:45:39 |
$20 |
Refund
Here is how a payment, followed by a refund would look like:
Invoice # | Type | Payment date | Amount |
---|---|---|---|
1029 |
ATTEMPT |
2013-04-12 22:45:39 |
$20 |
1029 |
REFUND |
2013-04-18 10:23:11 |
$-20 |
Chargeback
Here is how a payment, followed by a chargeback would look like:
Invoice # | Type | Payment date | Amount |
---|---|---|---|
1029 |
ATTEMPT |
2013-04-12 22:45:39 |
$20 |
1029 |
CHARGED_BACK |
2013-04-18 10:23:11 |
$-20 |
Payment
For an overview of the payment subsystem in Kill Bill, check this guide.
Overdue
Overview
Kill Bill offers an Overdue
(or also referred to as Dunning) feature, which is required for when users don’t pay their bills. In those cases, the merchant needs to take some action and so the feature must be customizable. Note that the Entitlement
and Overdue
modules in Kill Bill are tied to each other and are there to manage the customer experience with regards to her subscription(s):
-
The
Entitlement
module defines the behavior of the system when the user starts, cancels a subscription or makes some change in an existing subscription. It controls the level of service received by the user (from no service at all to full service) after such an operation occured. -
The
Overdue
module is in charge of altering the customer experience when payments are not met, and that potentially includes some degradation or even cancelation of the service. The overdue state is defined at the account level, which means that if a user has multiple subscriptions, and an invoice associated with one of them has not been paid, the behavior of the system with regard to the overdue state will be global for all subscriptions.
The Overdue module in Kill Bill relies on a configuration file which drives its behavior. The file is specifed through the use of the org.killbill.overdue.uri
system property. The Overdue module listens to payment events and then, based on the configuration it transitions the overdue state for an account to the appropriate state. Whether the payment was a failure or not, the Overdue module will recompute the state associated with the account and potentially make the transition to another state.
Configuration
The overdue configuration contains a list of the various states through which a customer who does not pay will go through. Each state has a name
and a condition
which is evaluated by the Overdue
module. Currently the condition to transition to a given state is based on the properties below, and the system will evaluate to true if all the part of the conditions are true:
-
numberOfUnpaidInvoicesEqualsOrExceeds
-
totalUnpaidInvoiceBalanceEqualsOrExceeds
-
timeSinceEarliestUnpaidInvoiceEqualsOrExceeds
-
responseForLastFailedPayment
: Specifies the state for the last payment -
responseForLastFailedPaymentIn
: (Not implemented) -
controlTag
: (Not implemented)
Additionally, the definition of an overdue state will also specify some ways to alter the behavior of the system:
-
subscriptionCancellationPolicy
: Whether or not to cancel the subscriptions associated with the account (and the cancellation policy that should be used). Choice is (NONE
,IMMEDIATE
,END_OF_TERM
) -
blockChanges
: Specifies whether the customer is allowed to make any plan change on his subscriptions -
disableEntitlementAndChangesBlocked
: The name is a bit misleading; is specifies whether the subscriptions are being paused, which means service (entitlement) will be disabled and billing will also be disabled. If the overdue state clears, both entitlement and billing would resume at the time of the clearance.
One can add an externalMessage
which can be retrieved by plugins listening to Overdue events, and displayed to the user.
Finally there is an additional property autoReevaluationInterval
that tell the system when to re-evaluate the state when nothing happens in the system: When an account transition to one of the overdue state — specified by the xml file (overdue.xml), two things can happen:
-
The user makes a payment OR the system retries previously failed payments
-
No payment attempt is being made
In the first case, the Overdue system will detect a payment occurred and it will recompute the state, transitioning the a new state if required. In the second case, however, since there was no trigger, we need a way to tell the overdue system to re-evaluate the state every so often so it can advance into the next state if required. That is what the autoReevaluationInterval property is about.
If you need an xsd file, you can find one here or generate one using the overdue xsd-tool:
curl -O 'http://search.maven.org/remotecontent?filepath=org/kill-bill/billing/killbill-overdue/x.y.z/killbill-overdue-x.y.z-xsd-tool.jar'
java -jar killbill-overdue-*-xsd-tool.jar schema.xsd
Tags
Kill Bill offers the ability to tag resources (account, invoice, payment, subscription, …) in the system. There are two main types of tags:
-
User tags
: Those tags are not interpreted by the system; there are a convininent way for admins, third party system to annotate specific existing resources. For instance, the support team could tag account resource associated with specific customer to group them. -
Control tags
: Those tags are interpreted to modify the behavior of the system:-
AUTO_PAY_OFF: This tag can only be associated to an account, and when set it means that the system will not attempt to trigger automatic payments after invoices have been generated. After this tag has been removed, the system will immediately attempt to issue the payments that were not made.
-
AUTO_INVOICING_OFF: This tag can only be associated to an account, and when set it means that the system will not attempt to invoice the customer. After this tag has been removed, the system will immediately attempt to issue invoice the account.
-
OVERDUE_ENFORCEMENT_OFF: This tag can only be associated to an account, and when set it means that the system will not attempt transition the account into an overdue state regardless of his potential failed payments. After this tag has been removed, the system will immediately recompute the current overdue state.
-
MANUAL_PAY: This tag can only be associated to an account, and when set it means that the system will not attempt to trigger automatic payments after invoices have been generated. The intent here is to have the customer make his payment outside of Kill Bill.
-
WRITTEN_OFF: This tag can only be associated to a specific invoice in such a way that it its balance is ignore by the system.
-
TEST: This tag can only be associated to an account, and it is used by analytics plugin so as to not be included set of accounts.
-
PARTNER: This tag can only be associated to an account, and it is used by analytics plugin so as to be interpreted differently.
-
Glossary
Account - An object representing a customer account. It contains details about the customer such as name, address, email address, phone number etc.
Bundle - A bundle is a collection of subscriptions associated with a single service instance. For example, I might have a base subscription for my phone plus an addon that gives me cheap international dialing. Because both Subscriptions are associated with the one phone, they collected into a single bundle. An account may own several Bundles, each with one or more Subscriptions.
Catalog - Catalogs describes the set of Products, Plans, Price Lists and Rules that are being made availabel to customers. A catalog lets Kill Bill know what is being offered for sale and how and how much to charge for it.
Payment Method - Payment methods store the details required for Kill Bill to trigger a payment. They represent things like credit cards, debit cards or Paypal accounts. Each account can have many Payment Methods and at most one Default Payment Method. Note that much of the representation of a Payment Method is plugin-specific and is actually stored by the Payment Plugin itself.
Plan - Plans are Catalog objects that define how a Product is to be paid for. They can have multiple phases (e.g. trial, discount, evergreen). The phase specifies the frequency of payment and the prices in multiple currencies. Each phase can have fixed and recurring prices associated with it. Each Product can have multiple Plans specifying different ways that the Product can be purchased (e.g. a monthly Plan and an annual Plan)
Price list - Price lists are collections of plans that might be associated with a particular program (e.g. an affiliate program or a discount program). A plan can be in many price lists. There must be a default price list that is used when no pricelist is specified. When a subscription changes plan, Catalog rules can be used to determine which Price list the new Plan should use.
Product - Products represent the product or service that the customer buys.
Subscription - A Subscription is a contract that associates an account with a plan and a specific start date. The subscription will trigger automated payments based on the terms of the plan.
Tag - Tag can be added to Accounts, Bundles or Subscriptions. There are two kinds: System Tags can impact the behaviour of the system, User Tags are for information only. System Tags include things like: AUTO_PAY_OFF or AUTO_BILLING_OFF. User Tags can be created through the admin UI and are used to identify collections of Users, Subscriptions or Bundles so that they can easily be found or reported on later.