Tích hợp Supabase với Stripe để xử lý thanh toán hiệu quả

26/02/2026 P T P Chung 7 phút đọc 0 bình luận

Tại sao nên kết hợp Supabase và Stripe trong xây dựng sản phẩm?

Khi xây dựng một sản phẩm kỹ thuật số, việc quản lý dữ liệu người dùng và xử lý thanh toán là hai yếu tố then chốt. Supabase cung cấp backend mạnh mẽ với cơ sở dữ liệu PostgreSQL, xác thực và lưu trữ file, trong khi Stripe đảm nhận mảng thanh toán với độ tin cậy cao. Kết hợp cả hai giúp tiết kiệm thời gian phát triển, đảm bảo bảo mật và mở rộng quy mô dễ dàng.

Thiết lập cơ bản

Trước khi bắt đầu tích hợp, cần có tài khoản Supabase và Stripe. Trong Supabase, tạo một dự án mới và lưu ý thông tin endpoint và khóa truy cập từ phần Settings. Ở Stripe, lấy public key và secret key từ Dashboard để sử dụng trong code.

Tiếp theo, khởi tạo dự án frontend với package manager như npm hoặc yarn, cài đặt @supabase/supabase-js@stripe/stripe-js. Với backend, có thể dùng Supabase Edge Functions để xử lý các tác vụ nhạy cảm như tạo payment intent.

Thiết lập cơ sở dữ liệu

Trong Supabase, tạo các bảng cần thiết để lưu thông tin subscription, plan, và payment. Ví dụ:

- plans: lưu các gói dịch vụ (name, price, interval) - subscriptions: liên kết user với plan, kèm status và timestamps - payments: ghi nhận mỗi lần thanh toán với amount, status, và metadata

Thiết lập foreign key giữa subscriptions.user_idauth.users.id để đảm bảo tính nhất quán dữ liệu.

Xây dựng luồng thanh toán

Frontend: Thu thập thông tin thẻ và tạo payment intent

import { createClient } from '@supabase/supabase-js';
import { loadStripe } from '@stripe/stripe-js';

const supabase = createClient('https://<project>.supabase.co', '<anon-key>'); const stripe = await loadStripe('<stripe-public-key>');

async function createCheckoutSession(planId) { const { data, error } = await supabase .from('plans') .select('*') .eq('id', planId) .single();

if (error) throw error;

const response = await fetch('/api/create-checkout-session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ planId: data.id, price: data.price }), });

const session = await response.json(); const result = await stripe.redirectToCheckout({ sessionId: session.id });

if (result.error) { // xử lý lỗi } }

Backend: Edge Function tạo session

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createStripeCheckout } from 'https://deno.land/x/stripe/mod.ts';

const stripe = createStripeCheckout({ secretKey: 'sk_test_...', baseUrl: 'https://api.stripe.com', });

Quảng cáo

300x250 In-Content Advertisement

serve(async (req) => { const body = await req.json(); const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], line_items: [{ price_data: { currency: 'usd', product_data: { name: 'Premium Plan', }, unit_amount: body.price, }, quantity: 1, }], mode: 'subscription', success_url: 'https://yourapp.com/success', cancel_url: 'https://yourapp.com/cancel', });

return new Response(JSON.stringify({ id: session.id }), { headers: { 'Content-Type': 'application/json' }, }); });

Xử lý webhook từ Stripe

Webhook giúp cập nhật trạng thái subscription khi có sự kiện như thanh toán thành công, thất bại, hoặc gia hạn. Trong Supabase, tạo một bảng stripe_events để log các sự kiện và Edge Function để xử lý:

import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createStripeWebhook } from 'https://deno.land/x/stripe/mod.ts';
import { createClient } from 'https://deno.land/x/[email protected]/mod.ts';

const supabase = createClient('https://<project>.supabase.co', '<anon-key>'); const stripe = createStripeWebhook({ secretKey: 'whsec_...', });

serve(async (req) => { const sig = req.headers.get('stripe-signature'); const body = await req.text();

const event = stripe.constructEvent(body, sig, 'endpoint_secret'); if (event.type === 'invoice.paid') { const subId = event.data.object.subscription; await supabase .from('subscriptions') .eq('stripe_subscription_id', subId) .update({ status: 'active' }); }

return new Response('Webhook received', { status: 200 }); });

Quản lý subscription trong ứng dụng

Khi người dùng đăng nhập, query bảng subscriptions để hiển thị gói đang dùng và ngày gia hạn. Nếu cần, cung cấp tính năng nâng cấp/giảm gói bằng cách tạo checkout session mới với plan khác.

const { data, error } = await supabase
  .from('subscriptions')
  .select('*')
  .eq('user_id', userId)
  .single();

if (data && data.status === 'active') { // hiển thị thông tin gói }

Bảo mật và validation

Mọi tác vụ nhạy cảm như tạo payment intent hay cập nhật subscription phải thực hiện ở backend. Không bao giờ để secret key lộ ra frontend. Validate mọi request từ client, kiểm tra quyền sở hữu dữ liệu trước khi cập nhật.

Kết luận

Tích hợp Supabase với Stripe giúp xây dựng hệ thống thanh toán nhanh chóng, bảo mật và dễ mở rộng. Bằng cách tận dụng sức mạnh của cả hai nền tảng, bạn có thể tập trung vào trải nghiệm người dùng thay vì lo lắng về cơ sở hạ tầng. Hãy bắt đầu với một luồng thanh toán đơn giản, kiểm thử kỹ lưỡng, và mở rộng dần theo nhu cầu thực tế của sản phẩm.

Quảng cáo

728x90 Bottom Advertisement

Thay thế bằng mã Google AdSense

Chia sẻ bài viết

Facebook Twitter

Bình luận

Chia sẻ ý kiến của bạn về bài viết này

Viết bình luận

Bình luận của bạn sẽ được kiểm duyệt trước khi hiển thị

Chưa có bình luận nào

Hãy là người đầu tiên bình luận về bài viết này!