跳到主要内容

CheckoutDonate

CheckoutDonate 组件为您的应用程序添加捐赠功能提供了一个灵活且易于集成的解决方案。它支持多种显示模式,从一个简单的打开结账对话框的按钮,到一个由您完全控制的自定义 UI。

该组件必须同时包装在 PaymentProviderDonateProvider 中才能正常工作。DonateProvider 管理应用程序特定范围内的捐赠实例的设置和状态。

工作原理

捐赠流程由 DonateProviderCheckoutDonate 共同协调。以下是其高级概述:

CheckoutDonate

  1. 初始化

    DonateProvider 从后端获取并缓存捐赠设置(如预设金额、按钮文本),这些设置由唯一的 mountLocation 标识。

  2. 渲染

    CheckoutDonate 根据检索到的设置及其 props 渲染一个按钮或自定义 UI。

  3. 交互

    当用户发起捐赠时,CheckoutDonate 会打开一个包含为该捐赠预先配置好的 CheckoutForm 的对话框。

  4. 支付

    用户通过 CheckoutForm 完成支付。

  5. 确认

    支付成功后,将触发 onPaid 回调,并且组件会自动刷新支持者列表。

Provider 设置

在使用 CheckoutDonate 之前,您必须使用 PaymentProviderDonateProvider 包装您的组件树。

Provider 设置示例

tsx
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

PropTypeDescription
settingsCheckoutDonateSettings必需。 此特定捐赠实例的配置。
onPaid(session) => void可选。支付成功后执行的回调函数。
onError(error) => void可选。发生错误时执行的回调函数。
mode'default' | 'inline' | 'custom'可选。渲染模式。默认为 'default'
livemodeboolean可选。覆盖来自 PaymentProviderlivemode
timeoutnumber可选。支付后等待关闭对话框的毫秒数。默认为 5000
theme'default' | 'inherit' | object可选。主题自定义选项。请参阅 Theming 指南。
children(openDialog, donateTotalAmount, supporters, loading, donateSettings) => React.ReactNode可选。仅在 mode="custom" 时使用的渲染属性函数。

CheckoutDonateSettings

此对象传递给 settings 属性,并定义了捐赠的核心细节。

PropertyTypeDescription
targetstring必需。 捐赠目标的唯一标识符(例如,帖子 ID、项目名称)。
titlestring必需。 显示在捐赠对话框顶部的标题。
descriptionstring必需。 显示在捐赠对话框中的简短描述。
referencestring必需。 与捐赠相关的 URL,用于参考。
beneficiariesPaymentBeneficiary[]必需。 定义资金接收者的对象数组。每个对象需要一个 address(收款人的 DID)和 share(百分比)。
amountobject可选。配置捐赠金额,包括 presets(例如,['1', '5', '10'])、默认的 presetminimummaximum,以及是否允许 custom 金额。
appearanceobject可选。自定义外观和感觉,包括 button(文本、图标、变体)和 history 显示('avatar''table')。

用法示例

默认模式

这是使用 CheckoutDonate 的最简单方法。它会渲染一个打开捐赠对话框的按钮,以及近期支持者的摘要。

默认捐赠按钮

tsx
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

tsx
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 合并而成。