@paykka/card-checkout-ui 0.5.15 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/card-checkout-ui.js +22 -0
- package/dist/card-checkout-ui.umd.cjs +19 -5
- package/dist/es/api/index.js +3 -0
- package/dist/es/api/modules/checkout/map.js +2 -1
- package/dist/es/api/modules/encrypted-card/index.js +54 -0
- package/dist/es/api/modules/get-browser-params.js +2 -2
- package/dist/es/api/modules/index.js +3 -0
- package/dist/es/components/AccountNameField/index.js +4 -0
- package/dist/es/components/AddressField/index.js +4 -0
- package/dist/es/components/AliPay/index.js +8 -8
- package/dist/es/components/ApplePay/index.js +71 -14
- package/dist/es/components/Card/index.js +56 -40
- package/dist/es/components/CardExpireDateField/index.js +8 -3
- package/dist/es/components/CardHolderNameField/index.js +4 -0
- package/dist/es/components/CardIBANField/index.js +4 -0
- package/dist/es/components/CardNumberField/index.js +34 -17
- package/dist/es/components/CardSecurityCodeField/index.js +8 -3
- package/dist/es/components/CardSelector/index.js +3 -0
- package/dist/es/components/CombinedEncryptedField/index.js +75 -0
- package/dist/es/components/EmailField/EmailField.js +4 -0
- package/dist/es/components/EncryptedCard/index.js +448 -0
- package/dist/es/components/GooglePay/index.js +57 -19
- package/dist/es/components/RecurringTip/index.js +1 -1
- package/dist/es/components/SecuredFieldsProvider/SecuredFieldsProvider.js +70 -25
- package/dist/es/components/SecuredIframe/index.js +190 -22
- package/dist/es/components/Sepa/index.js +16 -6
- package/dist/es/components/WechatPay/index.js +8 -8
- package/dist/es/components/index.js +4 -0
- package/dist/es/components/internal/CheckBox/CheckBox.js +1 -1
- package/dist/es/components/internal/Form/FormItem.js +28 -24
- package/dist/es/components/internal/Form/index.js +1 -0
- package/dist/es/components/internal/Form/type.js +15 -1
- package/dist/es/components/internal/Input/Input.js +9 -11
- package/dist/es/components/internal/Input/index.js +1 -0
- package/dist/es/components/internal/Input/type.js +13 -1
- package/dist/es/components/internal/Select/Select.js +2 -0
- package/dist/es/config.js +23 -6
- package/dist/es/constant.js +10 -0
- package/dist/es/core/PayKKaCheckout.js +62 -0
- package/dist/es/core/Session.js +3 -0
- package/dist/es/core/index.js +2 -0
- package/dist/es/core/query.js +4 -6
- package/dist/es/core.js +30 -30
- package/dist/es/hooks/useI18n.js +2 -2
- package/dist/es/hooks/usePayState.js +14 -25
- package/dist/es/i18n/I18n.js +11 -8
- package/dist/es/index.js +16 -3
- package/dist/es/out/fraud-detection.js +99 -0
- package/dist/es/style.css +8 -0
- package/dist/es/types/{radar.js → fraud-detection.js} +1 -1
- package/dist/es/types/index.js +49 -1
- package/dist/es/utils/card-brand/brands.js +16 -42
- package/dist/es/utils/index.js +11 -0
- package/dist/es/utils/load.js +14 -0
- package/dist/es/utils/style.js +37 -0
- package/dist/style.css +1 -1
- package/dist/types/api/modules/checkout/map.d.ts +1 -0
- package/dist/types/api/modules/encrypted-card/index.d.ts +6 -0
- package/dist/types/api/modules/encrypted-card/type.d.ts +31 -0
- package/dist/types/api/modules/get-browser-params.d.ts +2 -2
- package/dist/types/components/AliPay/type.d.ts +0 -4
- package/dist/types/components/ApplePay/type.d.ts +16 -7
- package/dist/types/components/ApplePay/utils.d.ts +3 -0
- package/dist/types/components/Card/type.d.ts +15 -5
- package/dist/types/components/CardExpireDateField/type.d.ts +1 -0
- package/dist/types/components/CardNumberField/type.d.ts +3 -0
- package/dist/types/components/CardSecurityCodeField/type.d.ts +1 -0
- package/dist/types/components/CombinedEncryptedField/CombinedEncryptedField.d.ts +4 -0
- package/dist/types/components/CombinedEncryptedField/index.d.ts +2 -0
- package/dist/types/components/CombinedEncryptedField/type.d.ts +15 -0
- package/dist/types/components/EncryptedCard/EncryptedCard.d.ts +4 -0
- package/dist/types/components/EncryptedCard/index.d.ts +4 -0
- package/dist/types/components/EncryptedCard/output.d.ts +9 -0
- package/dist/types/components/EncryptedCard/type.d.ts +85 -0
- package/dist/types/components/GooglePay/type.d.ts +17 -8
- package/dist/types/components/GooglePay/utils.d.ts +2 -0
- package/dist/types/components/SecuredFieldsProvider/type.d.ts +103 -22
- package/dist/types/components/SecuredIframe/useSecuredInput.d.ts +6 -2
- package/dist/types/components/Sepa/type.d.ts +0 -4
- package/dist/types/components/WechatPay/type.d.ts +0 -4
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/components/internal/Form/FormItem.d.ts +1 -1
- package/dist/types/components/internal/Form/type.d.ts +7 -0
- package/dist/types/components/internal/Input/Input.d.ts +1 -1
- package/dist/types/components/internal/Input/type.d.ts +6 -0
- package/dist/types/config.d.ts +10 -3
- package/dist/types/constant.d.ts +1 -0
- package/dist/types/core/PayKKaCheckout.d.ts +12 -0
- package/dist/types/core/index.d.ts +1 -0
- package/dist/types/core/query.d.ts +2 -2
- package/dist/types/hooks/useI18n.d.ts +2 -2
- package/dist/types/hooks/usePayState.d.ts +4 -22
- package/dist/types/i18n/I18n.d.ts +6 -5
- package/dist/types/i18n/locales/index.d.ts +1 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/out/fraud-detection.d.ts +9 -0
- package/dist/types/types/{radar.d.ts → fraud-detection.d.ts} +3 -2
- package/dist/types/types/index.d.ts +69 -1
- package/dist/types/utils/card-brand/brands.d.ts +3 -10
- package/dist/types/utils/card-brand/index.d.ts +10 -9
- package/dist/types/utils/format.d.ts +2 -3
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/load.d.ts +7 -0
- package/dist/types/utils/style.d.ts +17 -0
- package/package.json +2 -2
- package/dist/card-checkout-ui.iife.js +0 -8
- package/dist/es/out/radar.js +0 -123
- package/dist/types/out/radar.d.ts +0 -14
|
@@ -8,22 +8,32 @@ import { w, A, F, y, q, u } from "../../core.js";
|
|
|
8
8
|
import { SessionMode } from "../../constant.js";
|
|
9
9
|
import { cdnUrl, cdnOrigin, apiUrl } from "../../config.js";
|
|
10
10
|
import { safeParse } from "../../utils/index.js";
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return
|
|
16
|
-
})(
|
|
11
|
+
var EFieldType = /* @__PURE__ */ ((EFieldType2) => {
|
|
12
|
+
EFieldType2["CARD_NUMBER"] = "CARD_NUMBER";
|
|
13
|
+
EFieldType2["CVV"] = "CVV";
|
|
14
|
+
EFieldType2["EXPIRE_DATE"] = "EXPIRE_DATE";
|
|
15
|
+
return EFieldType2;
|
|
16
|
+
})(EFieldType || {});
|
|
17
17
|
var MessageAction = /* @__PURE__ */ ((MessageAction2) => {
|
|
18
18
|
MessageAction2["INIT"] = "init";
|
|
19
|
+
MessageAction2["ACTIVATED"] = "Activated";
|
|
20
|
+
MessageAction2["HIDDEN_IFRAME_READY"] = "hiddenIframeReady";
|
|
19
21
|
MessageAction2["FOCUS"] = "focus";
|
|
20
22
|
MessageAction2["BIN_VALUE"] = "binValue";
|
|
23
|
+
MessageAction2["BRAND"] = "brand";
|
|
21
24
|
MessageAction2["VALID_WITH_VALUE"] = "validWithValue";
|
|
22
25
|
MessageAction2["PAYMENT"] = "payment";
|
|
23
26
|
MessageAction2["AFTER_PAYMENT"] = "afterPayment";
|
|
24
27
|
MessageAction2["PAYMENT_ERROR"] = "paymentError";
|
|
25
28
|
MessageAction2["PAYMENT_TIMEOUT"] = "paymentTimeout";
|
|
26
29
|
MessageAction2["VALID_STATUS_CHANGED"] = "validStatusChanged";
|
|
30
|
+
MessageAction2["VALIDATE"] = "validate";
|
|
31
|
+
MessageAction2["VALIDATED"] = "validated";
|
|
32
|
+
MessageAction2["SET_CONFIG"] = "setConfig";
|
|
33
|
+
MessageAction2["AUTHORIZED"] = "authorized";
|
|
34
|
+
MessageAction2["ENCRYPT_CARD"] = "encryptCard";
|
|
35
|
+
MessageAction2["CARD_ENCRYPTED"] = "cardEncrypted";
|
|
36
|
+
MessageAction2["CARD_ENCRYPTION_FAILED"] = "cardEncryptionFailed";
|
|
27
37
|
return MessageAction2;
|
|
28
38
|
})(MessageAction || {});
|
|
29
39
|
const SECURED_FILED_ATTR = "data-sf";
|
|
@@ -94,7 +104,7 @@ class SecuredField {
|
|
|
94
104
|
}
|
|
95
105
|
}
|
|
96
106
|
const SecuredFieldsProvider = w((props, ref) => {
|
|
97
|
-
const { sessionMode, i18n } = props;
|
|
107
|
+
const { sessionMode, i18n, targetElement } = props;
|
|
98
108
|
const rootNodeRef = A(null);
|
|
99
109
|
const hiddenIframe = A(null);
|
|
100
110
|
const payment = (formData) => {
|
|
@@ -112,27 +122,45 @@ const SecuredFieldsProvider = w((props, ref) => {
|
|
|
112
122
|
return;
|
|
113
123
|
}
|
|
114
124
|
window.removeEventListener("message", onReceiveMessage);
|
|
115
|
-
console.log(hiddenIframe.current);
|
|
116
125
|
if (hiddenIframe.current) {
|
|
117
126
|
document.body.removeChild(hiddenIframe.current);
|
|
118
127
|
}
|
|
119
128
|
init();
|
|
129
|
+
},
|
|
130
|
+
encryptCard: (encryptedInfo) => {
|
|
131
|
+
const data = {
|
|
132
|
+
action: MessageAction.ENCRYPT_CARD,
|
|
133
|
+
...encryptedInfo
|
|
134
|
+
};
|
|
135
|
+
postMessageToIframe(data, hiddenIframe.current.contentWindow, cdnOrigin);
|
|
136
|
+
},
|
|
137
|
+
validate: () => {
|
|
138
|
+
Object.values(securedFieldMap.current).forEach((field) => {
|
|
139
|
+
const data = {
|
|
140
|
+
action: MessageAction.VALIDATE
|
|
141
|
+
};
|
|
142
|
+
postMessageToIframe(data, field.iframe.contentWindow, cdnOrigin);
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
setConfig: (config) => {
|
|
146
|
+
props.style = config.style;
|
|
120
147
|
}
|
|
121
148
|
}));
|
|
122
|
-
if (sessionMode !== SessionMode.EMBEDDED) {
|
|
149
|
+
if (!frames && sessionMode !== SessionMode.EMBEDDED) {
|
|
123
150
|
return props.children;
|
|
124
151
|
}
|
|
125
152
|
let fieldNodes = [];
|
|
153
|
+
const securedFieldMap = A({});
|
|
126
154
|
const securedFieldPlaceholderMap = {
|
|
127
|
-
[
|
|
128
|
-
[
|
|
129
|
-
[
|
|
155
|
+
[EFieldType.CARD_NUMBER]: i18n.get("card.cardNumber.placeholder"),
|
|
156
|
+
[EFieldType.CVV]: i18n.get("card.cardSecurityCode.placeholder"),
|
|
157
|
+
[EFieldType.EXPIRE_DATE]: i18n.get("card.cardExpireDate.placeholder")
|
|
130
158
|
};
|
|
131
159
|
y(() => {
|
|
132
160
|
init();
|
|
133
161
|
}, []);
|
|
134
162
|
const init = async () => {
|
|
135
|
-
fieldNodes = getFieldElements(rootNodeRef.current);
|
|
163
|
+
fieldNodes = getFieldElements(targetElement || rootNodeRef.current);
|
|
136
164
|
if (!fieldNodes.length) {
|
|
137
165
|
return;
|
|
138
166
|
}
|
|
@@ -161,7 +189,7 @@ const SecuredFieldsProvider = w((props, ref) => {
|
|
|
161
189
|
const initAllFieldIframe = () => {
|
|
162
190
|
fieldNodes.forEach((fieldNode) => {
|
|
163
191
|
const fieldType = fieldNode.getAttribute(SECURED_FILED_ATTR);
|
|
164
|
-
new SecuredField({
|
|
192
|
+
securedFieldMap.current[fieldType] = new SecuredField({
|
|
165
193
|
fieldNode,
|
|
166
194
|
hiddenIframe: hiddenIframe.current,
|
|
167
195
|
hiddenIframeName: hiddenIframe.current.name,
|
|
@@ -170,9 +198,7 @@ const SecuredFieldsProvider = w((props, ref) => {
|
|
|
170
198
|
iframeClassName: SECURED_IFRAME_CLASS_NAME,
|
|
171
199
|
fieldType,
|
|
172
200
|
placeholder: securedFieldPlaceholderMap[fieldType],
|
|
173
|
-
style:
|
|
174
|
-
paddingLeft: "12px"
|
|
175
|
-
},
|
|
201
|
+
style: props.style,
|
|
176
202
|
supportedCardBrands: props.supportedCardBrands,
|
|
177
203
|
onFocus: props.onFocus,
|
|
178
204
|
onBinValue: props.onBinValue,
|
|
@@ -184,6 +210,7 @@ const SecuredFieldsProvider = w((props, ref) => {
|
|
|
184
210
|
});
|
|
185
211
|
};
|
|
186
212
|
const onReceiveMessage = q((event) => {
|
|
213
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
187
214
|
const { data, origin } = event;
|
|
188
215
|
if (origin !== cdnOrigin) {
|
|
189
216
|
return;
|
|
@@ -194,29 +221,47 @@ const SecuredFieldsProvider = w((props, ref) => {
|
|
|
194
221
|
}
|
|
195
222
|
switch (feedbackData.action) {
|
|
196
223
|
case MessageAction.FOCUS:
|
|
197
|
-
props.onFocus(feedbackData);
|
|
224
|
+
(_a = props.onFocus) == null ? void 0 : _a.call(props, feedbackData);
|
|
198
225
|
break;
|
|
199
226
|
case MessageAction.BIN_VALUE:
|
|
200
|
-
props.onBinValue(feedbackData);
|
|
227
|
+
(_b = props.onBinValue) == null ? void 0 : _b.call(props, feedbackData);
|
|
228
|
+
break;
|
|
229
|
+
case MessageAction.BRAND:
|
|
230
|
+
(_c = props.onBrand) == null ? void 0 : _c.call(props, feedbackData);
|
|
201
231
|
break;
|
|
202
232
|
case MessageAction.AFTER_PAYMENT:
|
|
203
|
-
props.onAfterPayment(feedbackData);
|
|
233
|
+
(_d = props.onAfterPayment) == null ? void 0 : _d.call(props, feedbackData);
|
|
204
234
|
break;
|
|
205
235
|
case MessageAction.PAYMENT_ERROR:
|
|
206
|
-
props.onPaymentError(feedbackData);
|
|
236
|
+
(_e = props.onPaymentError) == null ? void 0 : _e.call(props, feedbackData);
|
|
207
237
|
break;
|
|
208
238
|
case MessageAction.PAYMENT_TIMEOUT:
|
|
209
|
-
props.onPaymentTimeout(feedbackData);
|
|
239
|
+
(_f = props.onPaymentTimeout) == null ? void 0 : _f.call(props, feedbackData);
|
|
210
240
|
break;
|
|
211
241
|
case MessageAction.VALID_STATUS_CHANGED:
|
|
212
|
-
props.onValidStatusChanged(feedbackData);
|
|
242
|
+
(_g = props.onValidStatusChanged) == null ? void 0 : _g.call(props, feedbackData);
|
|
243
|
+
break;
|
|
244
|
+
case MessageAction.AUTHORIZED:
|
|
245
|
+
(_h = props.onAuthorized) == null ? void 0 : _h.call(props, feedbackData);
|
|
246
|
+
break;
|
|
247
|
+
case MessageAction.ACTIVATED:
|
|
248
|
+
(_i = props.onActivated) == null ? void 0 : _i.call(props, feedbackData);
|
|
249
|
+
break;
|
|
250
|
+
case MessageAction.CARD_ENCRYPTED:
|
|
251
|
+
(_j = props.onCardEncrypted) == null ? void 0 : _j.call(props, feedbackData);
|
|
252
|
+
break;
|
|
253
|
+
case MessageAction.CARD_ENCRYPTION_FAILED:
|
|
254
|
+
(_k = props.onCardEncryptionFailed) == null ? void 0 : _k.call(props, feedbackData);
|
|
255
|
+
break;
|
|
256
|
+
case MessageAction.VALIDATED:
|
|
257
|
+
(_l = props.onValidated) == null ? void 0 : _l.call(props, feedbackData);
|
|
213
258
|
break;
|
|
214
259
|
}
|
|
215
260
|
}, []);
|
|
216
|
-
return /* @__PURE__ */ u("div", { ref: rootNodeRef, children: props.children });
|
|
261
|
+
return /* @__PURE__ */ u("div", { ref: rootNodeRef, children: !targetElement && props.children });
|
|
217
262
|
});
|
|
218
263
|
export {
|
|
219
|
-
|
|
264
|
+
EFieldType,
|
|
220
265
|
MessageAction,
|
|
221
266
|
SecuredFieldsProvider,
|
|
222
267
|
postMessageToIframe
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { A, h, y, u, b } from "../../core.js";
|
|
2
2
|
import { clamp, isExpired, safeParse } from "../../utils/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { EFieldType, MessageAction, postMessageToIframe } from "../SecuredFieldsProvider/SecuredFieldsProvider.js";
|
|
4
4
|
import { getSupportedCardBrands, getSupportedCardBrandsLengths, findCardBrand } from "../../utils/card-brand/index.js";
|
|
5
5
|
import { limitedToNumber, trimAll } from "../../utils/format.js";
|
|
6
6
|
import { isUndefined, isNil } from "../../utils/is.js";
|
|
7
|
-
import "../../utils/card-brand/brands.js";
|
|
8
|
-
import "../../utils/system-info/get-browser-info.js";
|
|
9
7
|
import { cdnOrigin, setApiUrl, setCDNUrl } from "../../config.js";
|
|
8
|
+
import { generateClassNameMap, style2String, createPlaceholderStyle, loadStyle } from "../../utils/style.js";
|
|
10
9
|
import { isTimeoutError } from "../../api/http.js";
|
|
11
10
|
import { cardPay } from "../../api/modules/card/index.js";
|
|
11
|
+
import { encryptCard } from "../../api/modules/encrypted-card/index.js";
|
|
12
12
|
const useSecuredInput = () => {
|
|
13
13
|
let fieldType;
|
|
14
14
|
let supportedCardBrands;
|
|
@@ -16,6 +16,7 @@ const useSecuredInput = () => {
|
|
|
16
16
|
const [cardBin, setCardBin] = h("");
|
|
17
17
|
let brands;
|
|
18
18
|
let brandLengths;
|
|
19
|
+
const [brand, setBrand] = h(void 0);
|
|
19
20
|
const initSecuredInput = (options) => {
|
|
20
21
|
fieldType = options.fieldType;
|
|
21
22
|
supportedCardBrands = options.supportedCardBrands;
|
|
@@ -29,25 +30,28 @@ const useSecuredInput = () => {
|
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
32
|
switch (fieldType) {
|
|
32
|
-
case
|
|
33
|
+
case EFieldType.CVV: {
|
|
33
34
|
config = {
|
|
34
35
|
maxLength: 4,
|
|
36
|
+
inputMode: "numeric",
|
|
35
37
|
onInput: onInputCVV,
|
|
36
38
|
validator: cvvValidator
|
|
37
39
|
};
|
|
38
40
|
break;
|
|
39
41
|
}
|
|
40
|
-
case
|
|
42
|
+
case EFieldType.CARD_NUMBER: {
|
|
41
43
|
config = {
|
|
42
44
|
maxLength: 23,
|
|
45
|
+
inputMode: "numeric",
|
|
43
46
|
onInput: onInputCardNumber,
|
|
44
47
|
validator: cardNumberValidator
|
|
45
48
|
};
|
|
46
49
|
break;
|
|
47
50
|
}
|
|
48
|
-
case
|
|
51
|
+
case EFieldType.EXPIRE_DATE: {
|
|
49
52
|
config = {
|
|
50
53
|
maxLength: 5,
|
|
54
|
+
inputMode: "numeric",
|
|
51
55
|
onInput: onInputExpireDate,
|
|
52
56
|
validator: expireDateValidator
|
|
53
57
|
};
|
|
@@ -62,6 +66,7 @@ const useSecuredInput = () => {
|
|
|
62
66
|
value.current = currentTarget.value = val;
|
|
63
67
|
};
|
|
64
68
|
const onInputCardNumber = (event) => {
|
|
69
|
+
var _a;
|
|
65
70
|
const { inputType } = event;
|
|
66
71
|
const currentTarget = event.currentTarget;
|
|
67
72
|
const selectionStart = currentTarget.selectionStart;
|
|
@@ -73,7 +78,9 @@ const useSecuredInput = () => {
|
|
|
73
78
|
}
|
|
74
79
|
value.current = currentTarget.value = val;
|
|
75
80
|
currentTarget.setSelectionRange(pos, pos);
|
|
76
|
-
|
|
81
|
+
const newBin = trimAll(currentTarget.value).substring(0, 6);
|
|
82
|
+
setCardBin(newBin.length < 6 ? "" : newBin);
|
|
83
|
+
setBrand((_a = getCurrCardBrand(trimAll(currentTarget.value))) == null ? void 0 : _a.code);
|
|
77
84
|
};
|
|
78
85
|
const onInputExpireDate = (event) => {
|
|
79
86
|
const { inputType } = event;
|
|
@@ -145,7 +152,7 @@ const useSecuredInput = () => {
|
|
|
145
152
|
if (!brandLengths.includes(realValue.length)) {
|
|
146
153
|
throw new Error("card.cardNumber.incomplete");
|
|
147
154
|
}
|
|
148
|
-
const cardBrand =
|
|
155
|
+
const cardBrand = getCurrCardBrand(realValue);
|
|
149
156
|
if (!cardBrand) {
|
|
150
157
|
throw new Error("card.cardNumber.invalid");
|
|
151
158
|
}
|
|
@@ -159,18 +166,35 @@ const useSecuredInput = () => {
|
|
|
159
166
|
throw new Error("card.cardExpireDate.expired");
|
|
160
167
|
}
|
|
161
168
|
};
|
|
169
|
+
const getCurrCardBrand = (realValue) => {
|
|
170
|
+
return findCardBrand(realValue, brands);
|
|
171
|
+
};
|
|
172
|
+
const validate = () => {
|
|
173
|
+
if (fieldType === EFieldType.CARD_NUMBER) {
|
|
174
|
+
return cardNumberValidator();
|
|
175
|
+
} else if (fieldType === EFieldType.CVV) {
|
|
176
|
+
return cvvValidator();
|
|
177
|
+
} else if (fieldType === EFieldType.EXPIRE_DATE) {
|
|
178
|
+
return expireDateValidator();
|
|
179
|
+
}
|
|
180
|
+
};
|
|
162
181
|
return {
|
|
163
182
|
value,
|
|
164
183
|
cardBin,
|
|
165
184
|
initSecuredInput,
|
|
166
|
-
getConfigByFieldType
|
|
185
|
+
getConfigByFieldType,
|
|
186
|
+
getCurrCardBrand,
|
|
187
|
+
brand,
|
|
188
|
+
validate
|
|
167
189
|
};
|
|
168
190
|
};
|
|
191
|
+
const inputClassNameMap = generateClassNameMap("input");
|
|
169
192
|
const FieldIframe = (props) => {
|
|
170
193
|
const hiddenIframe = window.parent.frames[props.hiddenIframeName];
|
|
171
194
|
const inputRef = A(null);
|
|
172
|
-
const { initSecuredInput, getConfigByFieldType, cardBin, value } = useSecuredInput();
|
|
195
|
+
const { initSecuredInput, getConfigByFieldType, getCurrCardBrand, cardBin, value, brand } = useSecuredInput();
|
|
173
196
|
const [hasInit, setHasInit] = h(false);
|
|
197
|
+
const inputId = "securedInput";
|
|
174
198
|
const initInput = () => {
|
|
175
199
|
initSecuredInput({
|
|
176
200
|
fieldType: props.fieldType,
|
|
@@ -179,47 +203,128 @@ const FieldIframe = (props) => {
|
|
|
179
203
|
postMessageToIframe(message, window.parent);
|
|
180
204
|
}
|
|
181
205
|
});
|
|
206
|
+
processInputStyleConfig(props.style);
|
|
207
|
+
};
|
|
208
|
+
const processInputStyleConfig = (style = {}) => {
|
|
209
|
+
const { base, hover, focus, valid, invalid, placeholder } = style;
|
|
210
|
+
const baseStyleStr = `input { ${style2String(base)} }`;
|
|
211
|
+
const hoverStyleStr = `input.${inputClassNameMap.hover} { ${style2String(hover)} }`;
|
|
212
|
+
const focusStyleStr = `input.${inputClassNameMap.focus} { ${style2String(focus)} }`;
|
|
213
|
+
const validStyleStr = `input.${inputClassNameMap.valid} { ${style2String(valid)} }`;
|
|
214
|
+
const invalidStyleStr = `input.${inputClassNameMap.invalid} { ${style2String(invalid)} }`;
|
|
215
|
+
const placeholderStyleStr = createPlaceholderStyle("input", placeholder == null ? void 0 : placeholder.base);
|
|
216
|
+
const placeholderFocusStyleStr = createPlaceholderStyle(
|
|
217
|
+
`input.${inputClassNameMap.focus}`,
|
|
218
|
+
placeholder == null ? void 0 : placeholder.focus
|
|
219
|
+
);
|
|
220
|
+
const styleStr = `
|
|
221
|
+
${baseStyleStr}
|
|
222
|
+
${hoverStyleStr}
|
|
223
|
+
${focusStyleStr}
|
|
224
|
+
${validStyleStr}
|
|
225
|
+
${invalidStyleStr}
|
|
226
|
+
${placeholderStyleStr}
|
|
227
|
+
${placeholderFocusStyleStr}
|
|
228
|
+
`;
|
|
229
|
+
const styleId = "securedInputStyle";
|
|
230
|
+
if (!document.querySelector(`style#${styleId}`)) {
|
|
231
|
+
loadStyle(styleStr, { id: styleId });
|
|
232
|
+
}
|
|
182
233
|
};
|
|
183
234
|
y(() => {
|
|
235
|
+
initInput();
|
|
184
236
|
const inputConfig = getConfigByFieldType();
|
|
185
237
|
const inputEl = inputRef.current;
|
|
186
238
|
inputEl.oninput = inputConfig.onInput;
|
|
187
239
|
inputEl.maxLength = inputConfig.maxLength;
|
|
188
|
-
inputEl.
|
|
240
|
+
inputEl.inputMode = inputConfig.inputMode;
|
|
241
|
+
inputEl.onfocus = () => {
|
|
242
|
+
var _a;
|
|
243
|
+
(_a = inputEl == null ? void 0 : inputEl.classList) == null ? void 0 : _a.add(inputClassNameMap.focus);
|
|
244
|
+
sendFocusMessage(true);
|
|
245
|
+
};
|
|
189
246
|
inputEl.onblur = () => {
|
|
190
|
-
|
|
247
|
+
var _a;
|
|
191
248
|
try {
|
|
249
|
+
(_a = inputEl == null ? void 0 : inputEl.classList) == null ? void 0 : _a.remove(inputClassNameMap.focus);
|
|
192
250
|
if (isNil(value.current) || value.current === "") {
|
|
193
|
-
|
|
251
|
+
processValidStatusChanged("unValidate");
|
|
252
|
+
sendFocusMessage(false);
|
|
194
253
|
return;
|
|
195
254
|
}
|
|
196
255
|
inputConfig.validator();
|
|
197
|
-
|
|
256
|
+
processValidStatusChanged("success");
|
|
198
257
|
} catch (error) {
|
|
199
|
-
|
|
258
|
+
processValidStatusChanged("error", error);
|
|
200
259
|
}
|
|
260
|
+
sendFocusMessage(false);
|
|
261
|
+
};
|
|
262
|
+
inputEl.onmouseenter = (e) => {
|
|
263
|
+
var _a;
|
|
264
|
+
const inputEl2 = e.target;
|
|
265
|
+
(_a = inputEl2 == null ? void 0 : inputEl2.classList) == null ? void 0 : _a.add(inputClassNameMap.hover);
|
|
266
|
+
};
|
|
267
|
+
inputEl.onmouseleave = (e) => {
|
|
268
|
+
var _a;
|
|
269
|
+
const inputEl2 = e.target;
|
|
270
|
+
(_a = inputEl2 == null ? void 0 : inputEl2.classList) == null ? void 0 : _a.remove(inputClassNameMap.hover);
|
|
201
271
|
};
|
|
202
272
|
setHasInit(true);
|
|
273
|
+
sendActivatedMessage();
|
|
274
|
+
window.addEventListener("message", onReceiveMessage);
|
|
203
275
|
}, []);
|
|
204
|
-
|
|
276
|
+
const onReceiveMessage = (event) => {
|
|
277
|
+
const { data } = event;
|
|
278
|
+
const parsedData = safeParse(data);
|
|
279
|
+
if (!Reflect.has(parsedData, "action")) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (parsedData.action === MessageAction.VALIDATE) {
|
|
283
|
+
try {
|
|
284
|
+
const inputConfig = getConfigByFieldType();
|
|
285
|
+
inputConfig.validator();
|
|
286
|
+
processValidStatusChanged("success");
|
|
287
|
+
sendValidateMessage("success");
|
|
288
|
+
} catch (error) {
|
|
289
|
+
processValidStatusChanged("error", error);
|
|
290
|
+
sendValidateMessage("error");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
};
|
|
205
294
|
y(() => {
|
|
206
295
|
if (!hasInit) {
|
|
207
296
|
return;
|
|
208
297
|
}
|
|
209
298
|
sendBinValueMessage(cardBin);
|
|
210
299
|
}, [cardBin]);
|
|
300
|
+
y(() => {
|
|
301
|
+
if (!hasInit) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
sendBrandMessage(brand);
|
|
305
|
+
}, [brand]);
|
|
211
306
|
y(() => {
|
|
212
307
|
if (!hasInit) {
|
|
213
308
|
return;
|
|
214
309
|
}
|
|
215
310
|
if (!value) {
|
|
216
|
-
|
|
311
|
+
processValidStatusChanged("unValidate");
|
|
217
312
|
}
|
|
218
313
|
}, [value]);
|
|
219
314
|
const sendBinValueMessage = (binValue) => {
|
|
315
|
+
var _a;
|
|
220
316
|
const data = {
|
|
221
317
|
action: MessageAction.BIN_VALUE,
|
|
222
318
|
binValue,
|
|
319
|
+
fieldType: props.fieldType,
|
|
320
|
+
brand: (_a = getCurrCardBrand(binValue)) == null ? void 0 : _a.code
|
|
321
|
+
};
|
|
322
|
+
postMessageToIframe(data, window.parent);
|
|
323
|
+
};
|
|
324
|
+
const sendBrandMessage = (brand2) => {
|
|
325
|
+
const data = {
|
|
326
|
+
action: MessageAction.BRAND,
|
|
327
|
+
brand: brand2,
|
|
223
328
|
fieldType: props.fieldType
|
|
224
329
|
};
|
|
225
330
|
postMessageToIframe(data, window.parent);
|
|
@@ -232,6 +337,19 @@ const FieldIframe = (props) => {
|
|
|
232
337
|
};
|
|
233
338
|
postMessageToIframe(data, window.parent);
|
|
234
339
|
};
|
|
340
|
+
const processValidStatusChanged = (status, err) => {
|
|
341
|
+
const inputEl = inputRef.current;
|
|
342
|
+
if (status === "unValidate") {
|
|
343
|
+
inputEl.classList.remove(inputClassNameMap.valid, inputClassNameMap.invalid);
|
|
344
|
+
} else if (status === "success") {
|
|
345
|
+
inputEl.classList.add(inputClassNameMap.valid);
|
|
346
|
+
inputEl.classList.remove(inputClassNameMap.invalid);
|
|
347
|
+
} else {
|
|
348
|
+
inputEl.classList.add(inputClassNameMap.invalid);
|
|
349
|
+
inputEl.classList.remove(inputClassNameMap.valid);
|
|
350
|
+
}
|
|
351
|
+
sendValidStatusChanged(status, err);
|
|
352
|
+
};
|
|
235
353
|
const sendValidStatusChanged = (status, err) => {
|
|
236
354
|
const validData = {
|
|
237
355
|
action: MessageAction.VALID_STATUS_CHANGED,
|
|
@@ -243,6 +361,9 @@ const FieldIframe = (props) => {
|
|
|
243
361
|
if (status !== "success") {
|
|
244
362
|
return;
|
|
245
363
|
}
|
|
364
|
+
sendValidWithValueMessage();
|
|
365
|
+
};
|
|
366
|
+
const sendValidWithValueMessage = () => {
|
|
246
367
|
const validWithValueData = {
|
|
247
368
|
action: MessageAction.VALID_WITH_VALUE,
|
|
248
369
|
value: value.current,
|
|
@@ -250,12 +371,27 @@ const FieldIframe = (props) => {
|
|
|
250
371
|
};
|
|
251
372
|
postMessageToIframe(validWithValueData, hiddenIframe, cdnOrigin);
|
|
252
373
|
};
|
|
374
|
+
const sendActivatedMessage = () => {
|
|
375
|
+
const data = {
|
|
376
|
+
action: MessageAction.ACTIVATED,
|
|
377
|
+
fieldType: props.fieldType
|
|
378
|
+
};
|
|
379
|
+
postMessageToIframe(data, window.parent);
|
|
380
|
+
};
|
|
381
|
+
const sendValidateMessage = (status) => {
|
|
382
|
+
const data = {
|
|
383
|
+
action: MessageAction.VALIDATED,
|
|
384
|
+
fieldType: props.fieldType,
|
|
385
|
+
status
|
|
386
|
+
};
|
|
387
|
+
postMessageToIframe(data, window.parent);
|
|
388
|
+
};
|
|
253
389
|
return /* @__PURE__ */ u(
|
|
254
390
|
"input",
|
|
255
391
|
{
|
|
392
|
+
id: inputId,
|
|
256
393
|
ref: inputRef,
|
|
257
394
|
placeholder: props.placeholder,
|
|
258
|
-
style: props.style,
|
|
259
395
|
autocomplete: "off",
|
|
260
396
|
disabled: !hasInit
|
|
261
397
|
}
|
|
@@ -268,7 +404,7 @@ const HiddenIframe = () => {
|
|
|
268
404
|
cardNo: "",
|
|
269
405
|
cvv: ""
|
|
270
406
|
};
|
|
271
|
-
const onReceiveMessage = (event) => {
|
|
407
|
+
const onReceiveMessage = async (event) => {
|
|
272
408
|
const { data } = event;
|
|
273
409
|
const parsedData = safeParse(data);
|
|
274
410
|
if (!Reflect.has(parsedData, "action")) {
|
|
@@ -277,15 +413,15 @@ const HiddenIframe = () => {
|
|
|
277
413
|
if (parsedData.action === MessageAction.VALID_WITH_VALUE) {
|
|
278
414
|
const feedbackData = parsedData;
|
|
279
415
|
switch (feedbackData.fieldType) {
|
|
280
|
-
case
|
|
416
|
+
case EFieldType.CVV: {
|
|
281
417
|
formData.cvv = feedbackData.value;
|
|
282
418
|
break;
|
|
283
419
|
}
|
|
284
|
-
case
|
|
420
|
+
case EFieldType.CARD_NUMBER: {
|
|
285
421
|
formData.cardNo = trimAll(feedbackData.value);
|
|
286
422
|
break;
|
|
287
423
|
}
|
|
288
|
-
case
|
|
424
|
+
case EFieldType.EXPIRE_DATE: {
|
|
289
425
|
const [expMonth, expYear] = feedbackData.value.split("/");
|
|
290
426
|
formData.expMonth = expMonth;
|
|
291
427
|
formData.expYear = `20${expYear}`;
|
|
@@ -295,6 +431,15 @@ const HiddenIframe = () => {
|
|
|
295
431
|
} else if (parsedData.action === MessageAction.PAYMENT) {
|
|
296
432
|
const feedbackData = parsedData;
|
|
297
433
|
pay(feedbackData.formData, feedbackData.locale);
|
|
434
|
+
} else if (parsedData.action === MessageAction.ENCRYPT_CARD) {
|
|
435
|
+
const feedbackData = parsedData;
|
|
436
|
+
try {
|
|
437
|
+
const res = await encryptCard({ ...feedbackData, ...formData });
|
|
438
|
+
sendCardEncryptedMessage(res);
|
|
439
|
+
} catch (error) {
|
|
440
|
+
console.log("error", error);
|
|
441
|
+
sendCardEncryptionFailedMessage(error);
|
|
442
|
+
}
|
|
298
443
|
}
|
|
299
444
|
};
|
|
300
445
|
window.addEventListener("message", onReceiveMessage);
|
|
@@ -339,6 +484,29 @@ const HiddenIframe = () => {
|
|
|
339
484
|
};
|
|
340
485
|
postMessageToIframe(data, window.parent);
|
|
341
486
|
};
|
|
487
|
+
const sendHiddenIframeReadyMessage = () => {
|
|
488
|
+
const data = {
|
|
489
|
+
action: MessageAction.HIDDEN_IFRAME_READY
|
|
490
|
+
};
|
|
491
|
+
postMessageToIframe(data, window.parent);
|
|
492
|
+
};
|
|
493
|
+
const sendCardEncryptedMessage = (encryptedInfo) => {
|
|
494
|
+
const data = {
|
|
495
|
+
action: MessageAction.CARD_ENCRYPTED,
|
|
496
|
+
encryptedInfo
|
|
497
|
+
};
|
|
498
|
+
postMessageToIframe(data, window.parent);
|
|
499
|
+
};
|
|
500
|
+
const sendCardEncryptionFailedMessage = (error) => {
|
|
501
|
+
const data = {
|
|
502
|
+
action: MessageAction.CARD_ENCRYPTION_FAILED,
|
|
503
|
+
error
|
|
504
|
+
};
|
|
505
|
+
postMessageToIframe(data, window.parent);
|
|
506
|
+
};
|
|
507
|
+
y(() => {
|
|
508
|
+
sendHiddenIframeReadyMessage();
|
|
509
|
+
}, []);
|
|
342
510
|
return /* @__PURE__ */ u(b, {});
|
|
343
511
|
};
|
|
344
512
|
const SecuredIframe = () => {
|
|
@@ -17,6 +17,7 @@ import { useRetry } from "../../hooks/useRetry.js";
|
|
|
17
17
|
import { AddressField } from "../AddressField/index.js";
|
|
18
18
|
import { EmailField, createEmailCore } from "../EmailField/EmailField.js";
|
|
19
19
|
import { SubmitButton } from "../SubmitButton/index.js";
|
|
20
|
+
import "../internal/Form/type.js";
|
|
20
21
|
import "../internal/Form/context.js";
|
|
21
22
|
import "../internal/Form/FormItem.js";
|
|
22
23
|
import { Form } from "../internal/Form/Form.js";
|
|
@@ -27,10 +28,9 @@ const { bem } = useBEM("sepa");
|
|
|
27
28
|
const fieldClassNames = bem("field");
|
|
28
29
|
const Sepa = w((props, ref) => {
|
|
29
30
|
var _a, _b, _c, _d, _e, _f;
|
|
30
|
-
const { sessionId, clientKey } = props;
|
|
31
31
|
let addressState = createAddressCore();
|
|
32
32
|
let emailState = createEmailCore();
|
|
33
|
-
const { i18n, session, sessionReady } = usePayState(
|
|
33
|
+
const { i18n, session, sessionReady } = usePayState();
|
|
34
34
|
const addressFieldRef = A(null);
|
|
35
35
|
const emailFieldRef = A(null);
|
|
36
36
|
const formRef = A(null);
|
|
@@ -160,8 +160,8 @@ const Sepa = w((props, ref) => {
|
|
|
160
160
|
});
|
|
161
161
|
const getPaymentParams = async () => {
|
|
162
162
|
return {
|
|
163
|
-
sessionId,
|
|
164
|
-
clientKey,
|
|
163
|
+
sessionId: session.sessionId,
|
|
164
|
+
clientKey: session.clientKey,
|
|
165
165
|
payment: {
|
|
166
166
|
holderName: form.holderName,
|
|
167
167
|
iban: trimAll(form.iban)
|
|
@@ -182,7 +182,10 @@ const Sepa = w((props, ref) => {
|
|
|
182
182
|
try {
|
|
183
183
|
const paymentParams = await getPaymentParams();
|
|
184
184
|
const options = { locale: i18n.locale, timeout };
|
|
185
|
-
const res = search ? await getSepaPayInfo(
|
|
185
|
+
const res = search ? await getSepaPayInfo(
|
|
186
|
+
{ sessionId: session.sessionId, clientKey: session.clientKey },
|
|
187
|
+
options
|
|
188
|
+
) : await sepaPay(paymentParams, options);
|
|
186
189
|
return processAfterPayment(res, search);
|
|
187
190
|
} catch (error) {
|
|
188
191
|
if (isTimeoutError(error)) {
|
|
@@ -250,7 +253,14 @@ const Sepa = w((props, ref) => {
|
|
|
250
253
|
session
|
|
251
254
|
},
|
|
252
255
|
children: sessionReady && isCheckoutEnabled && i18n.ready.value && /* @__PURE__ */ u(Form, { form, ref: setFormRef, onFormChange: (form2) => setForm(form2), children: /* @__PURE__ */ u("div", { className: normalizedClass(COMMON_CLASS_NAME, bem()), style: formStyle, children: [
|
|
253
|
-
/* @__PURE__ */ u("div", { className: fieldClassNames, children: /* @__PURE__ */ u(
|
|
256
|
+
/* @__PURE__ */ u("div", { className: fieldClassNames, children: /* @__PURE__ */ u(
|
|
257
|
+
EmailField,
|
|
258
|
+
{
|
|
259
|
+
ref: emailFieldRef,
|
|
260
|
+
value: form.email,
|
|
261
|
+
disabled: !!disabledEmail.current
|
|
262
|
+
}
|
|
263
|
+
) }),
|
|
254
264
|
/* @__PURE__ */ u("div", { className: fieldClassNames, children: /* @__PURE__ */ u("div", { className: bem("iban-wrapper"), children: /* @__PURE__ */ u(IBANField, {}) }) }),
|
|
255
265
|
/* @__PURE__ */ u("div", { className: bem("holder-name"), children: /* @__PURE__ */ u(AccountNameField, {}) }),
|
|
256
266
|
requiredBill && /* @__PURE__ */ u("div", { className: bem("address"), children: /* @__PURE__ */ u(
|
|
@@ -7,14 +7,15 @@ import "../../utils/system-info/get-browser-info.js";
|
|
|
7
7
|
import { formatAmount } from "../../utils/format.js";
|
|
8
8
|
import { getWechatPayInfo, wechatPay } from "../../api/modules/wechat-pay/index.js";
|
|
9
9
|
import { CoreContext } from "../../core/context.js";
|
|
10
|
-
import { createAddressCore } from "../../core/Address.js";
|
|
11
|
-
import { useBEM } from "../../hooks/useBEM.js";
|
|
12
10
|
import "../../i18n/util.js";
|
|
13
11
|
import "../../i18n/locales/index.js";
|
|
12
|
+
import { createAddressCore } from "../../core/Address.js";
|
|
13
|
+
import { useBEM } from "../../hooks/useBEM.js";
|
|
14
14
|
import { usePayState } from "../../hooks/usePayState.js";
|
|
15
15
|
import { useRetry } from "../../hooks/useRetry.js";
|
|
16
16
|
import { AddressField } from "../AddressField/index.js";
|
|
17
17
|
import { EmailField, createEmailCore } from "../EmailField/EmailField.js";
|
|
18
|
+
import "../internal/Form/type.js";
|
|
18
19
|
import "../internal/Form/context.js";
|
|
19
20
|
import "../internal/Form/FormItem.js";
|
|
20
21
|
import { Form } from "../internal/Form/Form.js";
|
|
@@ -23,7 +24,6 @@ import { RecurringTip } from "../RecurringTip/index.js";
|
|
|
23
24
|
import { SubmitButton } from "../SubmitButton/index.js";
|
|
24
25
|
const { bem } = useBEM("wechat-pay");
|
|
25
26
|
const WechatPay = w((props, ref) => {
|
|
26
|
-
const { sessionId, clientKey } = props;
|
|
27
27
|
let addressState = createAddressCore();
|
|
28
28
|
let emailState = createEmailCore();
|
|
29
29
|
const emailFieldRef = A(null);
|
|
@@ -57,7 +57,7 @@ const WechatPay = w((props, ref) => {
|
|
|
57
57
|
submitButtonStatus,
|
|
58
58
|
errorMsg,
|
|
59
59
|
sessionReady
|
|
60
|
-
} = usePayState(
|
|
60
|
+
} = usePayState();
|
|
61
61
|
const formRef = A(null);
|
|
62
62
|
const [form, setForm] = h({
|
|
63
63
|
email: "",
|
|
@@ -119,14 +119,14 @@ const WechatPay = w((props, ref) => {
|
|
|
119
119
|
try {
|
|
120
120
|
const res = search ? await getWechatPayInfo(
|
|
121
121
|
{
|
|
122
|
-
sessionId,
|
|
123
|
-
clientKey
|
|
122
|
+
sessionId: session.sessionId,
|
|
123
|
+
clientKey: session.clientKey
|
|
124
124
|
},
|
|
125
125
|
{ locale: i18n.locale, timeout }
|
|
126
126
|
) : await wechatPay(
|
|
127
127
|
{
|
|
128
|
-
sessionId,
|
|
129
|
-
clientKey,
|
|
128
|
+
sessionId: session.sessionId,
|
|
129
|
+
clientKey: session.clientKey,
|
|
130
130
|
bill: requiredBill ? {
|
|
131
131
|
email: form.email,
|
|
132
132
|
...form.address,
|