DEV Community

Cover image for How I Built a Serverless Micro-SaaS Billing Backend with n8n & Stripe in 2 Hours
Ruesch Manny
Ruesch Manny

Posted on

How I Built a Serverless Micro-SaaS Billing Backend with n8n & Stripe in 2 Hours

⚡ TL;DR — Ready-to-Deploy Automation Blueprints:


Building billing infrastructure from scratch is a trap. It drains development time, invites critical bugs, and often forces you into expensive Backend-as-a-Service (BaaS) subscriptions that eat your margins as you scale. Managing Stripe webhook events and database synchronization manually often leads to failed transactions, out-of-sync user states, and delayed launches.

Instead of paying a monthly premium for a third-party quota manager or writing thousands of lines of boilerplate Node.js code, I built a completely self-hosted, event-driven backend using n8n.

In this guide, I'll show you how to architect a Serverless Micro-SaaS Backend Kit that handles Stripe synchronization, quota logic, and REST API provisioning using an n8n engine.


1. The Bottleneck: Why SaaS Billing is a Trap

When building a micro-SaaS, the core product usually takes 20% of the time. The other 80% is spent on:

  • Listening to customer.subscription.updated and invoice.payment_failed webhooks.
  • Managing race conditions when webhooks arrive out of order.
  • Mapping Stripe Price IDs to internal user credits.
  • Exposing an API to your frontend to check if a user is allowed to perform an action.

Commercial solutions abstract this, but you lose control over your data pipeline and pay a tax on your revenue. By using n8n (Self-hosted Event-driven Automation), you get a visual, infrastructure-as-code environment where every step of the billing lifecycle is transparent, easily modifiable, and completely free of vendor lock-in.

2. The Architecture: Self-Hosted Event-Driven Billing

To build a robust billing pipeline in n8n, we rely on a specific sequence of nodes to handle ingress, acknowledge the event, route the logic, and update the database.

Here is the high-level node architecture:

  1. Webhook Node (Ingress): Listens for incoming Stripe events.
  2. Respond to Webhook Node: Instantly returns a 200 OK to Stripe. Crucial: Stripe will retry and eventually disable your webhook if you don't respond quickly. By acknowledging immediately, we decouple the processing time from the webhook response.
  3. Code Node (Sanitization & Parsing): Extracts the Customer ID, Price ID, and Event Type.
  4. Switch Node (Router): Routes the flow based on event types (e.g., subscription.created, subscription.deleted).
  5. HTTP Request Node / Database Node: Syncs the updated quota and tier to your database (Postgres, Supabase, Firebase, etc.).

3. The Code & Logic: Webhooks, Routers, and Quotas

Let’s dive into the core n8n Code Nodes that power the brain of this engine.

Step A: Event Parsing & Action Routing

Stripe sends massive JSON payloads. We don't need all of it. We use a JavaScript Code node to normalize the payload and determine what action our database needs to take.

// n8n Code Node: Parse Stripe Event
const event = $input.item.json.body;
const eventType = event.type;
const customerId = event.data.object.customer;
const status = event.data.object.status; // active, past_due, canceled

let action = 'IGNORE';

// Determine routing logic
if (['customer.subscription.created', 'customer.subscription.updated'].includes(eventType)) {
  action = status === 'active' ? 'UPSERT_SUBSCRIPTION' : 'SUSPEND_ACCESS';
} else if (eventType === 'customer.subscription.deleted') {
  action = 'REVOKE_ACCESS';
} else if (eventType === 'invoice.payment_failed') {
  action = 'MARK_PAST_DUE';
}

return { 
  json: { 
    action, 
    eventType, 
    customerId, 
    stripe_payload: event.data.object 
  } 
};
Enter fullscreen mode Exit fullscreen mode

Step B: Automated User Quota Management

Once routed to the UPSERT_SUBSCRIPTION branch via an n8n Switch Node, we need to calculate how many credits the user gets based on what they bought.

// n8n Code Node: Quota Assignment
const stripeData = $input.item.json.stripe_payload;
const priceId = stripeData.items.data[0].price.id;

// Define your SaaS tiers natively in the workflow
const planMapping = {
  'price_123_basic_monthly': { tier: 'Basic', credits: 1000, features: ['api_access'] },
  'price_456_pro_monthly': { tier: 'Pro', credits: 5000, features: ['api_access', 'priority_queue'] }
};

const plan = planMapping[priceId] || { tier: 'Free', credits: 0, features: [] };

return { 
  json: {
    stripe_customer_id: $input.item.json.customerId,
    allocated_credits: plan.credits,
    tier: plan.tier,
    subscription_status: 'active'
  } 
};
Enter fullscreen mode Exit fullscreen mode

From here, an HTTP Request node (or native Postgres node) takes this structured JSON and runs an UPDATE users SET credits = {{ $json.allocated_credits }} WHERE stripe_customer_id = {{ $json.stripe_customer_id }} query.

4. Deployment & Performance: Idempotency & Scaling

When pushing this n8n engine to production, you must account for Stripe's behavior and system scaling:

  • Idempotency is Non-Negotiable: Stripe may send the same webhook twice. To prevent double-crediting a user's account, store the Stripe Event ID in a dedicated processed_events database table. Use an n8n Postgres node at the start of your workflow to check if the event ID exists. If it does, halt the workflow.
  • Queue Mode for High Volume: If your SaaS takes off, a single n8n instance might choke on thousands of concurrent webhooks. Deploy n8n in Queue Mode using Redis. This allows worker nodes to process the webhook ingestion pipeline asynchronously, ensuring zero dropped payments.
  • Pre-configured REST API Endpoints: Use n8n's Webhook nodes configured to GET methods. Your front end can simply call GET https://n8n.yourdomain.com/webhook/user-quota?customer_id=123. The workflow queries your DB and returns a JSON response in milliseconds using the Respond to Webhook node.

5. Skip the Setup: Get the Turnkey n8n Blueprint

Building this architecture teaches you a lot about event-driven design, but constructing the error handling, missing payment routing, and database sync nodes from scratch can still take days of testing and debugging.

If you want to skip the trial-and-error and instantly deploy a production-ready billing engine, I've packaged my exact internal architecture into a downloadable blueprint.

The Serverless Micro-SaaS Backend Kit: Stripe Sync & Quota Management includes the complete n8n Workflow JSON blueprint, pre-configured REST API endpoints for frontend integration, and a full node configuration guide.

You can grab the turnkey package and import it directly into your n8n workspace today:

Stop rebuilding the wheel for every SaaS project. Standardize your billing on n8n, own your infrastructure, and get back to building your core product.


🛠️ D'autres outils MR Studio qui pourraient vous intéresser :

Top comments (0)