Stripe 是一个支付处理平台,可让您在线接受付款.通过 superun 的 Stripe 集成,您可以轻松地将支付功能添加到您的应用程序中,包括一次性支付,订阅和市场功能.
superun 现在允许您完全通过 聊天 设置 Stripe.
聊天驱动的自动设置(推荐)
连接 superun Cloud(或 Supabase),并在 研发 → 服务 → Stripe 中设定好 Stripe 凭证(如下文的设定步骤),然后只需在聊天中描述你的需求:
*“添加三个订阅级别:基本版为 9 美元/月,专业版为 29 美元/月,企业版为 99 美元/月”
*“为我的电子书创建一次性结账,价格为 29 美元”
*“为我的产品页面设置付款表格”
superun 生成结账组件,数据库表和支付逻辑,除非您要求,否则无需手动编码或 Webhook.
- 对于一次性销售,请确保您的购物车或产品页面已正常运行.
- 对于 订阅,请确认 superun Cloud(或 Supabase)身份验证已到位,以便 superun 可以将 Stripe 客户链接到每个用户的 id
- 使用聊天驱动流程进行订阅和一次性付款.
- 切勿在聊天中粘贴您的 Stripe 密钥. 请在 研发 → 服务 → Stripe 中通过 STRIPE_API_KEY 栏位进行设定.
- Webhook 是可选择加入的. 如果需要使用 Webhook,请在 STRIPE_WEBHOOK_SECRET 栏位填入 Stripe 的 Webhook 签名密钥,让 superun 可以验证事件.
- 在 浏览器控制台 → 网络/错误,superun Cloud → 日志 和 Stripe 仪表板 → 日志 中进行调试.
- 始终在 Stripe 测试模式下进行测试,然后进行部署.
什么是 Stripe
Stripe 提供一整套支付 API 和工具:
- **付款处理:**接受信用Card,数字钱包和本地付款方式
- 订阅: 定期计费和订阅管理
- 市场: 多方支付和市场功能
- 连接: 市场和平台的平台支付
- 计费: 发票和计费管理
- 税收: 自动税收计算和合规性
主要优点
- 全球覆盖范围: 接受全球客户的付款
- **多种付款方式:**信用Card,数字钱包,银行转账等
- 开发人员友好: 记录完善的 API 和出色的开发人员体验
- 合规性: 符合 PCI DSS 标准,安全处理敏感支付数据
- 实时: 即时付款处理和网络钩子通知
在集成 Stripe 之前,请确保满足以下先决条件:
- 项目必须连接到 superun Cloud(或 Supabase). 详细了解 superun Cloud 或 Supabase 集成
- 具有正确配置产品的 Stripe 帐户(用于订阅)
- 一个工作的前端:
- 对于单个产品销售,请确保购物车和结帐页面正常运行.
- 对于订阅,设置登录功能和不和的定价等级.
请Note意
Stripe 集成在预览版中不起作用.要测试集成,请确保部署您的项目.尝试该功能时,您还应该确保在 Stripe 中处于测试模式.测试付款时,使用测试卡号:“4242 4242 4242 4242”,任意 3 位数字作为 CVC,以及任意未来日期.
Stripe 支付设置(无代码聊天流程)
superun 现在为您生成所有 Stripe 逻辑.当你通过 研发 → 服务 → Stripe 设定好 STRIPE_API_KEY(以及可选的 STRIPE_WEBHOOK_SECRET)并且项目已连接到 superun Cloud(或 Supabase)后,只需在聊天中告诉 superun 你需要什么,无需手动编码.
第 1 步:准备您的项目
- superun Cloud (或 Supabase)已连接
- Stripe 密钥 通过 研发 → 服务 → Stripe 进行设定
*(可选)价格或产品 ID 可从 Stripe 仪表板获取
第2步:在聊天中描述您的付款需求
示例:*“为我的’数字课程’创建一次性结账,价格为 29 美元”
*“设置年度高级计划,价格为 99 美元,与每个用户的 ID 绑定”
*“添加三个订阅级别:基本版为 9 美元/月,专业版为 29 美元/月,企业版为 99 美元/月”
*“为我的产品页面创建付款表格”
第 3 步:审核併申请
superun 自动搭建支付组件,数据库表(如果使用 superun Cloud)和 UI 元素(全部与用户 ID 相关联)的支架.检查预览,然后单击应用进行部署.
- 订阅应始终链接到 superun Cloud(或 Supabase)中经过身份验证的用户的“id”,以实现安全,基于角色的访问.
1. 创建 Stripe 帐户
- 前往 Stripe.com 并注册
- 完成帐户设置过程
- 验证您的企业Info
- 激活您的帐户(测试模式立即可用)
2. 获取您的 API 密钥
在您的 Stripe 仪表板中:
- 转到 开发人员 → API 密钥
- 复制您的可发布密钥(以“pk_test_”或“pk_live_”开头)
- 复制您的密钥(以“sk_test_”或“sk_live_”开头)
- 确保您的密钥安全,切勿在客户端代码中公开它
重要安全Warning切勿将您的 密钥 直接粘贴到 superun 聊天中.将其视为您家的钥匙 - 暴露它可能会导致未经授权的访问您的 Stripe 帐户.相反,请使用 研发 → 服务 → Stripe 功能安全地存储它.
3. 在 superun 中配置 Stripe
您可以通过两种方式启用 Stripe 集成:
选项 1:通过研发服务启用(推荐)
- 在你的 superun 项目中,前往 研发 分页
- 打开 服务,选择 Stripe
- 在 STRIPE_API_KEY 栏位贴上你的 Stripe Secret Key(例如
sk_test_... 或 sk_live_...)
- (可选)在 STRIPE_WEBHOOK_SECRET 栏位贴上 Stripe 的 Webhook 签名密钥(例如
whsec_...),如果你打算使用 Webhook
- 点击 Save Changes,等待 Stripe 整合显示启用完成
superun 会根据这些凭证自动为你的项目配置 Stripe.
选项 2:通过聊天启用
您还可以通过在聊天中询问 superun 来启用 Stripe:
Enable Stripe payment processing for my project
或者
Add Stripe integration with test keys
superun 将指导您完成设置过程并自动配置集成.出现提示时,使用 研发 → 服务 安全地添加您的 API 密钥.
手动付款设置(高级)
推荐: 使用上面描述的 聊天驱动流程 来实现最简单的设置.以下部分适用于想要手动实施付款或自定义生成的代码的高级用户.
安装 Stripe SDK
当您启用 Stripe 集成时,superun 自动包含 Stripe SDK,但您也可以手动安装:
npm install @stripe/stripe-js
初始化 Stripe
import { loadStripe } from '@stripe/stripe-js';
// Initialize Stripe
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
一次性付款
创建付款意图
// Server-side: Create payment intent
const createPaymentIntent = async (amount, currency = 'usd') => {
const response = await fetch('/api/create-payment-intent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: amount * 100, // Amount in cents
currency,
}),
});
const { clientSecret } = await response.json();
return clientSecret;
};
处理付款
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const [loading, setLoading] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
if (!stripe || !elements) {
return;
}
setLoading(true);
// Create payment intent
const clientSecret = await createPaymentIntent(50); // $50.00
// Confirm payment
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
},
});
if (error) {
console.error('Payment failed:', error);
} else if (paymentIntent.status === 'succeeded') {
console.log('Payment succeeded:', paymentIntent);
// Handle successful payment
}
setLoading(false);
};
return (
<form onSubmit={handleSubmit}>
<CardElement
options={{
style: {
base: {
fontSize: '16px',
color: '#424770',
'::placeholder': {
color: '#aab7c4',
},
},
},
}}
/>
<button disabled={!stripe || loading}>
{loading ? 'Processing...' : 'Pay $50.00'}
</button>
</form>
);
};
// Wrap your app with Elements
const App = () => {
return (
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>
);
};
创建订阅
// Create a subscription
const createSubscription = async (priceId, customerId) => {
const response = await fetch('/api/create-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
priceId,
customerId,
}),
});
const { subscription } = await response.json();
return subscription;
};
订阅管理
// Cancel a subscription
const cancelSubscription = async (subscriptionId) => {
const response = await fetch('/api/cancel-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
subscriptionId,
}),
});
const { subscription } = await response.json();
return subscription;
};
// Update subscription
const updateSubscription = async (subscriptionId, newPriceId) => {
const response = await fetch('/api/update-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
subscriptionId,
newPriceId,
}),
});
const { subscription } = await response.json();
return subscription;
};
客户管理
创建客户
// Create a customer
const createCustomer = async (email, name) => {
const response = await fetch('/api/create-customer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
name,
}),
});
const { customer } = await response.json();
return customer;
};
客户门户
// Create customer portal session
const createPortalSession = async (customerId) => {
const response = await fetch('/api/create-portal-session', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
customerId,
}),
});
const { url } = await response.json();
return url;
};
// Redirect to customer portal
const handleManageSubscription = async () => {
const url = await createPortalSession(customerId);
window.location.href = url;
};
高级集成:Webhooks 和 superun Cloud
对于复杂的支付结构,例如订阅和基于角色的访问,superun 建议使用 superun Cloud(或 Supabase)来安全地处理 Stripe 集成.这允许正确的 Webhook 处理,订阅管理和基于支付级别的基于角色的访问控制.
对于基本支付流程,Webhook 是可选. superun 可以在没有 Webhooks 的情况下处理付款,但设置它们可以实现实时更新和更好的订阅管理.
设置 Webhooks
第 1 步:连接 superun Cloud
入门很简单. superun 使连接 superun Cloud 变得毫不费力:
- 转到 研发 → 服务
2. 找到 superun Cloud 并点击 启用
3. 按照说明设置您的云项目
4. 连接后,superun Cloud 可实现安全支付处理,订阅管理,Webhook 处理,客户数据存储和错误处理.
第 2 步:检索 Webhook 端点 URL
superun 生成 Webhook 处理程序后,从以下位置检索端点 URL:
- superun Cloud → 函数 → 您的 webhook 函数
- 或者在聊天中询问 superun:“我的 Stripe webhook 端点 URL 是什么?”
第 3 步:在 Stripe 仪表板中配置 Webhook
- 转到 Stripe 仪表板 → 开发人员 → Webhooks → 添加端点
- 输入第 2 步中的 Webhook URL
- 选择您要监听的事件:
付款意图.成功
付款意图.付款失败
客户.订阅.创建
客户.订阅.更新
客户.订阅.已删除
- 复制 Webhook 签名密钥(以
whsec_ 开头)
第 4 步:安全存储 Webhook 密钥
将 Webhook 签名密钥存储在您的 superun Cloud 环境变量中,或者在聊天中询问 superun 以帮助您安全地配置它.如果不确定如何命名秘密,请在 免费咨询 中向 superun 寻求指导.
处理 Webhooks
// webhook handler
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).end();
}
const sig = req.headers['stripe-signature'];
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
} catch (err) {
console.error('Webhook signature verification failed:', err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log('Payment succeeded:', paymentIntent.id);
// Update your database, send confirmation email, etc.
break;
case 'customer.subscription.created':
const subscription = event.data.object;
console.log('Subscription created:', subscription.id);
// Activate user's premium features
break;
case 'customer.subscription.updated':
const updatedSubscription = event.data.object;
console.log('Subscription updated:', updatedSubscription.id);
// Update subscription status
break;
case 'customer.subscription.deleted':
const deletedSubscription = event.data.object;
console.log('Subscription cancelled:', deletedSubscription.id);
// Deactivate user's premium features
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
res.json({ received: true });
}
高级功能
付款方式
// Save payment method for future use
const savePaymentMethod = async (customerId, paymentMethodId) => {
const response = await fetch('/api/save-payment-method', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
customerId,
paymentMethodId,
}),
});
const { paymentMethod } = await response.json();
return paymentMethod;
};
// List customer's payment methods
const getPaymentMethods = async (customerId) => {
const response = await fetch(`/api/payment-methods/${customerId}`);
const { paymentMethods } = await response.json();
return paymentMethods;
};
// Create an invoice
const createInvoice = async (customerId, items) => {
const response = await fetch('/api/create-invoice', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
customerId,
items,
}),
});
const { invoice } = await response.json();
return invoice;
};
// Send invoice to customer
const sendInvoice = async (invoiceId) => {
const response = await fetch('/api/send-invoice', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
invoiceId,
}),
});
const { invoice } = await response.json();
return invoice;
};
市场支付
// Create a connected account
const createConnectedAccount = async (email, country) => {
const response = await fetch('/api/create-connected-account', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
country,
}),
});
const { account } = await response.json();
return account;
};
// Create account link for onboarding
const createAccountLink = async (accountId) => {
const response = await fetch('/api/create-account-link', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
accountId,
}),
});
const { url } = await response.json();
return url;
};
测试您的集成
测试模式设置
- 使用 Stripe 的测试模式在上线前安全地测试付款
- 在 Stripe 仪表板中切换到测试模式(在右上角切换)
- 使用测试 API 密钥(以
pk_test_ 和 sk_test_ 开头)
测试Card
使用这些测试Card号进行测试:
- 支付成功:
4242 4242 4242 4242
- 任何未来的到期日期(例如 12/25)
- 任何 3 位 CVC(例如 123)
- 拒绝付款:
4000 0000 0000 0002
- 需要身份验证:
4000 0025 0000 3155
- 资金不足:
4000 0000 0000 9995
重要提示: Stripe 集成在预览模式下不起作用.确保部署您的应用程序来测试集成.
测试场景
// Test different payment scenarios
const testCards = {
success: '4242424242424242',
declined: '4000000000000002',
requiresAuth: '4000002500003155',
insufficientFunds: '4000000000009995',
};
// Test webhook events
const testWebhook = async () => {
const response = await fetch('/api/test-webhook', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
eventType: 'payment_intent.succeeded',
data: { /* test data */ },
}),
});
const result = await response.json();
return result;
};
安全最佳实践
环境变量
# .env.local
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
服务器端验证
// Always validate on the server
const validatePayment = async (paymentIntentId) => {
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
if (paymentIntent.status !== 'succeeded') {
throw new Error('Payment not completed');
}
return paymentIntent;
};
Webhook 安全
// Verify webhook signatures
const verifyWebhook = (payload, signature, secret) => {
try {
const event = stripe.webhooks.constructEvent(payload, signature, secret);
return event;
} catch (err) {
throw new Error('Invalid webhook signature');
}
};
常见模式
付款表格组件
const PaymentForm = ({ amount, onSuccess, onError }) => {
const stripe = useStripe();
const elements = useElements();
const [loading, setLoading] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
if (!stripe || !elements) {
return;
}
setLoading(true);
try {
const { error, paymentIntent } = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: elements.getElement(CardElement),
},
}
);
if (error) {
onError(error);
} else if (paymentIntent.status === 'succeeded') {
onSuccess(paymentIntent);
}
} catch (err) {
onError(err);
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button disabled={!stripe || loading}>
{loading ? 'Processing...' : `Pay ${amount}`}
</button>
</form>
);
};
订阅状态组件
const SubscriptionStatus = ({ customerId }) => {
const [subscription, setSubscription] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchSubscription = async () => {
try {
const response = await fetch(`/api/subscription/${customerId}`);
const data = await response.json();
setSubscription(data.subscription);
} catch (error) {
console.error('Error fetching subscription:', error);
} finally {
setLoading(false);
}
};
fetchSubscription();
}, [customerId]);
if (loading) return <div>Loading...</div>;
if (!subscription) return <div>No active subscription</div>;
return (
<div>
<h3>Subscription Status: {subscription.status}</h3>
<p>Current Period: {subscription.current_period_start} - {subscription.current_period_end}</p>
<p>Amount: ${subscription.items.data[0].price.unit_amount / 100}</p>
</div>
);
};
调试和故障排除
第 1 步
打开开发人员工具(在 Chrome 中右键单击 → 检查 → 控制台).
第 3 步
复制错误消息并在聊天中向 superun 寻求调试帮助.
第 1 步
转到 研发 → 服务 → superun Cloud
第 3 步
检查 Webhook 错误和付款处理问题.
第 1 步
导航到 Stripe 仪表板 → 开发人员 → Webhooks
第 3 步
查看 Events 选项Card以确认 Stripe 正在正确发送数据.
第 1 步
切换到 免费咨询 并询问 superun 后续问题.
第 2 步
逐步描述您的问题:
*“我的付款表格没有display”
*“尚未创建订阅”
*“Webhook 不起作用”
第 3 步
使用橡皮鸭方法并逐步解释您的问题以澄清问题.
常见问题
问:付款失败并display“您的Card被拒绝”
答:这可能是由于:
- 在实时模式下使用测试Card(反之亦然)
- 资金不足(测试Card请使用
4242 4242 4242 4242)
- 不支持银行Card在线支付
- Card详细Info不正确
- 银行阻止交易
问:未收到 Webhook
答:检查:
- Webhook URL 可从互联网访问
- Webhook 端点返回 200 状态
- Webhook 签名密钥正确
- 在 Stripe 仪表板中正确选择事件
- 您正在部署模式(而非预览)下进行测试
问:测试付款不起作用
答:确保:
- 您正在使用测试 API 密钥(
pk_test_ 和 sk_test_)
- 测试Card号码正确(
4242 4242 4242 4242)
- 金额以美分为单位(例如,10.00 美元 = 1000 美分)
- 您的应用程序已部署(Stripe 在预览模式下不起作用)
- 您在 Stripe 仪表板中处于 测试模式
问:订阅 webhook 未触发
答:验证:
- 订阅创建成功
- 为订阅事件选择Webhook事件
- Webhook 端点正在正确处理事件
- Webhook 机密正确存储在 superun Cloud 中
需要帮助吗?
查看我们的常见问题解答,了解常见的 Stripe 集成问题和故障排除提示.