/how-to-build-lovable

How to build Billing system with Lovable?

Learn to build a secure, scalable billing system with Lovable including payment integration, subscription management, invoicing and best practices

Book a free  consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

How to build Billing system with Lovable?

 

What we’re building / changing (plain English)

 

We’ll add a basic billing flow: create Stripe Checkout sessions from the app, store subscription metadata in Supabase, and surface a simple “Subscribe / Manage” UI. Server API routes live inside the Lovable app and use Secrets (no terminal). Webhook handling is optional — if you need production webhooks, export to GitHub and deploy where Stripe can reach your endpoint.

 

Lovable-native approach

 

Work entirely inside Lovable Chat Mode: ask Lovable to create API route files, client UI components, and Supabase table SQL. Configure Secrets via Lovable Cloud Secrets UI. Use Preview to test Checkout (it will open Checkout in a Stripe-hosted page). For webhooks or advanced deployment, use GitHub export/sync and deploy to a host that accepts Stripe webhooks.

 

Meta-prompts to paste into Lovable

 

Prompt 1 — Add server API route to create Stripe Checkout session

 

Goal: Add a POST API endpoint /api/create-checkout that creates a Stripe Checkout session for the current user and returns the session URL.

  • Files to create: api/create-checkout/route.ts
  • What to put in the file: Implement a POST handler that reads JSON {priceId, userId}, uses process.env.STRIPE_SECRET to create a Checkout session with success/cancel URLs pointing to /billing/success and /billing/cancel, and upserts session info to Supabase using process.env.SUPABASE_SERVICE\_ROLE or call a supabase client with service role secret.
  • Acceptance criteria: Done when route.ts exists, uses STRIPE\_SECRET env var, and returns {url: session.url}.
  • Secrets/integrations: In Lovable Cloud Secrets UI add STRIPE_SECRET, SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE (if using service role). Also ensure Supabase DB has a subscriptions table (see Prompt 2).

 

// create api/create-checkout/route.ts
import Stripe from 'stripe'
// // create supabase client using service role or anon key
export async function POST(req) {
  const { priceId, userId } = await req.json()
  const stripe = new Stripe(process.env.STRIPE_SECRET)
  const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    mode: 'subscription',
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/billing/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/billing/cancel`,
    metadata: { userId }
  })
  // // upsert to supabase subscriptions table (optional)
  return new Response(JSON.stringify({ url: session.url }), { status: 200 })
}

 

Prompt 2 — Create Supabase table SQL and minimal client helper

 

Goal: Create SQL migration file to add subscriptions table and a client helper to read/write subscription status.

  • Files to create: db/migrations/001_create_subscriptions.sql and utils/supabaseClient.ts
  • Acceptance criteria: SQL file exists with CREATE TABLE subscriptions(...), and supabaseClient.ts exports a function to get/update subscription record using SUPABASE_URL and SUPABASE_SERVICE\_ROLE or anon key.
  • Secrets: uses SUPABASE_URL and SUPABASE_SERVICE\_ROLE from Secrets UI.

 

-- db/migrations/001_create_subscriptions.sql
-- // simple subscriptions table
CREATE TABLE IF NOT EXISTS subscriptions (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id text NOT NULL,
  stripe_subscription_id text,
  status text,
  price_id text,
  created_at timestamptz DEFAULT now(),
  updated_at timestamptz DEFAULT now()
);

 

Prompt 3 — Add front-end UI: /billing page and actions

 

Goal: Add a page at src/pages/billing.tsx (or routes depending on project) with Subscribe button, calls /api/create-checkout, and shows current subscription state via supabaseClient.

  • Files to modify/create: src/pages/billing.tsx (or src/app/billing/page.tsx for app router), components/Billing.tsx
  • Acceptance criteria: UI shows user subscription status, a Subscribe button that opens Stripe Checkout (redirects to session.url returned by API).
  • Secrets: uses NEXT_PUBLIC_APP_URL in Secrets (or set in project settings) for success_url.

 

// src/pages/billing.tsx
import { useState, useEffect } from 'react'
// // use fetch to POST to /api/create-checkout and redirect to returned url

 

How to verify in Lovable Preview

 

  • Preview the app in Lovable Preview. Go to /billing, click Subscribe. The app should POST to /api/create-checkout and redirect you to Stripe Checkout (Stripe shows the hosted payment UI if keys are correct).
  • Database: After returning from Checkout, manually verify the subscriptions table in Supabase (or trigger a webhook/DB update) shows a record if your API upserted it.

 

How to Publish / re-publish

 

  • Publish from Lovable Publish to deploy the app with Secrets. For production webhooks, export to GitHub and deploy to a platform (Vercel, Netlify) that exposes a public webhook URL; document webhook secret to Stripe and set it in Lovable Secrets or in deployed env.

 

Common pitfalls in Lovable (and how to avoid them)

 

  • Missing Secrets: Checkout will fail silently if STRIPE_SECRET or NEXT_PUBLIC_APP_URL is missing. Add them in Lovable Cloud Secrets UI before testing.
  • Webhook needs public URL: Preview URL is temporary; for stable Stripe webhooks use GitHub export + deploy to a platform with a stable URL.
  • Environment mismatch: Use NEXT_PUBLIC_ prefix for client-visible values (Stripe publishable key). Never expose STRIPE\_SECRET to client code.

 

Validity bar

 

This plan uses only Lovable-native features: Chat Mode edits to create files, Preview to test, Secrets UI to store env variables, and Publish/GitHub export when a public webhook or custom deployment is required. If you want, paste each prompt above into Lovable Chat Mode one at a time and run Preview after each change.

 

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

How to add a secure Stripe webhook receiver with simulator

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

How to implement an idempotent Publish Invoice API

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

How to add a token-bucket rate limiter to Billing

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

Best Practices for Building a Billing system with AI Code Generators

Start simple and safe: use a proven payments provider (Stripe), keep authoritative billing state in your DB (e.g., Supabase), protect all secrets with Lovable Secrets, verify webhooks, add idempotency and reconciliation, and treat AI-generated billing code as a draft that you must review, test, and run via GitHub CI or your cloud deploy (because Lovable has no terminal). Do not deploy billing logic without tests, webhook verification, and operational monitoring.

 

Architecture & components

 

  • Payments: Stripe for charges/subscriptions, webhooks for events.
  • Data store: Supabase/Postgres as the single source of truth for customers, subscriptions, invoices.
  • Server: Serverless endpoints (Vercel, Netlify) or small backend (Node/Express) to handle webhooks and customer-initiated endpoints.
  • Secrets: Store API keys in Lovable Secrets UI and reference via process.env in code.
  • Deployment: Use Lovable Publish or export to GitHub and run CI/CD (GitHub Actions) for migrations/deploys.

 

Lovable workflow constraints & practical patterns

 

  • No terminal in Lovable: Create migration scripts and CI workflows in the repo. Export/sync to GitHub from Lovable to run commands in CI (migrations, builds, deploys).
  • Secrets: Add Stripe keys in Lovable Secrets UI. Never paste keys into chat or files.
  • Preview & Publish: Use Preview to exercise routes locally in Lovable’s preview, then Publish or GitHub export for production.
  • GitHub sync: Push generated code to GitHub and use Actions for DB migrations and deployment; treat Lovable as the editor & code-review assistant, not as runtime for ops.

 

Security & operational best practices

 

  • Verify webhooks: Always verify Stripe signatures server-side.
  • Idempotency: Use idempotency keys for charge/retry to avoid double-billing.
  • Reconciliation: Periodic job to compare Stripe state with DB and surface mismatches.
  • Least privilege: Use restricted API keys for webhook handlers and background jobs.
  • Monitoring & alerts: Instrument billing flows, set alerts on failed charges or webhook processing errors.

 

How to use AI code generators safely in billing

 

  • Prompt for intent, not final code: Ask generator to produce code plus explanations and edge-case tests.
  • Manual review: Always read generated code for security, rounding, currency, taxes, refunds.
  • Automated tests: Write unit + integration tests (webhook signature tests, idempotency tests) before trusting generated logic.

 

// Stripe webhook handler (Node/Express) - verify signature and idempotency
const express = require('express')
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
const bodyParser = require('body-parser')

const app = express()
// Stripe requires raw body for signature verification
app.post('/webhook', bodyParser.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature']
  let event
  try {
    // STRIPE_WEBHOOK_SECRET must be set in Lovable Secrets
    event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET)
  } catch (err) {
    // signature verification failed
    return res.status(400).send(`Webhook Error: ${err.message}`)
  }

  // idempotency: use event.id to ensure we process only once
  // // pseudo: if processed(event.id) return res.status(200)
  // handle event types
  if (event.type === 'invoice.paid') {
    // update your Supabase/Postgres billing tables here
  }

  res.status(200).send('ok')
})

module.exports = app

 

-- Minimal billing tables for Supabase/Postgres
CREATE TABLE customers (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  stripe_customer_id text UNIQUE,
  email text
);

CREATE TABLE subscriptions (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  customer_id uuid REFERENCES customers(id),
  stripe_subscription_id text UNIQUE,
  status text,
  current_period_end timestamptz
);

 

Final checklist before production

 

  • Secrets stored in Lovable Secrets UI.
  • Webhook signature verification implemented.
  • Idempotency and retry logic added.
  • CI runs migrations and deploy (GitHub Actions after Lovable → GitHub export).
  • Automated tests and reconciliation jobs in place.
  • Manual code review of any AI-generated billing code.


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.