@blocklet/payment-react 1.20.10 → 1.20.12
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/components/promotion-code.d.ts +19 -0
- package/es/components/promotion-code.js +153 -0
- package/es/contexts/payment.d.ts +8 -0
- package/es/contexts/payment.js +10 -1
- package/es/index.d.ts +2 -1
- package/es/index.js +3 -1
- package/es/libs/util.d.ts +5 -1
- package/es/libs/util.js +23 -0
- package/es/locales/en.js +40 -15
- package/es/locales/zh.js +29 -0
- package/es/payment/form/index.js +7 -1
- package/es/payment/index.js +19 -0
- package/es/payment/product-item.js +32 -3
- package/es/payment/summary.d.ts +5 -2
- package/es/payment/summary.js +193 -16
- package/lib/components/promotion-code.d.ts +19 -0
- package/lib/components/promotion-code.js +155 -0
- package/lib/contexts/payment.d.ts +8 -0
- package/lib/contexts/payment.js +13 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +8 -0
- package/lib/libs/util.d.ts +5 -1
- package/lib/libs/util.js +29 -0
- package/lib/locales/en.js +40 -15
- package/lib/locales/zh.js +29 -0
- package/lib/payment/form/index.js +8 -1
- package/lib/payment/index.js +23 -0
- package/lib/payment/product-item.js +46 -0
- package/lib/payment/summary.d.ts +5 -2
- package/lib/payment/summary.js +153 -11
- package/package.json +9 -9
- package/src/components/promotion-code.tsx +184 -0
- package/src/contexts/payment.tsx +15 -0
- package/src/index.ts +2 -0
- package/src/libs/util.ts +35 -0
- package/src/locales/en.tsx +40 -15
- package/src/locales/zh.tsx +29 -0
- package/src/payment/form/index.tsx +10 -1
- package/src/payment/index.tsx +22 -0
- package/src/payment/product-item.tsx +37 -2
- package/src/payment/summary.tsx +201 -16
package/lib/locales/en.js
CHANGED
|
@@ -109,8 +109,8 @@ module.exports = (0, _flat.default)({
|
|
|
109
109
|
know: "I know",
|
|
110
110
|
relatedSubscription: "Subscription",
|
|
111
111
|
connect: {
|
|
112
|
-
defaultScan: "Use following methods to complete this action",
|
|
113
|
-
scan: "Use following methods to complete this {action}",
|
|
112
|
+
defaultScan: "Use the following methods to complete this action",
|
|
113
|
+
scan: "Use the following methods to complete this {action}",
|
|
114
114
|
confirm: "Confirm",
|
|
115
115
|
cancel: "Cancel"
|
|
116
116
|
},
|
|
@@ -160,14 +160,14 @@ module.exports = (0, _flat.default)({
|
|
|
160
160
|
},
|
|
161
161
|
inactive: "Donation feature is not enabled",
|
|
162
162
|
enable: "Enable Donation",
|
|
163
|
-
enableSuccess: "
|
|
164
|
-
configPrompt: "
|
|
163
|
+
enableSuccess: "Successfully enabled",
|
|
164
|
+
configPrompt: "The donation feature is enabled. You can configure donation options in Payment Kit",
|
|
165
165
|
configNow: "Configure Now",
|
|
166
166
|
later: "Configure Later",
|
|
167
167
|
configTip: "Configure donation settings in Payment Kit"
|
|
168
168
|
},
|
|
169
169
|
cardPay: "{action} with bank card",
|
|
170
|
-
empty: "
|
|
170
|
+
empty: "Nothing to pay",
|
|
171
171
|
per: "per",
|
|
172
172
|
pay: "Pay {payee}",
|
|
173
173
|
try1: "Try {name}",
|
|
@@ -181,8 +181,8 @@ module.exports = (0, _flat.default)({
|
|
|
181
181
|
least: "continue with at least",
|
|
182
182
|
completed: {
|
|
183
183
|
payment: "Thanks for your purchase",
|
|
184
|
-
subscription: "Thanks for
|
|
185
|
-
setup: "Thanks for
|
|
184
|
+
subscription: "Thanks for subscribing",
|
|
185
|
+
setup: "Thanks for subscribing",
|
|
186
186
|
donate: "Thanks for your tip",
|
|
187
187
|
tip: "A payment to {payee} has been completed. You can view the details of this payment in your account."
|
|
188
188
|
},
|
|
@@ -191,7 +191,7 @@ module.exports = (0, _flat.default)({
|
|
|
191
191
|
progress: "Progress {progress}%",
|
|
192
192
|
delivered: "Installation completed",
|
|
193
193
|
failed: "Processing failed",
|
|
194
|
-
failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience
|
|
194
|
+
failedMsg: "An exception occurred during installation. We will automatically process a refund for you. We apologize for the inconvenience. Thank you for your understanding!"
|
|
195
195
|
},
|
|
196
196
|
confirm: {
|
|
197
197
|
withStake: "By confirming, you allow {payee} to charge your account for future payments and, if necessary, slash your stake. You can cancel your subscription or withdraw your stake at any time.",
|
|
@@ -240,14 +240,39 @@ module.exports = (0, _flat.default)({
|
|
|
240
240
|
},
|
|
241
241
|
emptyItems: {
|
|
242
242
|
title: "Nothing to show here",
|
|
243
|
-
description: "
|
|
243
|
+
description: "It seems this checkout session is not configured properly"
|
|
244
244
|
},
|
|
245
245
|
orderSummary: "Order Summary",
|
|
246
246
|
paymentDetails: "Payment Details",
|
|
247
247
|
productListTotal: "Includes {total} items",
|
|
248
|
+
promotion: {
|
|
249
|
+
add_code: "Add promotion code",
|
|
250
|
+
enter_code: "Enter promotion code",
|
|
251
|
+
placeholder: "Enter code",
|
|
252
|
+
apply: "Apply",
|
|
253
|
+
applied: "Applied promotion codes",
|
|
254
|
+
dialog: {
|
|
255
|
+
title: "Add promotion code"
|
|
256
|
+
},
|
|
257
|
+
error: {
|
|
258
|
+
unknown: "Unknown error",
|
|
259
|
+
network: "Network error occurred",
|
|
260
|
+
removal: "Failed to remove code"
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
coupon: {
|
|
264
|
+
noDiscount: "No discount",
|
|
265
|
+
percentage: "{percent}% off",
|
|
266
|
+
fixedAmount: "{amount} {symbol} off",
|
|
267
|
+
terms: {
|
|
268
|
+
forever: "{couponOff} forever",
|
|
269
|
+
once: "{couponOff} once",
|
|
270
|
+
repeating: "{couponOff} for {months} month{months > 1 ? 's' : ''}"
|
|
271
|
+
}
|
|
272
|
+
},
|
|
248
273
|
connectModal: {
|
|
249
274
|
title: "{action}",
|
|
250
|
-
scan: "Use following methods to complete this payment",
|
|
275
|
+
scan: "Use the following methods to complete this payment",
|
|
251
276
|
confirm: "Confirm",
|
|
252
277
|
cancel: "Cancel"
|
|
253
278
|
},
|
|
@@ -330,7 +355,7 @@ module.exports = (0, _flat.default)({
|
|
|
330
355
|
summary: "Summary",
|
|
331
356
|
products: "Products",
|
|
332
357
|
update: "Update Information",
|
|
333
|
-
empty: "
|
|
358
|
+
empty: "It seems you do not have any subscriptions or payments here",
|
|
334
359
|
cancel: {
|
|
335
360
|
button: "Unsubscribe",
|
|
336
361
|
title: "Cancel your subscription",
|
|
@@ -341,7 +366,7 @@ module.exports = (0, _flat.default)({
|
|
|
341
366
|
tip: "We would love your feedback, it will help us improve our service",
|
|
342
367
|
too_expensive: "The service is too expensive",
|
|
343
368
|
missing_features: "Features are missing for this service",
|
|
344
|
-
switched_service: "I have switched to alternative service",
|
|
369
|
+
switched_service: "I have switched to an alternative service",
|
|
345
370
|
unused: "I no longer use this service",
|
|
346
371
|
customer_service: "The customer service is poor",
|
|
347
372
|
too_complex: "The service is too complex to use",
|
|
@@ -352,7 +377,7 @@ module.exports = (0, _flat.default)({
|
|
|
352
377
|
pastDue: {
|
|
353
378
|
button: "Pay",
|
|
354
379
|
invoices: "Past Due Invoices",
|
|
355
|
-
warning: "Past due invoices need to be paid immediately, otherwise you
|
|
380
|
+
warning: "Past due invoices need to be paid immediately, otherwise you cannot make new purchases anymore.",
|
|
356
381
|
alert: {
|
|
357
382
|
title: "You have unpaid invoices",
|
|
358
383
|
customMessage: "Please pay immediately, otherwise new purchases or subscriptions will be prohibited.",
|
|
@@ -405,7 +430,7 @@ module.exports = (0, _flat.default)({
|
|
|
405
430
|
amountApplied: "Applied Credit",
|
|
406
431
|
pay: "Pay this invoice",
|
|
407
432
|
paySuccess: "You have successfully paid the invoice",
|
|
408
|
-
payError: "Failed to
|
|
433
|
+
payError: "Failed to pay the invoice",
|
|
409
434
|
renew: "Renew the subscription",
|
|
410
435
|
renewSuccess: "You have successfully renewed the subscription",
|
|
411
436
|
renewError: "Failed to renew the subscription",
|
|
@@ -433,7 +458,7 @@ module.exports = (0, _flat.default)({
|
|
|
433
458
|
viewAll: "View all",
|
|
434
459
|
empty: "There are no subscriptions here",
|
|
435
460
|
changePayment: "Change payment method",
|
|
436
|
-
trialLeft: "
|
|
461
|
+
trialLeft: "Trial Left",
|
|
437
462
|
owner: "Subscription Owner"
|
|
438
463
|
},
|
|
439
464
|
overdue: {
|
package/lib/locales/zh.js
CHANGED
|
@@ -233,6 +233,35 @@ module.exports = (0, _flat.default)({
|
|
|
233
233
|
add: "\u6DFB\u52A0\u5230\u8BA2\u5355",
|
|
234
234
|
remove: "\u4ECE\u8BA2\u5355\u79FB\u9664"
|
|
235
235
|
},
|
|
236
|
+
promotion: {
|
|
237
|
+
add_code: "\u6DFB\u52A0\u4FC3\u9500\u7801",
|
|
238
|
+
enter_code: "\u8F93\u5165\u4FC3\u9500\u7801",
|
|
239
|
+
apply: "\u5E94\u7528",
|
|
240
|
+
applied: "\u5DF2\u5E94\u7528\u7684\u4FC3\u9500\u7801",
|
|
241
|
+
placeholder: "\u8F93\u5165\u4FC3\u9500\u7801",
|
|
242
|
+
duration_once: "1\u6B21\u4F18\u60E0 {amount} {symbol}",
|
|
243
|
+
duration_repeating: "{months}\u4E2A\u6708\u4F18\u60E0 {amount} {symbol}",
|
|
244
|
+
duration_forever: "\u6C38\u4E45\u4F18\u60E0 {amount} {symbol}",
|
|
245
|
+
dialog: {
|
|
246
|
+
title: "\u6DFB\u52A0\u4FC3\u9500\u7801"
|
|
247
|
+
},
|
|
248
|
+
error: {
|
|
249
|
+
invalid: "\u65E0\u6548\u7684\u4FC3\u9500\u7801",
|
|
250
|
+
expired: "\u4FC3\u9500\u7801\u5DF2\u8FC7\u671F",
|
|
251
|
+
used: "\u4FC3\u9500\u7801\u5DF2\u88AB\u4F7F\u7528",
|
|
252
|
+
not_applicable: "\u4FC3\u9500\u7801\u4E0D\u9002\u7528\u4E8E\u6B64\u8BA2\u5355"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
coupon: {
|
|
256
|
+
noDiscount: "\u65E0\u4F18\u60E0",
|
|
257
|
+
percentage: "{percent}%",
|
|
258
|
+
fixedAmount: "{amount} {symbol}",
|
|
259
|
+
terms: {
|
|
260
|
+
forever: "\u6C38\u4E45\u4EAB {couponOff} \u6298\u6263",
|
|
261
|
+
once: "\u5355\u6B21\u4EAB {couponOff} \u6298\u6263",
|
|
262
|
+
repeating: "{months} \u4E2A\u6708\u5185\u4EAB {couponOff} \u6298\u6263"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
236
265
|
credit: {
|
|
237
266
|
oneTimeInfo: "\u4ED8\u6B3E\u5B8C\u6210\u540E\u60A8\u5C06\u83B7\u5F97 {amount} {symbol} \u989D\u5EA6",
|
|
238
267
|
recurringInfo: "\u60A8\u5C06{period}\u83B7\u5F97 {amount} {symbol} \u989D\u5EA6",
|
|
@@ -122,7 +122,8 @@ function PaymentForm({
|
|
|
122
122
|
const {
|
|
123
123
|
session,
|
|
124
124
|
connect,
|
|
125
|
-
payable
|
|
125
|
+
payable,
|
|
126
|
+
setPaymentState
|
|
126
127
|
} = (0, _payment.usePaymentContext)();
|
|
127
128
|
const subscription = (0, _subscription.useSubscription)("events");
|
|
128
129
|
const formErrorPosition = "bottom";
|
|
@@ -174,6 +175,12 @@ function PaymentForm({
|
|
|
174
175
|
subscription.on("checkout.session.completed", onCheckoutComplete);
|
|
175
176
|
}
|
|
176
177
|
}, [subscription]);
|
|
178
|
+
(0, _react.useEffect)(() => {
|
|
179
|
+
setPaymentState({
|
|
180
|
+
paying: state.submitting || state.paying,
|
|
181
|
+
stripePaying: state.stripePaying
|
|
182
|
+
});
|
|
183
|
+
}, [state.submitting, state.paying, state.stripePaying]);
|
|
177
184
|
const mergeUserInfo = (customerInfo, userInfo) => {
|
|
178
185
|
return {
|
|
179
186
|
...(userInfo || {}),
|
package/lib/payment/index.js
CHANGED
|
@@ -149,6 +149,13 @@ function PaymentInner({
|
|
|
149
149
|
if (onChange) {
|
|
150
150
|
onChange(methods.getValues());
|
|
151
151
|
}
|
|
152
|
+
if (state.checkoutSession?.discounts?.length) {
|
|
153
|
+
_api.default.post(`/api/checkout-sessions/${state.checkoutSession.id}/recalculate-promotion`, {
|
|
154
|
+
currency_id: currencyId
|
|
155
|
+
}).then(() => {
|
|
156
|
+
onPromotionUpdate();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
152
159
|
}, [currencyId]);
|
|
153
160
|
const onUpsell = async (from, to) => {
|
|
154
161
|
try {
|
|
@@ -244,6 +251,19 @@ function PaymentInner({
|
|
|
244
251
|
_Toast.default.error((0, _util2.formatError)(err));
|
|
245
252
|
}
|
|
246
253
|
};
|
|
254
|
+
const onPromotionUpdate = async () => {
|
|
255
|
+
try {
|
|
256
|
+
const {
|
|
257
|
+
data
|
|
258
|
+
} = await _api.default.get(`/api/checkout-sessions/retrieve/${state.checkoutSession.id}`);
|
|
259
|
+
setState({
|
|
260
|
+
checkoutSession: data.checkoutSession
|
|
261
|
+
});
|
|
262
|
+
} catch (err) {
|
|
263
|
+
console.error(err);
|
|
264
|
+
_Toast.default.error((0, _util2.formatError)(err));
|
|
265
|
+
}
|
|
266
|
+
};
|
|
247
267
|
const handlePaid = result => {
|
|
248
268
|
setState({
|
|
249
269
|
checkoutSession: result.checkoutSession
|
|
@@ -292,6 +312,9 @@ function PaymentInner({
|
|
|
292
312
|
donationSettings: paymentLink?.donation_settings,
|
|
293
313
|
action,
|
|
294
314
|
completed,
|
|
315
|
+
checkoutSession: state.checkoutSession,
|
|
316
|
+
onPromotionUpdate,
|
|
317
|
+
paymentMethods,
|
|
295
318
|
showFeatures
|
|
296
319
|
}), mode === "standalone" && !isMobile && /* @__PURE__ */(0, _jsxRuntime.jsx)(_footer.default, {
|
|
297
320
|
className: "cko-footer",
|
|
@@ -183,6 +183,52 @@ function ProductItem({
|
|
|
183
183
|
children: pricing.secondary
|
|
184
184
|
})]
|
|
185
185
|
})]
|
|
186
|
+
}), item.discount_amounts && item.discount_amounts.length > 0 && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, {
|
|
187
|
+
direction: "row",
|
|
188
|
+
spacing: 1,
|
|
189
|
+
sx: {
|
|
190
|
+
mt: 1,
|
|
191
|
+
alignItems: "center"
|
|
192
|
+
},
|
|
193
|
+
children: item.discount_amounts.map(discountAmount => /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Chip, {
|
|
194
|
+
icon: /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.LocalOffer, {
|
|
195
|
+
sx: {
|
|
196
|
+
fontSize: "0.8rem !important"
|
|
197
|
+
}
|
|
198
|
+
}),
|
|
199
|
+
label: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
200
|
+
sx: {
|
|
201
|
+
display: "flex",
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
gap: 0.5
|
|
204
|
+
},
|
|
205
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
206
|
+
component: "span",
|
|
207
|
+
sx: {
|
|
208
|
+
fontSize: "0.75rem",
|
|
209
|
+
fontWeight: "medium"
|
|
210
|
+
},
|
|
211
|
+
children: discountAmount.promotion_code?.code || "DISCOUNT"
|
|
212
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
|
|
213
|
+
component: "span",
|
|
214
|
+
sx: {
|
|
215
|
+
fontSize: "0.75rem"
|
|
216
|
+
},
|
|
217
|
+
children: ["(-", (0, _util.formatAmount)(discountAmount.amount || "0", currency.decimal), " ", currency.symbol, ")"]
|
|
218
|
+
})]
|
|
219
|
+
}),
|
|
220
|
+
size: "small",
|
|
221
|
+
variant: "filled",
|
|
222
|
+
sx: {
|
|
223
|
+
height: 20,
|
|
224
|
+
"& .MuiChip-icon": {
|
|
225
|
+
color: "warning.main"
|
|
226
|
+
},
|
|
227
|
+
"& .MuiChip-label": {
|
|
228
|
+
px: 1
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}, discountAmount.promotion_code))
|
|
186
232
|
}), showFeatures && features.length > 0 && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
187
233
|
sx: {
|
|
188
234
|
display: "flex",
|
package/lib/payment/summary.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DonationSettings, TLineItemExpanded, TPaymentCurrency } from '@blocklet/payment-types';
|
|
1
|
+
import type { DonationSettings, TLineItemExpanded, TPaymentCurrency, TCheckoutSession, TPaymentMethodExpanded } from '@blocklet/payment-types';
|
|
2
2
|
type Props = {
|
|
3
3
|
items: TLineItemExpanded[];
|
|
4
4
|
currency: TPaymentCurrency;
|
|
@@ -17,7 +17,10 @@ type Props = {
|
|
|
17
17
|
donationSettings?: DonationSettings;
|
|
18
18
|
action?: string;
|
|
19
19
|
completed?: boolean;
|
|
20
|
+
checkoutSession?: TCheckoutSession;
|
|
21
|
+
onPromotionUpdate?: () => void;
|
|
22
|
+
paymentMethods?: TPaymentMethodExpanded[];
|
|
20
23
|
showFeatures?: boolean;
|
|
21
24
|
};
|
|
22
|
-
export default function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onQuantityChange, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, completed, showFeatures, ...rest }: Props): import("react").JSX.Element;
|
|
25
|
+
export default function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onQuantityChange, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, completed, checkoutSession, paymentMethods, onPromotionUpdate, showFeatures, ...rest }: Props): import("react").JSX.Element;
|
|
23
26
|
export {};
|
package/lib/payment/summary.js
CHANGED
|
@@ -24,6 +24,7 @@ var _livemode = _interopRequireDefault(require("../components/livemode"));
|
|
|
24
24
|
var _payment = require("../contexts/payment");
|
|
25
25
|
var _mobile = require("../hooks/mobile");
|
|
26
26
|
var _loadingButton = _interopRequireDefault(require("../components/loading-button"));
|
|
27
|
+
var _promotionCode = _interopRequireDefault(require("../components/promotion-code"));
|
|
27
28
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
28
29
|
const ExpandMore = (0, _styles.styled)(props => {
|
|
29
30
|
const {
|
|
@@ -101,6 +102,9 @@ function PaymentSummary({
|
|
|
101
102
|
action = "",
|
|
102
103
|
trialEnd = 0,
|
|
103
104
|
completed = false,
|
|
105
|
+
checkoutSession = void 0,
|
|
106
|
+
paymentMethods = [],
|
|
107
|
+
onPromotionUpdate = _noop.default,
|
|
104
108
|
showFeatures = false,
|
|
105
109
|
...rest
|
|
106
110
|
}) {
|
|
@@ -111,7 +115,10 @@ function PaymentSummary({
|
|
|
111
115
|
const {
|
|
112
116
|
isMobile
|
|
113
117
|
} = (0, _mobile.useMobile)();
|
|
114
|
-
const
|
|
118
|
+
const {
|
|
119
|
+
paymentState,
|
|
120
|
+
...settings
|
|
121
|
+
} = (0, _payment.usePaymentContext)();
|
|
115
122
|
const [state, setState] = (0, _ahooks.useSetState)({
|
|
116
123
|
loading: false,
|
|
117
124
|
shake: false,
|
|
@@ -121,12 +128,40 @@ function PaymentSummary({
|
|
|
121
128
|
data,
|
|
122
129
|
runAsync
|
|
123
130
|
} = (0, _ahooks.useRequest)(() => checkoutSessionId ? fetchCrossSell(checkoutSessionId) : Promise.resolve(null));
|
|
124
|
-
const
|
|
131
|
+
const sessionDiscounts = checkoutSession?.discounts || [];
|
|
132
|
+
const allowPromotionCodes = !!checkoutSession?.allow_promotion_codes;
|
|
133
|
+
const hasDiscounts = sessionDiscounts?.length > 0;
|
|
134
|
+
const discountCurrency = paymentMethods && checkoutSession ? (0, _util2.findCurrency)(paymentMethods, hasDiscounts ? checkoutSession?.currency_id || currency.id : currency.id) || settings.settings?.baseCurrency : currency;
|
|
135
|
+
const headlines = (0, _util2.formatCheckoutHeadlines)(items, discountCurrency, {
|
|
125
136
|
trialEnd,
|
|
126
137
|
trialInDays
|
|
127
138
|
}, locale);
|
|
128
|
-
const staking = showStaking ? getStakingSetup(items,
|
|
129
|
-
const
|
|
139
|
+
const staking = showStaking ? getStakingSetup(items, discountCurrency, billingThreshold) : "0";
|
|
140
|
+
const getAppliedPromotionCodes = () => {
|
|
141
|
+
if (!sessionDiscounts?.length) return [];
|
|
142
|
+
return sessionDiscounts.map(discount => ({
|
|
143
|
+
id: discount.promotion_code || discount.coupon,
|
|
144
|
+
code: discount.verification_data?.code || "APPLIED",
|
|
145
|
+
discount_amount: discount.discount_amount
|
|
146
|
+
}));
|
|
147
|
+
};
|
|
148
|
+
const handlePromotionUpdate = () => {
|
|
149
|
+
onPromotionUpdate?.();
|
|
150
|
+
};
|
|
151
|
+
const handleRemovePromotion = async sessionId => {
|
|
152
|
+
if (paymentState.paying || paymentState.stripePaying) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
await _api.default.delete(`/api/checkout-sessions/${sessionId}/remove-promotion`);
|
|
157
|
+
onPromotionUpdate?.();
|
|
158
|
+
} catch (err) {
|
|
159
|
+
console.error("Failed to remove promotion code:", err);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const discountAmount = new _util.BN(checkoutSession?.total_details?.amount_discount || "0");
|
|
163
|
+
const subtotalAmount = (0, _util.fromUnitToToken)(new _util.BN((0, _util.fromTokenToUnit)(headlines.actualAmount, discountCurrency?.decimal)).add(new _util.BN(staking)).toString(), discountCurrency?.decimal);
|
|
164
|
+
const totalAmount = (0, _util.fromUnitToToken)(new _util.BN((0, _util.fromTokenToUnit)(subtotalAmount, discountCurrency?.decimal)).sub(discountAmount).toString(), discountCurrency?.decimal);
|
|
130
165
|
(0, _useBus.default)("error.REQUIRE_CROSS_SELL", () => {
|
|
131
166
|
setState({
|
|
132
167
|
shake: true
|
|
@@ -194,13 +229,13 @@ function PaymentSummary({
|
|
|
194
229
|
item: x,
|
|
195
230
|
settings: donationSettings,
|
|
196
231
|
onChange: onChangeAmount,
|
|
197
|
-
currency
|
|
198
|
-
}, `${x.price_id}-${
|
|
232
|
+
currency: discountCurrency
|
|
233
|
+
}, `${x.price_id}-${discountCurrency.id}`) : /* @__PURE__ */(0, _jsxRuntime.jsx)(_productItem.default, {
|
|
199
234
|
item: x,
|
|
200
235
|
items,
|
|
201
236
|
trialInDays,
|
|
202
237
|
trialEnd,
|
|
203
|
-
currency,
|
|
238
|
+
currency: discountCurrency,
|
|
204
239
|
onUpsell: handleUpsell,
|
|
205
240
|
onDownsell: handleDownsell,
|
|
206
241
|
adjustableQuantity: x.adjustable_quantity,
|
|
@@ -225,7 +260,7 @@ function PaymentSummary({
|
|
|
225
260
|
children: t("payment.checkout.cross_sell.remove")
|
|
226
261
|
})]
|
|
227
262
|
})
|
|
228
|
-
}, `${x.price_id}-${
|
|
263
|
+
}, `${x.price_id}-${discountCurrency.id}`))
|
|
229
264
|
}), data && items.some(x => x.price_id === data.id) === false && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Grow, {
|
|
230
265
|
in: true,
|
|
231
266
|
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, {
|
|
@@ -241,7 +276,7 @@ function PaymentSummary({
|
|
|
241
276
|
},
|
|
242
277
|
items,
|
|
243
278
|
trialInDays,
|
|
244
|
-
currency,
|
|
279
|
+
currency: discountCurrency,
|
|
245
280
|
trialEnd,
|
|
246
281
|
onUpsell: _noop.default,
|
|
247
282
|
onDownsell: _noop.default,
|
|
@@ -400,9 +435,116 @@ function PaymentSummary({
|
|
|
400
435
|
})
|
|
401
436
|
})]
|
|
402
437
|
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
|
|
403
|
-
children: [(0, _util2.formatAmount)(staking,
|
|
438
|
+
children: [(0, _util2.formatAmount)(staking, discountCurrency.decimal), " ", discountCurrency.symbol]
|
|
404
439
|
})]
|
|
405
440
|
})]
|
|
441
|
+
}), (allowPromotionCodes || hasDiscounts) && /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
442
|
+
direction: "row",
|
|
443
|
+
spacing: 1,
|
|
444
|
+
sx: {
|
|
445
|
+
justifyContent: "space-between",
|
|
446
|
+
alignItems: "center",
|
|
447
|
+
...(staking > 0 && {
|
|
448
|
+
borderTop: "1px solid",
|
|
449
|
+
borderColor: "divider",
|
|
450
|
+
pt: 1,
|
|
451
|
+
mt: 1
|
|
452
|
+
})
|
|
453
|
+
},
|
|
454
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
455
|
+
className: "base-label",
|
|
456
|
+
children: t("common.subtotal")
|
|
457
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
|
|
458
|
+
children: [(0, _util2.formatNumber)(subtotalAmount), " ", discountCurrency.symbol]
|
|
459
|
+
})]
|
|
460
|
+
}), allowPromotionCodes && !hasDiscounts && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
461
|
+
sx: {
|
|
462
|
+
mt: 1
|
|
463
|
+
},
|
|
464
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_promotionCode.default, {
|
|
465
|
+
checkoutSessionId: checkoutSession.id,
|
|
466
|
+
initialAppliedCodes: getAppliedPromotionCodes(),
|
|
467
|
+
disabled: completed,
|
|
468
|
+
onUpdate: handlePromotionUpdate,
|
|
469
|
+
currencyId: currency.id
|
|
470
|
+
})
|
|
471
|
+
}), hasDiscounts && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
472
|
+
sx: {
|
|
473
|
+
py: 1.5
|
|
474
|
+
},
|
|
475
|
+
children: sessionDiscounts.map(discount => {
|
|
476
|
+
const promotionCodeInfo = discount.promotion_code_details;
|
|
477
|
+
const couponInfo = discount.coupon_details;
|
|
478
|
+
const discountDescription = couponInfo ? (0, _util2.formatCouponTerms)(couponInfo, discountCurrency, locale) : "";
|
|
479
|
+
const notSupported = discountDescription === t("payment.checkout.coupon.noDiscount");
|
|
480
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
481
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
482
|
+
direction: "row",
|
|
483
|
+
spacing: 1,
|
|
484
|
+
sx: {
|
|
485
|
+
justifyContent: "space-between",
|
|
486
|
+
alignItems: "center"
|
|
487
|
+
},
|
|
488
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
489
|
+
direction: "row",
|
|
490
|
+
spacing: 1,
|
|
491
|
+
sx: {
|
|
492
|
+
alignItems: "center",
|
|
493
|
+
backgroundColor: "grey.100",
|
|
494
|
+
width: "fit-content",
|
|
495
|
+
px: 1,
|
|
496
|
+
py: 0.5,
|
|
497
|
+
borderRadius: 1
|
|
498
|
+
},
|
|
499
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
|
|
500
|
+
sx: {
|
|
501
|
+
fontWeight: "medium",
|
|
502
|
+
fontSize: "small",
|
|
503
|
+
display: "flex",
|
|
504
|
+
alignItems: "center",
|
|
505
|
+
gap: 0.5
|
|
506
|
+
},
|
|
507
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.LocalOffer, {
|
|
508
|
+
sx: {
|
|
509
|
+
color: "warning.main",
|
|
510
|
+
fontSize: "small"
|
|
511
|
+
}
|
|
512
|
+
}), promotionCodeInfo?.code || discount.verification_data?.code || t("payment.checkout.discount")]
|
|
513
|
+
}), !completed && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Button, {
|
|
514
|
+
size: "small",
|
|
515
|
+
disabled: paymentState.paying || paymentState.stripePaying,
|
|
516
|
+
onClick: () => handleRemovePromotion(checkoutSessionId),
|
|
517
|
+
sx: {
|
|
518
|
+
minWidth: "auto",
|
|
519
|
+
width: 16,
|
|
520
|
+
height: 16,
|
|
521
|
+
color: "text.secondary",
|
|
522
|
+
"&.Mui-disabled": {
|
|
523
|
+
color: "text.disabled"
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.Close, {
|
|
527
|
+
sx: {
|
|
528
|
+
fontSize: 14
|
|
529
|
+
}
|
|
530
|
+
})
|
|
531
|
+
})]
|
|
532
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Typography, {
|
|
533
|
+
sx: {
|
|
534
|
+
color: "text.secondary"
|
|
535
|
+
},
|
|
536
|
+
children: ["-", (0, _util2.formatAmount)(discount.discount_amount || "0", discountCurrency.decimal), " ", discountCurrency.symbol]
|
|
537
|
+
})]
|
|
538
|
+
}), discountDescription && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
539
|
+
sx: {
|
|
540
|
+
fontSize: "small",
|
|
541
|
+
color: notSupported ? "error.main" : "text.secondary",
|
|
542
|
+
mt: 0.5
|
|
543
|
+
},
|
|
544
|
+
children: discountDescription
|
|
545
|
+
})]
|
|
546
|
+
}, discount.promotion_code || discount.coupon || `discount-${discount.discount_amount}`);
|
|
547
|
+
})
|
|
406
548
|
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
407
549
|
sx: {
|
|
408
550
|
display: "flex",
|
|
@@ -415,7 +557,7 @@ function PaymentSummary({
|
|
|
415
557
|
className: "base-label",
|
|
416
558
|
children: [t("common.total"), " "]
|
|
417
559
|
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_amount.default, {
|
|
418
|
-
amount: `${totalAmount} ${
|
|
560
|
+
amount: `${totalAmount} ${discountCurrency.symbol}`,
|
|
419
561
|
sx: {
|
|
420
562
|
fontSize: "16px"
|
|
421
563
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.12",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -54,16 +54,16 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@arcblock/did-connect-react": "^3.1.
|
|
58
|
-
"@arcblock/ux": "^3.1.
|
|
59
|
-
"@arcblock/ws": "^1.
|
|
60
|
-
"@blocklet/theme": "^3.1.
|
|
61
|
-
"@blocklet/ui-react": "^3.1.
|
|
57
|
+
"@arcblock/did-connect-react": "^3.1.41",
|
|
58
|
+
"@arcblock/ux": "^3.1.41",
|
|
59
|
+
"@arcblock/ws": "^1.25.1",
|
|
60
|
+
"@blocklet/theme": "^3.1.41",
|
|
61
|
+
"@blocklet/ui-react": "^3.1.41",
|
|
62
62
|
"@mui/icons-material": "^7.1.2",
|
|
63
63
|
"@mui/lab": "7.0.0-beta.14",
|
|
64
64
|
"@mui/material": "^7.1.2",
|
|
65
65
|
"@mui/system": "^7.1.1",
|
|
66
|
-
"@ocap/util": "^1.
|
|
66
|
+
"@ocap/util": "^1.25.1",
|
|
67
67
|
"@stripe/react-stripe-js": "^2.9.0",
|
|
68
68
|
"@stripe/stripe-js": "^2.4.0",
|
|
69
69
|
"@vitejs/plugin-legacy": "^7.0.0",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@babel/core": "^7.27.4",
|
|
95
95
|
"@babel/preset-env": "^7.27.2",
|
|
96
96
|
"@babel/preset-react": "^7.27.1",
|
|
97
|
-
"@blocklet/payment-types": "1.20.
|
|
97
|
+
"@blocklet/payment-types": "1.20.12",
|
|
98
98
|
"@storybook/addon-essentials": "^7.6.20",
|
|
99
99
|
"@storybook/addon-interactions": "^7.6.20",
|
|
100
100
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -125,5 +125,5 @@
|
|
|
125
125
|
"vite-plugin-babel": "^1.3.1",
|
|
126
126
|
"vite-plugin-node-polyfills": "^0.23.0"
|
|
127
127
|
},
|
|
128
|
-
"gitHead": "
|
|
128
|
+
"gitHead": "e6c432f89c2bf305efc903c0809f4a0557c07774"
|
|
129
129
|
}
|