B2B SaaS Subscription Infrastructure in West Africa: Custom Paystack Wrappers vs. Lago vs. Chargebee
Building B2B recurring revenue systems in West Africa requires balancing local payment realities with flexible product tiering. We compare custom gateway wrappers, open-source Lago, and Chargebee to help you pick the right stack.
Most B2B software companies in Lagos follow a predictable trajectory. On day one, you wire up the standard Paystack or Flutterwave Subscription API. It works perfectly for your first ten self-serve customers paying N25,000 a month on local debit cards. But by month six, your billing architecture hits a brick wall.
An enterprise client asks to pay $2,000 annually via USD wire transfer while keeping their seat count dynamic. Your mid-market prospects insist on paying via quarterly NUBAN bank transfers because their corporate dollar cards are capped by central bank regulations. Meanwhile, local debit card recurring charges are failing at a 35% rate because of 3D-Secure (3DS) challenges and balance insufficient errors at midnight.
Suddenly, billing is no longer an integration task—it is core product architecture. Choosing how to manage subscription lifecycles, billing logic, and payment processing in West Africa requires evaluating three distinct architectural patterns: building a custom wrapper over local gateways, deploying an open-source billing engine like Lago, or leveraging a turnkey global platform like Chargebee.
The Core Challenges of West African SaaS Billing
Before picking a tool, you must understand why off-the-shelf Western billing engines fail locally without customization, and why simple payment gateway subscriptions break down as you scale.
First, currency volatility forces dual-catalog architecture. In Nigeria, pricing purely in USD alienates local SMEs hit by currency devaluations, while pricing purely in NGN exposes your business to extreme inflation risk. As discussed in our detailed guide on Dynamic FX Pricing for B2B SaaS in West Africa: Implementing Currency Peg Hedging Without Crushing SME Conversion, your system must maintain independent price books and support mid-cycle adjustments without breaking invoice generation.
Second, card auto-debit failure rates in Nigeria are exceptionally high. Unlike US or European markets where Visa and Mastercard recurring charges run smoothly in the background, Nigerian debit cards frequently require 3DS authentication for recurring mandates. Bank IT infrastructure downtime also causes transient payment failures. If your billing engine marks a tenant as 'unpaid' and locks them out after one failed webhook attempt, your churn will skyrocket.
Third, payment rail diversity is non-negotiable. B2B transactions in West Africa run primarily on virtual bank accounts (NUBANs) and direct bank transfers, not card auto-debits. Your system must decouple the billing logic (when an invoice is generated, what entitlements exist) from the collection mechanism (whether money arrives via Paystack card debit, Monnify dedicated virtual account, or manual USD wire).
Contender 1: Custom In-House Wrapper on Local Gateways
This approach involves writing custom subscription domain logic directly inside your core application database (Postgres or MySQL), using payment gateway APIs like Paystack or Flutterwave purely for tokenizing cards and triggering charges.
How It Works
You build custom subscriptions, plans, invoices, and entitlements tables in your backend. When a customer upgrades, your application calculates prorations, generates an internal invoice record, and calls the payment gateway API (e.g., Paystack API Documentation) to execute a charge against a stored authorization token or display a virtual account number.
The Trade-Offs
Building custom billing logic gives you total control over payment mechanics. You can handle manual NUBAN transfer reconciliation, offer custom 90-day deferred payment terms for government clients, and switch seamlessly between local collection channels without altering your underlying plan structures.
However, engineers routinely underestimate the maintenance drag of custom billing engines. Proration logic, tier upgrades, usage-based overage calculations, grace periods, and dunning workflows take hundreds of developer hours to build and test. Furthermore, handling race conditions during webhook delivery requires battle-tested concurrency control. If you don't use techniques like Preventing Double-Crediting in Paystack Webhooks: Postgres Advisory Locks vs. Redis Redlock, asynchronous gateway webhooks will lead to double-allocated usage quotas or inaccurate account suspensions.
Contender 2: Self-Hosted Open-Source Billing Engine (Lago)
Lago is an open-source, event-based billing engine designed to sit between your application logic and your payment processors. You host it on your own infrastructure (e.g., AWS or Hetzner) and connect it via webhooks.
How It Works
Your backend sends raw usage events (e.g., api_calls_executed, active_seats_count) to Lago via its REST API or SDKs. Lago handles subscription state machines, plan catalogs, usage aggregation, proration, and invoice generation. When an invoice is finalized, Lago triggers a payment workflow to an external payment service provider via custom webhooks or native integrations.
The Trade-Offs
Lago decouples complex subscription math from payment execution. According to the official Lago Documentation, the engine natively supports complex hybrid billing models (e.g., base fee + pay-as-you-go overages) across multiple currencies natively. This means you can maintain a unified global product catalog while mapping the payment execution layer to Paystack for NGN card debits, Monnify for NUBAN transfers, or Stripe for international card payments.
Because Lago is open-source and self-hostable, data residency and privacy compliance under NDPR stay completely under your control. The primary downside is operational overhead: your engineering team is responsible for managing Lago's Redis and Postgres dependencies, maintaining high availability for event ingestion, and writing the glue code that connects Lago webhooks to local West African payment gateways.
Contender 3: Global Turnkey SaaS (Chargebee / Stripe Billing)
Chargebee and Stripe Billing are fully managed cloud solutions that offer ready-made checkout flows, customer portals, tax compliance calculation, and dunning management.
How It Works
You integrate Chargebee's hosted checkout widgets or SDKs into your app. Chargebee manages the entire billing lifecycle, handles card retries, sends automated invoice emails, and provides churn analytics out of the box.
The Trade-Offs
From a pure developer experience standpoint, Chargebee is unmatched. You get sophisticated enterprise features—such as revenue recognition accounting (ASC 606), customer self-serve portals, and automated dunning management—with minimal custom code.
However, using global billing SaaS platforms in West Africa comes with significant friction. Native payment gateway support for African providers is limited or non-existent. Chargebee supports Stripe, Braintree, and Adyen out of the box, but integrating local West African processors like Paystack or Monnify requires building complex custom payment gateways via Chargebee's payment API. Furthermore, pricing models charged in USD per transaction hit your margins hard when paired with local payment gateway fees and unpredictable foreign exchange rates.
Comparison Table
| Evaluation Criteria | Custom In-House Wrapper | Open-Source Lago (Self-Hosted) | Chargebee / Stripe Billing | | :--- | :--- | :--- | :--- | | Upfront Dev Effort | Very High (3-6 months) | Moderate (2-4 weeks) | Low (3-7 days) | | Ongoing Maintenance | High (Engineers fix edge cases) | Low-Moderate (Infra maintenance) | Zero (Managed SaaS) | | Multi-Currency Support | Custom built (Hard) | Native & Highly Flexible | Native & Highly Flexible | | Local Rail Integration | Native (Paystack, Flutterwave) | Flexible (via Lago webhooks) | Complex (Custom Gateway API required) | | Usage-Based Metering | Hard to scale manually | Native event stream engine | Native (Requires higher tier plan) | | FX Fluctuation Handling| Custom implemented | Managed in Plan Rules | Managed in Plan Rules | | Cost Structure | Infra cost + Gateway fees | Server costs + Open-source/Self-hosted | High USD fee/mo + % of MRR | | Data Sovereignty (NDPR)| Complete control | Complete control | Third-party vendor storage |
Implementation Architecture: Event-Driven Billing with Lago and Local Rails
To see how an open-source billing engine solves the local payment disconnect, consider this TypeScript example using Node.js and Express. It receives invoice events from Lago, evaluates the payment rail required based on currency and customer profile, and dispatches payment collection to Paystack or virtual account rails.
import express, { Request, Response } from 'express';
import crypto from 'crypto';
import { PaystackClient } from './paystack-sdk';
const app = express();
app.use(express.json());
interface LagoInvoicePayload {
event_type: string;
invoice: {
lago_id: string;
currency: 'NGN' | 'USD';
total_amount_cents: number;
customer: {
external_id: string;
email: string;
metadata?: { preferred_rail?: 'card' | 'bank_transfer' };
};
};
}
app.post('/webhooks/lago', async (req: Request, res: Response) => {
const signature = req.headers['lago-signature'] as string;
if (!verifyWebhookSignature(JSON.stringify(req.body), signature)) {
return res.status(401).send('Invalid signature');
}
const { event_type, invoice } = req.body as LagoInvoicePayload;
if (event_type === 'invoice.created') {
try {
if (invoice.currency === 'NGN') {
if (invoice.customer.metadata?.preferred_rail === 'bank_transfer') {
// Assign dynamic virtual account for corporate transfer
await assignNubanForInvoice({
invoiceId: invoice.lago_id,
amountInKobo: invoice.total_amount_cents,
email: invoice.customer.email,
});
} else {
// Charge saved card token via Paystack
await PaystackClient.chargeAuthorization({
email: invoice.customer.email,
amount: invoice.total_amount_cents,
authorization_code: await getCustomerCardToken(invoice.customer.external_id),
metadata: { lago_invoice_id: invoice.lago_id }
});
}
} else if (invoice.currency === 'USD') {
// Route USD invoices to Stripe or wire payment instructions
await triggerUsdCollectionWorkflow(invoice);
}
return res.status(200).json({ status: 'processing_initiated' });
} catch (error) {
console.error(`Failed to execute collection for invoice ${invoice.lago_id}:`, error);
return res.status(500).json({ error: 'Collection execution failed' });
}
}
return res.status(200).send('Event unhandled');
});
function verifyWebhookSignature(payload: string, signature: string): boolean {
const hmac = crypto.createHmac('sha256', process.env.LAGO_WEBHOOK_SECRET || '');
const digest = Buffer.from(hmac.update(payload).digest('hex'), 'utf8');
const checksum = Buffer.from(signature || '', 'utf8');
return digest.length === checksum.length && crypto.timingSafeEqual(digest, checksum);
}
This pattern decouples complex plan subscriptions (managed cleanly by Lago) from execution logic. You preserve developer agility without forcing West African clients into card-only payment flows that fail high-value transactions.
Clear Recommendations by Use Case
Use Case 1: Early-Stage SaaS Targeting Local SMEs (< $5,000 MRR)
- Recommendation: Build a lightweight custom wrapper directly on Paystack or Monnify APIs.
- Why: At this stage, your plans are simple, you likely have under 50 paying customers, and your priority is fast validation. The operational overhead of deploying Lago or paying $250+/month for Chargebee isn't justified. Handle subscriptions in your database and use simple cron jobs for invoice generation.
Use Case 2: Scaling B2B SaaS with Multi-Rail & Usage Pricing ($5,000 – $50,000 MRR)
- Recommendation: Self-host Lago paired with local processors (Paystack/Monnify) for NGN and Stripe for USD.
- Why: You are introducing seat-based pricing, API overage charges, and annual enterprise billing. Writing this domain logic internally will consume 40% of your engineering backlog. Self-hosted Lago gives you robust pricing abstractions, multi-currency catalogs, and precise webhook events while keeping infrastructure costs low and allowing native integration with West African bank rails.
Use Case 3: Global SaaS Expanding into Africa with Foreign Parent Entity
- Recommendation: Chargebee or Stripe Billing using custom payment integration layers.
- Why: If 80% of your revenue is generated in USD or EUR, standardizing on Chargebee for ASC 606 revenue recognition, automated tax compliance, and global card processing outweighs local payment friction. Treat West African payment collection as a specialized edge case using custom integration endpoints.
Frequently Asked Questions
How should we handle recurring card failure rates on Nigerian cards?
Never cancel a subscription immediately after a single card failure. Set up a 7-to-14-day grace period with smart retry timing. Attempt charges early in the morning on typical salary paydays (25th to 30th of the month). Always send automated transactional WhatsApp or email notifications containing a fallback NUBAN virtual account link so users can resolve failed charges manually via bank transfer.
Can we use Stripe Billing directly for customers inside Nigeria?
Yes, but with limits. Stripe can bill Nigerian customers if you have an international entity (e.g., US Delaware C-Corp or UK LTD). However, international card charges on Nigerian debit cards face high failure rates due to bank-imposed monthly spend limits on foreign transactions. You will struggle to convert local SMEs unless you offer a local currency payment path.
How do we handle NDPR compliance with self-hosted billing engines?
Self-hosted Lago ensures all transaction metadata, usage records, and PII remain inside your primary cloud environment (such as AWS eu-west-1 or local hosting). Ensure that billing databases store tokenized card signatures rather than raw card credentials, and encrypt primary customer data at rest.
What is the most effective way to protect against sudden Naira devaluations?
Maintain a dual-catalog pricing structure. Quote base enterprise contracts in USD or pegged index rates, but allow settlement in Naira calculated at the prevailing interbank or official market rate on the exact day the invoice is generated and dispatched. Ensure your billing system supports dynamic rate updates prior to invoice generation.
Do not let subscription infrastructure block product velocity. If you are scaling beyond basic plans, audit your current billing stack today: isolate your domain billing logic from your gateway connectors, put retry grace periods in place for local card rails, and keep your plan catalog flexible enough to survive currency volatility.
Neobot Engineering Standard
Every system deployed by Neobot Tech incorporates enterprise baseline practices. We continuously audit our database topologies, REST API query paths, and frontend modular bundles to prevent latency spikes and ensure top-tier security posture.
Discussion
Comments Coming Soon
We are currently migrating our discussion engine to a new real-time database schema. Check back shortly to join the conversation.