payment-kit 1.21.14 → 1.21.15

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/blocklet.yml CHANGED
@@ -14,7 +14,7 @@ repository:
14
14
  type: git
15
15
  url: git+https://github.com/blocklet/payment-kit.git
16
16
  specVersion: 1.2.8
17
- version: 1.21.14
17
+ version: 1.21.15
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.21.14",
3
+ "version": "1.21.15",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
@@ -56,9 +56,9 @@
56
56
  "@blocklet/error": "^0.2.5",
57
57
  "@blocklet/js-sdk": "^1.16.53-beta-20251011-054719-4ed2f6b7",
58
58
  "@blocklet/logger": "^1.16.53-beta-20251011-054719-4ed2f6b7",
59
- "@blocklet/payment-broker-client": "1.21.14",
60
- "@blocklet/payment-react": "1.21.14",
61
- "@blocklet/payment-vendor": "1.21.14",
59
+ "@blocklet/payment-broker-client": "1.21.15",
60
+ "@blocklet/payment-react": "1.21.15",
61
+ "@blocklet/payment-vendor": "1.21.15",
62
62
  "@blocklet/sdk": "^1.16.53-beta-20251011-054719-4ed2f6b7",
63
63
  "@blocklet/ui-react": "^3.1.46",
64
64
  "@blocklet/uploader": "^0.2.15",
@@ -128,7 +128,7 @@
128
128
  "devDependencies": {
129
129
  "@abtnode/types": "^1.16.53-beta-20251011-054719-4ed2f6b7",
130
130
  "@arcblock/eslint-config-ts": "^0.3.3",
131
- "@blocklet/payment-types": "1.21.14",
131
+ "@blocklet/payment-types": "1.21.15",
132
132
  "@types/cookie-parser": "^1.4.9",
133
133
  "@types/cors": "^2.8.19",
134
134
  "@types/debug": "^4.1.12",
@@ -175,5 +175,5 @@
175
175
  "parser": "typescript"
176
176
  }
177
177
  },
178
- "gitHead": "31f93a8310fe5184be8dd4ff23b362906c8a66cf"
178
+ "gitHead": "fd48f9233f19514b537e30b013e09a7d9f7a9f48"
179
179
  }
@@ -13,9 +13,9 @@ import {
13
13
  } from '@blocklet/payment-react';
14
14
  import type { TInvoiceExpanded } from '@blocklet/payment-types';
15
15
  import { Avatar, CircularProgress, Typography } from '@mui/material';
16
- import { useLocalStorageState } from 'ahooks';
17
16
  import { useEffect, useState } from 'react';
18
17
  import { Link, useSearchParams } from 'react-router-dom';
18
+ import { useCacheState } from '../../hooks/cache-state';
19
19
  import CustomerLink from '../customer/link';
20
20
  import FilterToolbar from '../filter-toolbar';
21
21
  import InvoiceActions from './action';
@@ -129,11 +129,7 @@ export default function InvoiceList({
129
129
  const { t, locale } = useLocaleContext();
130
130
  const defaultPageSize = useDefaultPageSize(20);
131
131
 
132
- const urlStatus = searchParams.get('status');
133
- const urlCurrencyId = searchParams.get('currency_id');
134
- const urlCustomerId = searchParams.get('customer_id');
135
-
136
- const [search, setSearch] = useLocalStorageState<
132
+ const [search, setSearch] = useCacheState<
137
133
  SearchProps & { ignore_zero?: boolean; include_staking?: boolean; include_return_staking?: boolean }
138
134
  >(listKey, {
139
135
  defaultValue: {
@@ -147,19 +143,21 @@ export default function InvoiceList({
147
143
  include_staking: !!include_staking,
148
144
  include_return_staking: !!include_return_staking,
149
145
  },
146
+ getUrlParams: () => {
147
+ const params: Record<string, any> = {};
148
+ if (searchParams.has('status')) {
149
+ params.status = searchParams.get('status');
150
+ }
151
+ if (searchParams.has('currency_id')) {
152
+ params.currency_id = searchParams.get('currency_id');
153
+ }
154
+ if (searchParams.has('customer_id')) {
155
+ params.customer_id = searchParams.get('customer_id');
156
+ }
157
+ return params;
158
+ },
150
159
  });
151
160
 
152
- useEffect(() => {
153
- if (urlStatus || urlCurrencyId || urlCustomerId) {
154
- setSearch((prev) => ({
155
- ...prev!,
156
- ...(urlStatus && { status: urlStatus }),
157
- ...(urlCurrencyId && { currency_id: urlCurrencyId }),
158
- ...(urlCustomerId && { customer_id: urlCustomerId }),
159
- }));
160
- }
161
- }, [urlStatus, urlCurrencyId, urlCustomerId, setSearch]);
162
-
163
161
  const [data, setData] = useState({}) as any;
164
162
 
165
163
  const refresh = () =>
@@ -11,11 +11,11 @@ import {
11
11
  } from '@blocklet/payment-react';
12
12
  import type { TPaymentIntentExpanded } from '@blocklet/payment-types';
13
13
  import { Avatar, CircularProgress, Typography } from '@mui/material';
14
- import { useLocalStorageState } from 'ahooks';
15
14
  import { useEffect, useState } from 'react';
16
15
  import { Link, useSearchParams } from 'react-router-dom';
17
16
 
18
17
  import { debounce } from '../../libs/util';
18
+ import { useCacheState } from '../../hooks/cache-state';
19
19
  import CustomerLink from '../customer/link';
20
20
  import FilterToolbar from '../filter-toolbar';
21
21
  import PaymentIntentActions from './actions';
@@ -81,11 +81,7 @@ export default function PaymentList({
81
81
  const listKey = getListKey({ customer_id, invoice_id });
82
82
  const defaultPageSize = useDefaultPageSize(20);
83
83
 
84
- const urlStatus = searchParams.get('status');
85
- const urlCurrencyId = searchParams.get('currency_id');
86
- const urlCustomerId = searchParams.get('customer_id');
87
-
88
- const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
84
+ const [search, setSearch] = useCacheState<SearchProps>(listKey, {
89
85
  defaultValue: {
90
86
  status: '',
91
87
  customer_id,
@@ -93,19 +89,21 @@ export default function PaymentList({
93
89
  pageSize: defaultPageSize,
94
90
  page: 1,
95
91
  },
92
+ getUrlParams: () => {
93
+ const params: Record<string, any> = {};
94
+ if (searchParams.has('status')) {
95
+ params.status = searchParams.get('status');
96
+ }
97
+ if (searchParams.has('currency_id')) {
98
+ params.currency_id = searchParams.get('currency_id');
99
+ }
100
+ if (searchParams.has('customer_id')) {
101
+ params.customer_id = searchParams.get('customer_id');
102
+ }
103
+ return params;
104
+ },
96
105
  });
97
106
 
98
- useEffect(() => {
99
- if (urlStatus || urlCurrencyId || urlCustomerId) {
100
- setSearch((prev) => ({
101
- ...prev!,
102
- ...(urlStatus && { status: urlStatus }),
103
- ...(urlCurrencyId && { currency_id: urlCurrencyId }),
104
- ...(urlCustomerId && { customer_id: urlCustomerId }),
105
- }));
106
- }
107
- }, [urlStatus, urlCurrencyId, urlCustomerId, setSearch]);
108
-
109
107
  const [data, setData] = useState({}) as any;
110
108
 
111
109
  const fetchListData = () => {
@@ -11,13 +11,13 @@ import {
11
11
  } from '@blocklet/payment-react';
12
12
  import type { TPayoutExpanded } from '@blocklet/payment-types';
13
13
  import { Avatar, CircularProgress, Typography } from '@mui/material';
14
- import { useLocalStorageState } from 'ahooks';
15
14
  import { useEffect, useState } from 'react';
16
15
  import { Link, useSearchParams } from 'react-router-dom';
17
16
 
18
17
  import DID from '@arcblock/ux/lib/DID';
19
18
  import ShortenLabel from '@arcblock/ux/lib/UserCard/Content/shorten-label';
20
19
  import { debounce, getAppInfo } from '../../libs/util';
20
+ import { useCacheState } from '../../hooks/cache-state';
21
21
  import CustomerLink from '../customer/link';
22
22
  import FilterToolbar from '../filter-toolbar';
23
23
  import PayoutActions from './actions';
@@ -86,11 +86,7 @@ export default function PayoutList({
86
86
  const listKey = getListKey({ customer_id, payment_intent_id });
87
87
  const defaultPageSize = useDefaultPageSize(20);
88
88
 
89
- const urlStatus = searchParams.get('status');
90
- const urlCurrencyId = searchParams.get('currency_id');
91
- const urlCustomerId = searchParams.get('customer_id');
92
-
93
- const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
89
+ const [search, setSearch] = useCacheState<SearchProps>(listKey, {
94
90
  defaultValue: {
95
91
  status: status as string,
96
92
  customer_id,
@@ -98,19 +94,21 @@ export default function PayoutList({
98
94
  pageSize: defaultPageSize,
99
95
  page: 1,
100
96
  },
97
+ getUrlParams: () => {
98
+ const params: Record<string, any> = {};
99
+ if (searchParams.has('status')) {
100
+ params.status = searchParams.get('status');
101
+ }
102
+ if (searchParams.has('currency_id')) {
103
+ params.currency_id = searchParams.get('currency_id');
104
+ }
105
+ if (searchParams.has('customer_id')) {
106
+ params.customer_id = searchParams.get('customer_id');
107
+ }
108
+ return params;
109
+ },
101
110
  });
102
111
 
103
- useEffect(() => {
104
- if (urlStatus || urlCurrencyId || urlCustomerId) {
105
- setSearch((prev) => ({
106
- ...prev!,
107
- ...(urlStatus && { status: urlStatus }),
108
- ...(urlCurrencyId && { currency_id: urlCurrencyId }),
109
- ...(urlCustomerId && { customer_id: urlCustomerId }),
110
- }));
111
- }
112
- }, [urlStatus, urlCurrencyId, urlCustomerId, setSearch]);
113
-
114
112
  const [data, setData] = useState({}) as any;
115
113
 
116
114
  useEffect(() => {
@@ -11,7 +11,6 @@ import {
11
11
  } from '@blocklet/payment-react';
12
12
  import type { TRefundExpanded } from '@blocklet/payment-types';
13
13
  import { Avatar, CircularProgress, Typography } from '@mui/material';
14
- import { useLocalStorageState } from 'ahooks';
15
14
  import { useEffect, useState } from 'react';
16
15
  import { Link, useSearchParams } from 'react-router-dom';
17
16
 
@@ -19,6 +18,7 @@ import { capitalize, toLower } from 'lodash';
19
18
  import CustomerLink from '../customer/link';
20
19
  import FilterToolbar from '../filter-toolbar';
21
20
  import RefundActions from './actions';
21
+ import { useCacheState } from '../../hooks/cache-state';
22
22
 
23
23
  const fetchData = (params: Record<string, any> = {}): Promise<{ list: TRefundExpanded[]; count: number }> => {
24
24
  const search = new URLSearchParams();
@@ -96,11 +96,7 @@ export default function RefundList({
96
96
  const listKey = getListKey({ customer_id, invoice_id, subscription_id, payment_intent_id });
97
97
  const defaultPageSize = useDefaultPageSize(20);
98
98
 
99
- const urlStatus = searchParams.get('status');
100
- const urlCurrencyId = searchParams.get('currency_id');
101
- const urlCustomerId = searchParams.get('customer_id');
102
-
103
- const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
99
+ const [search, setSearch] = useCacheState<SearchProps>(listKey, {
104
100
  defaultValue: {
105
101
  status: status as string,
106
102
  customer_id,
@@ -110,19 +106,21 @@ export default function RefundList({
110
106
  pageSize: defaultPageSize,
111
107
  page: 1,
112
108
  },
109
+ getUrlParams: () => {
110
+ const params: Record<string, any> = {};
111
+ if (searchParams.has('status')) {
112
+ params.status = searchParams.get('status');
113
+ }
114
+ if (searchParams.has('currency_id')) {
115
+ params.currency_id = searchParams.get('currency_id');
116
+ }
117
+ if (searchParams.has('customer_id')) {
118
+ params.customer_id = searchParams.get('customer_id');
119
+ }
120
+ return params;
121
+ },
113
122
  });
114
123
 
115
- useEffect(() => {
116
- if (urlStatus || urlCurrencyId || urlCustomerId) {
117
- setSearch((prev) => ({
118
- ...prev!,
119
- ...(urlStatus && { status: urlStatus }),
120
- ...(urlCurrencyId && { currency_id: urlCurrencyId }),
121
- ...(urlCustomerId && { customer_id: urlCustomerId }),
122
- }));
123
- }
124
- }, [urlStatus, urlCurrencyId, urlCustomerId, setSearch]);
125
-
126
124
  const [data, setData] = useState({}) as any;
127
125
 
128
126
  const refresh = () =>
@@ -3,10 +3,10 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
3
3
  import { Status, api, formatTime, Table, useDefaultPageSize } from '@blocklet/payment-react';
4
4
  import type { TSubscriptionExpanded } from '@blocklet/payment-types';
5
5
  import { CircularProgress } from '@mui/material';
6
- import { useLocalStorageState } from 'ahooks';
7
6
  import { useEffect, useState } from 'react';
8
7
  import { Link, useSearchParams } from 'react-router-dom';
9
8
 
9
+ import { useCacheState } from '../../hooks/cache-state';
10
10
  import CustomerLink from '../customer/link';
11
11
  import FilterToolbar from '../filter-toolbar';
12
12
  import SubscriptionActions from './actions';
@@ -70,10 +70,7 @@ export default function SubscriptionList({
70
70
  const { t } = useLocaleContext();
71
71
  const defaultPageSize = useDefaultPageSize(20);
72
72
 
73
- const urlStatus = searchParams.get('status');
74
- const urlCustomerId = searchParams.get('customer_id');
75
-
76
- const [search, setSearch] = useLocalStorageState<SearchProps>(listKey, {
73
+ const [search, setSearch] = useCacheState<SearchProps>(listKey, {
77
74
  defaultValue: {
78
75
  status: (status || 'active') as string,
79
76
  customer_id,
@@ -81,18 +78,18 @@ export default function SubscriptionList({
81
78
  page: 1,
82
79
  price_id: '',
83
80
  },
81
+ getUrlParams: () => {
82
+ const params: Record<string, any> = {};
83
+ if (searchParams.has('status')) {
84
+ params.status = searchParams.get('status');
85
+ }
86
+ if (searchParams.has('customer_id')) {
87
+ params.customer_id = searchParams.get('customer_id');
88
+ }
89
+ return params;
90
+ },
84
91
  });
85
92
 
86
- useEffect(() => {
87
- if (urlStatus || urlCustomerId) {
88
- setSearch((prev) => ({
89
- ...prev!,
90
- ...(urlStatus && { status: urlStatus }),
91
- ...(urlCustomerId && { customer_id: urlCustomerId }),
92
- }));
93
- }
94
- }, [urlStatus, urlCustomerId, setSearch]);
95
-
96
93
  const [data, setData] = useState({}) as any;
97
94
 
98
95
  const refresh = () =>
@@ -0,0 +1,84 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ type StorageType = 'localStorage' | 'sessionStorage' | 'cookie';
4
+
5
+ interface CacheStateOptions<T> {
6
+ defaultValue: T;
7
+ storage?: StorageType;
8
+ getUrlParams?: () => Partial<T>;
9
+ clearUrlParams?: () => void;
10
+ }
11
+
12
+ const getStorageValue = <T>(key: string, storage: StorageType): T | undefined => {
13
+ try {
14
+ if (storage === 'cookie') {
15
+ const matches = document.cookie.match(
16
+ new RegExp(`(?:^|; )${key.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1')}=([^;]*)`)
17
+ );
18
+ return matches?.[1] ? JSON.parse(decodeURIComponent(matches[1])) : undefined;
19
+ }
20
+ const storageObj = storage === 'sessionStorage' ? sessionStorage : localStorage;
21
+ const value = storageObj.getItem(key);
22
+ return value ? JSON.parse(value) : undefined;
23
+ } catch {
24
+ return undefined;
25
+ }
26
+ };
27
+
28
+ const setStorageValue = <T>(key: string, value: T, storage: StorageType): void => {
29
+ try {
30
+ const serialized = JSON.stringify(value);
31
+ if (storage === 'cookie') {
32
+ document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(serialized)}; path=/`;
33
+ return;
34
+ }
35
+ const storageObj = storage === 'sessionStorage' ? sessionStorage : localStorage;
36
+ storageObj.setItem(key, serialized);
37
+ } catch (error) {
38
+ console.error(`Failed to set ${storage} value:`, error);
39
+ }
40
+ };
41
+
42
+ const getInitialValue = <T>(
43
+ key: string,
44
+ storage: StorageType,
45
+ defaultValue: T,
46
+ getUrlParams?: () => Partial<T>,
47
+ clearUrlParams?: () => void
48
+ ): T => {
49
+ const cachedValue = getStorageValue<T>(key, storage);
50
+ const urlParams = getUrlParams?.();
51
+
52
+ if (urlParams && Object.keys(urlParams).length > 0) {
53
+ const mergedValue = {
54
+ ...(cachedValue || defaultValue),
55
+ ...urlParams,
56
+ };
57
+ setStorageValue(key, mergedValue, storage);
58
+ clearUrlParams?.();
59
+ return mergedValue;
60
+ }
61
+
62
+ return cachedValue !== undefined ? cachedValue : defaultValue;
63
+ };
64
+
65
+ export const useCacheState = <T = any>(key: string, options: CacheStateOptions<T>) => {
66
+ const { defaultValue, storage = 'localStorage', getUrlParams, clearUrlParams } = options;
67
+
68
+ const [state, setState] = useState<T>(() =>
69
+ getInitialValue(key, storage, defaultValue, getUrlParams, clearUrlParams)
70
+ );
71
+
72
+ const setStateAndStorage = useCallback(
73
+ (value: T | ((prev: T) => T)) => {
74
+ setState((prevState) => {
75
+ const nextState = typeof value === 'function' ? (value as (prev: T) => T)(prevState) : value;
76
+ setStorageValue(key, nextState, storage);
77
+ return nextState;
78
+ });
79
+ },
80
+ [key, storage]
81
+ );
82
+
83
+ return [state, setStateAndStorage] as const;
84
+ };
@@ -1135,7 +1135,7 @@ export default function Overview() {
1135
1135
  }}>
1136
1136
  <Typography
1137
1137
  component={Link}
1138
- to={metric.link}
1138
+ to={`${metric.link}?status=`}
1139
1139
  sx={{
1140
1140
  fontSize: '1.5rem',
1141
1141
  fontWeight: 600,