@blocklet/payment-react 1.19.22 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.aigne/doc-smith/config.yaml +114 -0
  2. package/.aigne/doc-smith/output/structure-plan.json +361 -0
  3. package/.aigne/doc-smith/preferences.yml +55 -0
  4. package/.aigne/doc-smith/upload-cache.yaml +264 -0
  5. package/README.md +2 -3
  6. package/docs/_sidebar.md +33 -0
  7. package/docs/components-business-auto-topup.md +238 -0
  8. package/docs/components-business-overdue-invoice-payment.md +231 -0
  9. package/docs/components-business-resume-subscription.md +177 -0
  10. package/docs/components-business.md +45 -0
  11. package/docs/components-checkout-checkout-donate.md +199 -0
  12. package/docs/components-checkout-checkout-form.md +185 -0
  13. package/docs/components-checkout-checkout-table.md +228 -0
  14. package/docs/components-checkout.md +131 -0
  15. package/docs/components-history-credit-grants-list.md +98 -0
  16. package/docs/components-history-credit-transactions-list.md +116 -0
  17. package/docs/components-history-invoice-list.md +104 -0
  18. package/docs/components-history-payment-list.md +65 -0
  19. package/docs/components-history.md +92 -0
  20. package/docs/components-ui-form-elements-address-form.md +150 -0
  21. package/docs/components-ui-form-elements-country-select.md +105 -0
  22. package/docs/components-ui-form-elements-currency-selector.md +124 -0
  23. package/docs/components-ui-form-elements-phone-input.md +160 -0
  24. package/docs/components-ui-form-elements.md +125 -0
  25. package/docs/components-ui-payment-summary.md +157 -0
  26. package/docs/components-ui-pricing-table.md +227 -0
  27. package/docs/components-ui.md +44 -0
  28. package/docs/components.md +95 -0
  29. package/docs/getting-started.md +111 -0
  30. package/docs/guides-theming.md +175 -0
  31. package/docs/guides-utilities.md +235 -0
  32. package/docs/guides.md +95 -0
  33. package/docs/hooks-use-mobile.md +70 -0
  34. package/docs/hooks-use-subscription.md +129 -0
  35. package/docs/hooks.md +84 -0
  36. package/docs/overview.md +87 -0
  37. package/docs/providers-donate-provider.md +175 -0
  38. package/docs/providers-payment-provider.md +245 -0
  39. package/docs/providers.md +101 -0
  40. package/es/payment/form/index.js +15 -1
  41. package/lib/payment/form/index.js +14 -1
  42. package/package.json +5 -5
  43. package/src/payment/form/index.tsx +16 -1
@@ -0,0 +1,231 @@
1
+ # OverdueInvoicePayment
2
+
3
+ The `OverdueInvoicePayment` component is designed to handle the payment of overdue invoices for a specific customer or subscription. It can operate in two modes: a default dialog mode that presents a pre-built UI for payment, or a custom mode that provides data and a payment handler to build a custom user interface.
4
+
5
+ This component streamlines the process of collecting late payments by summarizing amounts by currency and initiating a batch payment process through the user's DID Wallet.
6
+
7
+ ## When to Use
8
+
9
+ Use this component in your application's subscription management or customer billing sections to:
10
+
11
+ - Prompt users to pay for a subscription that has fallen into a `past_due` status.
12
+ - Allow customers to clear all outstanding invoices across multiple subscriptions in a single operation.
13
+
14
+ ## Component Logic Flow
15
+
16
+ The component follows a clear sequence to manage overdue payments:
17
+
18
+ ```d2
19
+ shape: sequence_diagram
20
+
21
+ User: "User"
22
+ App: "Your Application"
23
+ OIP: "OverdueInvoicePayment"
24
+ PaymentProvider: "PaymentProvider"
25
+ API: "Payment Service API"
26
+
27
+ User -> App: "Views page with overdue invoices"
28
+ App -> OIP: "Renders with subscriptionId or customerId"
29
+ OIP -> API: "GET /overdue/invoices"
30
+ API -> OIP: "Returns summary & invoices list"
31
+
32
+ alt "Invoices exist"
33
+ OIP -> App: "Renders payment UI (dialog/custom)"
34
+ User -> OIP: "Clicks 'Pay Now'"
35
+ OIP -> PaymentProvider: "Calls connect.open()"
36
+ PaymentProvider -> User: "Shows DID Wallet connect modal"
37
+ User -> PaymentProvider: "Scans & confirms payment"
38
+ PaymentProvider -> API: "Processes batch payment"
39
+ API -> PaymentProvider: "Payment successful"
40
+ PaymentProvider -> OIP: "Triggers onSuccess"
41
+ OIP -> OIP: "Refreshes invoice data"
42
+ OIP -> App: "Calls onPaid() & closes UI"
43
+ else "No overdue invoices"
44
+ OIP -> App: "Displays success/empty message"
45
+ end
46
+ ```
47
+
48
+ ## Props
49
+
50
+ | Prop | Type | Description |
51
+ | --- | --- | --- |
52
+ | `subscriptionId` | `string` | Optional. The ID of the subscription to check for overdue invoices. Either `subscriptionId` or `customerId` must be provided. |
53
+ | `customerId` | `string` | Optional. The customer's ID (or DID) to check for all overdue invoices across their subscriptions. |
54
+ | `mode` | `'default' \| 'custom'` | Optional. The rendering mode. `'default'` displays a pre-built dialog. `'custom'` uses a render prop for a custom UI. Defaults to `'default'`. |
55
+ | `onPaid` | `(id, currencyId, type) => void` | Optional. A callback function executed after all overdue invoices are paid. It receives the source ID (`subscriptionId` or `customerId`), the currency ID, and the source type (`'subscription'` or `'customer'`). |
56
+ | `dialogProps` | `object` | Optional. Props to pass to the underlying Material-UI `Dialog` component in `default` mode. Can be used to control its `open` state, `title`, and `onClose` behavior. |
57
+ | `detailLinkOptions` | `object` | Optional. An object to configure the "view details" link in the default dialog. Shape: `{ enabled?: boolean, onClick?: (e) => void, title?: string }`. |
58
+ | `successToast` | `boolean` | Optional. If `true`, a success toast notification is shown upon successful payment. Defaults to `true`. |
59
+ | `alertMessage` | `string` | Optional. A custom message to append to the default alert text when checking by `customerId`. |
60
+ | `children` | `function` | Optional. A render prop function used only when `mode="custom"`. It receives `handlePay` and `data` as arguments. |
61
+ | `authToken` | `string` | Optional. An authentication token for API requests, useful for cross-origin scenarios where session cookies are not available. |
62
+
63
+ ## Usage
64
+
65
+ > All examples assume you have set up `PaymentProvider` and a `useSessionContext` hook to provide session data. The `useSessionContext` hook is a local utility to access your application's session context. For a complete guide on this setup, please refer to the [PaymentProvider documentation](./providers-payment-provider.md).
66
+
67
+ ### Default Mode Usage
68
+
69
+ In its default mode, the component renders a dialog that summarizes the overdue payments and prompts the user to pay. This is the quickest way to implement overdue payment handling.
70
+
71
+ #### Handling a Single Subscription's Overdue Invoices
72
+
73
+ Provide the `subscriptionId` to target a specific subscription. A dialog will appear if there are any overdue invoices.
74
+
75
+ ```tsx
76
+ import { PaymentProvider, OverdueInvoicePayment } from '@blocklet/payment-react';
77
+ // This is a local utility to get session info from your app's context.
78
+ // See the PaymentProvider docs for setup details.
79
+ import { useSessionContext } from 'src/hooks/session';
80
+
81
+ function SubscriptionDetailsPage({ subscriptionId }) {
82
+ const { session, connect: connectApi } = useSessionContext();
83
+
84
+ const handlePaymentSuccess = () => {
85
+ console.log('All overdue invoices for the subscription have been paid.');
86
+ // You can refresh the subscription status here
87
+ };
88
+
89
+ if (!session || !connectApi) {
90
+ return <div>Loading session...</div>;
91
+ }
92
+
93
+ return (
94
+ <PaymentProvider session={session} connect={connectApi}>
95
+ <OverdueInvoicePayment
96
+ subscriptionId={subscriptionId}
97
+ onPaid={handlePaymentSuccess}
98
+ />
99
+ </PaymentProvider>
100
+ );
101
+ }
102
+ ```
103
+
104
+ #### Handling All of a Customer's Overdue Invoices
105
+
106
+ Provide the `customerId` (which can be the user's DID) to consolidate all overdue invoices from all of their subscriptions into a single payment flow.
107
+
108
+ ```tsx
109
+ import { PaymentProvider, OverdueInvoicePayment } from '@blocklet/payment-react';
110
+ // This is a local utility to get session info from your app's context.
111
+ // See the PaymentProvider docs for setup details.
112
+ import { useSessionContext } from 'src/hooks/session';
113
+
114
+ function CustomerDashboard() {
115
+ const { session, connect: connectApi } = useSessionContext();
116
+
117
+ if (!session?.user?.did || !connectApi) {
118
+ return <div>Loading session...</div>;
119
+ }
120
+
121
+ return (
122
+ <PaymentProvider session={session} connect={connectApi}>
123
+ <OverdueInvoicePayment
124
+ customerId={session.user.did}
125
+ onPaid={() => {
126
+ console.log("All of the customer's overdue invoices are paid.");
127
+ // Refresh customer data or redirect
128
+ }}
129
+ dialogProps={{
130
+ title: 'Outstanding Payments',
131
+ }}
132
+ />
133
+ </PaymentProvider>
134
+ );
135
+ }
136
+ ```
137
+
138
+ ### Custom Mode Usage
139
+
140
+ For full control over the user interface, set `mode="custom"`. This allows you to build a completely custom component for handling overdue payments using the `children` render prop.
141
+
142
+ The render prop receives two arguments:
143
+ 1. `handlePay`: A function to trigger the payment process. It takes a `SummaryItem` object as an argument.
144
+ 2. `data`: An object containing all the necessary information about the overdue invoices.
145
+
146
+ #### Building a Custom UI
147
+
148
+ Here is an example of creating a custom card to display overdue payment information and trigger payments.
149
+
150
+ ```tsx
151
+ import {
152
+ PaymentProvider,
153
+ OverdueInvoicePayment,
154
+ Amount,
155
+ } from '@blocklet/payment-react';
156
+ import { Card, CardContent, Typography, Button, Stack } from '@mui/material';
157
+ // This is a local utility to get session info from your app's context.
158
+ // See the PaymentProvider docs for setup details.
159
+ import { useSessionContext } from 'src/hooks/session';
160
+
161
+ function CustomOverdueUI({ subscriptionId }) {
162
+ const { session, connect: connectApi } = useSessionContext();
163
+
164
+ if (!session || !connectApi) {
165
+ return <div>Loading session...</div>;
166
+ }
167
+
168
+ return (
169
+ <PaymentProvider session={session} connect={connectApi}>
170
+ <OverdueInvoicePayment
171
+ subscriptionId={subscriptionId}
172
+ mode="custom"
173
+ onPaid={() => console.log('Paid!')}>
174
+ {(handlePay, { summary, invoices, subscription }) => {
175
+ if (!invoices || invoices.length === 0) {
176
+ return <Typography>No overdue payments. All good!</Typography>;
177
+ }
178
+
179
+ return (
180
+ <Card variant="outlined">
181
+ <CardContent>
182
+ <Typography variant="h6" gutterBottom>
183
+ Action Required for {subscription?.description}
184
+ </Typography>
185
+ <Typography color="error" gutterBottom>
186
+ You have {invoices.length} overdue invoice(s).
187
+ </Typography>
188
+ <Stack spacing={2} sx={{ mt: 2 }}>
189
+ {Object.values(summary).map((info) => (
190
+ <Stack
191
+ key={info.currency.id}
192
+ direction="row"
193
+ justifyContent="space-between"
194
+ alignItems="center">
195
+ <Typography>
196
+ Total Due: <Amount amount={info.amount} decimal={info.currency.decimal} symbol={info.currency.symbol} />
197
+ </Typography>
198
+ <Button
199
+ onClick={() => handlePay(info)}
200
+ variant="contained"
201
+ color="primary">
202
+ Pay Now
203
+ </Button>
204
+ </Stack>
205
+ ))}
206
+ </Stack>
207
+ </CardContent>
208
+ </Card>
209
+ );
210
+ }}
211
+ </OverdueInvoicePayment>
212
+ </PaymentProvider>
213
+ );
214
+ }
215
+ ```
216
+
217
+ #### Custom Mode `data` Object
218
+
219
+ The `data` object passed to the `children` render prop contains the following fields:
220
+
221
+ | Field | Type | Description |
222
+ | --- | --- | --- |
223
+ | `subscription` | `Subscription` | The full subscription object, if `subscriptionId` was provided. |
224
+ | `summary` | `{ [key: string]: SummaryItem }` | An object summarizing the total amount due, grouped by currency ID. Each `SummaryItem` contains `amount`, `currency`, and `method`. |
225
+ | `invoices` | `Invoice[]` | An array of the raw overdue invoice objects. |
226
+ | `subscriptionCount` | `number` | The number of subscriptions with overdue payments, if `customerId` was provided. |
227
+ | `detailUrl` | `string` | A pre-generated URL to the detailed invoice or subscription page. |
228
+
229
+ ### Note on Payment Methods
230
+
231
+ The batch payment flow initiated by this component currently supports wallet-based payments (like ArcBlock, Ethereum). It does not support batch payments via Stripe. If an overdue invoice's payment method is Stripe, the component will guide the user to a page where they can pay manually.
@@ -0,0 +1,177 @@
1
+ # ResumeSubscription
2
+
3
+ The `ResumeSubscription` component provides a user interface for resuming a canceled subscription. It handles the necessary logic, including prompting the user to re-stake funds if required, and appears as a modal dialog by default.
4
+
5
+ This component must be used within a [`PaymentProvider`](./providers-payment-provider.md) to access the required payment context.
6
+
7
+ ## How It Works
8
+
9
+ The component streamlines the subscription recovery process. When rendered, it first checks if the subscription requires a new stake to be resumed. Based on this information, it presents one of two flows:
10
+
11
+ 1. **Direct Resume**: If no new stake is needed, the user can confirm to directly reactivate the subscription.
12
+ 2. **Resume with Re-Stake**: If a stake is required, the component will initiate a wallet connection flow, asking the user to approve the staking transaction to resume their subscription.
13
+
14
+ ```d2
15
+ shape: sequence_diagram
16
+
17
+ User
18
+ "React App"
19
+ "ResumeSubscription"
20
+ "Payment API"
21
+ "DID Wallet"
22
+
23
+ User -> "React App": "Clicks 'Resume Subscription'"
24
+ "React App" -> "ResumeSubscription": "Renders with subscriptionId"
25
+
26
+ "ResumeSubscription" -> "Payment API": "GET /recover-info"
27
+ "Payment API" --> "ResumeSubscription": "{ needStake }"
28
+
29
+ alt "Direct Resume (needStake is false)" {
30
+ "ResumeSubscription" -> "Payment API": "PUT /recover"
31
+ "Payment API" --> "ResumeSubscription": "{ subscription }"
32
+ }
33
+
34
+ alt "Re-Stake Required (needStake is true)" {
35
+ "ResumeSubscription" -> "DID Wallet": "Opens connect for 're-stake'"
36
+ User -> "DID Wallet": "Approves transaction"
37
+ "DID Wallet" --> "ResumeSubscription": "onSuccess()"
38
+ }
39
+
40
+ "ResumeSubscription" -> "Payment API": "GET /subscriptions/:id (on success)"
41
+ "Payment API" --> "ResumeSubscription": "Updated subscription data"
42
+ "ResumeSubscription" -> "React App": "onResumed(subscription)"
43
+ "React App" -> User: "UI is updated"
44
+ ```
45
+
46
+ ## Props
47
+
48
+ | Prop | Type | Description |
49
+ | :--------------- | :------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
50
+ | `subscriptionId` | `string` | **Required.** The ID of the subscription to be resumed. |
51
+ | `onResumed` | `(sub: Subscription \| TSubscriptionExpanded) => void` | Optional. A callback function that is executed after the subscription has been successfully resumed. It receives the updated subscription object as an argument. |
52
+ | `dialogProps` | `object` | Optional. Props to customize the underlying Material-UI Dialog component. Default: `{ open: true }`. Key properties include:<br />- `open`: `boolean`, controls visibility.<br />- `onClose`: `() => void`, a callback for when the dialog is closed.<br />- `title`: `string`, overrides the default dialog title. |
53
+ | `successToast` | `boolean` | Optional. If `true`, a success toast notification is shown upon successful resumption. Defaults to `true`. |
54
+ | `authToken` | `string` | Optional. An authentication token to be included in API requests. This is useful for cross-origin requests or when the application manages authentication separately. |
55
+
56
+ ## Usage Examples
57
+
58
+ <div class="lead">All examples require the component to be wrapped in a `PaymentProvider`. The `session` and `connect` props are obtained using a custom `useSessionContext` hook, which represents your application's authentication state. For detailed setup instructions, please refer to the <a href="/providers/payment-provider">PaymentProvider documentation</a>.</div>
59
+
60
+ ### Basic Usage
61
+
62
+ This example shows the simplest way to use `ResumeSubscription`. The dialog will be open by default, and a success toast will appear upon completion.
63
+
64
+ ```tsx
65
+ import React from 'react';
66
+ import { PaymentProvider, ResumeSubscription } from '@blocklet/payment-react';
67
+
68
+ // Placeholder for your application's session context hook.
69
+ // See the PaymentProvider documentation for setup details.
70
+ import { useSessionContext } from '../hooks/use-session-context';
71
+
72
+ function SubscriptionManagementPage({ subscriptionId, refetchSubscription }) {
73
+ // session and connect are derived from your application's auth service.
74
+ const { session, connect } = useSessionContext();
75
+
76
+ if (!session) {
77
+ return <div>Loading session...</div>;
78
+ }
79
+
80
+ return (
81
+ <PaymentProvider session={session} connect={connect}>
82
+ <ResumeSubscription
83
+ subscriptionId={subscriptionId}
84
+ onResumed={(subscription) => {
85
+ console.log('Subscription resumed:', subscription);
86
+ // Update your application's state here.
87
+ refetchSubscription();
88
+ }}
89
+ />
90
+ </PaymentProvider>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ### Controlling the Dialog
96
+
97
+ You can manage the dialog's visibility from a parent component by passing its state down through `dialogProps`.
98
+
99
+ ```tsx
100
+ import React, { useState } from 'react';
101
+ import { Button } from '@mui/material';
102
+ import { PaymentProvider, ResumeSubscription } from '@blocklet/payment-react';
103
+
104
+ // Placeholder for your application's session context hook.
105
+ // See the PaymentProvider documentation for setup details.
106
+ import { useSessionContext } from '../hooks/use-session-context';
107
+
108
+ function SubscriptionDetails({ subscriptionId, refetchSubscription }) {
109
+ const [isResumeDialogOpen, setResumeDialogOpen] = useState(false);
110
+ const { session, connect } = useSessionContext();
111
+
112
+ const handleCloseDialog = () => {
113
+ setResumeDialogOpen(false);
114
+ };
115
+
116
+ if (!session) {
117
+ return <div>Loading session...</div>;
118
+ }
119
+
120
+ return (
121
+ <PaymentProvider session={session} connect={connect}>
122
+ <Button onClick={() => setResumeDialogOpen(true)}>
123
+ Resume Subscription
124
+ </Button>
125
+
126
+ {isResumeDialogOpen && (
127
+ <ResumeSubscription
128
+ subscriptionId={subscriptionId}
129
+ onResumed={() => {
130
+ console.log('Subscription has been resumed.');
131
+ handleCloseDialog();
132
+ refetchSubscription(); // Refresh subscription data in parent component.
133
+ }}
134
+ dialogProps={{
135
+ open: isResumeDialogOpen,
136
+ onClose: handleCloseDialog,
137
+ title: 'Confirm Subscription Renewal',
138
+ }}
139
+ />
140
+ )}
141
+ </PaymentProvider>
142
+ );
143
+ }
144
+ ```
145
+
146
+ ### Usage with an Authentication Token
147
+
148
+ If your API requests require an authentication token, provide it using the `authToken` prop. This is useful for secure communication between different services or Blocklets.
149
+
150
+ ```tsx
151
+ import React from 'react';
152
+ import { PaymentProvider, ResumeSubscription } from '@blocklet/payment-react';
153
+
154
+ // Placeholder for your application's session context hook.
155
+ // See the PaymentProvider documentation for setup details.
156
+ import { useSessionContext } from '../hooks/use-session-context';
157
+
158
+ function SecureSubscriptionResume({ subscriptionId, token }) {
159
+ const { session, connect } = useSessionContext();
160
+
161
+ if (!session) {
162
+ return <div>Loading session...</div>;
163
+ }
164
+
165
+ return (
166
+ <PaymentProvider session={session} connect={connect}>
167
+ <ResumeSubscription
168
+ subscriptionId={subscriptionId}
169
+ authToken={token}
170
+ onResumed={(subscription) => {
171
+ console.log('Subscription resumed securely:', subscription.id);
172
+ }}
173
+ />
174
+ </PaymentProvider>
175
+ );
176
+ }
177
+ ```
@@ -0,0 +1,45 @@
1
+ # Business Logic Components
2
+
3
+ Business logic components are specialized React components designed to handle complex, high-level user flows related to subscription and invoice management. These components encapsulate API calls, state management, and user interactions for common scenarios, allowing you to integrate sophisticated features with minimal effort.
4
+
5
+ These components are ready to be integrated into your application to address specific business needs, such as recovering revenue from failed payments or improving user retention.
6
+
7
+ ```d2
8
+ direction: down
9
+
10
+ "User Application": {
11
+ shape: cloud
12
+ }
13
+
14
+ "Business Logic Components": {
15
+ shape: package
16
+ "OverdueInvoicePayment"
17
+ "ResumeSubscription"
18
+ "Auto-Topup Components"
19
+ }
20
+
21
+ "Payment Service API": {
22
+ shape: database
23
+ }
24
+
25
+ "User Application" -> "Business Logic Components": "Integrates"
26
+ "Business Logic Components.OverdueInvoicePayment" -> "Payment Service API": "Pays for overdue invoices"
27
+ "Business Logic Components.ResumeSubscription" -> "Payment Service API": "Reactivates subscription"
28
+ "Business Logic Components.Auto-Topup Components" -> "Payment Service API": "Configures auto-recharge"
29
+ ```
30
+
31
+ This section provides an overview of the available business logic components. For detailed API references and usage examples, select a component below.
32
+
33
+ <x-cards data-columns="3">
34
+ <x-card data-title="OverdueInvoicePayment" data-icon="lucide:alert-circle" data-href="/components/business/overdue-invoice-payment">
35
+ A component that provides a complete UI flow for handling overdue invoices for a subscription or an entire customer account.
36
+ </x-card>
37
+ <x-card data-title="ResumeSubscription" data-icon="lucide:refresh-cw" data-href="/components/business/resume-subscription">
38
+ A component that facilitates resuming a previously canceled subscription, including handling complex scenarios like re-staking.
39
+ </x-card>
40
+ <x-card data-title="Auto-Topup Components" data-icon="lucide:battery-charging" data-href="/components/business/auto-topup">
41
+ A set of components for managing automatic credit top-ups when a user's balance falls below a configured threshold.
42
+ </x-card>
43
+ </x-cards>
44
+
45
+ After handling these business-specific tasks, you may want to display the results to the user. Proceed to the [History Components](./components-history.md) section to learn how to display lists of invoices, payments, and credit transactions.
@@ -0,0 +1,199 @@
1
+ # CheckoutDonate
2
+
3
+ The `CheckoutDonate` component provides a flexible way to implement donation functionality in your application. It supports several display modes, from a simple pre-built button to a fully custom UI, and handles the entire donation flow, including displaying supporter history.
4
+
5
+ To function correctly, `CheckoutDonate` must be wrapped within both a [`PaymentProvider`](./providers-payment-provider.md) and a [`DonateProvider`](./providers-donate-provider.md).
6
+
7
+ ## Props
8
+
9
+ | Prop | Type | Description |
10
+ |---|---|---|
11
+ | `settings` | `CheckoutDonateSettings` | **Required.** An object containing the configuration for the donation instance, such as target, title, and beneficiaries. |
12
+ | `onPaid` | `(session: TCheckoutSessionExpanded) => void` | Optional. A callback function that is executed after a donation is successfully paid. |
13
+ | `onError` | `(error: any) => void` | Optional. A callback function that is executed if an error occurs during the payment process. |
14
+ | `livemode` | `boolean` | Optional. Toggles between live and test payment modes. If not set, it inherits the value from `PaymentProvider`. |
15
+ | `timeout` | `number` | Optional. The time in milliseconds to wait before closing the checkout dialog after a successful payment. Defaults to `5000`. |
16
+ | `mode` | `'default' \| 'inline' \| 'custom'` | Optional. Determines the rendering mode of the component. Defaults to `'default'`. |
17
+ | `inlineOptions` | `{ button?: ButtonType }` | Optional. Customization options for the button when `mode` is set to `'inline'`. |
18
+ | `theme` | `'default' \| 'inherit' \| PaymentThemeOptions` | Optional. Controls the component's theme. See the [Theming guide](./guides-theming.md) for more details. Defaults to `'default'`. |
19
+ | `children` | `(openDialog, donateTotalAmount, supporters, loading, donateSettings) => React.ReactNode` | Optional. A render prop function used when `mode` is `'custom'`. See the Custom Mode section for details. |
20
+
21
+ ### `CheckoutDonateSettings`
22
+
23
+ This object configures the donation's behavior and appearance.
24
+
25
+ | Property | Type | Description |
26
+ |---|---|---|
27
+ | `target` | `string` | **Required.** A unique identifier for the donation instance (e.g., a post ID like `"post-123"`). |
28
+ | `title` | `string` | **Required.** The title displayed in the donation modal. |
29
+ | `description` | `string` | **Required.** A description shown in the donation modal. |
30
+ | `reference` | `string` | **Required.** A reference link for the donation, such as the URL of the page where the donation is being made. |
31
+ | `beneficiaries` | `PaymentBeneficiary[]` | **Required.** An array of objects defining who receives the donation and their respective shares. |
32
+ | `amount` | `object` | Optional. Configures donation amounts, including presets, min/max values, and whether custom amounts are allowed. Inherits from `DonateProvider` if not set. |
33
+ | `appearance` | `object` | Optional. Customizes the look and feel of the donation button and supporter history display (`'avatar'` or `'table'`). Inherits from `DonateProvider` if not set. |
34
+
35
+ ## Basic Usage
36
+
37
+ Here is a basic example of how to set up `CheckoutDonate`. This will render a default donation button and a list of supporters.
38
+
39
+ ```tsx
40
+ import {
41
+ PaymentProvider,
42
+ DonateProvider,
43
+ CheckoutDonate
44
+ } from '@blocklet/payment-react';
45
+
46
+ // This is a placeholder for your application's session management.
47
+ // See the documentation for PaymentProvider for details on how to set up this context.
48
+ import { useSessionContext } from '../contexts/session'; // Adjust path as needed
49
+
50
+ function DonationSection() {
51
+ const { session, connectApi } = useSessionContext();
52
+
53
+ return (
54
+ <PaymentProvider session={session} connect={connectApi}>
55
+ <DonateProvider
56
+ mountLocation="unique-page-identifier"
57
+ description="Donations for this page"
58
+ >
59
+ <CheckoutDonate
60
+ settings={{
61
+ target: "post-123", // Unique ID for this donation target
62
+ title: "Support the Author",
63
+ description: "If you find this article helpful, feel free to buy me a coffee.",
64
+ reference: "https://your-site.com/posts/123",
65
+ beneficiaries: [
66
+ {
67
+ address: "did:abt:z123...", // Beneficiary's DID address
68
+ share: "100",
69
+ },
70
+ ],
71
+ }}
72
+ onPaid={(session) => console.log('Donation successful:', session.id)}
73
+ />
74
+ </DonateProvider>
75
+ </PaymentProvider>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ## Usage Modes
81
+
82
+ The `CheckoutDonate` component can be rendered in three different modes, controlled by the `mode` prop.
83
+
84
+ ### Default Mode
85
+
86
+ When `mode` is `'default'` (or omitted), the component renders a donation button. Below the button, it displays a history of supporters, which can be configured to show as avatars or a table via `settings.appearance.history.variant`.
87
+
88
+ ```tsx
89
+ <CheckoutDonate
90
+ settings={{
91
+ target: "post-456",
92
+ title: "Support Our Project",
93
+ description: "Every little bit helps!",
94
+ reference: "https://your-site.com/projects/our-project",
95
+ beneficiaries: [{ address: "did:abt:z456...", share: "100" }],
96
+ appearance: {
97
+ button: {
98
+ text: 'Buy me a coffee ☕',
99
+ variant: 'contained',
100
+ },
101
+ history: {
102
+ variant: 'table', // or 'avatar'
103
+ },
104
+ },
105
+ }}
106
+ />
107
+ ```
108
+
109
+ ### Inline Mode
110
+
111
+ Setting `mode="inline"` renders a button that opens a popover when hovered over. The popover contains the donation button and a summary of supporters. This is useful for more compact UIs.
112
+
113
+ ```tsx
114
+ <CheckoutDonate
115
+ mode="inline"
116
+ settings={{
117
+ target: "post-789",
118
+ title: "Tip Jar",
119
+ description: "Thanks for your support!",
120
+ reference: "https://your-site.com/posts/789",
121
+ beneficiaries: [{ address: "did:abt:z789...", share: "100" }],
122
+ }}
123
+ inlineOptions={{
124
+ button: {
125
+ text: 'Tip',
126
+ variant: 'outlined',
127
+ }
128
+ }}
129
+ />
130
+ ```
131
+
132
+ ### Custom Mode
133
+
134
+ For complete control over the UI, use `mode="custom"`. This mode uses a render prop passed as the `children` of the component. The function provides you with the state and actions needed to build your own interface.
135
+
136
+ The `children` function receives the following arguments:
137
+
138
+ | Argument | Type | Description |
139
+ |---|---|---|
140
+ | `openDialog` | `() => void` | A function to call to open the donation payment modal. |
141
+ | `donateTotalAmount` | `string` | A formatted string representing the total amount donated (e.g., `"125.50 USDT"`). |
142
+ | `supporters` | `DonateHistory` | An object containing supporter data, including the list of supporters, currency, and payment method details. |
143
+ | `loading` | `boolean` | A boolean indicating if the supporter data is currently being fetched. |
144
+ | `donateSettings` | `DonationSettings` | The processed donation settings object, including defaults inherited from `DonateProvider`. |
145
+
146
+ Here is an example of a custom donation UI:
147
+
148
+ ```tsx
149
+ import { CheckoutDonate, formatAmount } from '@blocklet/payment-react';
150
+ import { Button, CircularProgress, Typography, List, ListItem, ListItemText } from '@mui/material';
151
+
152
+ // Assuming PaymentProvider and DonateProvider are set up in a parent component.
153
+
154
+ function CustomDonationDisplay() {
155
+ return (
156
+ <CheckoutDonate
157
+ mode="custom"
158
+ settings={{
159
+ target: "post-123",
160
+ title: "Support the Author",
161
+ description: "Your support is appreciated!",
162
+ reference: "https://your-site.com/posts/123",
163
+ beneficiaries: [{ address: "did:abt:z123...", share: "100" }],
164
+ }}
165
+ >
166
+ {(openDonate, totalAmount, supporters, loading) => (
167
+ <div>
168
+ <Typography variant="h5">Our Supporters</Typography>
169
+ <Button variant="contained" onClick={openDonate} sx={{ my: 2 }}>Support Us</Button>
170
+ {loading ? (
171
+ <CircularProgress />
172
+ ) : (
173
+ <div>
174
+ <Typography variant="subtitle1">Total Donations: {totalAmount}</Typography>
175
+ <List>
176
+ {supporters.supporters && supporters.supporters.map(supporter => (
177
+ <ListItem key={supporter.id}>
178
+ <ListItemText
179
+ primary={supporter.customer?.name}
180
+ secondary={`${formatAmount(supporter.amount_total, supporters.currency?.decimal)} ${supporters.currency?.symbol}`}
181
+ />
182
+ </ListItem>
183
+ ))}
184
+ </List>
185
+ </div>
186
+ )}
187
+ </div>
188
+ )}
189
+ </CheckoutDonate>
190
+ );
191
+ }
192
+ ```
193
+ This custom setup gives you full control over the presentation of donation information.
194
+
195
+ ## Admin Features
196
+
197
+ If the current user session has an `owner` or `admin` role, a settings icon will appear in the title of the donation dialog. Clicking this icon opens the donation configuration interface, allowing administrators to modify donation settings directly from the UI.
198
+
199
+ This feature requires that the `DonateProvider` is properly configured and that the underlying Payment Kit blocklet supports this functionality.