跳转到主要内容

概述

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 CloudSupabase 集成
  • 具有正确配置产品的 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

第 1 步:准备您的项目

  • superun Cloud (或 Supabase)已连接
  • Stripe 密钥 通过 研发 → 服务 → Stripe 进行设定 *(可选)价格或产品 ID 可从 Stripe 仪表板获取
2

第2步:在聊天中描述您的付款需求

示例:*“为我的’数字课程’创建一次性结账,价格为 29 美元” *“设置年度高级计划,价格为 99 美元,与每个用户的 ID 绑定” *“添加三个订阅级别:基本版为 9 美元/月,专业版为 29 美元/月,企业版为 99 美元/月” *“为我的产品页面创建付款表格”
3

第 3 步:审核併申请

superun 自动搭建支付组件,数据库表(如果使用 superun Cloud)和 UI 元素(全部与用户 ID 相关联)的支架.检查预览,然后单击应用进行部署.
  • 订阅应始终链接到 superun Cloud(或 Supabase)中经过身份验证的用户的“id”,以实现安全,基于角色的访问.

入门

1. 创建 Stripe 帐户

  1. 前往 Stripe.com 并注册
  2. 完成帐户设置过程
  3. 验证您的企业Info
  4. 激活您的帐户(测试模式立即可用)

2. 获取您的 API 密钥

在您的 Stripe 仪表板中:
  1. 转到 开发人员 → API 密钥
  2. 复制您的可发布密钥(以“pk_test_”或“pk_live_”开头)
  3. 复制您的密钥(以“sk_test_”或“sk_live_”开头)
  4. 确保您的密钥安全,切勿在客户端代码中公开它
重要安全Warning切勿将您的 密钥 直接粘贴到 superun 聊天中.将其视为您家的钥匙 - 暴露它可能会导致未经授权的访问您的 Stripe 帐户.相反,请使用 研发 → 服务 → Stripe 功能安全地存储它.

3. 在 superun 中配置 Stripe

您可以通过两种方式启用 Stripe 集成:

选项 1:通过研发服务启用(推荐)

  1. 在你的 superun 项目中,前往 研发 分页
  2. 打开 服务,选择 Stripe
  3. STRIPE_API_KEY 栏位贴上你的 Stripe Secret Key(例如 sk_test_...sk_live_...
  4. (可选)在 STRIPE_WEBHOOK_SECRET 栏位贴上 Stripe 的 Webhook 签名密钥(例如 whsec_...),如果你打算使用 Webhook
  5. 点击 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

第 1 步:连接 superun Cloud

入门很简单. superun 使连接 superun Cloud 变得毫不费力:
  1. 转到 研发 → 服务 2. 找到 superun Cloud 并点击 启用 3. 按照说明设置您的云项目 4. 连接后,superun Cloud 可实现安全支付处理,订阅管理,Webhook 处理,客户数据存储和错误处理.
2

第 2 步:检索 Webhook 端点 URL

superun 生成 Webhook 处理程序后,从以下位置检索端点 URL:
  • superun Cloud函数 → 您的 webhook 函数
  • 或者在聊天中询问 superun:“我的 Stripe webhook 端点 URL 是什么?”
3

第 3 步:在 Stripe 仪表板中配置 Webhook

  1. 转到 Stripe 仪表板开发人员Webhooks添加端点
  2. 输入第 2 步中的 Webhook URL
  3. 选择您要监听的事件:
  • 付款意图.成功
  • 付款意图.付款失败
  • 客户.订阅.创建
  • 客户.订阅.更新
  • 客户.订阅.已删除
  1. 复制 Webhook 签名密钥(以 whsec_ 开头)
4

第 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

第 1 步

打开开发人员工具(在 Chrome 中右键单击 → 检查 → 控制台).
2

第 2 步

查找错误并查看付款事件日志.
3

第 3 步

复制错误消息并在聊天中向 superun 寻求调试帮助.
1

第 1 步

转到 研发 → 服务 → superun Cloud
2

第 2 步

导航到 日志函数日志
3

第 3 步

检查 Webhook 错误和付款处理问题.
1

第 1 步

导航到 Stripe 仪表板开发人员Webhooks
2

第 2 步

单击您的 Webhook 端点
3

第 3 步

查看 Events 选项Card以确认 Stripe 正在正确发送数据.
1

第 1 步

切换到 免费咨询 并询问 superun 后续问题.
2

第 2 步

逐步描述您的问题: *“我的付款表格没有display” *“尚未创建订阅” *“Webhook 不起作用”
3

第 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 集成问题和故障排除提示.