@blocklet/payment-react
Version:
Reusable react components for payment kit v2
259 lines (217 loc) • 9.72 kB
Markdown
# CheckoutDonate
`CheckoutDonate` 元件提供了一個彈性且易於整合的解決方案,可為您的應用程式增加捐贈功能。它支援多種顯示模式,從開啟結帳對話方塊的簡單按鈕到由您完全控制的自訂 UI。
此元件必須同時被 `PaymentProvider` 和 `DonateProvider` 包裹才能正常運作。`DonateProvider` 負責管理應用程式特定範圍內捐贈實例的設定和狀態。
## 運作方式
捐贈流程由 `DonateProvider` 和 `CheckoutDonate` 共同協調。以下是高層次的概述:
```d2 How It Works icon=graph-ql:diagram
direction: down
user: {
shape: c4-person
}
app: {
label: "您的 React 應用程式"
checkout-donate: {
label: "CheckoutDonate"
}
checkout-form: {
label: "CheckoutForm (在對話方塊中)"
}
}
payment-api: {
label: "支付後端 API"
shape: cylinder
}
# 初始載入
app.checkout-donate -> payment-api: "獲取設定和支持者"
# 捐贈流程
user -> app.checkout-donate: "1. 點擊捐贈"
app.checkout-donate -> app.checkout-form: "2. 開啟帶有 CheckoutForm 的對話方塊"
app.checkout-form -> payment-api: "3. 處理支付"
payment-api -> app.checkout-form: "4. 回傳成功"
app.checkout-form -> app.checkout-donate: "5. 觸發 onPaid 回呼"
app.checkout-donate -> payment-api: "6. 重新獲取支持者列表"
payment-api -> app.checkout-donate: "7. 回傳更新後的支持者"
```
1. **初始化**:`DonateProvider` 從後端獲取並快取捐贈設定(如預設金額、按鈕文字),並透過唯一的 `mountLocation` 進行識別。
2. **渲染**:`CheckoutDonate` 根據檢索到的設定及其 props 渲染按鈕或自訂 UI。
3. **互動**:當使用者發起捐贈時,`CheckoutDonate` 會開啟一個包含為該捐贈預先設定好的 `CheckoutForm` 的對話方塊。
4. **支付**:使用者透過 `CheckoutForm` 完成支付。
5. **確認**:成功支付後,會觸發 `onPaid` 回呼,且元件會自動刷新支持者列表。
## Provider 設定
在使用 `CheckoutDonate` 之前,您必須用 `PaymentProvider` 和 `DonateProvider` 包裹您的元件樹。
```tsx Provider Setup Example icon=logos:react
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '/payment-react';
import { useSessionContext } from '../hooks/session-context'; // 您的 session context hook
function DonationPage() {
const { session, connect } = useSessionContext();
// 確保在渲染 provider 之前載入 session
if (!session) {
return <div>Loading...</div>;
}
return (
<PaymentProvider session={session} connect={connect}>
<DonateProvider
mountLocation="unique-page-identifier" // 此捐贈情境的唯一金鑰
description="給我很棒的部落格文章的捐贈"
defaultSettings={{
btnText: '支持我',
}}>
{/* 您的 CheckoutDonate 元件放在這裡 */}
<CheckoutDonate
settings={{
target: "post-123",
title: "支持作者",
description: "如果您覺得這篇文章有幫助,歡迎請我喝杯咖啡",
reference: "https://your-site.com/posts/123",
beneficiaries: [
{
address: "z2qa...",
share: "100",
},
],
}}
/>
</DonateProvider>
</PaymentProvider>
);
}
```
更多詳情,請參閱 [`DonateProvider`](./providers-donate-provider.md) 文件。
## 元件 Props
### `DonateProps`
| Prop | Type | Description |
| --- | --- | --- |
| `settings` | `CheckoutDonateSettings` | **必填。** 此特定捐贈實例的設定。 |
| `onPaid` | `(session) => void` | 選填。成功支付後執行的回呼函式。 |
| `onError` | `(error) => void` | 選填。發生錯誤時執行的回呼函式。 |
| `mode` | `'default' \| 'inline' \| 'custom'` | 選填。渲染模式。預設為 `'default'`。 |
| `livemode` | `boolean` | 選填。覆寫來自 `PaymentProvider` 的 `livemode`。 |
| `timeout` | `number` | 選填。支付後關閉對話方塊前等待的毫秒數。預設為 `5000`。 |
| `theme` | `'default' \| 'inherit' \| object` | 選填。主題自訂選項。請參閱 [主題設定](./guides-theming.md) 指南。 |
| `children` | `(openDialog, donateTotalAmount, supporters, loading, donateSettings) => React.ReactNode` | 選填。僅在 `mode="custom"` 時使用的 render prop 函式。 |
### `CheckoutDonateSettings`
此物件被傳遞給 `settings` prop,並定義了捐贈的核心細節。
| Property | Type | Description |
| --- | --- | --- |
| `target` | `string` | **必填。** 捐贈目標的唯一識別碼(例如,文章 ID、專案名稱)。 |
| `title` | `string` | **必填。** 顯示在捐贈對話方塊頂部的標題。 |
| `description` | `string` | **必填。** 顯示在捐贈對話方塊中的簡短描述。 |
| `reference` | `string` | **必填。** 與捐贈相關的 URL,用於參考。 |
| `beneficiaries` | `PaymentBeneficiary[]` | **必填。** 一個物件陣列,定義資金接收者。每個物件都需要 `address`(收款人的 DID)和 `share`(百分比)。 |
| `amount` | `object` | 選填。設定捐贈金額,包括 `presets`(例如 `['1', '5', '10']`)、預設的 `preset`、`minimum`、`maximum` 以及是否允許 `custom` 金額。 |
| `appearance` | `object` | 選填。自訂外觀和風格,包括 `button`(文字、圖示、樣式)和 `history` 顯示(`'avatar'` 或 `'table'`)。 |
## 使用範例
### 預設模式
這是使用 `CheckoutDonate` 最簡單的方式。它會渲染一個按鈕,該按鈕會開啟一個捐贈對話方塊,並附上近期支持者的摘要。
```tsx Default Donation Button icon=logos:react
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '/payment-react';
import { useSessionContext } from '../hooks/session-context';
function App() {
const { session, connect } = useSessionContext();
if (!session) {
return <div>Loading session...</div>;
}
return (
<PaymentProvider session={session} connect={connect}>
<DonateProvider
mountLocation="blog-post-123"
description="給部落格文章 123 的捐贈"
defaultSettings={{
btnText: '請我喝杯咖啡',
historyType: 'avatar',
}}>
<CheckoutDonate
settings={{
target: 'post-123',
title: '支持作者',
description: '如果您覺得這篇文章有幫助,請考慮小額捐款。',
reference: 'https://example.com/posts/123',
beneficiaries: [
{
address: 'z2qa...gCLd', // 作者的 DID 地址
share: '100',
},
],
}}
onPaid={() => {
console.log('捐贈成功!');
}}
/>
</DonateProvider>
</PaymentProvider>
);
}
```
### 自訂 UI 模式
若要完全控制使用者介面,請使用 `mode="custom"` 並提供一個 render prop 作為 `children`。此函式讓您能存取捐贈狀態,包括募集的總金額和支持者列表,從而讓您能夠建立完全自訂的顯示方式。
```tsx Custom Donation UI icon=logos:react
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '/payment-react';
import { useSessionContext } from '../hooks/session-context';
import { CircularProgress, Button } from '@mui/material';
function CustomDonationDisplay() {
const { session, connect } = useSessionContext();
if (!session) {
return <div>Loading session...</div>;
}
const donateSettings = {
target: 'post-123',
title: '支持作者',
description: '如果您覺得這篇文章有幫助,請考慮小額捐款。',
reference: 'https://example.com/posts/123',
beneficiaries: [
{
address: 'z2qa...gCLd', // 作者的 DID 地址
share: '100',
},
],
};
return (
<PaymentProvider session={session} connect={connect}>
<DonateProvider
mountLocation="blog-post-123"
description="給部落格文章 123 的捐贈">
<CheckoutDonate mode="custom" settings={donateSettings}>
{(openDonate, totalAmount, supporters, loading, settings) => (
<div style={{ border: '1px solid #ccc', padding: '16px', borderRadius: '8px' }}>
<h2>我們的支持者</h2>
<p>總捐贈金額:<strong>{totalAmount}</strong></p>
<Button variant="contained" onClick={openDonate}>
{settings?.appearance?.button?.text || '立即捐贈'}
</Button>
{loading ? (
<CircularProgress style={{ marginTop: '16px' }} />
) : (
<ul style={{ listStyle: 'none', padding: 0, marginTop: '16px' }}>
{(supporters.supporters || []).map((supporter) => (
<li key={supporter.id}>
<span>{supporter.customer?.name}</span>
</li>
))}
</ul>
)}
</div>
)}
</CheckoutDonate>
</DonateProvider>
</PaymentProvider>
);
}
```
`children` 函式會收到以下參數:
- `openDonate`:一個手動觸發捐贈對話方塊的函式。
- `totalAmount`:已捐贈總金額的格式化字串(例如 `"125.00 T"`)。
- `supporters`:一個 `DonateHistory` 物件,包含 `supporters` 陣列和貨幣資訊。
- `loading`:一個布林值,表示是否正在獲取支持者資料。
- `settings`:已解析的捐贈設定,由 `DonateProvider` 和 props 合併而成。