跳轉到主要內容

概述

Stripe 是一個支付處理平台,可讓您在線接受付款。通過 Superun 的 Stripe 集成,您可以輕鬆地將支付功能添加到您的應用程序中,包括一次性支付、訂閱和市場功能。 Superun 現在允許您完全通過 聊天 設置 Stripe。 聊天驅動的自動設置(推薦) 連接 Superun Cloud (或 Supabase)並通過 Build 選項卡 → Service 部分保存您的 Stripe 密鑰 後,只需描述您的需求: *“添加三個訂閱級別:基本版為 9 美元/月,專業版為 29 美元/月,企業版為 99 美元/月” *“為我的電子書創建一次性結賬,價格為 29 美元” *“為我的產品頁面設置付款表格” Superun 生成結賬組件、數據庫表和支付邏輯,除非您要求,否則無需手動編碼或 Webhook。
  • 對於一次性銷售,請確保您的購物車或產品頁面已正常運行。
    • 對於 訂閱,請確認 Superun Cloud(或 Supabase)身份驗證已到位,以便 Superun 可以將 Stripe 客戶鏈接到每個用戶的 id

要點

  • 使用聊天驅動流程進行訂閱和一次性付款。
  • **切勿在聊天中粘貼您的 Stripe 密鑰。 ** 通過 構建 選項卡 → 服務 部分 → Stripe啟用 進行配置。
  • **Webhook 是可選擇加入的。 ** Superun 可以在沒有 Webhooks 的情況下處理付款,但您可以針對高級用例進行設置。
  • 瀏覽器控制台 → 網絡/錯誤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 邏輯。通過 Build 選項卡 → Service 部分配置您的 Stripe 密鑰,並且您的項目 連接到 Superun Cloud(或 Supabase),只需在聊天中告訴 Superun 您需要什麼,無需手動編碼。
1

第 1 步:準備您的項目

  • Superun Cloud (或 Supabase)已連接
  • Stripe 密鑰 通過 構建 選項Card添加 → 服務 部分 → 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 帳戶。相反,請使用 Build 選項卡 → Service 部分 → StripeEnable 功能安全地存儲它。

3. 在 Superun 中配置 Stripe

您可以通過兩種方式啟用 Stripe 集成:

選項 1:通過構建服務啟用(推薦)

  1. 在您的 Superun 項目中,轉到 Build 選項卡
  2. 滾動到服務部分 3.找到Stripe並點擊啟用
  3. 出現提示時輸入您的可發布密鑰和秘密密鑰
  4. 選擇您的環境(測試或實時)
Superun 將自動配置您的項目以使用 Stripe。

選項 2:通過聊天啟用

您還可以通過在聊天中詢問 Superun 來啟用 Stripe:
Enable Stripe payment processing for my project
或者
Add Stripe integration with test keys
Superun 將指導您完成設置過程並自動配置集成。出現提示時,使用 Build 選項卡 → Service 部分安全地添加您的 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. 轉到 構建 選項Card → 服務 部分 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 步

轉到 構建 選項Card → 服務 部分 → 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 集成問題和故障排除提示。