CheckoutDonate 组件为您的应用程序添加捐赠功能提供了一个灵活且易于集成的解决方案。它支持多种显示模式,从一个简单的打开结账对话框的按钮,到一个由您完全控制的自定义 UI。
该组件必须同时包装在 PaymentProvider 和 DonateProvider 中才能正常工作。DonateProvider 管理应用程序特定范围内的捐赠实例的设置和状态。
工作原理
捐赠流程由 DonateProvider 和 CheckoutDonate 共同协调。以下是其高级概述:

初始化
DonateProvider从后端获取并缓存捐赠设置(如预设金额、按钮文本),这些设置由唯一的mountLocation标识。渲染
CheckoutDonate根据检索到的设置及其 props 渲染一个按钮或自定义 UI。交互
当用户发起捐赠时,
CheckoutDonate会打开一个包含为该捐赠预先配置好的CheckoutForm的对话框。支付
用户通过
CheckoutForm完成支付。确认
支付成功后,将触发
onPaid回调,并且组件会自动刷新支持者列表。
Provider 设置
在使用 CheckoutDonate 之前,您必须使用 PaymentProvider 和 DonateProvider 包装您的组件树。
Provider 设置示例
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context'; // 你的会话上下文钩子
function DonationPage() {
const { session, connect } = useSessionContext();
// 确保在渲染 provider 之前已加载会话
if (!session) {
return <div>加载中...</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 文档。
组件属性
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 | 可选。主题自定义选项。请参阅 Theming 指南。 |
children | (openDialog, donateTotalAmount, supporters, loading, donateSettings) => React.ReactNode | 可选。仅在 mode="custom" 时使用的渲染属性函数。 |
CheckoutDonateSettings
此对象传递给 settings 属性,并定义了捐赠的核心细节。
| 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 的最简单方法。它会渲染一个打开捐赠对话框的按钮,以及近期支持者的摘要。
默认捐赠按钮
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context';
function App() {
const { session, connect } = useSessionContext();
if (!session) {
return <div>加载会话中...</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" 并提供一个渲染属性作为 children。此函数让您能够访问捐赠状态,包括筹集到的总金额和支持者列表,从而允许您构建一个完全自定义的显示。
自定义捐赠 UI
import {
PaymentProvider,
DonateProvider,
CheckoutDonate,
} from '@blocklet/payment-react';
import { useSessionContext } from '../hooks/session-context';
import { CircularProgress, Button } from '@mui/material';
function CustomDonationDisplay() {
const { session, connect } = useSessionContext();
if (!session) {
return <div>加载会话中...</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 合并而成。