The Problem
Kill Bill is a portfolio of 16 independent Java‑/JavaScript‑based projects that together form a subscription‑billing platform. The lack of a lockfile means mvn builds are non‑reproducible across environments, and the GitHub Actions workflows reference third‑party actions only by version tag, so the exact code executing with repository secrets can change without notice.
What This Does
Kill Bill delivers a modular billing and payments stack that can be deployed on‑prem or in the cloud. Core capabilities are split across self‑contained modules:
- util (421 files, 399 code) – utilities, templating, call‑context handling.
- invoice (228 files, 220 code) – invoice generation, rendering, and mailing.
- payment (196 files, 188 code) – payment method integration, gateway adapters, and transaction lifecycle.
- catalog (181 files, 157 code) – product/catalog model, pricing, and taxonomy.
- jaxrs (156 files, 150 code) – REST API surface via JAX‑RS (Jersey).
- profiles (179 files, 119 code) – UI profiles for Kill Bill and Kill Pay, including
index.htmlentry points. - api (117 files, 116 code) – thin client‑facing API contracts.
- subscription (124 files, 111 code) – subscription creation, renewal, and cancellation.
- beatrix (174 files, 107 code) – test harness and fixture library.
- entitlement (66 files, 64 code) – feature‑flag and entitlement logic.
- overdue, account, tenant, usage, junction, currency – smaller focused modules.
Entry points for the web UIs are profiles/killbill/src/main/webapp/index.html and profiles/killpay/src/main/webapp/index.html. The platform is built with Maven; a full build from the root runs mvn clean install. Individual modules can be built with their own pom.xml (e.g., account/pom.xml, payment/pom.xml). No Dockerfile is present; containers are typically assembled from the Maven artifacts.
How It Is Wired
The static analysis reports 13 internal modules, 0 import edges, 0 circular dependencies after examining 1500 of 1720 code files (Java 1485, JavaScript 13, Ruby 2). Each module owns its own package space (e.g., org.killbill.billing.util, org.killbill.billing.payment) and exposes a thin service interface. Integration between modules occurs through the JAX‑RS resources in jaxrs/ and the Spring‑managed beans defined in the respective src/main/java directories; there are no direct Java‑to‑JavaScript import edges, so the Java back‑end and the JavaScript front‑ends communicate via HTTP/JSON contracts.
The most‑connected “hubs” in the import graph are the web‑library files under profiles/killbill/src/main/webapp/lib and profiles/killpay/src/main/webapp/lib (e.g., jquery.slideto.min, object-assign-pollyfill). These have Ca 0 Ce 0 instability 0, indicating they are leaf dependencies with no outward import edges from other modules.
A typical request flow:
- HTTP entry –
jaxrsresources (NodeCommandPropertyJson.java, etc.) receive a JSON payload. - Service delegation – the resource forwards to a service bean (e.g.,
DefaultCatalogTranslator.javainutil) that may call catalog or subscription logic. - Domain execution – invoice or payment modules perform the business logic, touching their own DAOs (
AccountDao.java,InvoiceModelDao.java, etc.). - Persistence – SQL DAOs generate statements stored under
src/main/resources/org/killbill/billing/*/dao/*.sql.stg.
Because there are no circular import edges, changing one module (e.g., swapping a payment gateway) does not force recompilation of the others, but it does require the contract at the JAX‑RS boundary to remain compatible.
How To Use It
Setup
# Clone the repository (verbatim URL)
git clone https://github.com/moses-y/killbill.git
# Build the entire project (Maven)
cd killbill
mvn clean install -DskipTests # produces JARs for all 16 modules
Configuration The platform is configured via Spring properties. A typical location is profiles/killbill/src/main/resources/org/killbill/billing/killbill.properties (create from the provided example-killbill.properties). Required environment variables are documented in the README; key ones include KILLBILL_API_KEY, KILLBILL_API_SECRET, and database connection URLs.
Running it To start the embedded Jetty server (Spring Boot plugin) for the Kill Bill profile:
# From the root, run the killbill profile
mvn spring-boot:run -Dspring-boot.run.profiles=killbill
The UI becomes available at http://localhost:8080. For the Kill Pay profile, use -Dspring-boot.run.profiles=killpay.
Testing Unit tests live in each module’s src/test (e.g., account/src/test/java/org/killbill/billing/account/AccountTestSuiteNoDB.java). Run the suite with mvn test.
Real‑World Use
A SaaS startup wants to replace a costly third‑party billing provider. They clone Kill Bill, configure their PostgreSQL database and Stripe API keys in killbill.properties, then run mvn spring-boot:run -Pkillbill. The team can immediately begin creating plans via the UI (profiles/killbill/src/main/webapp/index.html) or programmatically through the JAX‑RS API (jaxrs/src/main/java/org/killbill/billing/jaxrs/). When they need to add a new payment method, they edit the payment module’s gateway adapter and rebuild only that module – the rest of the system remains untouched.
Code Health & Issues
- HIGH – Pin third‑party GitHub Actions to a commit SHA. Evidence:
.github/workflows/ci.yml@java21,s4u/maven-settings-action@v4.0.0,ruby/setup-ruby@v1,.github/workflows/codeql-analysis.yml@java21. Fix: replace@vNwith the 40‑character SHA; let Dependabot bump SHAs.
- MEDIUM – Declare least‑privilege permissions for
GITHUB_TOKEN. Evidence: 4 workflows declare no permissions, 2 reference secrets. Fix: addpermissions: contents: readat the top of each workflow and widen per‑job only where needed.
- MEDIUM – Move large binaries to Git LFS or out of the repository. Evidence:
profiles/killbill/src/main/webapp/lib/swagger-ui-bundle.js.map5.4 MB (plus other >5 MB blobs). Fix: track extensions with LFS or move datasets to object storage and fetch in a setup step.
- LOW – Set
timeout-minuteson workflow jobs. Evidence: 3 workflows (codeql-analysis.yml) declare no job timeout. Fix: add a realistictimeout-minutesto each job.
- LOW – Add repository convention files this project lacks. Evidence: missing
.editorconfig,.gitattributes, formatter config. Fix: add.editorconfig,.gitattributeswithtext=auto eol=lf, and a formatter config (e.g., Google Java Format).
The Bottom Line
Kill Bill is a well‑structured, modular open‑source billing platform that excels when you need fine‑grained control over subscriptions, invoicing, and payments across many independent services. Its 16‑project layout avoids monolithic entanglement, but the absence of a dependency lockfile and unpinned GitHub Actions introduces reproducibility risk. Teams comfortable with Maven‑driven Java back‑ends and JavaScript front‑ends, and who can enforce the listed CI hygiene fixes, will find it a solid foundation for a custom billing stack.