<!-- OSSAlt AI-readable guide source -->
<!-- Canonical: https://ossalt.com/guides/how-to-migrate-from-stripe-to-kill-bill-2026 -->
<!-- Raw Markdown: https://ossalt.com/guides/how-to-migrate-from-stripe-to-kill-bill-2026/raw.md -->
<!-- Source path: content/guides/how-to-migrate-from-stripe-to-kill-bill-2026.mdx -->

---
og_image: "/images/guides/how-to-migrate-from-stripe-to-kill-bill-2026.webp"
title: "How to Migrate from Stripe Billing to Kill Bill in 2026"
description: "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."
date: "2026-03-08"
author: "OSSAlt Team"
tags: ["kill-bill", "stripe", "billing", "subscriptions", "migration", "open-source", "self-hosted", "2026"]
---
## 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)

```yaml
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

```bash
# 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:

```bash
# 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:

```bash
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
<?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:

```bash
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

```bash
# 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:

```bash
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.

```bash
# 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:

```bash
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):**
```javascript
const subscription = await stripe.subscriptions.create({
  customer: customerId,
  items: [{ price: 'price_pro_monthly' }],
  trial_period_days: 14,
});
```

**After (Kill Bill API):**
```javascript
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):**
```javascript
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
const isActive = subscription.status === 'active';
```

**After (Kill Bill):**
```javascript
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:

```java
// 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:

1. Stop creating new subscriptions in Stripe Billing
2. As each customer's Stripe subscription renews, migrate it to Kill Bill
3. Cancel the Stripe subscription after the period covered (avoid double billing)
4. 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](/guides/best-open-source-billing-invoicing-tools-2026). For the Lago vs Kill Bill decision specifically, see [Lago vs Kill Bill vs Stripe Billing 2026](/guides/lago-vs-kill-bill-vs-stripe-billing-2026). For security hardening of the self-hosted billing infrastructure, see [self-hosting security checklist 2026](/guides/self-hosting-security-checklist-2026).

## Find More Billing Alternatives

[Browse all Stripe Billing alternatives on OSSAlt](https://ossalt.com) — 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](https://www.ossalt.com/alternatives/stripe-billing).*
