Skip to main content

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.

·OSSAlt Team
Share:

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:

  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)

FeeStripe BillingKill 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

FeeStripe BillingKill 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.