@blocklet/payment-react 1.16.1 → 1.16.3

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 (2) hide show
  1. package/README.md +374 -77
  2. package/package.json +8 -8
package/README.md CHANGED
@@ -1,80 +1,314 @@
1
1
  # Payment Kit Components
2
2
 
3
+ ## Quick Start
4
+
5
+ ### 1. Installation
6
+ ```bash
7
+ npm install @blocklet/payment-react @mui/material @emotion/react @emotion/styled
8
+ ```
9
+
10
+ ### 2. Basic Setup
3
11
  ```tsx
4
- import { CheckoutForm, CheckoutTable, PaymentProvider } from '@blocklet/payment-react';
5
- import { Paper, Typography } from '@mui/material';
6
- import React from 'react';
7
- import { useSearchParams } from 'react-router-dom';
8
-
9
- import { useSessionContext } from '../contexts/session';
10
-
11
- export default function CheckoutPage() {
12
- const [params] = useSearchParams();
13
- const { session, connectApi } = useSessionContext();
14
-
15
- if (params.get('type') === 'session') {
16
- return (
17
- <PaymentProvider session={session} connect={connectApi}>
18
- <Typography variant="h4" gutterBottom>
19
- Checkout with session
20
- </Typography>
21
- <Paper sx={{ p: 3, display: 'inline-block' }} elevation={3}>
22
- <CheckoutForm id="cs_9zeD2yCgPXT9Vit9bab2vVC3V7DFjHiKvyoLzVTVzAf4XSU2oLWY67vKy7" mode="inline" />
23
- </Paper>
24
- </PaymentProvider>
25
- );
26
- }
27
-
28
- if (params.get('type') === 'link') {
29
- return (
30
- <PaymentProvider session={session} connect={connectApi}>
31
- <Typography variant="h4" gutterBottom>
32
- Checkout with payment link
33
- </Typography>
34
- <Paper sx={{ p: 3, display: 'inline-block' }} elevation={3}>
35
- <CheckoutForm id="plink_oB1I6FNeHKSkuq81fhJy0vIZ" mode="inline" />
36
- </Paper>
37
- </PaymentProvider>
38
- );
39
- }
40
-
41
- if (params.get('type') === 'table') {
42
- return (
43
- <PaymentProvider session={session} connect={connectApi}>
44
- <Typography variant="h4" gutterBottom>
45
- Checkout with pricing table
46
- </Typography>
47
- <Paper sx={{ p: 3, display: 'inline-block' }} elevation={3}>
48
- <CheckoutTable id="prctbl_kOsaIiPrsHAwwALaKgy17mIl" mode="inline" />
49
- </Paper>
50
- </PaymentProvider>
51
- );
52
- }
53
-
54
- return null;
12
+ import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
13
+
14
+ function App() {
15
+ return (
16
+ <PaymentProvider session={session} connect={connectApi}>
17
+ <CheckoutForm
18
+ id="plink_xxx"
19
+ mode="inline"
20
+ showCheckoutSummary={true}
21
+ onChange={(state) => console.log(state)}
22
+ />
23
+ </PaymentProvider>
24
+ );
55
25
  }
26
+ ```
27
+
28
+ ## Component Usage
29
+
30
+ ### Core Components
31
+
32
+ ```tsx
33
+ import { CheckoutForm, CheckoutTable, CheckoutDonate, PaymentProvider } from '@blocklet/payment-react';
34
+
35
+ // Checkout with session
36
+ <CheckoutForm
37
+ id="cs_xxx"
38
+ mode="inline"
39
+ showCheckoutSummary={true}
40
+ onChange={(state) => console.log(state)}
41
+ />
42
+
43
+ // Checkout with payment link
44
+ <CheckoutForm
45
+ id="plink_xxx"
46
+ mode="inline"
47
+ />
56
48
 
49
+ // Pricing table
50
+ <CheckoutTable
51
+ id="prctbl_xxx"
52
+ mode="inline"
53
+ />
54
+
55
+ // Donation form
56
+ <CheckoutDonate
57
+ mode="inline"
58
+ settings={{
59
+ target: 'donation-target',
60
+ title: 'Support Us',
61
+ description: 'Help us continue our work',
62
+ beneficiaries: [{
63
+ address: 'wallet_address',
64
+ share: '100'
65
+ }],
66
+ amount: {
67
+ minimum: '0.01',
68
+ maximum: '1',
69
+ custom: true
70
+ }
71
+ }}
72
+ />
57
73
  ```
58
74
 
59
- ## I18n
75
+ ### Form Components
60
76
 
61
77
  ```tsx
62
- import { createTranslator, translations as extraTranslations } from '@blocklet/payment-react';
63
- import merge from 'lodash/merge';
78
+ import {
79
+ FormInput,
80
+ PhoneInput,
81
+ AddressForm,
82
+ CurrencySelector,
83
+ CountrySelect
84
+ } from '@blocklet/payment-react';
64
85
 
65
- import en from './en';
66
- import zh from './zh';
86
+ // Phone input with validation
87
+ <PhoneInput
88
+ name="phone"
89
+ countryFieldName="billing_address.country"
90
+ />
67
91
 
68
- // eslint-disable-next-line import/prefer-default-export
69
- export const translations = merge({ zh, en }, extraTranslations);
92
+ // Address form
93
+ <AddressForm
94
+ mode="required"
95
+ stripe={false}
96
+ sx={{}}
97
+ />
98
+
99
+ // Currency selector
100
+ <CurrencySelector
101
+ value={0}
102
+ onChange={(index) => {}}
103
+ currencies={[
104
+ {
105
+ id: 'currency_id',
106
+ symbol: '$',
107
+ logo: 'currency_logo_url',
108
+ name: 'USD',
109
+ method: { name: 'Payment Method' }
110
+ }
111
+ ]}
112
+ />
113
+
114
+ // Country select
115
+ <CountrySelect
116
+ value="us"
117
+ onChange={(value: CountryIso2) => {}}
118
+ name="country"
119
+ sx={{}}
120
+ />
121
+ ```
122
+
123
+ ### Display Components
124
+
125
+ ```tsx
126
+ import {
127
+ PricingItem,
128
+ TruncatedText,
129
+ TxGas,
130
+ TxLink,
131
+ ProductSkeleton,
132
+ } from '@blocklet/payment-react';
133
+
134
+ // Display pricing information
135
+ <PricingItem
136
+ productId="prod_xxx"
137
+ quantity={1}
138
+ priceId="price_xxx"
139
+ >
140
+ {(pricing, product) => (
141
+ <div>
142
+ <div>Total: {pricing.totalPrice}</div>
143
+ <div>Product: {product?.name}</div>
144
+ </div>
145
+ )}
146
+ </PricingItem>
147
+
148
+ // Display transaction gas fee
149
+ <TxGas
150
+ details={paymentDetails}
151
+ method={paymentMethod}
152
+ />
153
+
154
+ // Display transaction link
155
+ <TxLink
156
+ details={paymentDetails}
157
+ method={paymentMethod}
158
+ mode="dashboard"
159
+ align="left"
160
+ />
161
+
162
+ // Loading skeleton
163
+ <ProductSkeleton />
164
+
165
+ // Truncate long text
166
+ <TruncatedText
167
+ text="Very long text..."
168
+ maxLength={20}
169
+ />
70
170
  ```
71
171
 
72
- ## Updates
172
+ ### Donation Components
173
+
174
+ ```tsx
175
+ import { CheckoutDonate } from '@blocklet/payment-react';
176
+
177
+ // Basic usage
178
+ <CheckoutDonate
179
+ mode="default" // 'default' | 'inline' | 'custom'
180
+ settings={{
181
+ target: 'donation-target',
182
+ title: 'Support Us',
183
+ description: 'Help us continue our work',
184
+ beneficiaries: [{
185
+ address: 'wallet_address',
186
+ share: '100'
187
+ }],
188
+ amount: {
189
+ minimum: '0.01',
190
+ maximum: '100',
191
+ custom: true
192
+ },
193
+ appearance: {
194
+ button: {
195
+ text: 'Donate Now',
196
+ icon: <FavoriteIcon />,
197
+ size: 'large',
198
+ color: 'primary',
199
+ variant: 'contained'
200
+ },
201
+ history: {
202
+ variant: 'avatar' // 'avatar' | 'table'
203
+ }
204
+ }
205
+ }}
206
+ />
207
+
208
+ // Custom render mode
209
+ <CheckoutDonate
210
+ mode="custom"
211
+ settings={{
212
+ target: 'custom-donation',
213
+ // ... other settings
214
+ }}
215
+ >
216
+ {(openDonate, totalAmount, supporters) => (
217
+ <div>
218
+ <button onClick={openDonate}>
219
+ Support Us
220
+ </button>
221
+ <div>Total Donations: {totalAmount}</div>
222
+ <div>Supporters: {supporters.supporters.length}</div>
223
+ {supporters.supporters.map(supporter => (
224
+ <div key={supporter.id}>
225
+ <img src={supporter.customer?.avatar} alt={supporter.customer?.name} />
226
+ <span>{supporter.customer?.name}</span>
227
+ <span>{formatAmount(supporter.amount_total, supporters.currency.decimal)} {supporters.currency.symbol}</span>
228
+ </div>
229
+ ))}
230
+ </div>
231
+ )}
232
+ </CheckoutDonate>
233
+ ```
234
+
235
+ ### Lazy Loading Components
236
+
237
+ The SDK provides `createLazyComponent` for optimizing bundle size by loading components and their dependencies on demand:
238
+
239
+ ```tsx
240
+ import { createLazyComponent } from '@blocklet/payment-react';
241
+
242
+ // 1. Create lazy component with dependencies
243
+ const LazyComponent = createLazyComponent(async () => {
244
+ // Load dependencies in parallel
245
+ const [dep1, dep2] = await Promise.all([
246
+ import('heavy-dependency-1'),
247
+ import('heavy-dependency-2')
248
+ ]);
249
+
250
+ // Store dependencies for reuse
251
+ const dependencies = {
252
+ Component1: dep1.Component1,
253
+ Component2: dep1.Component2,
254
+ useHook1: dep2.useHook1,
255
+ useHook2: dep2.useHook2,
256
+ };
257
+
258
+ // Make dependencies available to child components
259
+ globalThis.__DEPENDENCIES__ = dependencies;
260
+
261
+ // Load and return the actual component that uses these dependencies
262
+ const { default: Component } = await import('./MyComponent');
263
+ return Component;
264
+ });
265
+
266
+ // 2. Use dependencies in your component
267
+ // Access loaded dependencies
268
+ const {
269
+ Component1,
270
+ Component2,
271
+ useHook1,
272
+ useHook2
273
+ } = globalThis.__DEPENDENCIES__;
274
+ function MyComponent(props) {
275
+ // Use hooks from dependencies
276
+ const hook1Result = useHook1();
277
+ const hook2Result = useHook2();
278
+
279
+ return (
280
+ <div>
281
+ <Component1 {...hook1Result} />
282
+ <Component2 {...hook2Result} />
283
+ </div>
284
+ );
285
+ }
286
+
287
+ // 3. Use the lazy component
288
+ function App() {
289
+ return (
290
+ <LazyComponent
291
+ prop1="value1"
292
+ prop2="value2"
293
+ onEvent={() => {}}
294
+ />
295
+ );
296
+ }
297
+ ```
298
+
299
+ Key features:
300
+ - 🚀 Loads dependencies on demand
301
+ - 📦 Reduces initial bundle size
302
+ - 🌐 Provides global access to loaded dependencies
303
+ - ⚡️ Supports parallel loading
304
+ - 🔄 Handles async initialization
305
+ - ❌ Built-in error handling
306
+
307
+ ## Theme Customization
73
308
 
74
- #### theme
75
309
  Since version 1.14.22, the component includes a built-in theme provider. If you need to modify the styles of internal components, you need to pass the `theme` property to override or inherit the external theme.
76
310
 
77
- | option |description |
311
+ | option | description |
78
312
  | --- | --- |
79
313
  | default [default value] | wrapped with built-in PaymentThemeProvider |
80
314
  | inherit | use the parent component's themeProvider |
@@ -84,12 +318,12 @@ Since version 1.14.22, the component includes a built-in theme provider. If you
84
318
  export type PaymentThemeOptions = ThemeOptions & {
85
319
  sx?: SxProps;
86
320
  };
87
-
88
321
  ```
89
- ```js
322
+
323
+ ```tsx
90
324
  // 1. use themeOptions
91
- <CheckoutForm
92
- id="plink_oB1I6FNeHKSkuq81fhJy0vIZ"
325
+ <CheckoutForm
326
+ id="plink_xxx"
93
327
  onChange={console.info}
94
328
  theme={{
95
329
  components: {
@@ -110,8 +344,8 @@ export type PaymentThemeOptions = ThemeOptions & {
110
344
 
111
345
  // 2. use theme sx
112
346
  <CheckoutForm
113
- id="plink_oB1I6FNeHKSkuq81fhJy0vIZ"
114
- mode="inline-minimal"
347
+ id="plink_xxx"
348
+ showCheckoutSummary={false}
115
349
  onChange={console.info}
116
350
  theme={{
117
351
  sx: {
@@ -127,21 +361,84 @@ export type PaymentThemeOptions = ThemeOptions & {
127
361
  />
128
362
  ```
129
363
 
130
- #### showCheckoutSummary
364
+ ## I18n Support
131
365
 
132
- Since version 1.14.23, if you need to hide the product column, we recommend using `showCheckoutSummary=false` instead of `mode=inline-minimal`. We aim for better semantics.
133
- ```js
134
- // bad
366
+ ```tsx
367
+ import { createTranslator, translations as extraTranslations } from '@blocklet/payment-react';
368
+ import merge from 'lodash/merge';
369
+
370
+ import en from './en';
371
+ import zh from './zh';
372
+
373
+ export const translations = merge({ zh, en }, extraTranslations);
374
+ ```
375
+
376
+ ## Recent Updates
377
+
378
+ ### v1.14.23
379
+ We recommend using `showCheckoutSummary={false}` instead of `mode=inline-minimal` for better semantics:
380
+
381
+ ```tsx
382
+ // Recommended
135
383
  <CheckoutForm
136
- id="plink_oB1I6FNeHKSkuq81fhJy0vIZ"
137
- mode="inline-minimal"
384
+ id="plink_xxx"
385
+ showCheckoutSummary={false}
138
386
  onChange={console.info}
139
387
  />
140
388
 
141
- // good
389
+ // Not recommended
142
390
  <CheckoutForm
143
- id="plink_oB1I6FNeHKSkuq81fhJy0vIZ"
144
- showCheckoutSummary={false}
391
+ id="plink_xxx"
392
+ mode="inline-minimal"
145
393
  onChange={console.info}
146
394
  />
147
- ```
395
+ ```
396
+
397
+ ### Status & Utility Components
398
+ ```tsx
399
+ import {
400
+ Status,
401
+ Livemode,
402
+ Switch,
403
+ Link,
404
+ Amount
405
+ } from '@blocklet/payment-react';
406
+
407
+ // Status indicator for payment states
408
+ <Status
409
+ label="active"
410
+ color="success"
411
+ size="small"
412
+ sx={{ margin: 1 }}
413
+ />
414
+
415
+ // Live/Test mode indicator
416
+ <Livemode livemode={false} />
417
+
418
+ // Custom switch button
419
+ <Switch
420
+ checked={true}
421
+ onChange={(checked) => console.log('Switched:', checked)}
422
+ size="small"
423
+ color="primary"
424
+ />
425
+
426
+ // Safe navigation link
427
+ <Link
428
+ href="https://example.com"
429
+ confirmBeforeNavigate={true}
430
+ confirmMessage="Are you sure to leave?"
431
+ target="_blank"
432
+ />
433
+
434
+ // Amount display with formatting
435
+ <Amount
436
+ value={1000}
437
+ currency={{
438
+ symbol: '$',
439
+ decimal: 2
440
+ }}
441
+ variant="body1"
442
+ color="primary"
443
+ />
444
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/payment-react",
3
- "version": "1.16.1",
3
+ "version": "1.16.3",
4
4
  "description": "Reusable react components for payment kit v2",
5
5
  "keywords": [
6
6
  "react",
@@ -53,15 +53,15 @@
53
53
  }
54
54
  },
55
55
  "dependencies": {
56
- "@arcblock/did-connect": "^2.10.65",
57
- "@arcblock/ux": "^2.10.65",
58
- "@arcblock/ws": "^1.18.139",
59
- "@blocklet/ui-react": "^2.10.65",
56
+ "@arcblock/did-connect": "^2.10.67",
57
+ "@arcblock/ux": "^2.10.67",
58
+ "@arcblock/ws": "^1.18.147",
59
+ "@blocklet/ui-react": "^2.10.67",
60
60
  "@mui/icons-material": "^5.16.6",
61
61
  "@mui/lab": "^5.0.0-alpha.173",
62
62
  "@mui/material": "^5.16.6",
63
63
  "@mui/system": "^5.16.6",
64
- "@ocap/util": "^1.18.139",
64
+ "@ocap/util": "^1.18.147",
65
65
  "@stripe/react-stripe-js": "^2.7.3",
66
66
  "@stripe/stripe-js": "^2.4.0",
67
67
  "@vitejs/plugin-legacy": "^5.4.1",
@@ -92,7 +92,7 @@
92
92
  "@babel/core": "^7.25.2",
93
93
  "@babel/preset-env": "^7.25.2",
94
94
  "@babel/preset-react": "^7.24.7",
95
- "@blocklet/payment-types": "1.16.1",
95
+ "@blocklet/payment-types": "1.16.3",
96
96
  "@storybook/addon-essentials": "^7.6.20",
97
97
  "@storybook/addon-interactions": "^7.6.20",
98
98
  "@storybook/addon-links": "^7.6.20",
@@ -122,5 +122,5 @@
122
122
  "vite-plugin-babel": "^1.2.0",
123
123
  "vite-plugin-node-polyfills": "^0.21.0"
124
124
  },
125
- "gitHead": "590597d056e31eafd2b8ebd2a9d0a0c236c33440"
125
+ "gitHead": "6accc56a51e4ea0906e65f69dc5f41eaa82685fb"
126
126
  }