@intercartx/booster-core 0.0.1-beta.3 → 0.0.1-beta.30

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 (68) hide show
  1. package/README.md +379 -1
  2. package/dist/api/config/index.d.ts +2 -0
  3. package/dist/api/config/index.js +7 -0
  4. package/dist/api/index.d.ts +1 -0
  5. package/dist/api/index.js +1 -0
  6. package/dist/api/order/index.d.ts +1 -0
  7. package/dist/api/order/index.js +1 -0
  8. package/dist/api/order/quick.d.ts +12 -0
  9. package/dist/api/order/quick.js +4 -0
  10. package/dist/api/order/types.d.ts +4 -0
  11. package/dist/api/order/types.js +5 -0
  12. package/dist/api/types.d.ts +18 -14
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +2 -0
  15. package/dist/models/business/CustomInfo.js +1 -1
  16. package/dist/models/business/ErrorTip.d.ts +9 -0
  17. package/dist/models/business/ErrorTip.js +27 -0
  18. package/dist/models/business/FullScreeenLoading.js +3 -0
  19. package/dist/models/business/OrderSummary.d.ts +4 -2
  20. package/dist/models/business/OrderSummary.js +67 -6
  21. package/dist/models/business/PaypalModal.d.ts +1 -0
  22. package/dist/models/business/PaypalModal.js +34 -3
  23. package/dist/models/business/address/Address.js +2 -0
  24. package/dist/models/business/address/AddressSuggestion.js +2 -2
  25. package/dist/models/business/address/MultiRegions.d.ts +1 -0
  26. package/dist/models/business/address/MultiRegions.js +5 -0
  27. package/dist/models/business/fees/ShippingMethods.js +2 -0
  28. package/dist/models/business/fees/Tips.d.ts +1 -0
  29. package/dist/models/business/fees/Tips.js +7 -1
  30. package/dist/models/business/index.d.ts +1 -0
  31. package/dist/models/business/index.js +1 -0
  32. package/dist/models/business/pay-button/ACHPaymentHandler.js +5 -4
  33. package/dist/models/business/pay-button/PPPaymentHandler.js +7 -2
  34. package/dist/models/business/pay-button/PayButton.d.ts +1 -0
  35. package/dist/models/business/pay-button/PayButton.js +55 -1
  36. package/dist/models/business/pay-button/cc-handler/DefaultCCPaymentHandler.d.ts +1 -0
  37. package/dist/models/business/pay-button/cc-handler/DefaultCCPaymentHandler.js +78 -4
  38. package/dist/models/business/pay-button/cc-handler/FxpCCPaymentHandler.js +3 -3
  39. package/dist/models/business/pay-button/cc-handler/StripeCCPaymentHandler.d.ts +2 -0
  40. package/dist/models/business/pay-button/cc-handler/StripeCCPaymentHandler.js +100 -42
  41. package/dist/models/business/payment/CCPayment.js +15 -10
  42. package/dist/models/business/payment/FxpCCPayment.js +15 -10
  43. package/dist/models/business/payment/StripeCCPayment.d.ts +1 -0
  44. package/dist/models/business/payment/StripeCCPayment.js +20 -11
  45. package/dist/report-event.d.ts +2 -0
  46. package/dist/report-event.js +12 -0
  47. package/dist/styles/address.css +1 -1
  48. package/dist/styles/button.css +7 -1
  49. package/dist/styles/checkout-page.css +1 -1
  50. package/dist/styles/custom-info.css +1 -1
  51. package/dist/styles/error-tip.css +1 -0
  52. package/dist/styles/fee.css +1 -1
  53. package/dist/styles/fxp-payment.css +1 -1
  54. package/dist/styles/global.css +1 -1
  55. package/dist/styles/input.css +1 -1
  56. package/dist/styles/loading.css +1 -1
  57. package/dist/styles/order-summary.css +1 -1
  58. package/dist/styles/payment.css +1 -1
  59. package/dist/styles/paypal-modal.css +1 -1
  60. package/dist/styles/phone-input.css +1 -1
  61. package/dist/styles/select-list.css +1 -1
  62. package/dist/styles/select.css +1 -1
  63. package/dist/styles/stripe-payment.css +1 -1
  64. package/dist/styles/theme.css +1 -1
  65. package/dist/types.d.ts +4 -2
  66. package/dist/types.js +2 -0
  67. package/dist/validate/phone.js +14 -5
  68. package/package.json +34 -11
@@ -1,20 +1,28 @@
1
1
  import { CheckoutEvents } from "../../types";
2
- import { divide100, minus, plus } from "../../utils";
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
- if (!productInfo || !productInfo.display.length)
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 = productInfo.display.map(product => ({
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, minus(product.originPrice, product.price));
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
  }
@@ -4,6 +4,7 @@ interface PaypalModalProps {
4
4
  onVisibleChange?: (visible: boolean) => void;
5
5
  }
6
6
  export declare class PaypalModalModel extends BusinessModel {
7
+ #private;
7
8
  visible: boolean;
8
9
  onVisibleChange: (visible: boolean) => void;
9
10
  countDown: number;
@@ -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
- // const { paypal_url } = await solidGetPaypalURL(EPaymentAction.ONFAIL, i18n.locale)
35
- // window.location.replace(paypal_url)
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();
@@ -23,6 +23,8 @@ export class AddressModel extends BusinessModel {
23
23
  province: addressData.province,
24
24
  zip: addressData.zip,
25
25
  });
26
+ // 关闭multiRegions的验证
27
+ this.multiRegions.clearErrorValues();
26
28
  };
27
29
  this.address1 = new AddressSuggestModel({
28
30
  label: 'Address',
@@ -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.feeSetting) === null || _b === void 0 ? void 0 : _b.tip) !== null && _c !== void 0 ? _c : true;
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);
@@ -9,3 +9,4 @@ export * from './OrderSummary';
9
9
  export * from './PaypalModal';
10
10
  export * from './fees';
11
11
  export * from './FullScreeenLoading';
12
+ export * from './ErrorTip';
@@ -9,3 +9,4 @@ export * from './OrderSummary';
9
9
  export * from './PaypalModal';
10
10
  export * from './fees';
11
11
  export * from './FullScreeenLoading';
12
+ export * from './ErrorTip';
@@ -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
- return;
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 === 4004 && __classPrivateFieldGet(this, _ACHPaymentHandler_orderResult, "f")) {
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
- return;
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
  }
@@ -16,5 +16,6 @@ export declare class PayButtonModel extends BusinessModel {
16
16
  validatePayment(): Promise<boolean>;
17
17
  preparePaymentData(): any;
18
18
  handlePayment(): Promise<void>;
19
+ invalidHandler(): Promise<void>;
19
20
  }
20
21
  export {};
@@ -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
- return this.paymentHandler.handlePayment();
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
- return;
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 === 4004 && __classPrivateFieldGet(this, _FxpCCPaymentHandler_orderResult, "f")) {
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.sku) !== null && _b !== void 0 ? _b : '0'}#,#${orderAmount}#,#${(_c = curr.quantity) !== null && _c !== void 0 ? _c : '0'}`;
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
  }