payment-kit 1.25.8 → 1.26.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 (115) hide show
  1. package/api/src/crons/index.ts +24 -0
  2. package/api/src/libs/archive/config.ts +254 -0
  3. package/api/src/libs/archive/executor.ts +729 -0
  4. package/api/src/libs/archive/index.ts +7 -0
  5. package/api/src/libs/archive/lock.ts +50 -0
  6. package/api/src/libs/archive/policy.ts +55 -0
  7. package/api/src/libs/archive/query.ts +136 -0
  8. package/api/src/libs/archive/snapshot.ts +291 -0
  9. package/api/src/libs/archive/store.ts +200 -0
  10. package/api/src/libs/session.ts +43 -25
  11. package/api/src/queues/archive.ts +32 -0
  12. package/api/src/queues/subscription.ts +3 -1
  13. package/api/src/routes/archive.ts +176 -0
  14. package/api/src/routes/checkout-sessions.ts +50 -34
  15. package/api/src/routes/index.ts +2 -0
  16. package/api/src/routes/meters.ts +28 -0
  17. package/api/src/routes/payment-stats.ts +167 -20
  18. package/api/src/store/migrations/20260203-archive.ts +12 -0
  19. package/api/src/store/migrations/20260204-revenue-snapshot.ts +19 -0
  20. package/api/src/store/models/archive-lock.ts +55 -0
  21. package/api/src/store/models/archive-metadata.ts +132 -0
  22. package/api/src/store/models/index.ts +9 -0
  23. package/api/src/store/models/revenue-snapshot.ts +110 -0
  24. package/api/tests/libs/archive-config.spec.ts +185 -0
  25. package/api/tests/libs/archive-executor.spec.ts +678 -0
  26. package/api/tests/libs/archive-lock.spec.ts +130 -0
  27. package/api/tests/libs/archive-policy.spec.ts +255 -0
  28. package/api/tests/libs/archive-query.spec.ts +267 -0
  29. package/api/tests/libs/archive-store.spec.ts +159 -0
  30. package/blocklet.prefs.json +187 -0
  31. package/blocklet.yml +2 -1
  32. package/package.json +10 -10
  33. package/src/components/customer/actions.tsx +1 -1
  34. package/src/components/customer/credit-overview.tsx +3 -1
  35. package/src/components/customer/overdraft-protection.tsx +1 -1
  36. package/src/components/event/list.tsx +1 -1
  37. package/src/components/filter-toolbar.tsx +2 -2
  38. package/src/components/invoice/action.tsx +3 -3
  39. package/src/components/invoice/list.tsx +1 -1
  40. package/src/components/invoice/recharge.tsx +2 -2
  41. package/src/components/meter/add-usage-dialog.tsx +1 -1
  42. package/src/components/passport/actions.tsx +1 -1
  43. package/src/components/passport/assign.tsx +1 -1
  44. package/src/components/payment-currency/add.tsx +1 -1
  45. package/src/components/payment-currency/edit.tsx +1 -1
  46. package/src/components/payment-intent/actions.tsx +4 -4
  47. package/src/components/payment-intent/list.tsx +1 -1
  48. package/src/components/payment-link/actions.tsx +4 -4
  49. package/src/components/payment-link/item.tsx +1 -1
  50. package/src/components/payouts/list.tsx +1 -1
  51. package/src/components/payouts/portal/list.tsx +1 -1
  52. package/src/components/price/upsell-select.tsx +1 -1
  53. package/src/components/price/upsell.tsx +2 -2
  54. package/src/components/pricing-table/actions.tsx +3 -3
  55. package/src/components/pricing-table/product-item.tsx +1 -1
  56. package/src/components/product/actions.tsx +3 -3
  57. package/src/components/product/create.tsx +1 -1
  58. package/src/components/product/cross-sell.tsx +2 -2
  59. package/src/components/promotion/active-redemptions.tsx +1 -1
  60. package/src/components/refund/list.tsx +1 -1
  61. package/src/components/subscription/actions/index.tsx +1 -1
  62. package/src/components/subscription/items/usage-records.tsx +4 -2
  63. package/src/components/subscription/list.tsx +1 -1
  64. package/src/components/subscription/metrics.tsx +3 -3
  65. package/src/components/subscription/portal/actions.tsx +15 -12
  66. package/src/components/subscription/portal/list.tsx +1 -1
  67. package/src/components/webhook/attempts.tsx +4 -4
  68. package/src/hooks/subscription.ts +2 -2
  69. package/src/locales/en.tsx +4 -0
  70. package/src/locales/zh.tsx +4 -0
  71. package/src/pages/admin/billing/meter-events/index.tsx +3 -3
  72. package/src/pages/admin/billing/meters/index.tsx +1 -1
  73. package/src/pages/admin/billing/overdue/index.tsx +2 -2
  74. package/src/pages/admin/billing/subscriptions/detail.tsx +2 -2
  75. package/src/pages/admin/customers/customers/credit-grant/detail.tsx +1 -1
  76. package/src/pages/admin/customers/customers/credit-transaction/detail.tsx +1 -1
  77. package/src/pages/admin/customers/customers/detail.tsx +4 -4
  78. package/src/pages/admin/developers/events/detail.tsx +1 -1
  79. package/src/pages/admin/developers/webhooks/detail.tsx +1 -1
  80. package/src/pages/admin/developers/webhooks/index.tsx +1 -1
  81. package/src/pages/admin/overview.tsx +2 -0
  82. package/src/pages/admin/payments/intents/detail.tsx +2 -2
  83. package/src/pages/admin/payments/payouts/detail.tsx +2 -2
  84. package/src/pages/admin/payments/refunds/detail.tsx +2 -2
  85. package/src/pages/admin/products/coupons/detail.tsx +1 -1
  86. package/src/pages/admin/products/coupons/index.tsx +1 -1
  87. package/src/pages/admin/products/exchange-rate-providers/index.tsx +1 -1
  88. package/src/pages/admin/products/links/create.tsx +1 -1
  89. package/src/pages/admin/products/links/detail.tsx +2 -2
  90. package/src/pages/admin/products/links/index.tsx +1 -1
  91. package/src/pages/admin/products/passports/index.tsx +1 -1
  92. package/src/pages/admin/products/prices/actions.tsx +4 -4
  93. package/src/pages/admin/products/prices/detail.tsx +2 -2
  94. package/src/pages/admin/products/pricing-tables/create.tsx +1 -1
  95. package/src/pages/admin/products/pricing-tables/detail.tsx +2 -2
  96. package/src/pages/admin/products/pricing-tables/index.tsx +1 -1
  97. package/src/pages/admin/products/products/index.tsx +1 -1
  98. package/src/pages/admin/products/promotion-codes/actions.tsx +2 -2
  99. package/src/pages/admin/products/promotion-codes/detail.tsx +2 -2
  100. package/src/pages/admin/products/promotion-codes/list.tsx +1 -1
  101. package/src/pages/admin/settings/payment-methods/create.tsx +1 -1
  102. package/src/pages/admin/settings/payment-methods/edit.tsx +1 -1
  103. package/src/pages/admin/settings/payment-methods/index.tsx +2 -2
  104. package/src/pages/admin/tax/detail.tsx +2 -2
  105. package/src/pages/admin/tax/list.tsx +1 -1
  106. package/src/pages/checkout/pay.tsx +2 -2
  107. package/src/pages/customer/index.tsx +1 -1
  108. package/src/pages/customer/invoice/past-due.tsx +1 -1
  109. package/src/pages/customer/payout/detail.tsx +1 -1
  110. package/src/pages/customer/refund/list.tsx +1 -1
  111. package/src/pages/customer/subscription/change-payment.tsx +2 -2
  112. package/src/pages/customer/subscription/change-plan.tsx +3 -3
  113. package/src/pages/customer/subscription/detail.tsx +3 -3
  114. package/src/pages/integrations/donations/index.tsx +1 -1
  115. package/vite.config.ts +3 -1
@@ -0,0 +1,159 @@
1
+ import fs from 'fs';
2
+
3
+ import {
4
+ getArchiveDir,
5
+ getArchiveFilePath,
6
+ listArchiveFiles,
7
+ getFileSize,
8
+ cleanupOldArchiveFiles,
9
+ } from '../../src/libs/archive/store';
10
+
11
+ jest.mock('@blocklet/sdk/lib/config', () => ({
12
+ __esModule: true,
13
+ default: {
14
+ env: {
15
+ dataDir: '/tmp/test-payment-kit',
16
+ },
17
+ },
18
+ }));
19
+
20
+ jest.mock('fs');
21
+ jest.mock('../../src/libs/logger', () => ({
22
+ __esModule: true,
23
+ default: {
24
+ info: jest.fn(),
25
+ warn: jest.fn(),
26
+ error: jest.fn(),
27
+ },
28
+ }));
29
+
30
+ describe('archive/store', () => {
31
+ beforeEach(() => {
32
+ jest.clearAllMocks();
33
+ });
34
+
35
+ describe('getArchiveDir', () => {
36
+ it('should create archive directory if it does not exist', () => {
37
+ (fs.existsSync as jest.Mock).mockReturnValue(false);
38
+ (fs.mkdirSync as jest.Mock).mockReturnValue(undefined);
39
+
40
+ const result = getArchiveDir();
41
+
42
+ expect(result).toContain('archive');
43
+ expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('archive'), { recursive: true });
44
+ });
45
+
46
+ it('should not create directory if it already exists', () => {
47
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
48
+
49
+ getArchiveDir();
50
+
51
+ expect(fs.mkdirSync).not.toHaveBeenCalled();
52
+ });
53
+ });
54
+
55
+ describe('getArchiveFilePath', () => {
56
+ it('should return full path for archive file', () => {
57
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
58
+
59
+ const result = getArchiveFilePath('archive-2024.db');
60
+
61
+ expect(result).toContain('archive-2024.db');
62
+ expect(result).toContain('archive');
63
+ });
64
+ });
65
+
66
+ describe('listArchiveFiles', () => {
67
+ it('should return sorted list of .db files', () => {
68
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
69
+ (fs.readdirSync as jest.Mock).mockReturnValue([
70
+ 'archive-2025.db',
71
+ 'archive-2023.db',
72
+ 'archive-2024.db',
73
+ 'some-other-file.txt',
74
+ ]);
75
+
76
+ const result = listArchiveFiles();
77
+
78
+ expect(result).toHaveLength(3);
79
+ expect(result[0]).toContain('archive-2023.db');
80
+ expect(result[1]).toContain('archive-2024.db');
81
+ expect(result[2]).toContain('archive-2025.db');
82
+ });
83
+
84
+ it('should return empty array when no .db files', () => {
85
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
86
+ (fs.readdirSync as jest.Mock).mockReturnValue(['readme.txt', 'config.json']);
87
+
88
+ const result = listArchiveFiles();
89
+
90
+ expect(result).toHaveLength(0);
91
+ });
92
+ });
93
+
94
+ describe('getFileSize', () => {
95
+ it('should return file size in bytes', () => {
96
+ (fs.statSync as jest.Mock).mockReturnValue({ size: 1024 });
97
+
98
+ const result = getFileSize('/tmp/archive.db');
99
+
100
+ expect(result).toBe(1024);
101
+ });
102
+
103
+ it('should return 0 when file does not exist', () => {
104
+ (fs.statSync as jest.Mock).mockImplementation(() => {
105
+ throw new Error('ENOENT');
106
+ });
107
+
108
+ const result = getFileSize('/tmp/nonexistent.db');
109
+
110
+ expect(result).toBe(0);
111
+ });
112
+ });
113
+
114
+ describe('cleanupOldArchiveFiles', () => {
115
+ it('should not remove files when under max limit', () => {
116
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
117
+ (fs.readdirSync as jest.Mock).mockReturnValue(['archive-2023.db', 'archive-2024.db']);
118
+
119
+ const result = cleanupOldArchiveFiles(10);
120
+
121
+ expect(result).toHaveLength(0);
122
+ expect(fs.unlinkSync).not.toHaveBeenCalled();
123
+ });
124
+
125
+ it('should remove oldest files when exceeding max limit', () => {
126
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
127
+ (fs.readdirSync as jest.Mock).mockReturnValue([
128
+ 'archive-2021.db',
129
+ 'archive-2022.db',
130
+ 'archive-2023.db',
131
+ 'archive-2024.db',
132
+ ]);
133
+ (fs.unlinkSync as jest.Mock).mockReturnValue(undefined);
134
+
135
+ const result = cleanupOldArchiveFiles(2);
136
+
137
+ expect(result).toHaveLength(2);
138
+ expect(result).toContain('archive-2021.db');
139
+ expect(result).toContain('archive-2022.db');
140
+ expect(fs.unlinkSync).toHaveBeenCalledTimes(2);
141
+ });
142
+
143
+ it('should continue cleanup even if one file fails to delete', () => {
144
+ (fs.existsSync as jest.Mock).mockReturnValue(true);
145
+ (fs.readdirSync as jest.Mock).mockReturnValue(['archive-2022.db', 'archive-2023.db', 'archive-2024.db']);
146
+ (fs.unlinkSync as jest.Mock)
147
+ .mockImplementationOnce(() => {
148
+ throw new Error('Permission denied');
149
+ })
150
+ .mockReturnValue(undefined);
151
+
152
+ const result = cleanupOldArchiveFiles(1);
153
+
154
+ expect(fs.unlinkSync).toHaveBeenCalledTimes(2);
155
+ expect(result).toHaveLength(1);
156
+ expect(result).toContain('archive-2023.db');
157
+ });
158
+ });
159
+ });
@@ -0,0 +1,187 @@
1
+ {
2
+ "form": {
3
+ "labelCol": 6,
4
+ "wrapperCol": 12
5
+ },
6
+ "schema": {
7
+ "type": "object",
8
+ "properties": {
9
+ "8ezxt923qyy": {
10
+ "type": "void",
11
+ "x-component": "Card",
12
+ "x-component-props": {
13
+ "title": "Config"
14
+ },
15
+ "x-designable-id": "8ezxt923qyy",
16
+ "properties": {
17
+ "wvny47lybcc": {
18
+ "type": "void",
19
+ "x-component": "FormCollapse",
20
+ "x-component-props": {},
21
+ "name": "Data Retention",
22
+ "x-designable-id": "wvny47lybcc",
23
+ "properties": {
24
+ "5tiydb79qp2": {
25
+ "type": "void",
26
+ "x-component": "FormCollapse.CollapsePanel",
27
+ "x-component-props": {
28
+ "header": "Data Retention"
29
+ },
30
+ "x-designable-id": "5tiydb79qp2",
31
+ "properties": {
32
+ "retentionEnabled": {
33
+ "type": "boolean",
34
+ "title": "Enable Data Retention ",
35
+ "x-decorator": "FormItem",
36
+ "x-component": "Switch",
37
+ "x-validator": [],
38
+ "x-component-props": {},
39
+ "x-decorator-props": {},
40
+ "name": "retentionEnabled",
41
+ "default": false,
42
+ "description": "Archive expired data to reduce database size",
43
+ "x-designable-id": "886b4pe1o1y",
44
+ "x-index": 0
45
+ },
46
+ "scheduleEnabled": {
47
+ "type": "boolean",
48
+ "title": "Enable Scheduled Archive",
49
+ "x-decorator": "FormItem",
50
+ "x-component": "Switch",
51
+ "x-validator": [],
52
+ "x-component-props": {},
53
+ "x-decorator-props": {},
54
+ "description": "Run archive job automatically every day",
55
+ "name": "scheduleEnabled",
56
+ "default": true,
57
+ "x-reactions": {
58
+ "dependencies": [
59
+ {
60
+ "property": "value",
61
+ "type": "boolean",
62
+ "source": "8ezxt923qyy.wvny47lybcc.5tiydb79qp2.retentionEnabled",
63
+ "name": "retentionEnabled"
64
+ }
65
+ ],
66
+ "fulfill": {
67
+ "state": {
68
+ "visible": "{{$deps.retentionEnabled}}"
69
+ }
70
+ }
71
+ },
72
+ "x-designable-id": "53cmu3qg9j3",
73
+ "x-index": 1
74
+ },
75
+ "scheduleHour": {
76
+ "type": "number",
77
+ "title": " Archive Hour (0-23) ",
78
+ "x-decorator": "FormItem",
79
+ "x-component": "NumberPicker",
80
+ "x-validator": "number",
81
+ "x-component-props": {
82
+ "min": 0,
83
+ "max": 23
84
+ },
85
+ "x-decorator-props": {},
86
+ "name": "scheduleHour",
87
+ "default": 2,
88
+ "description": "Hour of day to\nrun the archive job (server Local\ntime)",
89
+ "x-reactions": {
90
+ "dependencies": [
91
+ {
92
+ "property": "value",
93
+ "type": "boolean",
94
+ "source": "8ezxt923qyy.wvny47lybcc.5tiydb79qp2.retentionEnabled",
95
+ "name": "retentionEnabled"
96
+ },
97
+ {
98
+ "property": "value",
99
+ "type": "boolean",
100
+ "source": "8ezxt923qyy.wvny47lybcc.5tiydb79qp2.scheduleEnabled",
101
+ "name": "scheduleEnabled"
102
+ }
103
+ ],
104
+ "fulfill": {
105
+ "state": {
106
+ "visible": "{{$deps.retentionEnabled === true && $deps.scheduleEnabled === true}}"
107
+ }
108
+ }
109
+ },
110
+ "x-designable-id": "dvdqp2aaszw",
111
+ "x-index": 2
112
+ },
113
+ "batchSize": {
114
+ "type": "number",
115
+ "title": "Batch Size ",
116
+ "x-decorator": "FormItem",
117
+ "x-component": "NumberPicker",
118
+ "x-validator": [],
119
+ "x-component-props": {
120
+ "min": 100
121
+ },
122
+ "x-decorator-props": {},
123
+ "name": "batchSize",
124
+ "default": 500,
125
+ "description": "Number of records to archive per batch. Smaller\nvalues reduce database load",
126
+ "x-reactions": {
127
+ "dependencies": [
128
+ {
129
+ "property": "value",
130
+ "type": "boolean",
131
+ "source": "8ezxt923qyy.wvny47lybcc.5tiydb79qp2.retentionEnabled",
132
+ "name": "retentionEnabled"
133
+ }
134
+ ],
135
+ "fulfill": {
136
+ "state": {
137
+ "visible": "{{$deps.retentionEnabled}}"
138
+ }
139
+ }
140
+ },
141
+ "x-designable-id": "5mdfl84f6xw",
142
+ "x-index": 3
143
+ },
144
+ "minFreeDiskMB": {
145
+ "type": "number",
146
+ "title": "Min Free Disk Space (MB)",
147
+ "x-decorator": "FormItem",
148
+ "x-component": "NumberPicker",
149
+ "x-validator": [],
150
+ "x-component-props": {
151
+ "min": 100
152
+ },
153
+ "x-decorator-props": {},
154
+ "name": "minFreeDiskMB",
155
+ "default": 1000,
156
+ "description": "Stop archiving when free disk space falls below this threshold (default 1GB)",
157
+ "x-reactions": {
158
+ "dependencies": [
159
+ {
160
+ "property": "value",
161
+ "type": "boolean",
162
+ "source": "8ezxt923qyy.wvny47lybcc.5tiydb79qp2.retentionEnabled",
163
+ "name": "retentionEnabled"
164
+ }
165
+ ],
166
+ "fulfill": {
167
+ "state": {
168
+ "visible": "{{$deps.retentionEnabled}}"
169
+ }
170
+ }
171
+ },
172
+ "x-designable-id": "ud3govolh1e",
173
+ "x-index": 4
174
+ }
175
+ },
176
+ "x-index": 0
177
+ }
178
+ },
179
+ "x-index": 0
180
+ }
181
+ },
182
+ "x-index": 0
183
+ }
184
+ },
185
+ "x-designable-id": "yfw4ta3wi0l"
186
+ }
187
+ }
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.25.8
17
+ version: 1.26.0
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
@@ -47,6 +47,7 @@ interfaces:
47
47
  - /api/products/**
48
48
  - /methods/**
49
49
  - /currencies/**
50
+ - /meters/public/**
50
51
  blockUnauthorized: false
51
52
  proxyBehavior: service
52
53
  community: ''
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.25.8",
3
+ "version": "1.26.0",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "prelint": "npm run types",
@@ -47,23 +47,23 @@
47
47
  "dependencies": {
48
48
  "@abtnode/cron": "^1.17.8-beta-20260104-120132-cb5b1914",
49
49
  "@arcblock/did": "^1.28.5",
50
- "@arcblock/did-connect-react": "^3.4.7",
50
+ "@arcblock/did-connect-react": "^3.5.1",
51
51
  "@arcblock/did-connect-storage-nedb": "^1.8.0",
52
52
  "@arcblock/did-util": "^1.28.5",
53
53
  "@arcblock/jwt": "^1.28.5",
54
- "@arcblock/react-hooks": "^3.4.7",
55
- "@arcblock/ux": "^3.4.7",
54
+ "@arcblock/react-hooks": "^3.5.1",
55
+ "@arcblock/ux": "^3.5.1",
56
56
  "@arcblock/validator": "^1.28.5",
57
57
  "@arcblock/vc": "^1.28.5",
58
58
  "@blocklet/did-space-js": "^1.2.15",
59
59
  "@blocklet/error": "^0.3.5",
60
60
  "@blocklet/js-sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
61
61
  "@blocklet/logger": "^1.17.8-beta-20260104-120132-cb5b1914",
62
- "@blocklet/payment-broker-client": "1.25.8",
63
- "@blocklet/payment-react": "1.25.8",
64
- "@blocklet/payment-vendor": "1.25.8",
62
+ "@blocklet/payment-broker-client": "1.26.0",
63
+ "@blocklet/payment-react": "1.26.0",
64
+ "@blocklet/payment-vendor": "1.26.0",
65
65
  "@blocklet/sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
66
- "@blocklet/ui-react": "^3.4.7",
66
+ "@blocklet/ui-react": "^3.5.1",
67
67
  "@blocklet/uploader": "^0.3.19",
68
68
  "@blocklet/xss": "^0.3.16",
69
69
  "@mui/icons-material": "^7.1.2",
@@ -132,7 +132,7 @@
132
132
  "devDependencies": {
133
133
  "@abtnode/types": "^1.17.8-beta-20260104-120132-cb5b1914",
134
134
  "@arcblock/eslint-config-ts": "^0.3.3",
135
- "@blocklet/payment-types": "1.25.8",
135
+ "@blocklet/payment-types": "1.26.0",
136
136
  "@types/cookie-parser": "^1.4.9",
137
137
  "@types/cors": "^2.8.19",
138
138
  "@types/debug": "^4.1.12",
@@ -179,5 +179,5 @@
179
179
  "parser": "typescript"
180
180
  }
181
181
  },
182
- "gitHead": "b40c46bcf52d4c1758bb10eb4c4583355960e18f"
182
+ "gitHead": "9585ec8bc077fc5f8a8c5946d05436b10576e145"
183
183
  }
@@ -25,7 +25,7 @@ export default function CustomerActions({ data, onChange, variant = 'compact' }:
25
25
  const onUpdateInfo = async (updates: TCustomerExpanded) => {
26
26
  try {
27
27
  setState({ loading: true });
28
- await api.put(`/api/customers/${data.id}`, updates).then((res) => res.data);
28
+ await api.put(`/api/customers/${data.id}`, updates).then((res: any) => res.data);
29
29
  Toast.success(t('common.saved'));
30
30
  onChange('update');
31
31
  } catch (err) {
@@ -117,7 +117,9 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
117
117
 
118
118
  const handleRecharge = async (currency: TPaymentCurrency) => {
119
119
  try {
120
- const response = await api.get(`/api/payment-currencies/${currency.id}/recharge-config`).then((res) => res.data);
120
+ const response = await api
121
+ .get(`/api/payment-currencies/${currency.id}/recharge-config`)
122
+ .then((res: any) => res.data);
121
123
  if (response.recharge_config && response.recharge_config.payment_url) {
122
124
  const url = new URL(response.recharge_config.payment_url);
123
125
  url.searchParams.set('redirect', window.location.href);
@@ -35,7 +35,7 @@ const fetchCycleAmount = (
35
35
  subscriptionId: string,
36
36
  params: { overdraftProtection: boolean }
37
37
  ): Promise<{ amount: string; gas: string; currency: TPaymentCurrency }> => {
38
- return api.get(`/api/subscriptions/${subscriptionId}/cycle-amount`, { params }).then((res) => res.data);
38
+ return api.get(`/api/subscriptions/${subscriptionId}/cycle-amount`, { params }).then((res: any) => res.data);
39
39
  };
40
40
 
41
41
  function safeAdd(currency: { decimal: number }, ...numbers: string[]) {
@@ -16,7 +16,7 @@ const fetchData = (params: Record<string, any> = {}): Promise<{ list: TEventExpa
16
16
  Object.keys(params).forEach((key) => {
17
17
  search.set(key, String(params[key]));
18
18
  });
19
- return api.get(`/api/events?${search.toString()}`).then((res) => res.data);
19
+ return api.get(`/api/events?${search.toString()}`).then((res: any) => res.data);
20
20
  };
21
21
 
22
22
  type SearchProps = {
@@ -30,7 +30,7 @@ const fetchUserData = (params: Record<string, any> = {}): Promise<{ list: TCusto
30
30
  }
31
31
  search.set(key, String(v));
32
32
  });
33
- return api.get(`api/customers?${search.toString()}`).then((res) => res.data);
33
+ return api.get(`api/customers?${search.toString()}`).then((res: any) => res.data);
34
34
  };
35
35
 
36
36
  const fetchSubscriptionItems = (params: Record<string, any> = {}): Promise<{ list: TCustomer[]; count: number }> => {
@@ -39,7 +39,7 @@ const fetchSubscriptionItems = (params: Record<string, any> = {}): Promise<{ lis
39
39
  const v = params[key];
40
40
  search.set(key, String(v));
41
41
  });
42
- return api.get(`api/subscription-items?${search.toString()}`).then((res) => res.data);
42
+ return api.get(`api/subscription-items?${search.toString()}`).then((res: any) => res.data);
43
43
  };
44
44
 
45
45
  type Props = {
@@ -55,7 +55,7 @@ export default function InvoiceActions({ data, variant = 'compact', onChange, mo
55
55
  try {
56
56
  setState({ loading: true });
57
57
  if (state.action === 'return-stake') {
58
- const result = await api.post(`/api/invoices/${data.id}/return-stake`).then((res) => res.data);
58
+ const result = await api.post(`/api/invoices/${data.id}/return-stake`).then((res: any) => res.data);
59
59
  if (result.success) {
60
60
  Toast.success(t('admin.invoice.returnStake.success'));
61
61
  } else {
@@ -69,11 +69,11 @@ export default function InvoiceActions({ data, variant = 'compact', onChange, mo
69
69
  invoiceId: data.id,
70
70
  },
71
71
  })
72
- .then((res) => res.data);
72
+ .then((res: any) => res.data);
73
73
  Toast.success(t('admin.invoice.retryUncollectible.success'));
74
74
  }
75
75
  if (state.action === 'void') {
76
- await api.post(`/api/invoices/${data.id}/void`).then((res) => res.data);
76
+ await api.post(`/api/invoices/${data.id}/void`).then((res: any) => res.data);
77
77
  Toast.success(t('admin.invoice.void.success'));
78
78
  }
79
79
  onChange(state.action);
@@ -52,7 +52,7 @@ const fetchData = (params: Record<string, any> = {}): Promise<{ list: TInvoiceEx
52
52
  search.set(key, String(v));
53
53
  });
54
54
 
55
- return api.get(`/api/invoices?${search.toString()}`).then((res) => res.data);
55
+ return api.get(`/api/invoices?${search.toString()}`).then((res: any) => res.data);
56
56
  };
57
57
 
58
58
  type SearchProps = {
@@ -35,12 +35,12 @@ const fetchData = (
35
35
  });
36
36
 
37
37
  if (subscriptionId) {
38
- return api.get(`/api/subscriptions/${subscriptionId}/recharge?${search.toString()}`).then((res) => res.data);
38
+ return api.get(`/api/subscriptions/${subscriptionId}/recharge?${search.toString()}`).then((res: any) => res.data);
39
39
  }
40
40
 
41
41
  if (currencyId) {
42
42
  search.set('currency_id', currencyId);
43
- return api.get(`/api/invoices/recharge?${search.toString()}`).then((res) => res.data);
43
+ return api.get(`/api/invoices/recharge?${search.toString()}`).then((res: any) => res.data);
44
44
  }
45
45
 
46
46
  return Promise.resolve({ list: [], count: 0 });
@@ -50,7 +50,7 @@ const addMeterEvent = (data: any): Promise<any> => {
50
50
  },
51
51
  ],
52
52
  })
53
- .then((res) => res.data);
53
+ .then((res: any) => res.data);
54
54
  };
55
55
 
56
56
  export default function AddUsageDialog({ open, onClose, meterId, customers, onSuccess }: AddUsageDialogProps) {
@@ -30,7 +30,7 @@ export default function PassportActions(rawProps: Props) {
30
30
  try {
31
31
  setState({ loading: true });
32
32
  // eslint-disable-next-line react/prop-types
33
- await api.delete(`/api/passports/assign/${props.data.name}`).then((res) => res.data);
33
+ await api.delete(`/api/passports/assign/${props.data.name}`).then((res: any) => res.data);
34
34
  Toast.success(t('common.saved'));
35
35
  } catch (err) {
36
36
  console.error(err);
@@ -6,7 +6,7 @@ import { useRequest } from 'ahooks';
6
6
  import { useEffect, useState } from 'react';
7
7
 
8
8
  const fetchData = (): Promise<any[]> => {
9
- return api.get('/api/passports').then((res) => res.data);
9
+ return api.get('/api/passports').then((res: any) => res.data);
10
10
  };
11
11
 
12
12
  export default function AssignPassportDialog(props: { id: string; onCancel: any }) {
@@ -116,7 +116,7 @@ export default function PaymentCurrencyAdd({
116
116
  dispatch('drawer.submitted');
117
117
  dispatch('paymentCurrency.added');
118
118
  })
119
- .catch((err) => {
119
+ .catch((err: any) => {
120
120
  setState({ loading: false });
121
121
  console.error(err);
122
122
  Toast.error(formatError(err));
@@ -132,7 +132,7 @@ export default function PaymentCurrencyEdit({
132
132
  dispatch('drawer.submitted');
133
133
  dispatch('paymentCurrency.updated');
134
134
  })
135
- .catch((err) => {
135
+ .catch((err: any) => {
136
136
  setState({ loading: false });
137
137
  console.error(err);
138
138
  Toast.error(formatError(err));
@@ -28,7 +28,7 @@ type Props = {
28
28
  };
29
29
 
30
30
  const fetchRefundData = (id: string) => {
31
- return api.get(`/api/payment-intents/${id}/refundable-amount`).then((res) => res.data);
31
+ return api.get(`/api/payment-intents/${id}/refundable-amount`).then((res: any) => res.data);
32
32
  };
33
33
 
34
34
  function RefundForm({ data, refundMaxAmount }: { data: TPaymentIntentExpanded; refundMaxAmount: string }) {
@@ -176,7 +176,7 @@ export function PaymentIntentActionsInner({ data, variant = 'compact', onChange
176
176
  });
177
177
  const [refundMaxAmount, setRefundMaxAmount] = useState('0');
178
178
  const isSlash = data.payment_details?.arcblock?.type === 'slash' && data.paymentMethod?.type === 'arcblock';
179
- const { runAsync: runRefundAmountAsync } = useRequest(
179
+ const { runAsync: runRefundAmountAsync } = useRequest<any, any[]>(
180
180
  () => {
181
181
  if (isSlash) {
182
182
  return Promise.resolve({ amount: '0' });
@@ -184,7 +184,7 @@ export function PaymentIntentActionsInner({ data, variant = 'compact', onChange
184
184
  return fetchRefundData(data.id);
185
185
  },
186
186
  {
187
- onSuccess: (res) => {
187
+ onSuccess: (res: any) => {
188
188
  const amount = formatBNStr(res?.amount, data.paymentCurrency.decimal);
189
189
  setRefundMaxAmount(amount);
190
190
  },
@@ -200,7 +200,7 @@ export function PaymentIntentActionsInner({ data, variant = 'compact', onChange
200
200
  }
201
201
  try {
202
202
  setState({ loading: true });
203
- await api.put(`/api/payment-intents/${data.id}/refund`, refund).then((res) => res.data);
203
+ await api.put(`/api/payment-intents/${data.id}/refund`, refund).then((res: any) => res.data);
204
204
  Toast.success(t('admin.paymentIntent.refundSuccess'));
205
205
  onChange('refund');
206
206
  runRefundAmountAsync();
@@ -31,7 +31,7 @@ const fetchData = (params: Record<string, any> = {}): Promise<{ list: TPaymentIn
31
31
  }
32
32
  search.set(key, String(v));
33
33
  });
34
- return api.get(`/api/payment-intents?${search.toString()}`).then((res) => res.data);
34
+ return api.get(`/api/payment-intents?${search.toString()}`).then((res: any) => res.data);
35
35
  };
36
36
 
37
37
  type SearchProps = {
@@ -28,7 +28,7 @@ export default function PaymentLinkActions({ data, variant = 'compact', onChange
28
28
  const onUpdate = async (updates: TPaymentLinkExpanded) => {
29
29
  try {
30
30
  setState({ loading: true });
31
- await api.put(`/api/payment-links/${data.id}`, updates).then((res) => res.data);
31
+ await api.put(`/api/payment-links/${data.id}`, updates).then((res: any) => res.data);
32
32
  Toast.success(t('common.saved'));
33
33
  onChange(state.action);
34
34
  } catch (err) {
@@ -41,7 +41,7 @@ export default function PaymentLinkActions({ data, variant = 'compact', onChange
41
41
  const onArchive = async () => {
42
42
  try {
43
43
  setState({ loading: true });
44
- await api.put(`/api/payment-links/${data.id}/archive`).then((res) => res.data);
44
+ await api.put(`/api/payment-links/${data.id}/archive`).then((res: any) => res.data);
45
45
  Toast.success(t('common.saved'));
46
46
  onChange(state.action);
47
47
  } catch (err) {
@@ -54,7 +54,7 @@ export default function PaymentLinkActions({ data, variant = 'compact', onChange
54
54
  const onRemove = async () => {
55
55
  try {
56
56
  setState({ loading: true });
57
- await api.delete(`/api/payment-links/${data.id}`).then((res) => res.data);
57
+ await api.delete(`/api/payment-links/${data.id}`).then((res: any) => res.data);
58
58
  Toast.success(t('common.removed'));
59
59
  onChange(state.action);
60
60
  } catch (err) {
@@ -72,7 +72,7 @@ export default function PaymentLinkActions({ data, variant = 'compact', onChange
72
72
  .put(`/api/payment-links/${data.id}`, {
73
73
  allow_promotion_codes: !data.allow_promotion_codes,
74
74
  })
75
- .then((res) => res.data);
75
+ .then((res: any) => res.data);
76
76
  Toast.success(t('common.saved'));
77
77
  onChange(state.action);
78
78
  } catch (err) {