Tại sao nên quản lý subscription và billing với Supabase và Stripe
Trong thời đại phần mềm SaaS, subscription và billing không chỉ là tính năng phụ – chúng là xương sống của mô hình kinh doanh. Tuy nhiên, nhiều startup thường gặp khó khăn khi phải tự xây dựng hệ thống thanh toán từ đầu, dẫn đến lãng phí thời gian và tiềm ẩn rủi ro bảo mật. Giải pháp tối ưu là kết hợp Supabase – nền tảng backend mạnh mẽ – với Stripe – công cụ thanh toán toàn cầu, giúp triển khai nhanh chóng và an toàn.
Các thành phần cốt lõi của hệ thống
Supabase: Backend linh hoạt và bảo mật
Supabase cung cấp cơ sở dữ liệu PostgreSQL, xác thực người dùng, và API REST/Realtime. Với khả năng mở rộng và tích hợp sẵn Row Level Security (RLS), bạn có thể kiểm soát chặt chẽ ai được xem hay thay đổi dữ liệu subscription.
Stripe: Nền tảng thanh toán toàn cầu
Stripe xử lý mọi khâu từ tạo subscription, quản lý khách hàng, đến thanh toán định kỳ. API mạnh mẽ và dashboard trực quan giúp bạn dễ dàng theo dõi doanh thu và trạng thái thanh toán.
Tích hợp webhook: Cầu nối giữa hai hệ thống
Webhook là chìa khóa để đồng bộ dữ liệu giữa Stripe và Supabase. Mỗi khi có sự kiện thanh toán (thành công, thất bại, gia hạn), Stripe sẽ gửi webhook tới backend của bạn, từ đó cập nhật trạng thái subscription trong database.
Triển khai từng bước
1. Thiết lập database và bảng subscription
Đầu tiên, tạo bảng subscriptions trong Supabase với các cột cần thiết:
– id (khóa chính)
– user_id (liên kết với người dùng)
– stripe_subscription_id (để đồng bộ với Stripe)
– status (active, canceled, past_due)
– plan (gói dịch vụ)
– current_period_end (thời điểm kết thúc kỳ thanh toán hiện tại)
CREATE TABLE subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES auth.users NOT NULL,
stripe_subscription_id TEXT UNIQUE,
status TEXT,
plan TEXT,
current_period_end BIGINT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);2. Cấu hình webhook trong Stripe
Trong dashboard Stripe, tạo endpoint webhook trỏ về URL của Supabase (ví dụ: https://your-project.supabase.co/webhooks/stripe). Chọn các sự kiện cần xử lý như:
– invoice.paid
– invoice.payment_failed
– customer.subscription.deleted
– customer.subscription.updated
3. Viết Cloud Function để xử lý webhook
Supabase cho phép viết Cloud Function bằng JavaScript/TypeScript. Function này sẽ lắng nghe webhook, xác thực chữ ký từ Stripe, và cập nhật database:
import { createClient } from '@supabase/supabase-js';
import { stripe } from 'stripe';
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY);
const stripe = new stripe(process.env.STRIPE_SECRET_KEY);
export default async function (req, res) {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
console.log(err.message);
return res.status(400).send();
}
switch (event.type) {
case 'invoice.paid':
// Cập nhật subscription thành active
break;
case 'invoice.payment_failed':
// Đánh dấu là past_due
break;
case 'customer.subscription.deleted':
// Cập nhật status thành canceled
break;
// ... các trường hợp khác
}
res.json({ received: true });
}