Recur
Recur
Recur 文件中心
開發者指南
框架整合指南Vanilla JS 整合指南Next.js 整合指南Astro 整合指南
開發者指南框架整合

Vanilla JS 整合指南

使用純 JavaScript 整合 Recur 訂閱結帳功能

Vanilla JS SDK 適用於任何網站環境,包括靜態網站、WordPress、PHP、或任何可以執行 JavaScript 的環境。

安裝

直接在 HTML 中引入:

<script src="https://unpkg.com/recur-tw@latest/dist/recur.umd.js"></script>

SDK 會自動掛載到 window.Recur。

npm install recur-tw
import Recur from 'recur-tw';

快速開始

初始化 SDK

const recur = Recur.init({
  publishableKey: 'pk_test_your_publishable_key'
});

開啟結帳

document.getElementById('subscribe-btn').addEventListener('click', async () => {
  await recur.checkout({
    productId: 'prod_xxx',  // 或使用 productSlug: 'pro-monthly'
    customerEmail: 'user@example.com',
    customerName: '王小明',
    mode: 'modal',  // 'modal' | 'redirect'
    onPaymentComplete: (result) => {
      console.log('訂閱成功!', result);
      // 導向成功頁面或顯示成功訊息
    },
    onError: (error) => {
      console.error('付款失敗:', error.message);
    }
  });
});

結帳模式

Modal 模式(彈窗)

在當前頁面彈出付款表單,用戶不離開你的網站:

await recur.checkout({
  productId: 'prod_xxx',
  customerEmail: 'user@example.com',
  customerName: '王小明',
  mode: 'modal',
  onSuccess: (result) => {
    // Checkout session 建立成功(付款前)
    console.log('Checkout created:', result.checkout.id);
  },
  onPaymentComplete: (result) => {
    // 付款完成
    console.log('訂閱 ID:', result.id);
    console.log('狀態:', result.status);
  },
  onError: (error) => {
    alert('錯誤:' + error.message);
  },
  onClose: () => {
    console.log('用戶關閉了付款視窗');
  }
});

Redirect 模式(導向)

導向 Recur 託管的結帳頁面,適合不想處理付款 UI 的情況:

await recur.redirectToCheckout({
  productId: 'prod_xxx',
  customerEmail: 'user@example.com',
  successUrl: 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancelUrl: 'https://yoursite.com/cancel'
});

{CHECKOUT_SESSION_ID} 會在導向時自動替換為實際的 session ID,你可以用它來查詢訂閱狀態。

取得產品列表

動態顯示你的訂閱方案:

const { products } = await recur.fetchProducts();

products.forEach(product => {
  console.log(product.id);           // prod_xxx
  console.log(product.name);         // "專業方案"
  console.log(product.price);        // 299
  console.log(product.billingPeriod); // "MONTHLY"
});

篩選特定類型的產品:

// 只取得訂閱類型產品
const { products } = await recur.fetchProducts({ type: 'SUBSCRIPTION' });

// 只取得一次性付款產品
const { products } = await recur.fetchProducts({ type: 'ONE_TIME' });

Customer Portal

讓客戶自助管理訂閱。由於 Portal 連結需要 Secret Key,你需要:

建立後端 API

在你的後端(PHP、Node.js 等)建立一個 API:

// 後端範例(Node.js / Express)
import { Recur } from 'recur-tw/server';

const recur = new Recur({
  secretKey: process.env.RECUR_SECRET_KEY
});

app.post('/api/portal', async (req, res) => {
  const { customerId } = req.body;

  const session = await recur.portal.sessions.create({
    customerId,
    returnUrl: 'https://yoursite.com/account'
  });

  res.json({ url: session.url });
});

前端呼叫 API

document.getElementById('manage-btn').addEventListener('click', async () => {
  const response = await fetch('/api/portal', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ customerId: 'cus_xxx' })
  });

  const { url } = await response.json();
  window.location.href = url;
});

完整範例

<!DOCTYPE html>
<html>
<head>
  <title>訂閱方案</title>
  <script src="https://unpkg.com/recur-tw@latest/dist/recur.umd.js"></script>
</head>
<body>
  <h1>選擇你的方案</h1>
  <div id="plans"></div>

  <script>
    const recur = Recur.init({
      publishableKey: 'pk_test_xxx'
    });

    async function loadPlans() {
      const { products } = await recur.fetchProducts({ type: 'SUBSCRIPTION' });
      const container = document.getElementById('plans');

      products.forEach(product => {
        const card = document.createElement('div');
        card.innerHTML = `
          <h3>${product.name}</h3>
          <p>NT$ ${product.price} / ${product.billingPeriod === 'MONTHLY' ? '月' : '年'}</p>
          <button onclick="subscribe('${product.id}')">訂閱</button>
        `;
        container.appendChild(card);
      });
    }

    async function subscribe(productId) {
      const email = prompt('請輸入你的 Email:');
      const name = prompt('請輸入你的姓名:');

      if (!email || !name) return;

      await recur.checkout({
        productId,
        customerEmail: email,
        customerName: name,
        mode: 'modal',
        onPaymentComplete: (result) => {
          alert('訂閱成功!感謝你的支持。');
          window.location.reload();
        },
        onError: (error) => {
          alert('訂閱失敗:' + error.message);
        }
      });
    }

    loadPlans();
  </script>
</body>
</html>

常見問題

Q: 如何處理 Webhook?

Webhook 需要後端來接收。請參考 Webhook 整合指南。

Q: 如何查詢用戶的訂閱狀態?

這需要使用 Server SDK(Secret Key),必須在後端執行:

// 後端
const subscription = await recur.subscriptions.retrieve('sub_xxx');
console.log(subscription.status); // 'active', 'canceled', etc.

Q: Modal 模式下樣式被網站 CSS 影響怎麼辦?

Recur SDK 已針對常見的 CSS 衝突做了處理。如果仍有問題,請確保你使用的是最新版本:

<script src="https://unpkg.com/recur-tw@latest/dist/recur.umd.js"></script>

下一步

  • Webhook 整合 - 接收訂閱事件通知
  • Customer Portal - 讓客戶自助管理訂閱
  • API 參考 - 完整的 API 文件

框架整合指南

選擇適合你專案的 Recur SDK 整合方式

Next.js 整合指南

在 Next.js App Router 中整合 Recur 訂閱功能

On this page

安裝快速開始初始化 SDK開啟結帳結帳模式Modal 模式(彈窗)Redirect 模式(導向)取得產品列表Customer Portal建立後端 API前端呼叫 API完整範例常見問題Q: 如何處理 Webhook?Q: 如何查詢用戶的訂閱狀態?Q: Modal 模式下樣式被網站 CSS 影響怎麼辦?下一步