Note! An updated version of this tutorial can be found here.
Kill Bill has been dockerized! In this post, I’m going to show you how to get started with your own Kill Bill installation, integrated with Stripe, running on Docker.
Setup
Start by installing Docker if you don’t have it yet.
You will also need a Stripe api key. To get one:
- Create a free account at Stripe.com
- Go to your API Key Settings
- Write down the Test Secret Key
Deep dive into the Kill Bill container
Our Docker image is based off the ubuntu:14.04
one. It comes with Tomcat and KPM (the Kill Bill package manager). Kill Bill is not yet present in the image: it is the role of KPM to fetch the Kill Bill war and its plugins. The first time the container is started, KPM will look at its configuration file (/etc/killbill/kpm.yml
) and lay down the bits accordingly. The reason for this deferred step is to let you customize the image if you want to (Kill Bill version, plugins, etc.).
You can start Kill Bill by running: docker run -tid --name killbilltest -p 8080:8080 killbill/killbill
--name killbilltest
assigns a name to the container, to be able to reference it easily later on-p 8080:8080
exports the port from the container, to access it from the host
Here are some useful commands:
docker logs -f killbilltest
to tail the Kill Bill logsdocker exec -ti killbilltest /bin/bash
to log-in to the containerdocker exec -ti killbilltest cat /etc/killbill/killbill.properties
to explore the Kill Bill configurationdocker exec -ti killbilltest cat /etc/killbill/kpm.yml
to explore the KPM configuration
When the installation is complete, retrieve the IP from the container host (on MacOS, run boot2docker ip
). We’ll assume this IP is 192.168.1.1 in the rest of this post. Kill Bill should then be available at http://192.168.1.1:8080. Note that if you want to use Swagger, the exploratory API tool shipped with Kill Bill, make sure to update the IP in the toolbar of http://192.168.1.1:8080/api.html.
At this point, Kill Bill is fully functional and you can run the 5′ tutorials from either our subscriptions userguide or payments userguide. Remember to update the IP address in the URLs with the one from the container host (boot2docker ip
on MacOS).
You can stop (docker stop killbilltest
) and restart the container (docker start killbilltest
) as will, without going through the installation process again. If you need to re-install or upgrade Kill Bill, you can force a re-installation by deleting /etc/killbill/kpm.yml
in the container and re-starting it.
MySQL container setup
At this point, you have a fully running Kill Bill setup. By default however, a file-based H2 database is used (exported at /var/lib/killbill
), which is good enough only for rapid prototyping. This section will show you how to setup a MySQL database instead.
Let’s setup a MariaDB container: docker run -tid --name mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -p 3306:3306 mariadb
.
Because Kill Bill uses InnoDB, you’ll need to change the default binlog
format by running (remember to update the IP address):
echo "set global binlog_format = 'ROW'" | mysql -h 192.168.1.1 -uroot -pmysecretpassword
The final step is to create the killbill
database and apply the DDL schema:
echo 'create database killbill' | mysql -h 192.168.1.1 -uroot -pmysecretpassword
curl https://docs.killbill.io/0.14/ddl.sql | mysql -h 192.168.1.1 -uroot killbill -pmysecretpassword
This will have created the killbill database along with its core tables.
Kill Bill with Stripe container setup
In this section, we are going to setup a Kill Bill container, with the Stripe plugin, linked against the MySQL container.
First, apply the DDL schema for the Stripe plugin (remember to update the IP address):
curl https://raw.githubusercontent.com/killbill/killbill-stripe-plugin/master/db/ddl.sql | mysql -h 192.168.1.1 -uroot killbill -pmysecretpassword
Second, create a configuration file $HOME/docker/etc/killbill/stripe.yml
with your API key:
:stripe:
:api_secret_key: 'sk_test_aaaabbbbccccdddd'
:api_publishable_key: 'pk_test_aaaabbbbccccdddd'
:test: true
Finally, run the image again (make sure to stop and delete the container we created in step 1):
docker stop killbilltest
docker rm killbilltest
docker run -tid \
--name killbilltest \
-p 8080:8080 \
--link mysql:mysql \
-v $HOME/docker/etc/killbill/stripe.yml:/etc/killbill/stripe.yml \
-e KILLBILL_PLUGIN_STRIPE=1 \
-e KILLBILL_CONFIG_DAO_URL=jdbc:mysql://mysql:3306/killbill \
-e KILLBILL_CONFIG_DAO_USER=root \
-e KILLBILL_CONFIG_DAO_PASSWORD=mysecretpassword \
-e KILLBILL_CONFIG_OSGI_DAO_URL=jdbc:mysql://mysql:3306/killbill \
-e KILLBILL_CONFIG_OSGI_DAO_USER=root \
-e KILLBILL_CONFIG_OSGI_DAO_PASSWORD=mysecretpassword \
killbill/killbill:0.14.0
Some notes:
KILLBILL_PLUGIN_STRIPE=1
tells KPM to install the Stripe plugin-v $HOME/docker/etc/killbill/stripe.yml:/etc/killbill/stripe.yml
exposes the localstripe.yml
to the containerKILLBILL_CONFIG_
parameters tell Kill Bill where the database is located (Kill Bill has two JDBC pools, one for the core and one of OSGI plugins). The special aliasmysql
is automatically setup by Docker in the container because of the link
The process will take a few minutes (the installation is similar to the first container we ran, but the extra Stripe plugin needs to be downloaded). You can monitor it by running: docker logs -f killbilltest
.
That’s it! Kill Bill is now up and running, using Stripe as a gateway!
Testing the integration
As usual, let’s start by creating a tenant:
curl -v \
-X POST \
-u admin:password \
-H 'Content-Type: application/json' \
-H 'X-Killbill-CreatedBy: admin' \
-d '{"apiKey": "bob", "apiSecret": "lazar"}' \
"http://192.168.1.1:8080/1.0/kb/tenants"
We first need to create an account for John, a shopper on our website:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{"name":"John Doe","email":"[email protected]","externalKey":"john-doe-1234","currency":"USD"}' \
"http://192.168.1.1:8080/1.0/kb/accounts"
The API will return a Location header with the UUID of the created account. We will assume it is 82c45d70-6f63-11e4-9803-0800200c9a66 in the rest of this blog, update the urls as needed.
The next step is to add a payment method, in our case a credit card, to his account. This credit card will be validated and stored by Stripe:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-X POST \
--data-binary '{
"pluginName": "killbill-stripe",
"pluginInfo": {
"properties": [
{
"key": "ccExpirationMonth",
"value": 12
},
{
"key": "ccExpirationYear",
"value": 2017
},
{
"key": "ccNumber",
"value": 4111111111111111
}
]
}
}' \
"http://192.168.1.1:8080/1.0/kb/accounts/82c45d70-6f63-11e4-9803-0800200c9a66/paymentMethods?isDefault=true"
You can take a look at the logs on Stripe on your dashboard and verify a new customer with a credit card was added here.
Now, let’s try to trigger a payment for that account:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
--data-binary '{"transactionType":"PURCHASE","amount":"15","currency":"USD","transactionExternalKey":"INV-002-PURCHASE"}' \
"http://192.168.1.1:8080/1.0/kb/accounts/82c45d70-6f63-11e4-9803-0800200c9a66/payments"
An example a bit more advanced is a partial capture. Start by authorizing a payment:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
--data-binary '{"transactionType":"AUTHORIZE","amount":"10","currency":"USD","transactionExternalKey":"INV-001-AUTH"}' \
"http://192.168.1.1:8080/1.0/kb/accounts/82c45d70-6f63-11e4-9803-0800200c9a66/payments"
Kill Bill will return the payment id, which you can use to trigger the (partial) capture:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
--data-binary '{"amount":"5","currency":"USD","transactionExternalKey":"INV-001-CAPTURE"}' \
"http://192.168.1.1:8080/1.0/kb/payments/3fef7d30-6f64-11e4-9803-0800200c9a66"
Note: the Stripe UI is a bit confusing for that usecase. Even though we’re just doing a partial capture, Stripe will show on the dashboard that $5 ($10 auth -$5 capture) was refunded (they also don’t seem to support multiple partial captures).
Next steps
You are now ready to integrate Kill Bill in your workflow. Jump to our userguide on how to get started. In a subsequent post, we’ll show you how you can seemlessly deploy your container to EC2.