Payment plugins integrate Kill Bill with a specific gateway (i.e. payment processor), such as Stripe or Braintree. While we already have many open-source payment plugins available on GitHub, this guide will give you pointers in case you need to develop your own.

Before reading this guide, make sure to familiarize yourself with the main payment userguide.

PaymentPluginApi overview

The PaymentPluginApi is the interface between Kill Bill and payment plugins.

Here are the actions the plugin can expose:

  • authorizePayment and capturePayment should trigger an authorization and capture respectfully (applies to credit cards only)

  • purchasePayment should trigger a generic payment (authorization with auto-capture for credit cards, ACH/SEPA, etc.)

  • voidPayment should void an authorization (credit cards only)

  • creditPayment should fund the payment method from your merchant account (similar to a refund, but no prior payment is required: this can be used to initiate an ACH for disbursement for instance)

  • refundPayment should reverse an existing (settled) charge

  • getPaymentInfo should return detailed information on the transactions for that payment (arbitrary properties can be populated in PaymentTransactionInfoPlugin#getProperties)

  • searchPayments should return payment transactions matching the specified searchKey (the implementation is up to the plugin)

  • addPaymentMethod should create the payment method in the gateway (e.g. store a token)

  • deletePaymentMethod should delete the payment method in the gateway (e.g. revoke a token)

  • getPaymentMethodDetail should return detailed information about the payment method (e.g. billing address)

  • setDefaultPaymentMethod should mark the payment method as the default one in the gateway (if the associated account in the gateway has several payment methods)

  • getPaymentMethods should list the payment methods in the gateway for that account (used by the refresh endpoint, when payment methods are added directly in the gateway, bypassing addPaymentMethod)

  • resetPaymentMethods, called at the end of a refresh call, should associate to that account the payment methods specified (this is useful if Kill Bill knows payment methods that are not yet in the gateway)

  • searchPaymentMethods should return payment methods matching the specified searchKey (the implementation is up to the plugin)

  • buildFormDescriptor should return enough metadata for the front-end to build a form or a redirect to a hosted payment page

  • processNotification should process payloads from the gateway to transition payments states

If an operation is not supported, the plugin must:

  • return an empty list when the return type is a list

  • return a transaction with status CANCELED if the return type is a PaymentTransactionInfoPlugin (see below)

  • return empty objects otherwise

PaymentPluginStatus states overview

When building PaymentTransactionInfoPlugin objects, it is very important to correctly populate the status type:

  • if the payment is successful, the plugin should return PROCESSED

  • if the payment is rejected by the gateway (insufficient funds, fails AVS check, fraud detected, etc.), the plugin should return ERROR

  • if the payment requires a completion step (3D-S verification, HPP, etc.), the plugin should return PENDING

  • if the gateway wasn’t contacted (DNS error, SSL handshake error, socket connect timeout, etc.), the plugin should return CANCELED

  • for all other cases (socket read timeout, 500 returned, etc.), the plugin should return UNDEFINED

You should try to avoid UNDEFINED as much as possible, because it is the only case where Kill Bill cannot retry payments (since the payment may or may not have happened).

Janitor integration

Kill Bill will attempt to fix PENDING and UNKNOWN states by polling the plugin via getPaymentInfo: if the plugin subsequently returns PROCESSED for example (maybe by querying the gateway directly), the internal payment state (as well as invoice balance, etc.) will be reflected.

The Janitor will match internal transactions against plugin transactions via the transaction id: make sure getKbTransactionPaymentId is correctly implemented.

Plugin Activation

When a payment operation occurs, Kil Bill will chose which payment plugin to go to based on the paymentMethodId specified. The paymentMethodId will map to an specific payment method, which in turns contains the name of the plugin to chose for the payment.

Payment plugins framework

To help with writing payment plugins, we developed a Java framework which ensures that the plugin will respect the previous mentioned conditions. If you are developing your own plugin, we strongly encourage you to use this library. The easiest is to copy an existing plugin and modify it for your gateway. The Adyen plugin is a good starting point.