The purpose of this document is to explain how to customize an invoice sent via the Email Notification Plugin.


  • You have Kill Bill, Kaui, and the database set up as explained in the Getting Started Guide.

  • You have the email notification plugin (version 0.7.0 or higher) installed as explained in the Email Notification Plugin document.


The email notification plugin can be used to send emails to customers when certain predefined events occur. The plugin defines some email templates which determine the body of the email. Users can also upload their own custom templates. Sometimes users may wish to customize the invoice data sent in the email by including additional fields. This can be achieved by creating a custom plugin as explained in this document.

Plugin Tutorial

We have created a sample plugin that demonstrates a custom invoice formatter. You can use this as a starting point for developing your plugin. Let us now take a closer look at how you can create a similar custom plugin.

Initial Setup

  1. Create a new Maven project.

  2. Copy the pom.xml from the sample project.

Create InvoiceFormatter class

First, you need to create an InvoiceFormatter class similar to CustomInvoiceFormatter as follows:

public class CustomInvoiceFormatter extends DefaultInvoiceFormatter {

	public CustomInvoiceFormatter(Map<String, String> translator, Invoice invoice, Locale locale) {
		super(translator, invoice, locale);
		logger.info("Creating CustomInvoiceFormatter");

	private static final Logger logger = LoggerFactory.getLogger(CustomInvoiceFormatter.class);

    private String newInvoiceMessage="Here is your new invoice!!";

	public String getNewInvoiceMessage() {
		return newInvoiceMessage;

  • The CustomInvoiceFormatter class extends org.killbill.billing.plugin.notification.generator.formatters.DefaultInvoiceFormatter.

  • A field called newInvoiceMessage is defined. This is a custom field. It has a corresponding getNewInvoiceMessage method.

  • You can add other custom fields as required. For each field, ensure that the field is initialized and that there is a getter method that returns the value of the field.

Create InvoiceFormatterFactory class

Next, you need to create an InvoiceFormatterFactory class similar to the CustomInvoiceFormatterFactory class. This is responsible for creating an InvoiceFormatter.

public class CustomInvoiceFormatterFactory implements InvoiceFormatterFactory {

	private static final Logger logger = LoggerFactory.getLogger(CustomInvoiceFormatterFactory.class);

	public CustomInvoiceFormatterFactory() {
		logger.info("Creating CustomInvoiceFormatterFactory");

	public InvoiceFormatter createInvoiceFormatter(Map<String, String> translator, Invoice invoice, Locale locale,
			TenantContext context) {
		return new CustomInvoiceFormatter(translator, invoice, locale);

  • The CustomInvoiceFormatterFactory implements the org.killbill.billing.plugin.notification.api.InvoiceFormatterFactory interface.

  • It has a createInvoiceFormatter formatter method that creates and returns a CustomInvoiceFormatter object.

Create Activator

Finally, you need to create an Activator class similar to the CustomInvoiceFormatterActivator. As with other plugins, the Activator class is responsible for registering the plugin with Kill Bill.

public class CustomInvoiceFormatterActivator extends KillbillActivatorBase{

	public static final String PLUGIN_NAME = "custom-email-invoice-formatter-plugin";

	private CustomInvoiceFormatterFactory customInvoiceFormatterFactory;
	private ServiceRegistration<InvoiceFormatterFactory> registration = null;

	public void start(final BundleContext context) throws Exception {

		// create CustomInvoiceFormatterFactory
		customInvoiceFormatterFactory = new CustomInvoiceFormatterFactory();
		Hashtable<String, Object> properties = new Hashtable<>();
		registration = context.registerService(InvoiceFormatterFactory.class, customInvoiceFormatterFactory,
				properties); // register factory as OSGi service


	public void stop(final BundleContext context) throws Exception {
		if (registration != null) {
			registration = null;
		// Do additional work on shutdown (optional)

  • The CustomInvoiceFormatterActivator extends the org.killbill.billing.osgi.libs.killbill.KillbillActivatorBase class.

  • The start method creates a CustomInvoiceFormatterFactory and registers it as an OGGi service as shown above.

  • The stop method unregisters the service.

Build and Deploy

Once the code changes as done, the custom plugin can be built and deployed as explained below.

  1. Build the code using the following Maven command:

    mvn clean install -DskipTests=true
  2. Install the plugin using the following kpm command (Replace <path_to_install_plugin> with the path where you want to install the plugin. This path should match the path specified by the org.killbill.osgi.bundle.install.dir property in the Kill Bill configuration file):

    kpm install_java_plugin 'dev-custom-invoice-formatter' --from-source-file=target/custom-invoice-formatter-plugin*-SNAPSHOT.jar --destination=<path_to_install_plugin>


In order to test the plugin,you need to upload an email template with the new invoice fields and execute the steps that would trigger the email.

For example, in order to include the newInvoiceMessage field created earlier in the invoice creation email, you will need to do the following:

  • Upload the SampleInvoiceCreation_en_US.mustache template as explained here (This template includes the newInvoiceMessage field).

  • Trigger the invoice creation email as explained here.

  • Verify that the email includes the newInvoiceMessage field.