@blocklet/payment-react 1.24.1 → 1.24.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.
- package/es/contexts/payment.js +7 -0
- package/es/history/credit/transactions-list.js +167 -138
- package/es/history/invoice/list.js +88 -19
- package/es/locales/en.js +20 -4
- package/es/locales/zh.js +20 -4
- package/es/payment/product-item.js +2 -0
- package/lib/contexts/payment.js +4 -0
- package/lib/history/credit/transactions-list.js +247 -142
- package/lib/history/invoice/list.js +113 -28
- package/lib/locales/en.js +20 -4
- package/lib/locales/zh.js +20 -4
- package/lib/payment/product-item.js +2 -0
- package/package.json +3 -3
- package/src/contexts/payment.tsx +9 -0
- package/src/history/credit/transactions-list.tsx +214 -147
- package/src/history/invoice/list.tsx +114 -28
- package/src/locales/en.tsx +18 -2
- package/src/locales/zh.tsx +18 -2
- package/src/payment/product-item.tsx +4 -0
|
@@ -83,6 +83,9 @@ const InvoiceTable = _react.default.memo(props => {
|
|
|
83
83
|
locale
|
|
84
84
|
} = (0, _context.useLocaleContext)();
|
|
85
85
|
const navigate = (0, _reactRouterDom.useNavigate)();
|
|
86
|
+
const {
|
|
87
|
+
getCurrency
|
|
88
|
+
} = (0, _payment.usePaymentContext)();
|
|
86
89
|
const [search, setSearch] = (0, _react.useState)({
|
|
87
90
|
pageSize: pageSize || 10,
|
|
88
91
|
page: 1
|
|
@@ -222,52 +225,134 @@ const InvoiceTable = _react.default.memo(props => {
|
|
|
222
225
|
}
|
|
223
226
|
}
|
|
224
227
|
}, ...(relatedSubscription ? [{
|
|
225
|
-
label: t("common.
|
|
226
|
-
name: "
|
|
228
|
+
label: t("common.purchaseItems"),
|
|
229
|
+
name: "purchase_items",
|
|
227
230
|
options: {
|
|
228
231
|
customBodyRenderLite: (_, index) => {
|
|
229
232
|
const invoice = data?.list[index];
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
233
|
+
const lines = invoice.lines || [];
|
|
234
|
+
const items = lines.map(line => {
|
|
235
|
+
const name = line.price?.product?.name || line.description;
|
|
236
|
+
if (!name) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const quantity = Number(line.quantity || 0);
|
|
240
|
+
const label = Number.isFinite(quantity) && quantity > 1 ? `${name} x${quantity}` : name;
|
|
241
|
+
const lineKey = line.id || line.price?.id || line.price?.product?.id || line.description || name;
|
|
242
|
+
return {
|
|
243
|
+
key: String(lineKey),
|
|
244
|
+
label
|
|
245
|
+
};
|
|
246
|
+
}).filter(Boolean);
|
|
247
|
+
if (items.length === 0 && invoice.subscription?.description) {
|
|
248
|
+
items.push({
|
|
249
|
+
key: `subscription-${invoice.subscription_id || invoice.id}`,
|
|
250
|
+
label: invoice.subscription.description
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const isSubscription = Boolean(invoice.subscription_id);
|
|
254
|
+
const clickableProps = isSubscription ? {
|
|
255
|
+
onClick: e => handleRelatedSubscriptionClick(e, invoice)
|
|
256
|
+
} : {};
|
|
257
|
+
if (items.length === 0) {
|
|
258
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
259
|
+
sx: {
|
|
260
|
+
color: "text.lighter"
|
|
261
|
+
},
|
|
262
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
263
|
+
sx: {
|
|
264
|
+
fontSize: 14
|
|
265
|
+
},
|
|
266
|
+
children: t("common.none")
|
|
267
|
+
})
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
271
|
+
...clickableProps,
|
|
272
|
+
sx: isSubscription ? {
|
|
234
273
|
cursor: "pointer"
|
|
235
|
-
},
|
|
236
|
-
children:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
274
|
+
} : void 0,
|
|
275
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, {
|
|
276
|
+
spacing: 0.5,
|
|
277
|
+
children: items.map(item => /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
278
|
+
sx: {
|
|
279
|
+
fontSize: 14,
|
|
280
|
+
color: isSubscription ? "text.link" : "text.primary"
|
|
281
|
+
},
|
|
282
|
+
noWrap: true,
|
|
283
|
+
children: item.label
|
|
284
|
+
}, `${invoice.id}-item-${item.key}`))
|
|
285
|
+
})
|
|
244
286
|
});
|
|
245
287
|
}
|
|
246
288
|
}
|
|
247
|
-
}
|
|
248
|
-
label: t("common.
|
|
249
|
-
name: "
|
|
289
|
+
}, {
|
|
290
|
+
label: t("common.credits"),
|
|
291
|
+
name: "credits",
|
|
250
292
|
options: {
|
|
251
|
-
customBodyRenderLite: (
|
|
293
|
+
customBodyRenderLite: (_, index) => {
|
|
252
294
|
const invoice = data?.list[index];
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
295
|
+
const lines = invoice.lines || [];
|
|
296
|
+
const creditItems = [];
|
|
297
|
+
lines.forEach(line => {
|
|
298
|
+
const lineKey = String(line.id || line.price?.id || line.price?.product?.id || line.description || invoice.id);
|
|
299
|
+
const pushCreditItem = (suffix, label) => {
|
|
300
|
+
creditItems.push({
|
|
301
|
+
key: `${lineKey}-${suffix}`,
|
|
302
|
+
label
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
const creditConfig = line.price?.metadata?.credit_config;
|
|
306
|
+
const creditAmount = Number(creditConfig?.credit_amount || 0);
|
|
307
|
+
if (creditAmount > 0) {
|
|
308
|
+
const quantity = Number(line.quantity || 0);
|
|
309
|
+
const totalAmount = creditAmount * (Number.isFinite(quantity) && quantity > 0 ? quantity : 1);
|
|
310
|
+
const currencySymbol = getCurrency(creditConfig?.currency_id)?.symbol || creditConfig?.currency_id || "Credits";
|
|
311
|
+
pushCreditItem("amount", `+${(0, _util.formatCreditAmount)(String(totalAmount), currencySymbol)}`);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const scheduleConfig = creditConfig?.schedule;
|
|
315
|
+
const scheduledAmount = Number(scheduleConfig?.amount_per_grant || 0);
|
|
316
|
+
if (scheduleConfig?.enabled && scheduleConfig?.delivery_mode === "schedule" && scheduledAmount > 0) {
|
|
317
|
+
const quantity = Number(line.quantity || 0);
|
|
318
|
+
const totalAmount = scheduledAmount * (Number.isFinite(quantity) && quantity > 0 ? quantity : 1);
|
|
319
|
+
const currencySymbol = getCurrency(creditConfig?.currency_id)?.symbol || creditConfig?.currency_id || "Credits";
|
|
320
|
+
pushCreditItem("schedule", `+${(0, _util.formatCreditAmount)(String(totalAmount), currencySymbol)}`);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const creditInfo = line.price?.credit;
|
|
324
|
+
const creditInfoAmount = Number(creditInfo?.amount || 0);
|
|
325
|
+
if (creditInfoAmount > 0) {
|
|
326
|
+
const currencySymbol = creditInfo.currency?.symbol || "Credits";
|
|
327
|
+
pushCreditItem("credit", `+${(0, _util.formatCreditAmount)(String(creditInfoAmount), currencySymbol)}`);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
if (creditItems.length === 0) {
|
|
331
|
+
return "-";
|
|
332
|
+
}
|
|
333
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, {
|
|
334
|
+
spacing: 0.5,
|
|
335
|
+
children: creditItems.map(creditItem => /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
336
|
+
sx: {
|
|
337
|
+
fontSize: 14,
|
|
338
|
+
color: "success.main"
|
|
339
|
+
},
|
|
340
|
+
noWrap: true,
|
|
341
|
+
children: creditItem.label
|
|
342
|
+
}, `${invoice.id}-credit-${creditItem.key}`))
|
|
257
343
|
});
|
|
258
344
|
}
|
|
259
345
|
}
|
|
260
|
-
}, {
|
|
261
|
-
label: t("common.
|
|
262
|
-
name: "",
|
|
346
|
+
}] : []), {
|
|
347
|
+
label: t("common.updatedAt"),
|
|
348
|
+
name: "name",
|
|
263
349
|
options: {
|
|
264
|
-
sort: false,
|
|
265
350
|
customBodyRenderLite: (val, index) => {
|
|
266
351
|
const invoice = data?.list[index];
|
|
267
352
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
268
353
|
onClick: e => handleLinkClick(e, invoice),
|
|
269
354
|
sx: linkStyle,
|
|
270
|
-
children: (0, _util.
|
|
355
|
+
children: (0, _util.formatToDate)(invoice.created_at, locale, relatedSubscription ? "YYYY-MM-DD HH:mm" : "YYYY-MM-DD HH:mm:ss")
|
|
271
356
|
});
|
|
272
357
|
}
|
|
273
358
|
}
|
package/lib/locales/en.js
CHANGED
|
@@ -72,14 +72,24 @@ module.exports = (0, _flat.default)({
|
|
|
72
72
|
remainingBalance: "Remaining Balance",
|
|
73
73
|
credits: "credits",
|
|
74
74
|
ofCredits: "of credits",
|
|
75
|
+
creditActivity: {
|
|
76
|
+
consumption: "Credit Consumed",
|
|
77
|
+
paidGrant: "Credit Top-up",
|
|
78
|
+
paidAmount: "Paid {amount}",
|
|
79
|
+
promotionalGrant: "Bonus",
|
|
80
|
+
resetGrant: "Credit Reset",
|
|
81
|
+
repayment: "Repayment"
|
|
82
|
+
},
|
|
75
83
|
transferStatus: "Transaction Status",
|
|
76
84
|
sourceData: "Source Data",
|
|
77
85
|
viewGrant: "View Grant",
|
|
78
|
-
viewSubscription: "
|
|
86
|
+
viewSubscription: "Subscription Detail",
|
|
79
87
|
view: "View",
|
|
80
88
|
meterEvent: "Meter Event",
|
|
81
89
|
source: "Source",
|
|
82
90
|
viewDetail: "View Detail",
|
|
91
|
+
viewTransactionDetail: "Transaction Detail",
|
|
92
|
+
viewConsumptionDetail: "Consumption Detail",
|
|
83
93
|
customer: "Customer",
|
|
84
94
|
currency: "Currency",
|
|
85
95
|
custom: "Custom",
|
|
@@ -126,6 +136,8 @@ module.exports = (0, _flat.default)({
|
|
|
126
136
|
slashStakeAmount: "Slash Stake Amount",
|
|
127
137
|
know: "I know",
|
|
128
138
|
relatedSubscription: "Subscription",
|
|
139
|
+
subscriptionOrCredit: "Subscription / Credit",
|
|
140
|
+
purchaseItems: "Purchase Items",
|
|
129
141
|
connect: {
|
|
130
142
|
defaultScan: "Use the following methods to complete this action",
|
|
131
143
|
scan: "Use the following methods to complete this {action}",
|
|
@@ -133,8 +145,10 @@ module.exports = (0, _flat.default)({
|
|
|
133
145
|
cancel: "Cancel"
|
|
134
146
|
},
|
|
135
147
|
paymentMethod: "Payment Method",
|
|
136
|
-
viewInvoice: "
|
|
137
|
-
submit: "Submit"
|
|
148
|
+
viewInvoice: "Invoice Detail",
|
|
149
|
+
submit: "Submit",
|
|
150
|
+
expired: "Expired",
|
|
151
|
+
consumed: "Consumed"
|
|
138
152
|
},
|
|
139
153
|
payment: {
|
|
140
154
|
checkout: {
|
|
@@ -495,7 +509,9 @@ module.exports = (0, _flat.default)({
|
|
|
495
509
|
amount: "Amount",
|
|
496
510
|
paymentConfirmTitle: "Payment Confirmation",
|
|
497
511
|
paymentConfirmDescription: "After completing this payment, the payment method you use will be automatically set as the default for this subscription. Additionally, we will retry payment for any other unpaid invoices associated with this subscription.",
|
|
498
|
-
continue: "Continue"
|
|
512
|
+
continue: "Continue",
|
|
513
|
+
credit: "Credit",
|
|
514
|
+
creditRefresh: "Refresh every {interval} {unit}"
|
|
499
515
|
},
|
|
500
516
|
overduePayment: {
|
|
501
517
|
setupPaymentDescription: "Use your saved card or add a new one to complete payment via Stripe.",
|
package/lib/locales/zh.js
CHANGED
|
@@ -72,14 +72,24 @@ module.exports = (0, _flat.default)({
|
|
|
72
72
|
remainingBalance: "\u5269\u4F59\u4F59\u989D",
|
|
73
73
|
credits: "\u989D\u5EA6",
|
|
74
74
|
ofCredits: "\u989D\u5EA6",
|
|
75
|
+
creditActivity: {
|
|
76
|
+
consumption: "\u989D\u5EA6\u6D88\u8017",
|
|
77
|
+
paidGrant: "\u989D\u5EA6\u5145\u503C",
|
|
78
|
+
paidAmount: "\u652F\u4ED8 {amount}",
|
|
79
|
+
promotionalGrant: "\u8D60\u9001",
|
|
80
|
+
resetGrant: "\u989D\u5EA6\u91CD\u7F6E",
|
|
81
|
+
repayment: "\u652F\u4ED8\u6B20\u8D39"
|
|
82
|
+
},
|
|
75
83
|
transferStatus: "\u4EA4\u6613\u72B6\u6001",
|
|
76
84
|
sourceData: "\u6E90\u6570\u636E",
|
|
77
85
|
viewGrant: "\u67E5\u770B\u989D\u5EA6",
|
|
78
|
-
viewSubscription: "\
|
|
86
|
+
viewSubscription: "\u8BA2\u9605\u8BE6\u60C5",
|
|
79
87
|
view: "\u67E5\u770B",
|
|
80
88
|
meterEvent: "\u8BA1\u91CF\u4E8B\u4EF6",
|
|
81
89
|
source: "\u6765\u6E90",
|
|
82
90
|
viewDetail: "\u67E5\u770B\u8BE6\u60C5",
|
|
91
|
+
viewTransactionDetail: "\u4EA4\u6613\u8BE6\u60C5",
|
|
92
|
+
viewConsumptionDetail: "\u6D88\u8D39\u8BE6\u60C5",
|
|
83
93
|
customer: "\u5BA2\u6237",
|
|
84
94
|
currency: "\u5E01\u79CD",
|
|
85
95
|
custom: "\u81EA\u5B9A\u4E49",
|
|
@@ -126,6 +136,8 @@ module.exports = (0, _flat.default)({
|
|
|
126
136
|
slashStakeAmount: "\u7F5A\u6CA1\u91D1\u989D",
|
|
127
137
|
know: "\u6211\u77E5\u9053\u4E86",
|
|
128
138
|
relatedSubscription: "\u8BA2\u9605",
|
|
139
|
+
subscriptionOrCredit: "\u8BA2\u9605 / \u989D\u5EA6",
|
|
140
|
+
purchaseItems: "\u8D2D\u4E70\u9879",
|
|
129
141
|
connect: {
|
|
130
142
|
defaultScan: "\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u5B8C\u6210\u672C\u6B21\u64CD\u4F5C",
|
|
131
143
|
scan: "\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u5B8C\u6210\u672C\u6B21{action}",
|
|
@@ -133,8 +145,10 @@ module.exports = (0, _flat.default)({
|
|
|
133
145
|
cancel: "\u53D6\u6D88"
|
|
134
146
|
},
|
|
135
147
|
paymentMethod: "\u652F\u4ED8\u65B9\u5F0F",
|
|
136
|
-
viewInvoice: "\
|
|
137
|
-
submit: "\u63D0\u4EA4"
|
|
148
|
+
viewInvoice: "\u8D26\u5355\u8BE6\u60C5",
|
|
149
|
+
submit: "\u63D0\u4EA4",
|
|
150
|
+
expired: "\u5DF2\u8FC7\u671F",
|
|
151
|
+
consumed: "\u5DF2\u6D88\u8D39"
|
|
138
152
|
},
|
|
139
153
|
payment: {
|
|
140
154
|
checkout: {
|
|
@@ -497,7 +511,9 @@ module.exports = (0, _flat.default)({
|
|
|
497
511
|
payBatch: "\u652F\u4ED8\u6B20\u6B3E",
|
|
498
512
|
paymentConfirmTitle: "\u652F\u4ED8\u786E\u8BA4",
|
|
499
513
|
paymentConfirmDescription: "\u5B8C\u6210\u672C\u6B21\u652F\u4ED8\u540E\uFF0C\u60A8\u4F7F\u7528\u7684\u652F\u4ED8\u65B9\u5F0F\u5C06\u81EA\u52A8\u8BBE\u7F6E\u4E3A\u8BE5\u8BA2\u9605\u7684\u9ED8\u8BA4\u652F\u4ED8\u65B9\u5F0F\u3002\u6B64\u5916\uFF0C\u6211\u4EEC\u8FD8\u5C06\u5BF9\u8BE5\u8BA2\u9605\u7684\u5176\u4ED6\u6B20\u8D39\u8D26\u5355\u8FDB\u884C\u91CD\u8BD5\u6536\u8D39\u3002",
|
|
500
|
-
continue: "\u7EE7\u7EED"
|
|
514
|
+
continue: "\u7EE7\u7EED",
|
|
515
|
+
credit: "\u989D\u5EA6",
|
|
516
|
+
creditRefresh: "\u6BCF{interval}{unit}\u5237\u65B0"
|
|
501
517
|
},
|
|
502
518
|
payment: {
|
|
503
519
|
empty: "\u6CA1\u6709\u652F\u4ED8\u8BB0\u5F55",
|
|
@@ -113,7 +113,9 @@ function ProductItem({
|
|
|
113
113
|
if (!isCreditProduct || !pendingAmount) return null;
|
|
114
114
|
const pendingAmountBN = new _util.BN(pendingAmount || "0");
|
|
115
115
|
if (!pendingAmountBN.gt(new _util.BN(0))) return null;
|
|
116
|
+
if (!creditAmount || creditAmount <= 0) return null;
|
|
116
117
|
const creditAmountBN = (0, _util.fromTokenToUnit)(creditAmount, creditCurrency?.decimal || 2);
|
|
118
|
+
if (!creditAmountBN || creditAmountBN.isZero()) return null;
|
|
117
119
|
return Math.ceil(pendingAmountBN.mul(new _util.BN(100)).div(creditAmountBN).toNumber() / 100);
|
|
118
120
|
}, [isCreditProduct, pendingAmount, creditAmount, creditCurrency?.decimal]);
|
|
119
121
|
const initialQuantity = (0, _react.useMemo)(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.3",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@babel/core": "^7.27.4",
|
|
97
97
|
"@babel/preset-env": "^7.27.2",
|
|
98
98
|
"@babel/preset-react": "^7.27.1",
|
|
99
|
-
"@blocklet/payment-types": "1.24.
|
|
99
|
+
"@blocklet/payment-types": "1.24.3",
|
|
100
100
|
"@storybook/addon-essentials": "^7.6.20",
|
|
101
101
|
"@storybook/addon-interactions": "^7.6.20",
|
|
102
102
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -127,5 +127,5 @@
|
|
|
127
127
|
"vite-plugin-babel": "^1.3.1",
|
|
128
128
|
"vite-plugin-node-polyfills": "^0.23.0"
|
|
129
129
|
},
|
|
130
|
-
"gitHead": "
|
|
130
|
+
"gitHead": "6f2a963875ed4aced1db11f1c3a044c7f5deedd6"
|
|
131
131
|
}
|
package/src/contexts/payment.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { createContext, useContext, useEffect, useState } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import axios from 'axios';
|
|
9
9
|
import { joinURL } from 'ufo';
|
|
10
|
+
import useBus from 'use-bus';
|
|
10
11
|
import api from '../libs/api';
|
|
11
12
|
import { getPrefix, PAYMENT_KIT_DID } from '../libs/util';
|
|
12
13
|
import { CachedRequest } from '../libs/cached-request';
|
|
@@ -178,6 +179,14 @@ function PaymentProvider({
|
|
|
178
179
|
refreshDeps: [livemode],
|
|
179
180
|
});
|
|
180
181
|
|
|
182
|
+
// Listen for settings changes and force refresh
|
|
183
|
+
useBus(
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
['paymentMethod.created', 'paymentMethod.updated', 'paymentCurrency.added', 'paymentCurrency.updated'],
|
|
186
|
+
() => run(true),
|
|
187
|
+
[run]
|
|
188
|
+
);
|
|
189
|
+
|
|
181
190
|
useEffect(() => {
|
|
182
191
|
const didSpace = session?.user?.didSpace as
|
|
183
192
|
| {
|