@intercartx/booster-core 0.0.1-beta.3 → 0.0.1-beta.31
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/README.md +379 -1
- package/dist/api/config/index.d.ts +2 -0
- package/dist/api/config/index.js +7 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/order/get-order.d.ts +15 -0
- package/dist/api/order/index.d.ts +1 -0
- package/dist/api/order/index.js +1 -0
- package/dist/api/order/quick.d.ts +12 -0
- package/dist/api/order/quick.js +4 -0
- package/dist/api/order/types.d.ts +4 -0
- package/dist/api/order/types.js +5 -0
- package/dist/api/types.d.ts +18 -14
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/models/business/CustomInfo.js +1 -1
- package/dist/models/business/ErrorTip.d.ts +9 -0
- package/dist/models/business/ErrorTip.js +27 -0
- package/dist/models/business/FullScreeenLoading.js +3 -0
- package/dist/models/business/OrderSummary.d.ts +4 -2
- package/dist/models/business/OrderSummary.js +67 -6
- package/dist/models/business/PaypalModal.d.ts +1 -0
- package/dist/models/business/PaypalModal.js +34 -3
- package/dist/models/business/address/Address.js +2 -0
- package/dist/models/business/address/AddressSuggestion.js +2 -2
- package/dist/models/business/address/MultiRegions.d.ts +1 -0
- package/dist/models/business/address/MultiRegions.js +5 -0
- package/dist/models/business/fees/ShippingMethods.js +2 -0
- package/dist/models/business/fees/Tips.d.ts +1 -0
- package/dist/models/business/fees/Tips.js +7 -1
- package/dist/models/business/index.d.ts +1 -0
- package/dist/models/business/index.js +1 -0
- package/dist/models/business/pay-button/ACHPaymentHandler.js +5 -4
- package/dist/models/business/pay-button/PPPaymentHandler.js +7 -2
- package/dist/models/business/pay-button/PayButton.d.ts +1 -0
- package/dist/models/business/pay-button/PayButton.js +55 -1
- package/dist/models/business/pay-button/cc-handler/DefaultCCPaymentHandler.d.ts +1 -0
- package/dist/models/business/pay-button/cc-handler/DefaultCCPaymentHandler.js +78 -4
- package/dist/models/business/pay-button/cc-handler/FxpCCPaymentHandler.js +3 -3
- package/dist/models/business/pay-button/cc-handler/StripeCCPaymentHandler.d.ts +2 -0
- package/dist/models/business/pay-button/cc-handler/StripeCCPaymentHandler.js +100 -42
- package/dist/models/business/payment/CCPayment.js +15 -10
- package/dist/models/business/payment/FxpCCPayment.js +15 -10
- package/dist/models/business/payment/StripeCCPayment.d.ts +1 -0
- package/dist/models/business/payment/StripeCCPayment.js +20 -11
- package/dist/report-event.d.ts +2 -0
- package/dist/report-event.js +12 -0
- package/dist/styles/address.css +1 -1
- package/dist/styles/button.css +7 -1
- package/dist/styles/checkout-page.css +1 -1
- package/dist/styles/custom-info.css +1 -1
- package/dist/styles/error-tip.css +1 -0
- package/dist/styles/fee.css +1 -1
- package/dist/styles/fxp-payment.css +1 -1
- package/dist/styles/global.css +1 -1
- package/dist/styles/input.css +1 -1
- package/dist/styles/loading.css +1 -1
- package/dist/styles/order-summary.css +1 -1
- package/dist/styles/payment.css +1 -1
- package/dist/styles/paypal-modal.css +1 -1
- package/dist/styles/phone-input.css +1 -1
- package/dist/styles/select-list.css +1 -1
- package/dist/styles/select.css +1 -1
- package/dist/styles/stripe-payment.css +1 -1
- package/dist/styles/theme.css +1 -1
- package/dist/types.d.ts +4 -2
- package/dist/types.js +2 -0
- package/dist/validate/phone.js +14 -5
- package/package.json +34 -11
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import { CheckoutEvents } from "../../types";
|
|
2
|
-
import { divide100,
|
|
2
|
+
import { divide100, plus } from "../../utils";
|
|
3
3
|
import { globalState } from "../GlobalState";
|
|
4
4
|
import { BusinessModel } from "./Business";
|
|
5
5
|
export class OrderSummaryModel extends BusinessModel {
|
|
6
6
|
constructor() {
|
|
7
|
+
var _a, _b, _c;
|
|
7
8
|
super();
|
|
8
9
|
this.displayProductList = [];
|
|
10
|
+
this.isSubscription = false;
|
|
9
11
|
this.isOpen = false;
|
|
10
12
|
this.fees = {};
|
|
11
13
|
this.reactiveKeys = ['isOpen', 'isLoading', 'fees', 'total'];
|
|
12
14
|
const { processorData } = globalState.getConfig();
|
|
13
|
-
const { productInfo } = processorData
|
|
14
|
-
|
|
15
|
+
// const { productInfo } = processorData
|
|
16
|
+
const productInfo = processorData.productInfo;
|
|
17
|
+
if (!productInfo ||
|
|
18
|
+
('display' in productInfo && !productInfo.display.length) ||
|
|
19
|
+
('displays' in productInfo && !((_b = (_a = productInfo.displays[0]) === null || _a === void 0 ? void 0 : _a.display) === null || _b === void 0 ? void 0 : _b.length))) {
|
|
15
20
|
return;
|
|
21
|
+
}
|
|
22
|
+
this.isSubscription = 'subscription' in productInfo;
|
|
23
|
+
const display = 'display' in productInfo ? productInfo.display : (_c = productInfo.displays[0]) === null || _c === void 0 ? void 0 : _c.display;
|
|
16
24
|
// 价格单位转成元显示
|
|
17
|
-
this.displayProductList =
|
|
25
|
+
this.displayProductList = display.map(product => ({
|
|
18
26
|
...product,
|
|
19
27
|
price: divide100(product.price),
|
|
20
28
|
originPrice: divide100(product.originPrice),
|
|
@@ -29,13 +37,13 @@ export class OrderSummaryModel extends BusinessModel {
|
|
|
29
37
|
}
|
|
30
38
|
get totalSavings() {
|
|
31
39
|
const res = this.displayProductList.reduce((acc, product) => {
|
|
32
|
-
return plus(acc,
|
|
40
|
+
return plus(acc, divide100(product.discount * product.quantity));
|
|
33
41
|
}, '0');
|
|
34
42
|
return res;
|
|
35
43
|
}
|
|
36
44
|
get subtotal() {
|
|
37
45
|
const res = this.displayProductList.reduce((acc, product) => {
|
|
38
|
-
return plus(acc, product.price);
|
|
46
|
+
return plus(acc, Number(product.price) * product.quantity);
|
|
39
47
|
}, '0');
|
|
40
48
|
return res;
|
|
41
49
|
}
|
|
@@ -53,4 +61,57 @@ export class OrderSummaryModel extends BusinessModel {
|
|
|
53
61
|
toggleOpen() {
|
|
54
62
|
this.isOpen = !this.isOpen;
|
|
55
63
|
}
|
|
64
|
+
getSubscriptionPlanTexts() {
|
|
65
|
+
var _a, _b, _c, _d;
|
|
66
|
+
if (!this.isSubscription)
|
|
67
|
+
return [];
|
|
68
|
+
const productInfo = (_b = (_a = globalState.getConfig()) === null || _a === void 0 ? void 0 : _a.processorData) === null || _b === void 0 ? void 0 : _b.productInfo;
|
|
69
|
+
if (!productInfo || !((_c = productInfo === null || productInfo === void 0 ? void 0 : productInfo.displays) === null || _c === void 0 ? void 0 : _c.length))
|
|
70
|
+
return [];
|
|
71
|
+
const texts = [];
|
|
72
|
+
const { displays, subscription } = productInfo;
|
|
73
|
+
const currency = ((_d = globalState.getConfig()) === null || _d === void 0 ? void 0 : _d.currency) || 'USD';
|
|
74
|
+
displays.forEach((displayItem, index) => {
|
|
75
|
+
var _a;
|
|
76
|
+
// Calculate total price for this interval
|
|
77
|
+
const totalPrice = displayItem.display.reduce((sum, item) => {
|
|
78
|
+
return plus(sum, divide100(Number(item.price) * item.quantity));
|
|
79
|
+
}, '0');
|
|
80
|
+
// Get recurring type from pricePlan
|
|
81
|
+
const recurring = ((_a = subscription.pricePlan[index]) === null || _a === void 0 ? void 0 : _a.recurring) || 'month';
|
|
82
|
+
const interval = displayItem.interval;
|
|
83
|
+
// Format price with currency
|
|
84
|
+
const priceText = `${currency} ${totalPrice}`;
|
|
85
|
+
if (interval === -1) {
|
|
86
|
+
// Recurring forever
|
|
87
|
+
if (index === 0) {
|
|
88
|
+
// First and only plan, recurring forever
|
|
89
|
+
texts.push(`${priceText} per ${recurring}`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// After previous plans, recurring forever
|
|
93
|
+
texts.push(`Then ${priceText} per ${recurring}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (index === 0) {
|
|
97
|
+
// First interval with specific count
|
|
98
|
+
if (interval === 1) {
|
|
99
|
+
texts.push(`First ${recurring} at ${priceText}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
texts.push(`First ${interval} ${recurring}s at ${priceText}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Subsequent intervals with specific count
|
|
107
|
+
if (interval === 1) {
|
|
108
|
+
texts.push(`Then ${recurring} at ${priceText}`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
texts.push(`Then ${interval} ${recurring}s at ${priceText}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return texts;
|
|
116
|
+
}
|
|
56
117
|
}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _PaypalModalModel_PPPaymentHandler;
|
|
1
13
|
import { BusinessModel } from "./Business";
|
|
2
14
|
import { globalState } from "../GlobalState";
|
|
15
|
+
import { PPPaymentHandler } from "./pay-button/PPPaymentHandler";
|
|
16
|
+
import { CheckoutEvents } from "../../types";
|
|
17
|
+
import { HTTPError } from "../../api";
|
|
3
18
|
const COUNT_DOWN = 5;
|
|
4
19
|
export class PaypalModalModel extends BusinessModel {
|
|
5
20
|
constructor(props) {
|
|
@@ -7,6 +22,7 @@ export class PaypalModalModel extends BusinessModel {
|
|
|
7
22
|
this.visible = false;
|
|
8
23
|
this.onVisibleChange = () => { };
|
|
9
24
|
this.countDown = COUNT_DOWN;
|
|
25
|
+
_PaypalModalModel_PPPaymentHandler.set(this, null);
|
|
10
26
|
this.reactiveKeys = ['visible', 'countDown'];
|
|
11
27
|
this.timer = null;
|
|
12
28
|
this.startCountDown = () => {
|
|
@@ -30,12 +46,18 @@ export class PaypalModalModel extends BusinessModel {
|
|
|
30
46
|
if (!this.visible) {
|
|
31
47
|
return;
|
|
32
48
|
}
|
|
49
|
+
if (!__classPrivateFieldGet(this, _PaypalModalModel_PPPaymentHandler, "f")) {
|
|
50
|
+
__classPrivateFieldSet(this, _PaypalModalModel_PPPaymentHandler, new PPPaymentHandler(), "f");
|
|
51
|
+
}
|
|
33
52
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// console.log('Redirecting to PayPal...')
|
|
53
|
+
this.handleClose();
|
|
54
|
+
await __classPrivateFieldGet(this, _PaypalModalModel_PPPaymentHandler, "f").handlePayment();
|
|
37
55
|
}
|
|
38
56
|
catch (error) {
|
|
57
|
+
if (error instanceof HTTPError) {
|
|
58
|
+
const errJson = error.json;
|
|
59
|
+
globalState.emit(CheckoutEvents.ERROR_TIP_SHOW, errJson.message);
|
|
60
|
+
}
|
|
39
61
|
console.error('PayPal redirect failed:', error);
|
|
40
62
|
}
|
|
41
63
|
};
|
|
@@ -46,6 +68,14 @@ export class PaypalModalModel extends BusinessModel {
|
|
|
46
68
|
this.onVisibleChange = props.onVisibleChange;
|
|
47
69
|
}
|
|
48
70
|
props.visible && this.openModal();
|
|
71
|
+
globalState.on(CheckoutEvents.CREDIT_CARD_FAILED, (bool) => {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
const config = globalState.getConfig();
|
|
74
|
+
const isPPVisible = ((_a = config.paymentMethods) === null || _a === void 0 ? void 0 : _a.PP) && ((_b = config.paymentMethods) === null || _b === void 0 ? void 0 : _b.PP.visible);
|
|
75
|
+
if (isPPVisible) {
|
|
76
|
+
this.setVisible(bool);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
49
79
|
globalState.registerModel('paypalModal', this);
|
|
50
80
|
}
|
|
51
81
|
openModal() {
|
|
@@ -62,3 +92,4 @@ export class PaypalModalModel extends BusinessModel {
|
|
|
62
92
|
}
|
|
63
93
|
}
|
|
64
94
|
}
|
|
95
|
+
_PaypalModalModel_PPPaymentHandler = new WeakMap();
|
|
@@ -85,7 +85,7 @@ export class AddressSuggestModel extends BusinessModel {
|
|
|
85
85
|
__classPrivateFieldSet(this, _AddressSuggestModel_sessionToken, result.sessionToken, "f");
|
|
86
86
|
if (result.suggestions && result.suggestions.length > 0) {
|
|
87
87
|
this.suggestions = result.suggestions;
|
|
88
|
-
this.dropdown.handleOpen()
|
|
88
|
+
// this.dropdown.handleOpen()
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
91
|
this.clearSuggestions();
|
|
@@ -116,7 +116,7 @@ export class AddressSuggestModel extends BusinessModel {
|
|
|
116
116
|
}
|
|
117
117
|
clearSuggestions() {
|
|
118
118
|
this.suggestions = [];
|
|
119
|
-
this.dropdown.handleClose()
|
|
119
|
+
// this.dropdown.handleClose()
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
_AddressSuggestModel_onChange = new WeakMap(), _AddressSuggestModel_onAddressSelect = new WeakMap(), _AddressSuggestModel_googleApiKey = new WeakMap(), _AddressSuggestModel_sessionToken = new WeakMap();
|
|
@@ -50,6 +50,7 @@ export declare class MultiRegionsModel extends BusinessModel<MultiRegionsData> i
|
|
|
50
50
|
getFieldModel(fieldName: string): InputModel<import("../../types").FieldProps> | SelectModel<import("../../types").FieldProps> | undefined;
|
|
51
51
|
getValue(): MultiRegionsData;
|
|
52
52
|
setValue(value: MultiRegionsData): void;
|
|
53
|
+
clearErrorValues(): void;
|
|
53
54
|
validate(): boolean;
|
|
54
55
|
clearAllFields(): void;
|
|
55
56
|
}
|
|
@@ -70,6 +70,11 @@ export class MultiRegionsModel extends BusinessModel {
|
|
|
70
70
|
this.province.setValue(value.province);
|
|
71
71
|
this.zip.setValue(value.zip);
|
|
72
72
|
}
|
|
73
|
+
clearErrorValues() {
|
|
74
|
+
this.city.setError('');
|
|
75
|
+
this.province.setError('');
|
|
76
|
+
this.zip.setError('');
|
|
77
|
+
}
|
|
73
78
|
validate() {
|
|
74
79
|
return [
|
|
75
80
|
this.city.validate(),
|
|
@@ -10,6 +10,8 @@ export class ShippingMethodsModel extends BusinessModel {
|
|
|
10
10
|
this.selectedMethod = null;
|
|
11
11
|
this.reactiveKeys = ['methodsList', 'selectedMethod'];
|
|
12
12
|
this.selectMethod = (methodId) => {
|
|
13
|
+
if (!methodId)
|
|
14
|
+
return;
|
|
13
15
|
const method = this.methodsList.find(method => method.shippingNo === methodId);
|
|
14
16
|
if (method) {
|
|
15
17
|
this.selectedMethod = method;
|
|
@@ -20,6 +20,7 @@ export declare class TipsModel extends BusinessModel<{
|
|
|
20
20
|
constructor();
|
|
21
21
|
get tip(): number;
|
|
22
22
|
handleChooseTip: (index: number) => void;
|
|
23
|
+
handleShowStatusChange: () => void;
|
|
23
24
|
handleTipMinus: () => void;
|
|
24
25
|
handleTipPlus: () => void;
|
|
25
26
|
handleTipUpdate: () => Promise<void>;
|
|
@@ -29,6 +29,9 @@ export class TipsModel extends BusinessModel {
|
|
|
29
29
|
this.customTip = '';
|
|
30
30
|
globalState.emit(CheckoutEvents.TIP_CHANGE, this.tip);
|
|
31
31
|
};
|
|
32
|
+
this.handleShowStatusChange = () => {
|
|
33
|
+
globalState.emit(CheckoutEvents.TIP_CHANGE, this.tip);
|
|
34
|
+
};
|
|
32
35
|
this.handleTipMinus = () => {
|
|
33
36
|
if (Number(this.customTip) > 1) {
|
|
34
37
|
this.customTip = (Number(this.customTip) - 1).toString();
|
|
@@ -64,7 +67,7 @@ export class TipsModel extends BusinessModel {
|
|
|
64
67
|
this.updateButtonStatus = EBtnStatus.Inactive;
|
|
65
68
|
}
|
|
66
69
|
};
|
|
67
|
-
this.showTip = (_c = (_b = (_a = globalState.getConfig()) === null || _a === void 0 ? void 0 : _a.
|
|
70
|
+
this.showTip = (_c = (_b = (_a = globalState.getConfig()) === null || _a === void 0 ? void 0 : _a.feeSettings) === null || _b === void 0 ? void 0 : _b.tip) !== null && _c !== void 0 ? _c : true;
|
|
68
71
|
globalState.on(CheckoutEvents.SUBTOTAL_CHANGE, (subtotal) => {
|
|
69
72
|
this.fixedOptions = FIXED_OPTIONS_PERCENTS.map(percent => ({
|
|
70
73
|
label: percent ? `${percent * 100}%` : 'None',
|
|
@@ -76,6 +79,9 @@ export class TipsModel extends BusinessModel {
|
|
|
76
79
|
}
|
|
77
80
|
get tip() {
|
|
78
81
|
var _a, _b;
|
|
82
|
+
if (!this.showTip) {
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
79
85
|
const tip = Number(this.customTip);
|
|
80
86
|
if (tip > 0) {
|
|
81
87
|
return Number(tip);
|
|
@@ -14,7 +14,7 @@ import { HTTPError } from "../../../api/helper";
|
|
|
14
14
|
import { apiCreateACHSubscriptionOrder } from "../../../api/order/ach";
|
|
15
15
|
import { apiConfirmSubscriptionOrderWithRetry } from "../../../api/order/order-confirm";
|
|
16
16
|
import { apiCreatePreOrder } from "../../../api/order/pre-order";
|
|
17
|
-
import { SubmissionAction } from "../../../api/order/types";
|
|
17
|
+
import { ResponseErrorCode, SubmissionAction } from "../../../api/order/types";
|
|
18
18
|
import { CheckoutEvents } from "../../../types";
|
|
19
19
|
import { getBrowserInfo } from "../../../utils/browserInfo";
|
|
20
20
|
import { globalState } from "../../GlobalState";
|
|
@@ -76,8 +76,9 @@ export class ACHPaymentHandler {
|
|
|
76
76
|
async handlePayment() {
|
|
77
77
|
try {
|
|
78
78
|
const isAllValid = await this.validatePayment();
|
|
79
|
-
if (!isAllValid)
|
|
80
|
-
|
|
79
|
+
if (!isAllValid) {
|
|
80
|
+
throw new Error('Invalid payment');
|
|
81
|
+
}
|
|
81
82
|
showLoading("Processing payment...");
|
|
82
83
|
const reqData = await this.preparePaymentData();
|
|
83
84
|
const { token } = globalState.getConfig();
|
|
@@ -104,7 +105,7 @@ export class ACHPaymentHandler {
|
|
|
104
105
|
console.error(error);
|
|
105
106
|
if (error instanceof HTTPError) {
|
|
106
107
|
const errJson = error.json;
|
|
107
|
-
if (errJson.code ===
|
|
108
|
+
if (errJson.code === ResponseErrorCode.ORDER_ALREADY_HAS_TRADE && __classPrivateFieldGet(this, _ACHPaymentHandler_orderResult, "f")) {
|
|
108
109
|
await this.handleApiACHOSubscriptionOrdered();
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
@@ -62,8 +62,10 @@ export class PPPaymentHandler {
|
|
|
62
62
|
var _a;
|
|
63
63
|
try {
|
|
64
64
|
const isAllValid = await this.validatePayment();
|
|
65
|
-
if (!isAllValid)
|
|
66
|
-
|
|
65
|
+
if (!isAllValid) {
|
|
66
|
+
throw new Error('Invalid payment');
|
|
67
|
+
}
|
|
68
|
+
;
|
|
67
69
|
showLoading('Processing payment...');
|
|
68
70
|
const reqData = await this.preparePaymentData();
|
|
69
71
|
const { token } = globalState.getConfig();
|
|
@@ -122,6 +124,9 @@ export class PPPaymentHandler {
|
|
|
122
124
|
}
|
|
123
125
|
catch (error) {
|
|
124
126
|
console.error(error);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
125
130
|
hideLoading();
|
|
126
131
|
}
|
|
127
132
|
}
|
|
@@ -10,12 +10,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
12
|
var _PayButtonModel_instances, _PayButtonModel_paymentConfig, _PayButtonModel_createPaymentHandler;
|
|
13
|
+
import { HTTPError, ResponseErrorCode } from "../../../api";
|
|
13
14
|
import { CheckoutEvents } from "../../../types";
|
|
14
15
|
import { globalState } from "../../GlobalState";
|
|
15
16
|
import { BusinessModel } from "../Business";
|
|
16
17
|
import { ACHPaymentHandler } from "./ACHPaymentHandler";
|
|
17
18
|
import { CCPaymentHandler } from "./CCPaymentHandler";
|
|
18
19
|
import { PPPaymentHandler } from "./PPPaymentHandler";
|
|
20
|
+
import { reportEvent } from "../../../report-event";
|
|
19
21
|
var PaymentMethod;
|
|
20
22
|
(function (PaymentMethod) {
|
|
21
23
|
PaymentMethod["PP"] = "PP";
|
|
@@ -48,7 +50,59 @@ export class PayButtonModel extends BusinessModel {
|
|
|
48
50
|
return this.paymentHandler.preparePaymentData();
|
|
49
51
|
}
|
|
50
52
|
async handlePayment() {
|
|
51
|
-
|
|
53
|
+
var _a, _b, _c;
|
|
54
|
+
try {
|
|
55
|
+
globalState.emit(CheckoutEvents.ERROR_TIP_SHOW, '');
|
|
56
|
+
await this.paymentHandler.handlePayment();
|
|
57
|
+
const productInfo = (_c = (_b = (_a = globalState.getConfig()) === null || _a === void 0 ? void 0 : _a.processorData) === null || _b === void 0 ? void 0 : _b.productInfo) !== null && _c !== void 0 ? _c : [];
|
|
58
|
+
reportEvent("PlaceAnOrder", productInfo);
|
|
59
|
+
// const config = globalState.getConfig().processorData.productInfo?.display || []
|
|
60
|
+
// const contents: TracksityContent[] = config.map((item) => ({
|
|
61
|
+
// content_id: item.productId || '',
|
|
62
|
+
// content_name: item.title || '',
|
|
63
|
+
// price: Number(item.price),
|
|
64
|
+
// quantity: Number(item.quantity),
|
|
65
|
+
// }))
|
|
66
|
+
// tracksityTracker.event("PlaceAnOrder", TracksityTracker.buildEcommerceData(contents))
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof HTTPError) {
|
|
70
|
+
const errJson = error.json;
|
|
71
|
+
globalState.emit(CheckoutEvents.ERROR_TIP_SHOW, errJson.message);
|
|
72
|
+
if (errJson.code === ResponseErrorCode.CREDIT_CARD_FAILED) {
|
|
73
|
+
globalState.emit(CheckoutEvents.CREDIT_CARD_FAILED, true);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
this.invalidHandler();
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
async invalidHandler() {
|
|
82
|
+
const invalidEl = window.document.querySelector('.itx-invalid');
|
|
83
|
+
if (invalidEl) {
|
|
84
|
+
const invalidInput = invalidEl;
|
|
85
|
+
if (invalidInput.focus)
|
|
86
|
+
invalidInput.focus();
|
|
87
|
+
invalidEl.scrollIntoView();
|
|
88
|
+
// 获取错误信息
|
|
89
|
+
// const feedBackEl =
|
|
90
|
+
// invalidEl.nextElementSibling?.nextElementSibling?.children[0]
|
|
91
|
+
// if (feedBackEl) {
|
|
92
|
+
// setErrorMessage((feedBackEl as HTMLElement).innerText)
|
|
93
|
+
// }
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const { stripeElements, stripeElId } = globalState.getAllValues();
|
|
97
|
+
if (stripeElements && stripeElId) {
|
|
98
|
+
const { error: submitError } = await stripeElements.submit();
|
|
99
|
+
if (submitError) {
|
|
100
|
+
const el = document.getElementById(stripeElId);
|
|
101
|
+
if (el) {
|
|
102
|
+
el.scrollIntoView();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
52
106
|
}
|
|
53
107
|
}
|
|
54
108
|
_PayButtonModel_paymentConfig = new WeakMap(), _PayButtonModel_instances = new WeakSet(), _PayButtonModel_createPaymentHandler = function _PayButtonModel_createPaymentHandler(paymentMethod) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OneTimeOrderProduct } from "../../../../api/types";
|
|
2
2
|
import { BaseCCPaymentHandler } from "./BaseCCPaymentHandler";
|
|
3
3
|
export declare class DefaultCCPaymentHandler extends BaseCCPaymentHandler {
|
|
4
|
+
#private;
|
|
4
5
|
validatePayment(): Promise<boolean>;
|
|
5
6
|
preparePaymentData(): Promise<{
|
|
6
7
|
products: OneTimeOrderProduct;
|
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _DefaultCCPaymentHandler_orderResult;
|
|
1
13
|
import { CheckoutEvents, hideLoading, showLoading } from "../../../../index";
|
|
2
14
|
import { apiCCOneTimeOrder } from "../../../../api/order/cc";
|
|
3
15
|
import { apiConfirmOneTimeOrderWithRetry } from "../../../../api/order/order-confirm";
|
|
4
16
|
import { apiCreatePreOrder } from "../../../../api/order/pre-order";
|
|
5
|
-
import { SubmissionAction } from "../../../../api/order/types";
|
|
17
|
+
import { ResponseErrorCode, SubmissionAction } from "../../../../api/order/types";
|
|
6
18
|
import { getBrowserInfo } from "../../../../utils/browserInfo";
|
|
7
19
|
import { encryptCreditCard } from "../../../../utils/encrypt";
|
|
8
20
|
import { globalState } from "../../../GlobalState";
|
|
9
21
|
import { BaseCCPaymentHandler } from "./BaseCCPaymentHandler";
|
|
22
|
+
import { HTTPError } from "../../../../api/helper";
|
|
10
23
|
export class DefaultCCPaymentHandler extends BaseCCPaymentHandler {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
_DefaultCCPaymentHandler_orderResult.set(this, null);
|
|
27
|
+
}
|
|
11
28
|
async validatePayment() {
|
|
12
29
|
return await globalState.validateAll();
|
|
13
30
|
}
|
|
@@ -58,11 +75,12 @@ export class DefaultCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
58
75
|
};
|
|
59
76
|
}
|
|
60
77
|
async handlePayment() {
|
|
61
|
-
var _a;
|
|
78
|
+
var _a, _b, _c, _d;
|
|
62
79
|
try {
|
|
63
80
|
const isAllValid = await this.validatePayment();
|
|
64
|
-
if (!isAllValid)
|
|
65
|
-
|
|
81
|
+
if (!isAllValid) {
|
|
82
|
+
throw new Error('Invalid payment');
|
|
83
|
+
}
|
|
66
84
|
showLoading('Processing payment...');
|
|
67
85
|
const reqData = await this.preparePaymentData();
|
|
68
86
|
const { paymentData, browser, confirmUrl, ...rest } = reqData;
|
|
@@ -71,6 +89,7 @@ export class DefaultCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
71
89
|
await apiCreatePreOrder(token, SubmissionAction.ONETIME, rest);
|
|
72
90
|
// 尝试支付
|
|
73
91
|
const res = await apiCCOneTimeOrder(token, reqData);
|
|
92
|
+
__classPrivateFieldSet(this, _DefaultCCPaymentHandler_orderResult, res, "f");
|
|
74
93
|
// 若需要 3DS 或外部跳转,在新窗口中打开,检测重定向后确认订单
|
|
75
94
|
if ((_a = res.action) === null || _a === void 0 ? void 0 : _a.url) {
|
|
76
95
|
const threeDSWindow = window.open(res.action.url, '_blank', 'width=800,height=600');
|
|
@@ -118,7 +137,62 @@ export class DefaultCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
118
137
|
}
|
|
119
138
|
catch (error) {
|
|
120
139
|
console.error(error);
|
|
140
|
+
if (error instanceof HTTPError) {
|
|
141
|
+
const errJson = error.json;
|
|
142
|
+
if (errJson.code === ResponseErrorCode.ORDER_ALREADY_HAS_TRADE && __classPrivateFieldGet(this, _DefaultCCPaymentHandler_orderResult, "f")) {
|
|
143
|
+
const { token } = globalState.getConfig();
|
|
144
|
+
if ((_b = __classPrivateFieldGet(this, _DefaultCCPaymentHandler_orderResult, "f").action) === null || _b === void 0 ? void 0 : _b.url) {
|
|
145
|
+
const threeDSWindow = window.open(__classPrivateFieldGet(this, _DefaultCCPaymentHandler_orderResult, "f").action.url, '_blank', 'width=800,height=600');
|
|
146
|
+
if (!threeDSWindow) {
|
|
147
|
+
console.error('Cannot open threeDS secure window, please check your browser settings');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const currentOrigin = window.location.origin;
|
|
151
|
+
const checkWindowRedirect = setInterval(() => {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
try {
|
|
154
|
+
if (threeDSWindow.closed) {
|
|
155
|
+
clearInterval(checkWindowRedirect);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const windowUrl = threeDSWindow.location.href;
|
|
159
|
+
if (windowUrl.startsWith(currentOrigin)) {
|
|
160
|
+
const url = new URL(windowUrl);
|
|
161
|
+
if (url.searchParams.has('token') || url.searchParams.has('tradeId')) {
|
|
162
|
+
clearInterval(checkWindowRedirect);
|
|
163
|
+
threeDSWindow.close();
|
|
164
|
+
showLoading('Confirming order...');
|
|
165
|
+
apiConfirmOneTimeOrderWithRetry(token, { tradeId: (_b = (_a = __classPrivateFieldGet(this, _DefaultCCPaymentHandler_orderResult, "f")) === null || _a === void 0 ? void 0 : _a.tradeId) !== null && _b !== void 0 ? _b : '' })
|
|
166
|
+
.then((paid) => paid ? globalState.emit(CheckoutEvents.ORDER_COMPLETED, token) : null)
|
|
167
|
+
.catch((error) => console.error('Order confirmation failed:', error))
|
|
168
|
+
.finally(() => hideLoading());
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
// 跨域无法读取 URL,继续检查(等待重定向到我们的域名后就能读取了)
|
|
175
|
+
}
|
|
176
|
+
}, 500);
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
clearInterval(checkWindowRedirect);
|
|
179
|
+
}, 5 * 60 * 1000);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// 确认订单(带重试)
|
|
183
|
+
const paid = await apiConfirmOneTimeOrderWithRetry(token, { tradeId: (_d = (_c = __classPrivateFieldGet(this, _DefaultCCPaymentHandler_orderResult, "f")) === null || _c === void 0 ? void 0 : _c.tradeId) !== null && _d !== void 0 ? _d : '' });
|
|
184
|
+
if (paid) {
|
|
185
|
+
globalState.emit(CheckoutEvents.ORDER_COMPLETED, token);
|
|
186
|
+
}
|
|
187
|
+
hideLoading();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
121
194
|
hideLoading();
|
|
122
195
|
}
|
|
123
196
|
}
|
|
124
197
|
}
|
|
198
|
+
_DefaultCCPaymentHandler_orderResult = new WeakMap();
|
|
@@ -15,7 +15,7 @@ import { HTTPError } from "../../../../api/helper";
|
|
|
15
15
|
import { apiConfirmOneTimeOrderWithRetry } from "../../../../api/order";
|
|
16
16
|
import { apiCCOneTimeOrder } from "../../../../api/order/cc";
|
|
17
17
|
import { apiCreatePreOrder } from "../../../../api/order/pre-order";
|
|
18
|
-
import { SubmissionAction } from "../../../../api/order/types";
|
|
18
|
+
import { ResponseErrorCode, SubmissionAction } from "../../../../api/order/types";
|
|
19
19
|
import { getBrowserInfo } from "../../../../utils/browserInfo";
|
|
20
20
|
import { divide100 } from "../../../../utils/currency";
|
|
21
21
|
import { globalState } from "../../../GlobalState";
|
|
@@ -132,7 +132,7 @@ export class FxpCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
132
132
|
console.error(error);
|
|
133
133
|
if (error instanceof HTTPError) {
|
|
134
134
|
const errJson = error.json;
|
|
135
|
-
if (errJson.code ===
|
|
135
|
+
if (errJson.code === ResponseErrorCode.ORDER_ALREADY_HAS_TRADE && __classPrivateFieldGet(this, _FxpCCPaymentHandler_orderResult, "f")) {
|
|
136
136
|
await this.handleApiCCOneTimeOrdered();
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
@@ -167,7 +167,7 @@ export class FxpCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
167
167
|
if (prev.length >= 0) {
|
|
168
168
|
prev += `#;#`;
|
|
169
169
|
}
|
|
170
|
-
return prev + `${(_a = curr.title) !== null && _a !== void 0 ? _a : '0'}#,#${(_b = curr.
|
|
170
|
+
return prev + `${(_a = curr.title) !== null && _a !== void 0 ? _a : '0'}#,#${(_b = curr.productId) !== null && _b !== void 0 ? _b : '0'}#,#${orderAmount}#,#${(_c = curr.quantity) !== null && _c !== void 0 ? _c : '0'}`;
|
|
171
171
|
}, '');
|
|
172
172
|
const fxpReqData = [
|
|
173
173
|
{ name: "merNo", value: rest.merNo },
|
|
@@ -2,6 +2,7 @@ import { Stripe } from "@stripe/stripe-js";
|
|
|
2
2
|
import { CCSubmissionRequest } from "../../../../api/order/cc";
|
|
3
3
|
import { BaseCCPaymentHandler } from "./BaseCCPaymentHandler";
|
|
4
4
|
export declare class StripeCCPaymentHandler extends BaseCCPaymentHandler {
|
|
5
|
+
#private;
|
|
5
6
|
isSubscription(): boolean;
|
|
6
7
|
getButtonText(): "Subscription Payment" | "One-Time Payment";
|
|
7
8
|
validatePayment(): Promise<boolean>;
|
|
@@ -9,4 +10,5 @@ export declare class StripeCCPaymentHandler extends BaseCCPaymentHandler {
|
|
|
9
10
|
stripe: Stripe;
|
|
10
11
|
}>;
|
|
11
12
|
handlePayment(): Promise<void>;
|
|
13
|
+
handleStripeOrdered(): Promise<void>;
|
|
12
14
|
}
|