Building a SaaS billing system without Stripe limits

Introduction

Building a SaaS billing system without relying on Stripe is not only possible but also increasingly necessary for companies that value autonomy, compliance, and long-term scalability. While Stripe provides a robust set of tools for handling payments, it does not cover all the complexities of metered billing, credit systems, dunning flows, and entitlements. These are critical components of a modern SaaS billing infrastructure that must be implemented with care and precision.

Key Components of a SaaS Billing System

Metered Billing

Metered billing is the process of tracking and charging for specific usage of your product. This is particularly important for cloud-based services where customers may be using more than they are paying for. Implementing metered billing requires a system that can track usage, apply pricing, and generate invoices.

Here's an example of how you might structure a metered billing system using Bastionary:


      // Track usage for a specific customer
      const usage = await trackUsage(customerId, serviceId);
      
      // Apply pricing based on usage
      const price = await calculatePrice(usage, pricingModel);
      
      // Generate an invoice
      const invoice = await generateInvoice(customerId, usage, price);
      

Key Insight: Metered billing is not just about tracking usage—it's also about ensuring that customers are charged fairly and transparently.

Credit Systems

A credit system allows customers to use their credit balance to offset charges. This is particularly useful for customers who may have a negative balance due to overages or refunds. Implementing a credit system requires a system that can track credit balances, apply credits to invoices, and manage credit limits.

Here's an example of how you might structure a credit system using Bastionary:


      // Track credit balance for a specific customer
      const creditBalance = await trackCreditBalance(customerId);
      
      // Apply credit to an invoice
      const invoice = await applyCreditToInvoice(customerId, invoiceId, creditBalance);
      

Warning: Credit systems can be complex to implement. It's important to ensure that credits are applied correctly and that customers are not overcharged.

Dunning Flows

Dunning flows are the process of sending reminders to customers who have overdue payments. This is an important part of any SaaS billing system as it helps to reduce the risk of bad debt and ensures that customers are paying for their usage.

Here's an example of how you might structure a dunning flow using Bastionary:


      // Send a dunning reminder to a customer
      const reminder = await sendDunningReminder(customerId, invoiceId, daysOverdue);
      
      // Track the response to the reminder
      const response = await trackDunningResponse(customerId, reminderId);
      

Key Insight: Dunning flows are not just about sending reminders—they're also about ensuring that customers are aware of their obligations and that they are paying for their usage.

Conclusion

Building a SaaS billing system without relying on Stripe is not only possible but also increasingly necessary for companies that value autonomy, compliance, and long-term scalability. While Stripe provides a robust set of tools for handling payments, it does not cover all the complexities of metered billing, credit systems, dunning flows, and entitlements. These are critical components of a modern SaaS billing infrastructure that must be implemented with care and precision.

At Bastionary, we provide a self-hosted platform that