Open Source Software: The Kill Bill Story

Open Source Software: The Kill Bill Story

There has been a lot of ink written about software models and why/when it makes sense to use open-source software (OSS); there was recently an interesting article about that specific topic. The short story is that such decision is based on many different factors, including the available options (OSS and non OSS), engineering organization, short term/long term choices, company DNA, … In this post, i would like to focus on our project specifically by asking two questions, one addressed to folks looking for billing and payment solutions and one to the Kill Bill team (note that i am both asking the questions and answering them for all parties, which is quite convenient…) Fictitious Journalist: “So, you are looking for billing and payment solutions, what are your choices, why Kill Bill?” In the world of billing and payments, companies are left with 3 main options (all of them with their pros/cons): 1. SAAS model This is often presented as a turn key option that will solve all your problems so you can focus on your IP and not be distracted by things that are irrelevant to your business: This statement is true in the sense that pretty much any developer using (pretty much any language of his choice) could quickly integrate with a SAAS business and start processing subscriptions, or making payments through a gateway. However, it is also misleading for the following reasons: Each business will need its special business logic and so simply using the raw apis from the SAAS will not be enough; often there is a need for another system in front of that SAAS (to implement...
Bill Cycle Day Overrides

Bill Cycle Day Overrides

Until now, Kill Bill only allowed to configure the Bill Cycle Day (BCD) attached to each subscription through the use of billing alignment catalog rules. As a reminder, the BCD defines the day when a specific subscription gets billed. For instance assuming customers get billed in advance, then creating a monthly subscription on 6/1/2016 with a BCD=1 would generate a first invoice on the 6/1/2016 for the month of June, and then a next invoice on July 1st for the month of July, etc… In the current scheme, there are 3 different possible billing alignment policies, that are configured using special catalog rules: ACCOUNT: All subscriptions whose Plan is defined with an ACCOUNT alignment will use the same account level BCD. This allows to group all subscriptions for an account on the same invoice. The BCD is either set using api, or if not set, the system will infer that BCD when the first subscription on the account is created (by looking at the first Phase in the Plan whose recurring price is not 0). SUBSCRIPTION: The BCD is based on the subscription startDate and by also looking at the first Phase in the Plan whose recurring price is not 0. BUNDLE: This is similar to the SUBSCRIPTION case but the system will use the start date of the base subscription to compute the BCD. With the existing mechanism, the administrator configures once the various policies in the catalog and then everything happens automatically. This approach is convenient but rather static (does not allow to change a BCD for an existing subscription). In order to provide a more dynamic...
BlockingState Abstractions

BlockingState Abstractions

In this blog, we will explore the power behind the BlockingState abstraction inside Kill Bill. Overview: The BlockingState events were introduced in version 0.6.x, so while they are certainly not new, they were mostly used for internal purpose inside Kill Bill.  We recently enriched our apis to make them fully available to plugins. Let’s take a simple use case where a user subscribes to a monthly recurring Plan on January 1st 2016 (and catalog was configured to bill in advance). Each 1st of the month, the invoicing system takes as an input the subscription state (subscription events) and the user is billed for a full month. This works quite well, but how can we address the following questions:   Entitlement: The ability to separate what the user is billed for and the service that she receives (e.g if user cancels mid month, we may want to terminate the service right away and keep the billing until the end of the month) Overdue: The user does not pay its bills. We want to allow to introduce some states that will define a gradual degrade of the service until the user pays Pause/Resume: Ability to arbitrarily pause the billing (and/or its associated entitlement) for a period of time. The BlockingState events allow to introduce arbitrary states associated to subscriptions, and allow to modify the behavior of the system to block billing or entitlement periods, solving the original use cases we had and more…   Internals: Before looking at their usage, let’s review what they contain: stateName : A string that is to be interpreted by the service inserting such event blockingStateType : An...
Kill Bill 0.16.0 Released!

Kill Bill 0.16.0 Released!

We are excited to announce our new release Kill Bill 0.16.x (and we just released 0.16.1 to make it even better)! This is the result of 6 months of hard work and a lot has happened… so let’s review: Performance Improvement This has been a very long effort that started already in release 0.14.x and that we have continued forward. We have already posted some notes about the work and some results. Obviously performance is a never ending task because as the system evolves, it becomes necessary to verify there is no performance regression, but we now have a stable and performant system and all the tools to continue the work (tests, perf framework and baseline to compare numbers). Full Payment Stack One of the main focus of that release was around the payment subsystem. Kill Bill now offers a full payment subsystem (unrelated to the subscription/invoicing engine), with standalone payment apis (auth, capture, refund, …). The payment subsystem has been implemented on top of state machines that enforce correct transitions for payment transactions and offers 2 flexible payment plugin apis to extend the core payment system: The payment plugin api allows to extend the core payment system to interact with third party payment gateways or processors. We already have 16 such payment plugins (for Stripe, CyberSource, Adyen, PayPal, Braintree, …) The payment control plugin api allows to intercept payment operations in real time to customize the system. There are many use cases for this api (integration with fraud systems, payment routing, retry strategies, disbursement, currency conversion, …) We believe we can support any payment flows and integrate with...
Performance Numbers

Performance Numbers

In the past year, we have done a lot of work on performance, and we already had the opportunity to describe some of that work in a previous blog entry. We now feel it is time to provide some numbers, but numbers in themselves are meaningless, unless we provide some context. Expectations and target goal: A good place to start is to look at our software stack to get a sense of any limitation: We are relying on a standard set of battle-tested open-source components (Linux, MySQL, Tomcat, Java, Ruby, and all kinds of software libraries…). The best performance numbers we could expect would be with a Tomcat handler that simply returns 200 OK. Such a deployment could achieve 1,000 or even 10,000 requests per second. Now, if the handler needs to keep some persistent state, and each request requires fetching state from a database and writing new state, the numbers could easily be divided by 10, and we would expect results in the 100 to 1,000 requests per second. Another angle is to look at existing data from the industry: Amazon, the largest US eCommerce site, processed about 400 payments/second during black Friday. Also, as Pierre mentioned in his previous blog post, typical eCommerce sites usually process a few payments per second at most; a brief calculation shows that a system processing on average 10 payments per second of $10 would already result in $8M per day or over $3B per year. Based on those numbers (what we expect to achieve and what the industry needs), we understand our target goal is somewhere in the 100 to 1,000...