Kill Bill: plugins architecture

Kill Bill wasn’t our first billing system. As we developed these systems, even though the very core always looked the same (i.e. compute invoices and charge customers on a regular basis), it became obvious that each and every one of them required a great deal of flexibility and heavy business logic customization. In Kill Bill, while we addressed the need for plan customization via our catalog module and its set of rules and policies, we developed a plugin framework for pretty much anything else, from reacting to system events to third party integrations.

When designing this plugin framework, we quickly settled for an OSGI integration. This gave us a lot of features for free, such as lifecycle and isolation, and allowed us to support non Kill Bill specific bundles (we call these platform plugins). As an example, we run in production the Felix Web Console, which is a great debugging tool. OSGI is quite a complex framework though, so we tried to hide as much complexity as possible from the user who simply wants to develop a Kill Bill specific plugin. We made it so that all that is required is to implement certain interfaces that Kill Bill will use to communicate with the plugin. The type of interfaces implemented determine the type of plugin.

The first type of plugin supported is payment plugins. By default, Kill Bill doesn’t know about any payment gateway. Instead, each account has a series of payment methods (credit cards, PayPal accounts, Bitcoin wallets, etc.) attached to it, and each payment method is associated with a given plugin. There is no built-in concept of credit card for example: payment methods are completely generic, and it’s the role of the plugin to understand how to charge or refund the customer.

The second type of plugin supported is notification plugins. These react to system events (e.g. account creation or payment error). As an example, the Zendesk plugin listens to account creation and update events, and mirrors Kill Bill data into Zendesk. That way, both systems are always in sync, and Zendesk agents can access Kill Bill data directly in Zendesk tickets. Another example is the Analytics plugin, which listens to all events in the system, and maintains a set of reporting tables in real-time for business intelligence.

Both types of plugin have access to the full set of Kill Bill APIs. You could imagine writing a plugin which monitors cancellations of trials. Upon cancellation, the plugin could query Kill Bill to get the account contact details and reach the customer via email. Plugins can also expose custom HTTP endpoints (which will be served by the same container as Kill Bill) and have their own database tables (plugins share a custom JDBC connection pool, separate from the system).

Kill Bill plugin architecture

Historically, we wrote our first plugins in Java. Unfortunately, not many payment gateways provide Java libraries to access their APIs, and we had to implement our own (such as the Recurly Java library), considerably slowing down our development process. This also wouldn’t scale with the hundreds of gateways out there. Fortunately, the folks over at Shopify had developed Active Merchant, an abstraction library for dozens of payment gateways. Supporting Active Merchant would grant us access to all of these gateways pretty much for free.

The only caveat was that Active Merchant is a Ruby gem. We hence decided to build a Ruby – OSGI bridge, allowing one to write plugins in Ruby. Similar to the Java experience, we focused on hiding the OSGI complexity as much as possible. For example, you can easily develop Rack and Sinatra applications which the framework will proxy automatically via the Kill Bill container or use ActiveRecord to access the Kill Bill database. The first two plugins implemented in Ruby were for PayPal and Litle, plugins that are still running in production today at Ning. Since then, we have also developed a Stripe and Coinbase one, both in Ruby as well.

For more details on plugin deployment, check our userguide. To get started writing your own, you can start with our Hello Wold Java plugin and Hello World Ruby plugin. Get in touch in our Google group if you need help!

Leave a Reply