- Updated: March 23, 2026
- 7 min read
Integrating Stripe Metered Billing into the OpenClaw SaaS Boilerplate
How to Add Stripe Metered Billing to the OpenClaw SaaS Boilerplate
Answer: Integrating Stripe metered billing into the OpenClaw customer portal involves creating a metered product in Stripe, configuring API keys in OpenClaw, tracking usage on the backend (Node.js), displaying usage and invoices on the React frontend, testing end‑to‑end, and finally deploying the updated app on UBOS hosting.
1. Introduction
OpenClaw is a modern SaaS boilerplate that ships with authentication, a customer portal, and a flexible plugin system. When you need to charge customers based on actual consumption—such as API calls, storage usage, or seat‑based licensing—Stripe’s metered billing is the industry‑standard solution.
This guide walks developers through every step: from Stripe product creation to code implementation, testing, and deployment on UBOS. By the end, you’ll have a production‑ready metered‑billing flow that scales securely.
2. Prerequisites
- Running OpenClaw (Node.js ≥ 18, React ≥ 18) on your local machine.
- A Stripe account with metered‑usage documentation access.
- Node.js package manager (npm or yarn) and Git.
- Basic knowledge of REST APIs and React state management.
3. Creating a Stripe Metered Billing Product
Follow these steps in the Stripe Dashboard:
- Navigate to Products → Add product.
- Enter a name (e.g., API Calls) and description.
- Under Pricing model, select Metered usage.
- Set the unit amount (e.g., $0.001 per call) and the billing interval (monthly).
- Save the product and copy the Product ID (e.g.,
prod_ABC123).
4. Configuring OpenClaw to Use Stripe API Keys
OpenClaw stores secrets in .env. Add the following variables:
# .env
STRIPE_SECRET_KEY=sk_test_XXXXXXXXXXXXXXXXXXXXXXXX
STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXXXXXXXXXX
STRIPE_PRODUCT_ID=prod_ABC123
Restart the server so the environment variables are loaded.
5. Implementing Metered Usage Tracking in the Customer Portal
OpenClaw’s backend exposes a /api/usage endpoint. We’ll extend it to record usage events via Stripe’s UsageRecord API.
5.1 Backend (Node.js) – Adding the Endpoint
// src/routes/usage.js
const express = require('express');
const router = express.Router();
const Stripe = require('stripe');
const stripe = Stripe(process.env.STRIPE_SECRET_KEY);
/**
* POST /api/usage
* Body: { userId: string, quantity: number }
*/
router.post('/', async (req, res) => {
const { userId, quantity } = req.body;
if (!userId || !quantity) {
return res.status(400).json({ error: 'Missing parameters' });
}
try {
// 1️⃣ Retrieve the Stripe subscription for the user
const subscription = await stripe.subscriptions.list({
customer: userId,
limit: 1,
});
if (!subscription.data.length) {
return res.status(404).json({ error: 'Subscription not found' });
}
const subscriptionItemId = subscription.data[0].items.data[0].id;
// 2️⃣ Create a usage record
const usageRecord = await stripe.subscriptionItems.createUsageRecord(
subscriptionItemId,
{
quantity,
timestamp: Math.floor(Date.now() / 1000),
action: 'increment',
}
);
res.json({ success: true, usageRecord });
} catch (err) {
console.error('Stripe usage error:', err);
res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;
5.2 Frontend (React) – Reporting Usage
In the customer portal, add a button that sends usage data to the new endpoint.
// src/components/UsageButton.jsx
import { useState } from 'react';
import axios from 'axios';
export default function UsageButton({ userId }) {
const [loading, setLoading] = useState(false);
const [msg, setMsg] = useState('');
const reportUsage = async (qty) => {
setLoading(true);
try {
const res = await axios.post('/api/usage', {
userId,
quantity: qty,
});
setMsg(`✅ Recorded ${qty} units`);
} catch (e) {
setMsg('❌ Failed to record usage');
} finally {
setLoading(false);
}
};
return (
{msg && {msg}
}
);
}
5.3 Displaying Current Usage & Invoices
OpenClaw already ships a Billing page. Extend it to fetch usage summary:
// src/pages/Billing.jsx
import { useEffect, useState } from 'react';
import axios from 'axios';
export default function Billing() {
const [usage, setUsage] = useState(null);
const [invoice, setInvoice] = useState(null);
useEffect(() => {
async function fetchData() {
const [uRes, iRes] = await Promise.all([
axios.get('/api/stripe/usage'), // custom endpoint you’ll add
axios.get('/api/stripe/invoice'), // existing endpoint
]);
setUsage(uRes.data);
setInvoice(iRes.data);
}
fetchData();
}, []);
return (
Current Month Usage
{usage ? (
{usage.total_quantity} units used – ${usage.amount_due / 100} billed
) : (
Loading usage…
)}
Latest Invoice
{invoice ? (
View Invoice #{invoice.number}
) : (
Loading invoice…
)}
);
}
6. Testing the Integration
Before pushing to production, verify each piece works end‑to‑end.
- Unit tests: Use
jestto mock Stripe calls and assert thatcreateUsageRecordreceives the correct quantity. - Local sandbox: Stripe provides a test mode. Create a test customer, subscribe to the metered product, and call the
/api/usageendpoint with various quantities. - Dashboard verification: In the Stripe Dashboard, navigate to the test subscription → Usage records to see the recorded events.
- Frontend sanity check: Click the “Report 1 Unit” button and confirm the success message and updated usage display.
7. Best‑Practice Tips
7.1 Security
- Never expose
STRIPE_SECRET_KEYto the browser. Keep all Stripe calls server‑side. - Validate
userIdagainst your own authentication system before creating a usage record. - Rotate webhook secrets regularly and store them in a secret manager (e.g., AWS Secrets Manager).
7.2 Error Handling
- Implement exponential back‑off for transient Stripe API errors (HTTP 429, 5xx).
- Log failed usage events to a dead‑letter queue for later reconciliation.
- Return clear error messages to the UI so users understand if a usage report failed.
7.3 Scaling Considerations
- Batch usage records when possible (e.g., aggregate per minute) to stay under Stripe’s rate limits.
- Use a message broker (RabbitMQ, Kafka) to decouple usage collection from Stripe API calls.
- Cache subscription‑item IDs in Redis to avoid repeated look‑ups.
8. Deploying with UBOS Hosting
Once your code passes local tests, push it to your Git repository and let UBOS handle the rest. UBOS provides a one‑click OpenClaw hosting experience that includes automatic SSL, CI/CD pipelines, and horizontal scaling.
Follow these steps:
- Connect your GitHub repo to the UBOS dashboard.
- Select the UBOS templates for quick start that match the OpenClaw stack (Node.js + React).
- Configure environment variables (
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET,STRIPE_PRODUCT_ID) in the UBOS UI. - Enable the Workflow automation studio to trigger a webhook deployment whenever you merge to
main. - Review the UBOS pricing plans to ensure you have enough compute for expected traffic.
- Deploy! UBOS will provision containers, set up a PostgreSQL instance, and expose your app at a secure
https://URL.
After deployment, verify that the webhook endpoint (/api/stripe/webhook) is reachable from Stripe’s dashboard. Use the “Send test webhook” button to confirm that usage events are processed correctly in production.
9. Further Reading & Internal Resources
UBOS offers a rich ecosystem that can complement your billing workflow:
- UBOS platform overview – understand the underlying infrastructure.
- AI marketing agents – automate upsell emails based on usage.
- UBOS for startups – special pricing and support.
- UBOS solutions for SMBs – scaling tips for growing SaaS businesses.
- Enterprise AI platform by UBOS – integrate predictive analytics into your billing.
- Web app editor on UBOS – rapid UI prototyping for new billing dashboards.
- UBOS partner program – co‑marketing and technical support.
10. Conclusion and Next Steps
By following this guide you now have a fully functional Stripe metered‑billing integration inside the OpenClaw SaaS boilerplate. You can track usage in real time, generate accurate invoices, and scale the solution with UBOS’s managed hosting.
Next steps:
- Implement automated email notifications using AI marketing agents to alert customers when they approach usage thresholds.
- Explore AI Video Generator to create onboarding tutorials for your new billing UI.
- Set up a partner program to collaborate with other SaaS founders using OpenClaw.
Happy coding, and enjoy the frictionless revenue stream that metered billing brings to your SaaS product!
Andrii Bidochko
CTO UBOS
Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.