Recur
開發者指南React Hooks

useSubscribe

發起訂閱結帳、管理付款狀態的 React Hook

useSubscribe

useSubscribe 是發起結帳的主要 Hook,封裝了 useRecur().checkout() 並提供自動狀態管理。

需要在 RecurProvider 內使用。

基本用法

import { useSubscribe } from 'recur-tw';

function SubscribeButton() {
  const { subscribe, isLoading, error } = useSubscribe({
    onPaymentComplete: (subscription) => {
      console.log('付款成功!', subscription.id);
      window.location.href = '/welcome';
    },
  });

  return (
    <div>
      <button
        onClick={() => subscribe({
          productId: 'prod_xxx',
          customerEmail: 'user@example.com',
        })}
        disabled={isLoading}
      >
        {isLoading ? '處理中...' : '立即訂閱'}
      </button>
      {error && <p className="text-red-500">{error.message}</p>}
    </div>
  );
}

Options(初始化參數)

傳入 useSubscribe() 的 callback 設定:

參數類型說明
onSuccess(result) => voidCheckout session 建立成功(卡片表單已準備好)
onPaymentComplete(subscription) => void付款完成、訂閱已啟用
onError(error) => void發生錯誤
onPaymentFailed(error) => PaymentFailedAction | void付款失敗(卡號錯誤等),可回傳自訂行為
onPaymentCancel() => void用戶取消付款

subscribe() 參數

呼叫 subscribe() 時傳入的結帳選項:

參數類型必填說明
productIdstring是*產品 ID
productSlugstring是*或用產品 slug(二擇一)
customerEmailstring顧客 email
customerNamestring顧客名稱
externalCustomerIdstring您系統中的客戶 ID
promoCodestring優惠碼(搭配 usePromoCode 使用)
trialDaysnumber覆蓋預設試用天數
quantitynumber數量(預設 1)
metadataobject自訂資料(最多 10 key)
collectPaymentMethodstring'always''if_required'

Return 值

屬性類型說明
subscribe(options) => Promise<void>發起結帳
mutate(options) => Promise<void>subscribe 的別名
isLoadingboolean結帳流程進行中
errorCheckoutError | null錯誤物件
reset() => void清除錯誤狀態

useSubscribe vs useRecur

useSubscribeuseRecur
狀態管理內建(isLoading, error, reset)需自己管理
Callbacks透過 options 設定在 checkout() 內設定
推薦場景大多數情境需要完整控制流程時

搭配優惠碼

import { useSubscribe, usePromoCode } from 'recur-tw';

function Checkout({ userId, userEmail }) {
  const promo = usePromoCode({ customerId: userId });
  const { subscribe, isLoading } = useSubscribe();

  return (
    <div>
      <input onBlur={(e) => promo.apply(e.target.value)} />
      <button onClick={() => subscribe({
        productId: 'prod_xxx',
        customerEmail: userEmail,
        promoCode: promo.code,  // null = 不帶優惠碼
      })}>
        訂閱
      </button>
    </div>
  );
}

錯誤處理

const { subscribe, error, reset } = useSubscribe({
  onError: (err) => {
    if (err.code === 'DUPLICATE_SUBSCRIPTION') {
      alert('您已經訂閱了此方案');
    }
  },
  onPaymentFailed: (err) => {
    // 自訂付款失敗行為
    if (err.details?.failureCode === 'INSUFFICIENT_FUNDS') {
      return { action: 'show_message', message: '餘額不足,請更換付款方式' };
    }
    // 回傳 undefined 使用預設處理
  },
});

詳細的錯誤碼說明請參考 錯誤處理指南

Last updated on

On this page