@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.
- package/.aigne/doc-smith/config.yaml +114 -0
- package/.aigne/doc-smith/output/structure-plan.json +361 -0
- package/.aigne/doc-smith/preferences.yml +55 -0
- package/.aigne/doc-smith/upload-cache.yaml +264 -0
- package/README.md +2 -3
- package/docs/_sidebar.md +33 -0
- package/docs/components-business-auto-topup.md +238 -0
- package/docs/components-business-overdue-invoice-payment.md +231 -0
- package/docs/components-business-resume-subscription.md +177 -0
- package/docs/components-business.md +45 -0
- package/docs/components-checkout-checkout-donate.md +199 -0
- package/docs/components-checkout-checkout-form.md +185 -0
- package/docs/components-checkout-checkout-table.md +228 -0
- package/docs/components-checkout.md +131 -0
- package/docs/components-history-credit-grants-list.md +98 -0
- package/docs/components-history-credit-transactions-list.md +116 -0
- package/docs/components-history-invoice-list.md +104 -0
- package/docs/components-history-payment-list.md +65 -0
- package/docs/components-history.md +92 -0
- package/docs/components-ui-form-elements-address-form.md +150 -0
- package/docs/components-ui-form-elements-country-select.md +105 -0
- package/docs/components-ui-form-elements-currency-selector.md +124 -0
- package/docs/components-ui-form-elements-phone-input.md +160 -0
- package/docs/components-ui-form-elements.md +125 -0
- package/docs/components-ui-payment-summary.md +157 -0
- package/docs/components-ui-pricing-table.md +227 -0
- package/docs/components-ui.md +44 -0
- package/docs/components.md +95 -0
- package/docs/getting-started.md +111 -0
- package/docs/guides-theming.md +175 -0
- package/docs/guides-utilities.md +235 -0
- package/docs/guides.md +95 -0
- package/docs/hooks-use-mobile.md +70 -0
- package/docs/hooks-use-subscription.md +129 -0
- package/docs/hooks.md +84 -0
- package/docs/overview.md +87 -0
- package/docs/providers-donate-provider.md +175 -0
- package/docs/providers-payment-provider.md +245 -0
- package/docs/providers.md +101 -0
- package/es/payment/form/index.js +15 -1
- package/lib/payment/form/index.js +14 -1
- package/package.json +5 -5
- package/src/payment/form/index.tsx +16 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# PricingTable
|
|
2
|
+
|
|
3
|
+
The `PricingTable` component is a flexible UI element designed to display subscription plans and pricing options in a structured, user-friendly table. It allows users to browse different plans, switch between billing cycles (e.g., monthly, yearly), select a currency, and proceed to checkout by selecting a plan.
|
|
4
|
+
|
|
5
|
+
This component must be used within the context of a `PaymentProvider`, as it relies on the provider for payment settings and currency information. For detailed instructions on setting up the provider, refer to the [PaymentProvider documentation](./providers-payment-provider.md).
|
|
6
|
+
|
|
7
|
+
For a more integrated solution that bundles the pricing table with the complete checkout flow, consider using the higher-level [`CheckoutTable`](./components-checkout-checkout-table.md) component.
|
|
8
|
+
|
|
9
|
+
```d2
|
|
10
|
+
direction: down
|
|
11
|
+
|
|
12
|
+
"PaymentProvider": {
|
|
13
|
+
shape: class
|
|
14
|
+
"Provides Context (Settings, Currency, etc.)"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
"Your Application": {
|
|
18
|
+
shape: class
|
|
19
|
+
"Provides `table` data"
|
|
20
|
+
"Implements `onSelect` handler"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
"PricingTable": {
|
|
24
|
+
shape: package
|
|
25
|
+
"Renders UI"
|
|
26
|
+
" - Billing Cycle Toggles"
|
|
27
|
+
" - Currency Selector"
|
|
28
|
+
" - Plan Cards"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
"User": {
|
|
32
|
+
shape: person
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
"PaymentProvider" -> "PricingTable": "Provides context"
|
|
36
|
+
"Your Application" -> "PricingTable": "Passes props (`table`, `onSelect`)"
|
|
37
|
+
"User" -> "PricingTable": "Interacts (selects plan)"
|
|
38
|
+
"PricingTable" -> "Your Application": "Triggers `onSelect(priceId, currencyId)`"
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Props
|
|
43
|
+
|
|
44
|
+
The `PricingTable` component accepts the following props to customize its behavior and appearance:
|
|
45
|
+
|
|
46
|
+
| Prop | Type | Required | Default | Description |
|
|
47
|
+
|---|---|---|---|---|
|
|
48
|
+
| `table` | `TPricingTableExpanded` | Yes | - | An object containing the pricing table data, including a list of items (plans) to display. |
|
|
49
|
+
| `onSelect` | `(priceId: string, currencyId: string) => void` | Yes | - | A callback function that is invoked when a user clicks the action button for a plan. |
|
|
50
|
+
| `alignItems` | `'center' \| 'left'` | No | `'center'` | Controls the horizontal alignment of the pricing plans and controls. |
|
|
51
|
+
| `mode` | `'checkout' \| 'select'` | No | `'checkout'` | Determines the behavior and text of the action button. `'checkout'` is for direct payment, while `'select'` is for plan selection. |
|
|
52
|
+
| `interval` | `string` | No | `''` | The initially selected billing interval (e.g., 'month-1', 'year-1'). If empty, the first available interval is used. |
|
|
53
|
+
| `hideCurrency` | `boolean` | No | `false` | If `true`, the currency selection dropdown will be hidden from the user. |
|
|
54
|
+
|
|
55
|
+
## Usage Scenarios
|
|
56
|
+
|
|
57
|
+
### Basic Checkout Table
|
|
58
|
+
|
|
59
|
+
This is the default mode. The component displays plans with a subscription button. When a user clicks the button, the `onSelect` callback is triggered, which you can use to initiate a checkout session.
|
|
60
|
+
|
|
61
|
+
```jsx
|
|
62
|
+
import React from 'react';
|
|
63
|
+
import PricingTable from '@blocklet/payment-react/lib/components/pricing-table';
|
|
64
|
+
import { PaymentProvider } from '@blocklet/payment-react/lib/contexts/payment';
|
|
65
|
+
import { useSessionContext } from '../hooks/session'; // Your local session context hook
|
|
66
|
+
|
|
67
|
+
// Assume 'myPricingTableData' is fetched from your backend and conforms to TPricingTableExpanded
|
|
68
|
+
|
|
69
|
+
function MyPricingPage({ myPricingTableData }) {
|
|
70
|
+
const handleSubscription = async (priceId, currencyId) => {
|
|
71
|
+
console.log(`Starting subscription for price: ${priceId} with currency: ${currencyId}`);
|
|
72
|
+
// Add your logic to create a checkout session and redirect the user
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<PricingTable
|
|
77
|
+
table={myPricingTableData}
|
|
78
|
+
onSelect={handleSubscription}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Your component must be wrapped in PaymentProvider
|
|
84
|
+
function AppWithPayment() {
|
|
85
|
+
const { session, connectApi } = useSessionContext();
|
|
86
|
+
|
|
87
|
+
if (!session.user) {
|
|
88
|
+
return <button onClick={connectApi}>Connect Wallet</button>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Assume 'myPricingTableData' is available here
|
|
92
|
+
return (
|
|
93
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
94
|
+
<MyPricingPage myPricingTableData={myPricingTableData} />
|
|
95
|
+
</PaymentProvider>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Note:** The `useSessionContext` hook should be set up in your application to provide session information. For a detailed guide on how to configure this and the `PaymentProvider`, please see the [PaymentProvider documentation](./providers-payment-provider.md).
|
|
101
|
+
|
|
102
|
+
### Plan Selection Mode
|
|
103
|
+
|
|
104
|
+
By setting `mode='select'`, the component can be used as part of a larger form where the user selects a plan before proceeding. The action button text changes to "Select" or "Selected", and selected items are highlighted with a border.
|
|
105
|
+
|
|
106
|
+
In this mode, you need to manage the selected plan in your parent component's state and pass the `is_selected` property down to the `table` items.
|
|
107
|
+
|
|
108
|
+
```jsx
|
|
109
|
+
import React, { useState, useMemo } from 'react';
|
|
110
|
+
import PricingTable from '@blocklet/payment-react/lib/components/pricing-table';
|
|
111
|
+
import { PaymentProvider } from '@blocklet/payment-react/lib/contexts/payment';
|
|
112
|
+
import { useSessionContext } from '../hooks/session'; // Your local session context hook
|
|
113
|
+
|
|
114
|
+
function PlanSelectionForm({ myPricingTableData }) {
|
|
115
|
+
const [selectedPriceId, setSelectedPriceId] = useState(null);
|
|
116
|
+
|
|
117
|
+
const handlePlanSelect = (priceId, currencyId) => {
|
|
118
|
+
setSelectedPriceId(priceId);
|
|
119
|
+
console.log(`User selected price: ${priceId} in currency: ${currencyId}`);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Add is_selected property to the items based on the current state
|
|
123
|
+
const tableDataWithSelection = useMemo(() => ({
|
|
124
|
+
...myPricingTableData,
|
|
125
|
+
items: myPricingTableData.items.map(item => ({
|
|
126
|
+
...item,
|
|
127
|
+
is_selected: item.price_id === selectedPriceId,
|
|
128
|
+
})),
|
|
129
|
+
}), [myPricingTableData, selectedPriceId]);
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div>
|
|
133
|
+
<h2>Choose Your Plan</h2>
|
|
134
|
+
<PricingTable
|
|
135
|
+
table={tableDataWithSelection}
|
|
136
|
+
onSelect={handlePlanSelect}
|
|
137
|
+
mode="select"
|
|
138
|
+
alignItems="left"
|
|
139
|
+
/>
|
|
140
|
+
<button disabled={!selectedPriceId}>Continue to Checkout</button>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Your component must be wrapped in PaymentProvider
|
|
146
|
+
function AppWithPaymentSelection() {
|
|
147
|
+
const { session, connectApi } = useSessionContext();
|
|
148
|
+
|
|
149
|
+
if (!session.user) {
|
|
150
|
+
return <button onClick={connectApi}>Connect Wallet</button>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Assume 'myPricingTableData' is available here
|
|
154
|
+
return (
|
|
155
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
156
|
+
<PlanSelectionForm myPricingTableData={myPricingTableData} />
|
|
157
|
+
</PaymentProvider>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Data Structure for `table` prop
|
|
163
|
+
|
|
164
|
+
The `table` prop expects an object with a specific structure, `TPricingTableExpanded`. Here's a simplified overview of what it contains:
|
|
165
|
+
|
|
166
|
+
- **`id`**: A unique identifier for the pricing table.
|
|
167
|
+
- **`livemode`**: A boolean indicating if the table is in live or test mode.
|
|
168
|
+
- **`currency`**: A default currency object.
|
|
169
|
+
- **`items`**: An array of `TPricingTableItem` objects. Each item represents a single plan and contains:
|
|
170
|
+
- **`price_id`**: The unique ID for the price.
|
|
171
|
+
- **`product`**: An object with product details like `name`, `description`, and an array of `features`.
|
|
172
|
+
- **`price`**: An object with pricing details, including `unit_amount`, `currency_options`, and a `recurring` object that specifies the billing `interval` (e.g., 'month', 'year') and `interval_count`.
|
|
173
|
+
- **`is_highlight`** (optional): A boolean to highlight a specific plan.
|
|
174
|
+
- **`highlight_text`** (optional): Text to display in the highlight chip (e.g., "Most Popular").
|
|
175
|
+
|
|
176
|
+
### Example `table` Object
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"id": "pt_12345",
|
|
181
|
+
"livemode": true,
|
|
182
|
+
"currency": { "id": "usd", "symbol": "$" },
|
|
183
|
+
"items": [
|
|
184
|
+
{
|
|
185
|
+
"price_id": "price_basic_monthly",
|
|
186
|
+
"product": {
|
|
187
|
+
"name": "Basic Plan",
|
|
188
|
+
"description": "For individuals and small teams.",
|
|
189
|
+
"features": [
|
|
190
|
+
{ "name": "5 Projects" },
|
|
191
|
+
{ "name": "Basic Analytics" },
|
|
192
|
+
{ "name": "24/7 Support" }
|
|
193
|
+
],
|
|
194
|
+
"unit_label": "user"
|
|
195
|
+
},
|
|
196
|
+
"price": {
|
|
197
|
+
"unit_amount": "1000",
|
|
198
|
+
"currency_options": [{ "currency_id": "usd", "unit_amount": "1000" }],
|
|
199
|
+
"recurring": { "interval": "month", "interval_count": 1 }
|
|
200
|
+
},
|
|
201
|
+
"is_highlight": false
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"price_id": "price_pro_yearly",
|
|
205
|
+
"product": {
|
|
206
|
+
"name": "Pro Plan",
|
|
207
|
+
"description": "For growing businesses.",
|
|
208
|
+
"features": [
|
|
209
|
+
{ "name": "Unlimited Projects" },
|
|
210
|
+
{ "name": "Advanced Analytics" },
|
|
211
|
+
{ "name": "Priority Support" }
|
|
212
|
+
],
|
|
213
|
+
"unit_label": "user"
|
|
214
|
+
},
|
|
215
|
+
"price": {
|
|
216
|
+
"unit_amount": "25000",
|
|
217
|
+
"currency_options": [{ "currency_id": "usd", "unit_amount": "25000" }],
|
|
218
|
+
"recurring": { "interval": "year", "interval_count": 1 }
|
|
219
|
+
},
|
|
220
|
+
"is_highlight": true,
|
|
221
|
+
"highlight_text": "Popular"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
This component streamlines the creation of dynamic and interactive pricing pages. Once the user selects a plan, you can use the `onSelect` callback to guide them to the next step, which is often displaying a [PaymentSummary](./components-ui-payment-summary.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# UI Components
|
|
2
|
+
|
|
3
|
+
The UI Components are a collection of granular, self-contained React components designed for building custom payment and checkout experiences. Unlike the high-level [Checkout Components](./components-checkout.md), which manage an entire payment flow, UI Components give you full control over the layout and user experience by providing the essential building blocks for your interface.
|
|
4
|
+
|
|
5
|
+
This approach allows you to integrate payment functionality seamlessly into your existing application design. You can combine these components to construct a checkout process that is tailored to your specific requirements, as illustrated in the workflow below.
|
|
6
|
+
|
|
7
|
+
```d2
|
|
8
|
+
direction: down
|
|
9
|
+
|
|
10
|
+
A: "Display PricingTable Component"
|
|
11
|
+
B: "User Selects a Subscription Plan"
|
|
12
|
+
C: "Application State is Updated via onSelect Callback"
|
|
13
|
+
D: "Render PaymentSummary with Order Details"
|
|
14
|
+
E: "Render Form Elements (e.g., AddressForm)"
|
|
15
|
+
F: "User Clicks Custom 'Pay' Button"
|
|
16
|
+
G: "Application Logic Submits Payment to Backend"
|
|
17
|
+
|
|
18
|
+
A -> B: "User Action"
|
|
19
|
+
B -> C: "Triggers Callback"
|
|
20
|
+
C -> D: "Re-renders UI"
|
|
21
|
+
D -> E
|
|
22
|
+
E -> F: "User provides info"
|
|
23
|
+
F -> G: "Initiates Submission"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Below is an overview of the core UI components available. Each component has its own detailed documentation page.
|
|
27
|
+
|
|
28
|
+
<x-cards data-columns="3">
|
|
29
|
+
<x-card data-title="PricingTable" data-href="/components/ui/pricing-table" data-icon="lucide:table">
|
|
30
|
+
Renders a structured, responsive table of your subscription plans. It handles logic for switching between billing intervals and currencies, allowing users to make a selection.
|
|
31
|
+
</x-card>
|
|
32
|
+
<x-card data-title="PaymentSummary" data-href="/components/ui/payment-summary" data-icon="lucide:receipt">
|
|
33
|
+
Displays a detailed breakdown of an order, including line items, quantities, pricing, trial information, and the total amount due. Essential for transparency during checkout.
|
|
34
|
+
</x-card>
|
|
35
|
+
<x-card data-title="Form Elements" data-href="/components/ui/form-elements" data-icon="lucide:pencil-ruler">
|
|
36
|
+
A suite of individual inputs for collecting user data like billing addresses and phone numbers. They include built-in validation and are designed to be composed into any form.
|
|
37
|
+
</x-card>
|
|
38
|
+
</x-cards>
|
|
39
|
+
|
|
40
|
+
By combining these components, you can build a robust and user-friendly payment interface that fits perfectly within your application's design. To get started, explore the documentation for the component that best fits your immediate needs.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
Next, learn how to display your products and plans with the [PricingTable component](./components-ui-pricing-table.md).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
The `@blocklet/payment-react` library provides a comprehensive suite of pre-built React components designed to accelerate the development of payment, subscription, and donation features. These components are organized into logical categories to help you find the right tool for your specific use case, from high-level, all-in-one solutions to granular UI building blocks.
|
|
4
|
+
|
|
5
|
+
All components are designed to be composable and customizable, ensuring they can fit seamlessly into your application's design and logic.
|
|
6
|
+
|
|
7
|
+
### Component Architecture
|
|
8
|
+
|
|
9
|
+
The components are structured into distinct categories based on their functionality. This modular approach allows you to import only what you need and gives you a clear path for building your payment interfaces.
|
|
10
|
+
|
|
11
|
+
```d2
|
|
12
|
+
direction: down
|
|
13
|
+
|
|
14
|
+
"@blocklet/payment-react": {
|
|
15
|
+
shape: package
|
|
16
|
+
|
|
17
|
+
"Checkout Components": {
|
|
18
|
+
tooltip: "High-level components for complete payment flows"
|
|
19
|
+
"CheckoutForm": {}
|
|
20
|
+
"CheckoutTable": {}
|
|
21
|
+
"CheckoutDonate": {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
"UI Components": {
|
|
25
|
+
tooltip: "Granular building blocks for custom UIs"
|
|
26
|
+
"PricingTable": {}
|
|
27
|
+
"AddressForm": {}
|
|
28
|
+
"PaymentSummary": {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
"Business Logic Components": {
|
|
32
|
+
tooltip: "Components for specific business scenarios"
|
|
33
|
+
"ResumeSubscription": {}
|
|
34
|
+
"OverdueInvoicePayment": {}
|
|
35
|
+
"AutoTopup": {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
"History Components": {
|
|
39
|
+
tooltip: "Components for displaying historical data"
|
|
40
|
+
"CustomerInvoiceList": {}
|
|
41
|
+
"CustomerPaymentList": {}
|
|
42
|
+
"CreditGrantsList": {}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Provider Requirements
|
|
48
|
+
|
|
49
|
+
A critical concept to understand is that almost all components in this library must be wrapped within a `PaymentProvider` to function correctly. This provider supplies the necessary context, such as the user session and API connection details. Specific components, like `CheckoutDonate`, require an additional `DonateProvider`.
|
|
50
|
+
|
|
51
|
+
Before using any components, ensure your application is set up with the required context providers.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
|
|
55
|
+
// This is your application's custom hook for session management
|
|
56
|
+
import { useSessionContext } from '../hooks/session';
|
|
57
|
+
|
|
58
|
+
function App() {
|
|
59
|
+
// Fetch session and connectApi from your application's context.
|
|
60
|
+
const { session, connectApi } = useSessionContext();
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
// The PaymentProvider wraps all components that need payment context
|
|
64
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
65
|
+
{/* Now, components like CheckoutForm can be used */}
|
|
66
|
+
<CheckoutForm id="plink_xxx" mode="inline" />
|
|
67
|
+
</PaymentProvider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
In the examples throughout this documentation, `useSessionContext` is a placeholder for your application's own hook for managing user sessions. For a complete guide on how to set up the `PaymentProvider` and create a session context, please refer to the [PaymentProvider](./providers-payment-provider.md) documentation.
|
|
73
|
+
|
|
74
|
+
## Component Categories
|
|
75
|
+
|
|
76
|
+
Dive into the component categories to find the tools you need for your project. Each section provides detailed documentation and usage examples.
|
|
77
|
+
|
|
78
|
+
<x-cards data-columns="2">
|
|
79
|
+
<x-card data-title="Checkout Components" data-icon="lucide:shopping-cart" data-href="/components/checkout">
|
|
80
|
+
High-level components that encapsulate entire payment flows. The fastest way to integrate standard checkouts, pricing plan selections, and donation widgets.
|
|
81
|
+
</x-card>
|
|
82
|
+
<x-card data-title="UI Components" data-icon="lucide:layout-template" data-href="/components/ui">
|
|
83
|
+
Granular building blocks for creating custom interfaces, including forms, selectors, and display elements like `PricingTable` and `PaymentSummary`.
|
|
84
|
+
</x-card>
|
|
85
|
+
<x-card data-title="Business Logic Components" data-icon="lucide:briefcase" data-href="/components/business">
|
|
86
|
+
Handle specific, complex business scenarios like resuming subscriptions, paying overdue invoices, or configuring automatic credit top-ups.
|
|
87
|
+
</x-card>
|
|
88
|
+
<x-card data-title="History Components" data-icon="lucide:history" data-href="/components/history">
|
|
89
|
+
Display historical user data such as past invoices, payment lists, and credit grant histories for account management pages.
|
|
90
|
+
</x-card>
|
|
91
|
+
</x-cards>
|
|
92
|
+
|
|
93
|
+
## Next Steps
|
|
94
|
+
|
|
95
|
+
Now that you have an overview of the component categories, you can explore the specific documentation for the components that fit your needs. If you're looking for the fastest integration path, we recommend starting with the [Checkout Components](./components-checkout.md).
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
This guide provides a step-by-step walkthrough to get you up and running with `@blocklet/payment-react`. You will learn how to install the library, set up the essential `PaymentProvider`, and render your first payment form using the `CheckoutForm` component.
|
|
4
|
+
|
|
5
|
+
## 1. Installation
|
|
6
|
+
|
|
7
|
+
First, add the library to your project using npm or your preferred package manager.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @blocklet/payment-react
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 2. Set up PaymentProvider
|
|
14
|
+
|
|
15
|
+
Most components in `@blocklet/payment-react` require access to payment context, such as user session information and API configuration. The `PaymentProvider` component provides this context to all its children. You should wrap it around the root of your application or at least the section that handles payments.
|
|
16
|
+
|
|
17
|
+
To supply the necessary `session` and `connectApi` props, you should create a local session context using `@arcblock/did-connect-react`. This allows you to access authentication state throughout your app.
|
|
18
|
+
|
|
19
|
+
For a detailed guide on creating your `useSessionContext` hook, please refer to the [PaymentProvider documentation](./providers-payment-provider.md).
|
|
20
|
+
|
|
21
|
+
Once your context is set up, you can use it like this:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { PaymentProvider } from '@blocklet/payment-react';
|
|
25
|
+
import { useSessionContext } from '../path/to/your/session-context'; // Your local session context
|
|
26
|
+
|
|
27
|
+
function App() {
|
|
28
|
+
const { session, connectApi } = useSessionContext();
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
32
|
+
{/* Your payment components will go here */}
|
|
33
|
+
</PaymentProvider>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The relationship between the provider and the components it wraps can be visualized as follows:
|
|
39
|
+
|
|
40
|
+
```d2
|
|
41
|
+
direction: down
|
|
42
|
+
|
|
43
|
+
"Your App": {
|
|
44
|
+
"PaymentProvider": {
|
|
45
|
+
style: { fill: "#dbeafe" }
|
|
46
|
+
"CheckoutForm": {
|
|
47
|
+
label: "Renders the payment UI"
|
|
48
|
+
style: { fill: "#ede9fe" }
|
|
49
|
+
}
|
|
50
|
+
"Other Components": {
|
|
51
|
+
label: "e.g., CustomerInvoiceList"
|
|
52
|
+
style: { fill: "#ede9fe" }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
"Your App.PaymentProvider" -> "Your App.PaymentProvider.CheckoutForm": "Provides context (session, API)"
|
|
58
|
+
"Your App.PaymentProvider" -> "Your App.PaymentProvider.Other Components": "Provides context (session, API)"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 3. Add a Checkout Form
|
|
62
|
+
|
|
63
|
+
The `CheckoutForm` is the primary component for building a payment flow. It renders a complete payment interface based on a `paymentLink` ID (prefixed with `plink_`) or a `checkoutSession` ID (prefixed with `cs_`) that you create in your payment service backend.
|
|
64
|
+
|
|
65
|
+
## 4. Complete Example
|
|
66
|
+
|
|
67
|
+
This example combines the `PaymentProvider` and `CheckoutForm` to create a minimal, functional payment page. It uses the `useSessionContext` hook to provide the necessary authentication context.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import React from 'react';
|
|
71
|
+
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
|
|
72
|
+
|
|
73
|
+
// This import points to your local session context implementation.
|
|
74
|
+
// For setup details, see the PaymentProvider documentation.
|
|
75
|
+
import { useSessionContext } from '../path/to/your/session-context';
|
|
76
|
+
|
|
77
|
+
function MyPaymentPage() {
|
|
78
|
+
const { session, connectApi } = useSessionContext();
|
|
79
|
+
|
|
80
|
+
// It's good practice to ensure the session is loaded before rendering payment components.
|
|
81
|
+
if (!session || !session.user) {
|
|
82
|
+
return <div>Loading user session...</div>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
87
|
+
<CheckoutForm
|
|
88
|
+
id="plink_xxx" // IMPORTANT: Replace with your actual Payment Link ID
|
|
89
|
+
mode="inline" // Embeds the form directly in your UI
|
|
90
|
+
showCheckoutSummary={true}
|
|
91
|
+
onChange={(state) => console.log('Checkout State:', state)}
|
|
92
|
+
onPaid={() => alert('Payment Successful!')}
|
|
93
|
+
onError={(err) => alert(`Payment Failed: ${err.message}`)}
|
|
94
|
+
/>
|
|
95
|
+
</PaymentProvider>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default MyPaymentPage;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
In this example:
|
|
103
|
+
- We wrap `CheckoutForm` with `PaymentProvider` to provide the necessary context, obtained from our `useSessionContext` hook.
|
|
104
|
+
- The `id` prop is set to a Payment Link ID. This is **required**.
|
|
105
|
+
- `mode="inline"` renders the form within the current page flow.
|
|
106
|
+
- `showCheckoutSummary={true}` displays a summary of what the user is paying for.
|
|
107
|
+
- The `onChange`, `onPaid`, and `onError` callbacks allow you to monitor and react to the state of the checkout process.
|
|
108
|
+
|
|
109
|
+
## 5. Next Steps
|
|
110
|
+
|
|
111
|
+
You have now successfully integrated a basic payment form. To learn more about configuring the context for your payment components, see the [Providers](./providers.md) section. To explore the full range of available UI and business logic components, head over to the [Components](./components.md) documentation.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Theming
|
|
2
|
+
|
|
3
|
+
The `@blocklet/payment-react` library is built on Material-UI and includes a dedicated theme provider, `PaymentThemeProvider`, to ensure a consistent and polished look across all components. This guide explains how to customize the default theme to match your application's design system.
|
|
4
|
+
|
|
5
|
+
## `PaymentThemeProvider`
|
|
6
|
+
|
|
7
|
+
Most components in the library, such as `CheckoutForm`, are internally wrapped with `PaymentThemeProvider`. This provider establishes a cohesive visual foundation by extending ArcBlock's base theme with styles tailored for payment UIs. It defines a specific color palette, typography scale, and default styles for various MUI components.
|
|
8
|
+
|
|
9
|
+
The theme merging process follows a clear hierarchy to combine the base theme, default payment styles, and your custom overrides.
|
|
10
|
+
|
|
11
|
+
```d2
|
|
12
|
+
direction: down
|
|
13
|
+
|
|
14
|
+
"Parent MUI Theme"
|
|
15
|
+
|
|
16
|
+
is_ab_theme: "Is it an ArcBlock Theme?" {
|
|
17
|
+
shape: diamond
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
"Parent MUI Theme" -> is_ab_theme
|
|
21
|
+
|
|
22
|
+
use_parent: "Use Parent Theme as Base"
|
|
23
|
+
create_new: "Create New BlockletTheme as Base"
|
|
24
|
+
|
|
25
|
+
is_ab_theme -> use_parent: "Yes"
|
|
26
|
+
is_ab_theme -> create_new: "No"
|
|
27
|
+
|
|
28
|
+
base_theme: "Base Theme"
|
|
29
|
+
use_parent -> base_theme
|
|
30
|
+
create_new -> base_theme
|
|
31
|
+
|
|
32
|
+
default_payment_styles: "Default Payment Component Styles"
|
|
33
|
+
|
|
34
|
+
merge1: "Merge with Base Theme" {
|
|
35
|
+
shape: oval
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
base_theme -> merge1
|
|
39
|
+
default_payment_styles -> merge1
|
|
40
|
+
|
|
41
|
+
user_customizations: "User's Customizations (from 'theme' prop)"
|
|
42
|
+
|
|
43
|
+
final_theme: "Final Merged Theme"
|
|
44
|
+
|
|
45
|
+
merge1 -> final_theme
|
|
46
|
+
user_customizations -> final_theme
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Customization Methods
|
|
50
|
+
|
|
51
|
+
You can customize the theme by passing a `theme` prop to payment components like `CheckoutForm`. This prop accepts a `PaymentThemeOptions` object, offering two primary methods for customization.
|
|
52
|
+
|
|
53
|
+
In the following examples, `useSessionContext` is a hook from your local session management setup. For more details on setting up the required context, please refer to the [PaymentProvider documentation](./providers-payment-provider.md).
|
|
54
|
+
|
|
55
|
+
### 1. Overriding Component Styles
|
|
56
|
+
|
|
57
|
+
To modify the default styles of underlying Material-UI components, provide a `components` object in your theme configuration. This object follows the standard MUI `styleOverrides` structure and will be deeply merged with the default payment theme.
|
|
58
|
+
|
|
59
|
+
This method is ideal for making consistent changes to components like buttons, inputs, and chips across the payment UI.
|
|
60
|
+
|
|
61
|
+
**Example: Changing the Primary Button Color**
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
|
|
65
|
+
import { useSessionContext } from '/path/to/your/session/context'; // This path is specific to your project
|
|
66
|
+
|
|
67
|
+
function CustomStyledForm() {
|
|
68
|
+
const { session, connectApi } = useSessionContext();
|
|
69
|
+
|
|
70
|
+
if (!session) {
|
|
71
|
+
return <div>Loading session...</div>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
76
|
+
<CheckoutForm
|
|
77
|
+
id="plink_xxx"
|
|
78
|
+
theme={{
|
|
79
|
+
components: {
|
|
80
|
+
MuiButton: {
|
|
81
|
+
styleOverrides: {
|
|
82
|
+
containedPrimary: {
|
|
83
|
+
backgroundColor: '#1DC1C7',
|
|
84
|
+
color: '#fff',
|
|
85
|
+
'&:hover': {
|
|
86
|
+
backgroundColor: 'rgb(20, 135, 139)',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
</PaymentProvider>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 2. Using the `sx` Prop for Targeted Overrides
|
|
100
|
+
|
|
101
|
+
For more specific, one-off style adjustments, you can use the `sx` property within the `theme` object. This applies CSS directly to the component's wrapper element, allowing you to use class selectors to target nested elements.
|
|
102
|
+
|
|
103
|
+
This approach is useful when you need to style a specific element that doesn't have a direct `styleOverrides` entry or when you want to apply a quick fix without altering the global theme configuration.
|
|
104
|
+
|
|
105
|
+
**Example: Customizing the Submit Button**
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
|
|
109
|
+
import { useSessionContext } from '/path/to/your/session/context'; // This path is specific to your project
|
|
110
|
+
|
|
111
|
+
function TargetedStyleForm() {
|
|
112
|
+
const { session, connectApi } = useSessionContext();
|
|
113
|
+
|
|
114
|
+
if (!session) {
|
|
115
|
+
return <div>Loading session...</div>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<PaymentProvider session={session} connect={connectApi}>
|
|
120
|
+
<CheckoutForm
|
|
121
|
+
id="plink_xxx"
|
|
122
|
+
showCheckoutSummary={false}
|
|
123
|
+
theme={{
|
|
124
|
+
sx: {
|
|
125
|
+
// Note: The specific class name may vary.
|
|
126
|
+
// Inspect the element in your browser to find the correct selector.
|
|
127
|
+
'.cko-submit-button': {
|
|
128
|
+
backgroundColor: '#1DC1C7',
|
|
129
|
+
color: '#fff',
|
|
130
|
+
'&:hover': {
|
|
131
|
+
backgroundColor: 'rgb(20, 135, 139)',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
</PaymentProvider>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Understanding the Default Theme
|
|
143
|
+
|
|
144
|
+
To customize effectively, it's helpful to know what the default theme provides. The `PaymentThemeProvider` includes several key customizations.
|
|
145
|
+
|
|
146
|
+
### Custom Palette Extensions
|
|
147
|
+
|
|
148
|
+
The theme extends the standard MUI palette with additional colors for specific UI elements.
|
|
149
|
+
|
|
150
|
+
| Palette Key | Description |
|
|
151
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
152
|
+
| `palette.chip` | An object containing `text`, `background`, and `border` colors for different chip statuses: `success`, `default`, `secondary`, `error`, `warning`, and `info`. |
|
|
153
|
+
| `palette.text.lighter` | A lighter text color, typically mapped to `grey[400]`. |
|
|
154
|
+
| `palette.text.link` | The color for hyperlink text, mapped to `secondary.main`. |
|
|
155
|
+
|
|
156
|
+
### Global CSS Classes
|
|
157
|
+
|
|
158
|
+
The theme injects several global utility classes via `MuiCssBaseline` that you can use for styling consistency.
|
|
159
|
+
|
|
160
|
+
- **`.base-card`**: Applies standard padding, border-radius, background, border, and shadow for card-like containers.
|
|
161
|
+
- **`.base-label`**: A standard style for form labels and other descriptive text.
|
|
162
|
+
|
|
163
|
+
### CSS Variables for Light & Dark Modes
|
|
164
|
+
|
|
165
|
+
The entire color system is built upon a set of CSS variables that automatically adapt to light and dark modes. While you can override component styles directly, understanding this foundation helps explain the theme's adaptability.
|
|
166
|
+
|
|
167
|
+
| Variable | Light Mode Value | Dark Mode Value |
|
|
168
|
+
| ------------------------ | ---------------- | --------------- |
|
|
169
|
+
| `--backgrounds-bg-base` | `#ffffff` | `#1b1b1f` |
|
|
170
|
+
| `--foregrounds-fg-base` | `#030712` | `#edeef0` |
|
|
171
|
+
| `--stroke-border-base` | `#eff1f5` | `#2e3035` |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
Now that you understand how to customize the visual appearance of components, you may want to explore the utility functions that can help with data formatting and API requests. For more information, see the [Utilities](./guides-utilities.md) guide.
|