Open-source alternatives guide
How to Migrate from Stripe Billing to Kill Bill in 2026
Stripe Billing charges 0.5-0.8% of recurring revenue on top of payment processing fees. Kill Bill is a self-hosted open source billing platform with no.
The Stripe Billing Cost Problem
Stripe is excellent as a payment processor. At 2.9% + $0.30 per transaction, it's competitive. The cost problem compounds when you add Stripe Billing for subscription management.
Stripe Billing fees (2026):
- Starter: 0.5% of recurring revenue
- Scale: 0.8% of recurring revenue
- Plus the base payment processing fee (2.9% + $0.30)
For a SaaS business doing $500,000 ARR:
- Stripe Billing fee: $2,500-4,000/year (0.5-0.8%)
- Payment processing: ~$14,500/year (2.9%)
- Total: $17,000+/year
Stripe Billing's percentage fee is separate from payment processing. At $1M ARR, that's $5,000-8,000/year just for subscription management — before payment processing.
Kill Bill (Apache 2.0 license) is the most mature open source billing and subscription management platform. Self-hosted, no percentage fees, 10+ years of production use. You still pay Stripe (or another processor) for payment processing, but you eliminate the subscription management layer fee.
Important caveat: This migration is technically complex. Billing systems are critical infrastructure. Budget 2-8 weeks of engineering time for a production migration. This guide covers the approach and key decisions, not a copy-paste solution.
What Kill Bill Provides
Kill Bill is not a Stripe replacement — it doesn't process payments. It's a subscription management and billing engine that sits between your application and payment processors.
Kill Bill handles:
- Subscription lifecycle (create, upgrade, downgrade, cancel, pause)
- Billing plan changes and proration
- Invoice generation
- Payment orchestration (sends payment requests to your processor)
- Dunning (retry logic for failed payments)
- Credit management
- Tax calculation integration
- Revenue reporting
Payment processors Kill Bill works with:
- Stripe (Kill Bill sends payment requests to Stripe, eliminating Stripe Billing fee)
- Adyen
- Braintree
- PayPal
- Many others via plugins
The key: you use Kill Bill for subscription logic, Stripe just processes the individual payments. You pay Stripe's 2.9% processing fee but not the 0.5-0.8% Billing fee.
Before You Start: Is Kill Bill Right for You?
Kill Bill is a serious engineering commitment. It's appropriate when:
- You're processing $200K+ ARR and the percentage fee savings justify the engineering cost
- You need billing customization that Stripe Billing doesn't support
- Your billing model is complex (usage-based, tiered, hybrid)
- You require full control of billing data (financial services, compliance requirements)
Consider staying with Stripe Billing if:
- You're under $200K ARR (engineering cost outweighs savings)
- Your team doesn't have Java/backend experience
- You need features like Stripe Revenue Recovery (ML-based dunning)
- Simplicity is a higher priority than cost optimization
Other self-hosted alternatives to evaluate:
- Lago (GitHub: 7K+ stars, MIT): More modern codebase, easier setup than Kill Bill. Good for usage-based billing.
- BillaBear (Stripe Billing-specific alternative): PHP, simpler setup
- Medusa.js (for eCommerce): Better if you're in commerce rather than pure SaaS
Architecture Overview
Your Application
│
▼
Kill Bill API
├── Subscription Engine (plans, entitlements, proration)
├── Invoice Engine (billing calculation)
├── Payment Engine (orchestrates payment processors)
└── Plugin System
│
▼
Kill Bill Stripe Plugin
│
▼
Stripe API (payment processing only)
Your application talks to Kill Bill. Kill Bill handles billing logic. Kill Bill's Stripe plugin handles payment collection. Stripe's role is reduced to payment processing only.
Step 1: Set Up Kill Bill Infrastructure
Kill Bill runs on Java (JVM). Self-hosting options:
Docker Compose (Development/Testing)
services:
killbill:
image: killbill/killbill:latest
ports:
- "8080:8080"
environment:
KB_org.killbill.dao.url: jdbc:mysql://db:3306/killbill
KB_org.killbill.dao.user: root
KB_org.killbill.dao.password: killbill
KB_org.killbill.billing.osgi.bundles.jruby.version: LATEST
depends_on:
- db
kaui:
image: killbill/kaui:latest
ports:
- "9090:8080"
environment:
KAUI_CONFIG_DAO_URL: jdbc:mysql://db:3306/kaui
KAUI_CONFIG_DAO_USER: root
KAUI_CONFIG_DAO_PASSWORD: killbill
KAUI_KILLBILL_URL: http://killbill:8080
depends_on:
- db
db:
image: killbill/mariadb:latest
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: killbill
KAUI is Kill Bill's admin UI. It lets you manage accounts, subscriptions, and invoices through a web interface.
Production Deployment
For production, Kill Bill requires:
- 4GB RAM minimum (8GB recommended)
- MySQL or PostgreSQL database
- Persistent storage for the database
- Load balancer for horizontal scaling (Kill Bill is stateless)
Kill Bill is horizontally scalable — run multiple Kill Bill instances behind a load balancer for high availability.
Verify Installation
# Test Kill Bill API is running
curl -u admin:password http://localhost:8080/1.0/kb/test/clock
Step 2: Install the Stripe Plugin
Kill Bill uses plugins for payment processor integration. Install the Stripe plugin:
# Via Kill Bill admin API
curl -v \
-X POST \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: admin" \
"http://127.0.0.1:8080/1.0/kb/plugins/installPlugin" \
-d '{
"pluginKey": "stripe",
"pluginType": "PAYMENT",
"pluginVersion": "LATEST"
}'
Configure the Stripe plugin with your API keys:
curl -v \
-X POST \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: admin" \
"http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-stripe" \
-d "org.killbill.billing.plugin.stripe.apiKey=sk_live_your_stripe_secret_key"
Step 3: Create Your Catalog (Billing Plans)
Kill Bill's billing plans are defined in an XML catalog. This is the core configuration that determines what your customers can purchase.
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="CatalogSchema.xsd"
standaloneCatalog="false">
<effectiveDate>2026-01-01T00:00:00+00:00</effectiveDate>
<catalogName>MyProductCatalog</catalogName>
<currencies>
<currency>USD</currency>
<currency>EUR</currency>
</currencies>
<products>
<product name="Starter">
<category>BASE</category>
</product>
<product name="Professional">
<category>BASE</category>
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>END_OF_TERM</policy>
</changePolicyCase>
</changePolicy>
<cancelPolicy>
<cancelPolicyCase>
<policy>END_OF_TERM</policy>
</cancelPolicyCase>
</cancelPolicy>
</rules>
<plans>
<plan name="starter-monthly">
<product>Starter</product>
<initialPhases/>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>29.00</value>
</price>
</recurringPrice>
</recurring>
</finalPhase>
</plan>
<plan name="professional-monthly">
<product>Professional</product>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>14</number>
</duration>
<fixed>
<fixedPrice/>
</fixed>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>99.00</value>
</price>
</recurringPrice>
</recurring>
</finalPhase>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>starter-monthly</plan>
<plan>professional-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</catalog>
Upload this catalog via the Kill Bill API:
curl -v \
-X POST \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/xml" \
-H "X-Killbill-CreatedBy: admin" \
"http://127.0.0.1:8080/1.0/kb/catalog/xml" \
-d @catalog.xml
Step 4: Migrate Customer Data
The migration order matters:
1. Export Stripe Billing Data
# List all Stripe customers
stripe customers list --limit 100 > customers.json
# List all subscriptions
stripe subscriptions list --limit 100 --status=active > subscriptions.json
# List payment methods
stripe payment_methods list --limit 100 > payment_methods.json
2. Create Kill Bill Accounts
For each Stripe customer, create a Kill Bill account:
curl -v \
-X POST \
-u admin:password \
-H "Content-Type: application/json" \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "X-Killbill-CreatedBy: migration" \
"http://127.0.0.1:8080/1.0/kb/accounts" \
-d '{
"name": "Customer Name",
"email": "customer@example.com",
"currency": "USD",
"externalKey": "stripe_customer_id_here"
}'
Use the Stripe customer ID as externalKey — this lets you cross-reference records during migration.
3. Migrate Payment Methods
Stripe's Stripe.js payment tokens can be reused in Kill Bill via the Stripe plugin. The plugin stores a reference to the Stripe payment method — the actual card data stays in Stripe's vault.
# Add payment method to Kill Bill account (references existing Stripe payment method)
curl -v \
-X POST \
-u admin:password \
-H "Content-Type: application/json" \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "X-Killbill-CreatedBy: migration" \
"http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/paymentMethods" \
-d '{
"pluginName": "killbill-stripe",
"pluginInfo": {
"properties": [{
"key": "token",
"value": "stripe_payment_method_id_here"
}]
}
}'
No card re-capture required — existing Stripe payment methods transfer to Kill Bill's Stripe plugin seamlessly.
4. Create Subscriptions in Kill Bill
For each active Stripe subscription, create a corresponding Kill Bill subscription:
curl -v \
-X POST \
-u admin:password \
-H "Content-Type: application/json" \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "X-Killbill-CreatedBy: migration" \
"http://127.0.0.1:8080/1.0/kb/subscriptions" \
-d '{
"accountId": "kill-bill-account-id",
"planName": "professional-monthly",
"billCycleDayLocal": 15
}'
Set billCycleDayLocal to match the customer's existing Stripe billing day to minimize billing disruption.
Step 5: Update Your Application Integration
Your application needs to interact with Kill Bill instead of Stripe Billing:
Subscription Creation (Sign-up Flow)
Before (Stripe Billing):
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [{ price: 'price_pro_monthly' }],
trial_period_days: 14,
});
After (Kill Bill API):
const response = await fetch(`${KILLBILL_URL}/1.0/kb/subscriptions`, {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:password'),
'X-Killbill-ApiKey': KB_API_KEY,
'X-Killbill-ApiSecret': KB_API_SECRET,
'Content-Type': 'application/json',
'X-Killbill-CreatedBy': 'api',
},
body: JSON.stringify({
accountId: killBillAccountId,
planName: 'professional-monthly',
}),
});
Subscription Status Checks
Before (Stripe Billing):
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
const isActive = subscription.status === 'active';
After (Kill Bill):
const response = await fetch(`${KILLBILL_URL}/1.0/kb/subscriptions/${subscriptionId}`, {
headers: killBillHeaders,
});
const subscription = await response.json();
const isActive = subscription.state === 'ACTIVE';
Webhook Events
Kill Bill fires events that your application listens to, similar to Stripe webhooks:
// Kill Bill event types
ACCOUNT_CREATION
SUBSCRIPTION_CREATION
SUBSCRIPTION_CANCEL
INVOICE_CREATION
PAYMENT_SUCCESS
PAYMENT_FAILED
Configure Kill Bill webhooks (notifications) in the admin UI or API.
Step 6: Cancel Stripe Billing Subscriptions
Once Kill Bill is handling billing and your application is fully integrated:
- Stop creating new subscriptions in Stripe Billing
- As each customer's Stripe subscription renews, migrate it to Kill Bill
- Cancel the Stripe subscription after the period covered (avoid double billing)
- Once all subscriptions are in Kill Bill, downgrade your Stripe Billing plan
Important: Keep Stripe as your payment processor. You're only removing Stripe Billing (the subscription management layer). Stripe remains for payment processing.
Cost Savings Analysis
$500K ARR SaaS (Monthly Subscriptions)
| Fee | Stripe Billing | Kill Bill |
|---|---|---|
| Payment processing (2.9%) | $14,500 | $14,500 |
| Subscription management (0.5%) | $2,500 | $0 |
| Self-hosting (Hetzner CPX31) | $0 | $120 |
| Annual Total | $17,000 | $14,620 |
| Savings | $2,380/year |
$2M ARR SaaS
| Fee | Stripe Billing | Kill Bill |
|---|---|---|
| Payment processing (2.9%) | $58,000 | $58,000 |
| Subscription management (0.5%) | $10,000 | $0 |
| Self-hosting (Hetzner CCX13) | $0 | $420 |
| Annual Total | $68,000 | $58,420 |
| Savings | $9,580/year |
The engineering cost of migration is typically $20,000-50,000 in developer time. Break-even at $500K ARR happens within 8-20 years. Break-even at $2M ARR happens in 2-5 years.
This is why the migration calculation matters: Kill Bill makes most financial sense at $2M+ ARR, or for teams with compliance requirements that Stripe Billing can't meet.
Kill Bill Production Operations: Day-2 Concerns
Getting Kill Bill deployed is the beginning. The operational concerns that emerge in production billing are where the complexity of self-hosted billing infrastructure becomes concrete.
Subscription state machine management. Kill Bill's subscription state machine tracks each subscription through its lifecycle: trial, active, paused, cancelled, cancelled-at-period-end. Understanding which state your subscriptions are in and why is critical for billing correctness. Kill Bill's Admin UI shows subscription states and allows manual state transitions for edge cases (reactivating a cancelled subscription, extending a trial). Audit every state transition — Kill Bill logs all changes with timestamps and reasons, and this audit log is your defense when a customer disputes a charge.
Failed payment retry logic. Declined payments are inevitable: expired cards, insufficient funds, bank fraud holds. Kill Bill's Overdue System handles retries: define retry intervals (attempt immediately, then +3 days, then +7 days, then +14 days), configure whether to block access during overdue periods, and specify how many failures trigger subscription cancellation. Connect a card updater service (Stripe's Account Updater, Braintree's Card Updater) to automatically refresh expired card numbers — this alone recovers 20-30% of failed payments before any customer interaction is needed.
Proration and mid-cycle changes. When a customer upgrades from a $29/month plan to a $99/month plan partway through their billing cycle, the correct behavior is to credit them the unused days of the old plan and charge them the prorated cost of the new plan for the remaining days. Kill Bill handles proration automatically according to configurable proration policies. Verify that your proration policy matches customer expectations — some businesses prefer immediate full-price charge with a credit, others prefer a prorated adjustment. Misconfigured proration is a common source of customer complaints on self-hosted billing.
Multi-currency and international billing. If you bill customers in multiple currencies, Kill Bill handles currency-per-account assignment and stores pricing in multiple currencies per catalog entry. The payment plugin (Stripe, Adyen, Braintree) handles the actual currency conversion at the processor level. For VAT/GST compliance, Kill Bill can apply tax rules based on customer location, but you're responsible for maintaining the correct tax rates by jurisdiction and updating them when rates change. Consider a tax automation service (Avalara, TaxJar) for this if you operate in multiple countries with changing tax requirements.
Audit log and compliance access. Kill Bill maintains a complete immutable audit log of all billing events: invoices created, payments processed, credits applied, subscription changes. For financial audits, this log is your primary evidence. Ensure the audit log is backed up separately from the Kill Bill application data — PostgreSQL point-in-time recovery is the mechanism here. For PCI compliance, billing data (Kill Bill's database) should be isolated from application data, with network-level controls limiting access to the billing database from only the Kill Bill application and authorized administrators.
Dunning email sequence configuration. Dunning — the process of communicating with customers about failed payments — is a revenue recovery system that requires both technical configuration and copywriting. Kill Bill's dunning emails are template-based: define the sequence (failure notification day 0, first reminder day 3, second reminder day 7, final notice day 14), write the email copy for each stage, and configure whether each message should include a payment retry link. The tone should shift from neutral ("your payment failed") to urgent ("your subscription will be cancelled in 48 hours") as the sequence progresses. A/B test your dunning copy — the difference between "update your payment" and "keep your subscription active" as subject lines can be 10-15% in recovery rates.
Invoicing configuration and tax handling. Kill Bill generates invoices automatically at each billing period. Invoice templates are configurable — include your company logo, address, tax registration number, and the appropriate tax lines for your jurisdiction. For B2B invoicing in the EU, VAT must be shown separately with the applicable rate. Kill Bill's invoice template system (Mustache templates) gives full control over invoice layout. Tax calculation (determining which rate applies based on customer location and product type) is handled through Kill Bill's tax plugin or an external tax service integration.
For the broader billing platform comparison including Lago and BillaBear, see best open source billing and invoicing tools 2026. For the Lago vs Kill Bill decision specifically, see Lago vs Kill Bill vs Stripe Billing 2026. For security hardening of the self-hosted billing infrastructure, see self-hosting security checklist 2026.
Find More Billing Alternatives
Browse all Stripe Billing alternatives on OSSAlt — compare Kill Bill, Lago, BillaBear, and every other open source billing platform with deployment guides and use case comparisons.
See open source alternatives to Stripe on OSSAlt.
The SaaS-to-Self-Hosted Migration Guide (Free PDF)
Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.
Join 300+ self-hosters. Unsubscribe in one click.