Back in the days, when we started the design for Kill Bill, some of the first discussions we had were centered around catalog (definition of products, prices, behavior associated to each product or transition from one product to another, etc.).
We had lots of use cases that we knew about, such as providing support for trials and discount, grouping things on one or multiple invoices, providing support for subscription dependencies (add-ons), international support, and so forth. Our initial implementation was based on a static set of XML files, where each file represents a specific version of the catalog. XML proved to be a fairly good choice to represent our various abstractions and provide the flexibility
we wanted through the use of various catalog rules.
However, we also knew that our knowledge was incomplete, but the idea was that, as we would discover new use cases, we could enhance our object model. And this statement also happened to be true: when we started to implement some of the usage billing case scenarios, we added new usage sections in our catalog XML and again the XML representation was powerful enough to cover all the use cases we came across.
When we moved to fully implement the multi-tenancy feature, we then needed to have each tenant own its catalog. The XML based model was still a good fit. The only difference here, was that the catalog was not something that was shared across tenants any longer, but something that administrators of the various tenants could configure through the use of endpoints.
Then, one day, on the mailing list, we had a request to support price customization on a per-subscription basis. In the eventuality that one knows in advance all the possible set of prices, a static catalog would still work here, although it may become arbitrarily large and therefore would require some tooling to create, update, etc. But in a broader sense, where prices are all over the place (for instance, each customer may be assigned a specific price), we see the limitation of a static model. So, we implemented a feature called price override which is an extension of our static XML based catalog. When creating the subscription, an existing product from the (static) catalog must be provided, but in addition, one can override the price at the phase (and currency) level.
More recently, we encountered a use case where a company already had its own catalog that is used in many different parts of their existing system, and yet they want to rely on Kill Bill for the subscription management and invoicing part. One (easy) alternative here is to create a second version of that catalog (Kill Bill catalog), but of course we now end up with two versions that may not be in sync, and on top of that, all the pricing strategies now become much more complex to implement. So, in order to support that use case, we decided to add a new type of plugin API, namely the CatalogPluginApi: One can now implement a plugin that, on one hand will interact with the Kill Bill core catalog system to provide transparently all the catalog entries and on the other hand will interact with a third-party catalog system.
The new catalog plugin API opens the door for many different use cases, including all the use cases we described earlier with the static XML catalog. As long as one can fulfill the contract imposed by the API, there is no limitation in what could be implemented in such a plugin. The new feature is available in our 0.15.0 release and we created examples of a java plugin and ruby plugin to illustrate the use of the API.