@youidian/sdk 3.4.1 → 3.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.cjs +801 -11
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +44 -2
- package/dist/client.d.ts +44 -2
- package/dist/client.js +799 -11
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +872 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +870 -20
- package/dist/index.js.map +1 -1
- package/dist/login.cjs +14 -3
- package/dist/login.cjs.map +1 -1
- package/dist/login.js +14 -3
- package/dist/login.js.map +1 -1
- package/dist/server.cjs +71 -9
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +106 -1
- package/dist/server.d.ts +106 -1
- package/dist/server.js +71 -9
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -23,14 +23,231 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
23
23
|
var client_exports = {};
|
|
24
24
|
__export(client_exports, {
|
|
25
25
|
LoginUI: () => LoginUI,
|
|
26
|
+
MessageUI: () => MessageUI,
|
|
26
27
|
PaymentUI: () => PaymentUI,
|
|
27
28
|
createLoginUI: () => createLoginUI,
|
|
29
|
+
createMessageUI: () => createMessageUI,
|
|
28
30
|
createPaymentUI: () => createPaymentUI,
|
|
29
31
|
detectLoginEnvironment: () => detectLoginEnvironment,
|
|
30
32
|
handleLoginCallbackIfPresent: () => handleLoginCallbackIfPresent
|
|
31
33
|
});
|
|
32
34
|
module.exports = __toCommonJS(client_exports);
|
|
33
35
|
|
|
36
|
+
// src/brand-logo.ts
|
|
37
|
+
function ensureSdkBrandLogoStyles() {
|
|
38
|
+
if (document.getElementById?.("youidian-sdk-brand-logo-style")) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const style = document.createElement("style");
|
|
42
|
+
style.id = "youidian-sdk-brand-logo-style";
|
|
43
|
+
style.textContent = `
|
|
44
|
+
.youidian-sdk-brand-logo__ring,
|
|
45
|
+
.youidian-sdk-brand-logo__dot,
|
|
46
|
+
.youidian-sdk-brand-logo__copy,
|
|
47
|
+
.youidian-sdk-brand-logo__tagline {
|
|
48
|
+
transform-box: fill-box;
|
|
49
|
+
transform-origin: center;
|
|
50
|
+
will-change: opacity, transform;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__ring {
|
|
54
|
+
animation: youidian-sdk-brand-logo-ring 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__dot {
|
|
58
|
+
animation: youidian-sdk-brand-logo-dot 1400ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__copy {
|
|
62
|
+
animation: youidian-sdk-brand-logo-copy 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.youidian-sdk-brand-logo[data-animated="true"] .youidian-sdk-brand-logo__tagline {
|
|
66
|
+
animation: youidian-sdk-brand-logo-tagline 1600ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@keyframes youidian-sdk-brand-logo-ring {
|
|
70
|
+
0%,
|
|
71
|
+
100% {
|
|
72
|
+
opacity: 0.72;
|
|
73
|
+
transform: rotate(0deg) scale(0.98);
|
|
74
|
+
}
|
|
75
|
+
50% {
|
|
76
|
+
opacity: 1;
|
|
77
|
+
transform: rotate(8deg) scale(1.02);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@keyframes youidian-sdk-brand-logo-dot {
|
|
82
|
+
0%,
|
|
83
|
+
100% {
|
|
84
|
+
opacity: 0.58;
|
|
85
|
+
transform: scale(0.9);
|
|
86
|
+
}
|
|
87
|
+
50% {
|
|
88
|
+
opacity: 1;
|
|
89
|
+
transform: scale(1.08);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@keyframes youidian-sdk-brand-logo-copy {
|
|
94
|
+
0%,
|
|
95
|
+
100% {
|
|
96
|
+
opacity: 0.86;
|
|
97
|
+
transform: translateY(0);
|
|
98
|
+
}
|
|
99
|
+
50% {
|
|
100
|
+
opacity: 1;
|
|
101
|
+
transform: translateY(-1px);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@keyframes youidian-sdk-brand-logo-tagline {
|
|
106
|
+
0%,
|
|
107
|
+
100% {
|
|
108
|
+
opacity: 0.64;
|
|
109
|
+
}
|
|
110
|
+
50% {
|
|
111
|
+
opacity: 0.92;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.youidian-sdk-brand-logo__ring,
|
|
117
|
+
.youidian-sdk-brand-logo__dot,
|
|
118
|
+
.youidian-sdk-brand-logo__copy,
|
|
119
|
+
.youidian-sdk-brand-logo__tagline {
|
|
120
|
+
animation: none;
|
|
121
|
+
opacity: 1;
|
|
122
|
+
transform: none;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`;
|
|
126
|
+
document.head?.appendChild(style);
|
|
127
|
+
}
|
|
128
|
+
function createSdkBrandLogoMark({
|
|
129
|
+
animated,
|
|
130
|
+
inverted,
|
|
131
|
+
size,
|
|
132
|
+
theme,
|
|
133
|
+
variant = "brand"
|
|
134
|
+
}) {
|
|
135
|
+
ensureSdkBrandLogoStyles();
|
|
136
|
+
const mark = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
137
|
+
mark.setAttribute("viewBox", "0 0 512 512");
|
|
138
|
+
mark.setAttribute("fill", "none");
|
|
139
|
+
mark.setAttribute("aria-hidden", "true");
|
|
140
|
+
Object.assign(mark.style, {
|
|
141
|
+
width: `${size}px`,
|
|
142
|
+
height: `${size}px`,
|
|
143
|
+
color: inverted ? "#ffffff" : theme.primary,
|
|
144
|
+
display: "block",
|
|
145
|
+
flex: "0 0 auto",
|
|
146
|
+
overflow: "visible"
|
|
147
|
+
});
|
|
148
|
+
const logoGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
149
|
+
logoGroup.setAttribute(
|
|
150
|
+
"transform",
|
|
151
|
+
variant === "mark" ? "matrix(0.74 0 0 0.74 -124 -114)" : "matrix(0.58 0 0 0.58 -40 -31)"
|
|
152
|
+
);
|
|
153
|
+
const ring = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
154
|
+
ring.setAttribute("class", animated ? "youidian-sdk-brand-logo__ring" : "");
|
|
155
|
+
ring.setAttribute("fill", inverted ? "currentColor" : theme.primary);
|
|
156
|
+
ring.setAttribute(
|
|
157
|
+
"d",
|
|
158
|
+
"M704.298 679.54A264 264 0 1 1 704.298 309.46A49 49 0 0 1 634.4 378.149A166 166 0 1 0 634.4 610.851A49 49 0 0 1 704.298 679.54Z"
|
|
159
|
+
);
|
|
160
|
+
const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
161
|
+
dot.setAttribute("class", animated ? "youidian-sdk-brand-logo__dot" : "");
|
|
162
|
+
dot.setAttribute("fill", inverted ? "currentColor" : theme.secondary);
|
|
163
|
+
dot.setAttribute("cx", "714.5");
|
|
164
|
+
dot.setAttribute("cy", "490.5");
|
|
165
|
+
dot.setAttribute("r", "68");
|
|
166
|
+
dot.setAttribute("opacity", inverted ? "0.78" : "1");
|
|
167
|
+
logoGroup.appendChild(ring);
|
|
168
|
+
logoGroup.appendChild(dot);
|
|
169
|
+
mark.appendChild(logoGroup);
|
|
170
|
+
return mark;
|
|
171
|
+
}
|
|
172
|
+
function createSdkBrandLogo({
|
|
173
|
+
animated,
|
|
174
|
+
brand,
|
|
175
|
+
brandWidth,
|
|
176
|
+
copyWidth,
|
|
177
|
+
gap = 10,
|
|
178
|
+
markMarginRight,
|
|
179
|
+
markSize,
|
|
180
|
+
nameSize,
|
|
181
|
+
subtitleMarginTop = 6,
|
|
182
|
+
subtitleSize,
|
|
183
|
+
subtitleWeight = "800",
|
|
184
|
+
theme,
|
|
185
|
+
variant = "brand"
|
|
186
|
+
}) {
|
|
187
|
+
ensureSdkBrandLogoStyles();
|
|
188
|
+
const wrapper = document.createElement("div");
|
|
189
|
+
wrapper.className = "youidian-sdk-brand-logo";
|
|
190
|
+
wrapper.setAttribute("data-animated", animated ? "true" : "false");
|
|
191
|
+
Object.assign(wrapper.style, {
|
|
192
|
+
display: "inline-flex",
|
|
193
|
+
alignItems: "center",
|
|
194
|
+
justifyContent: "center",
|
|
195
|
+
gap: `${gap}px`,
|
|
196
|
+
width: brandWidth ? `${brandWidth}px` : void 0
|
|
197
|
+
});
|
|
198
|
+
const copy = document.createElement("div");
|
|
199
|
+
copy.className = "youidian-sdk-brand-logo__copy";
|
|
200
|
+
copy.setAttribute("data-brand-locale", brand.language);
|
|
201
|
+
Object.assign(copy.style, {
|
|
202
|
+
display: "flex",
|
|
203
|
+
flexDirection: "column",
|
|
204
|
+
alignItems: "flex-start",
|
|
205
|
+
justifyContent: "center",
|
|
206
|
+
lineHeight: "1",
|
|
207
|
+
width: copyWidth ? `${copyWidth}px` : void 0
|
|
208
|
+
});
|
|
209
|
+
const name = document.createElement("div");
|
|
210
|
+
name.className = "youidian-sdk-brand-logo__name";
|
|
211
|
+
name.textContent = brand.name;
|
|
212
|
+
Object.assign(name.style, {
|
|
213
|
+
color: theme.foreground,
|
|
214
|
+
fontFamily: brand.language === "zh" ? '"Noto Sans TC", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' : '"Unbounded", "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
215
|
+
fontSize: `${nameSize}px`,
|
|
216
|
+
fontWeight: brand.language === "zh" ? "900" : "800",
|
|
217
|
+
letterSpacing: brand.language === "zh" ? "0.08em" : "0.01em",
|
|
218
|
+
lineHeight: "1",
|
|
219
|
+
whiteSpace: "nowrap"
|
|
220
|
+
});
|
|
221
|
+
const subtitle = document.createElement("div");
|
|
222
|
+
subtitle.className = "youidian-sdk-brand-logo__tagline";
|
|
223
|
+
subtitle.textContent = brand.subtitle;
|
|
224
|
+
Object.assign(subtitle.style, {
|
|
225
|
+
color: theme.muted,
|
|
226
|
+
fontFamily: brand.language === "zh" ? '"Noto Sans TC", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif' : '"Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
227
|
+
fontSize: `${subtitleSize}px`,
|
|
228
|
+
fontWeight: subtitleWeight,
|
|
229
|
+
letterSpacing: brand.language === "zh" ? "0.24em" : "0.07em",
|
|
230
|
+
lineHeight: "1",
|
|
231
|
+
marginTop: `${subtitleMarginTop}px`,
|
|
232
|
+
textTransform: brand.language === "zh" ? "none" : "uppercase",
|
|
233
|
+
whiteSpace: "nowrap"
|
|
234
|
+
});
|
|
235
|
+
copy.appendChild(name);
|
|
236
|
+
copy.appendChild(subtitle);
|
|
237
|
+
const mark = createSdkBrandLogoMark({
|
|
238
|
+
animated,
|
|
239
|
+
size: markSize,
|
|
240
|
+
theme,
|
|
241
|
+
variant
|
|
242
|
+
});
|
|
243
|
+
if (typeof markMarginRight === "number") {
|
|
244
|
+
mark.style.marginRight = `${markMarginRight}px`;
|
|
245
|
+
}
|
|
246
|
+
wrapper.appendChild(mark);
|
|
247
|
+
wrapper.appendChild(copy);
|
|
248
|
+
return wrapper;
|
|
249
|
+
}
|
|
250
|
+
|
|
34
251
|
// src/hosted-modal.ts
|
|
35
252
|
var SDK_SUPPORTED_LOCALES = [
|
|
36
253
|
"en",
|
|
@@ -154,7 +371,7 @@ var HostedFrameModal = class {
|
|
|
154
371
|
const container = document.createElement("div");
|
|
155
372
|
Object.assign(container.style, {
|
|
156
373
|
width: options.width || "450px",
|
|
157
|
-
height: options.height || "min(
|
|
374
|
+
height: options.height || "min(680px, calc(100vh - 32px))",
|
|
158
375
|
backgroundColor: "transparent",
|
|
159
376
|
borderRadius: "28px",
|
|
160
377
|
overflow: "visible",
|
|
@@ -162,8 +379,7 @@ var HostedFrameModal = class {
|
|
|
162
379
|
boxShadow: "none",
|
|
163
380
|
maxWidth: "calc(100vw - 32px)",
|
|
164
381
|
maxHeight: "calc(100vh - 32px)",
|
|
165
|
-
transition: "
|
|
166
|
-
willChange: "height"
|
|
382
|
+
transition: "none"
|
|
167
383
|
});
|
|
168
384
|
const closeBtn = document.createElement("button");
|
|
169
385
|
closeBtn.innerHTML = "\xD7";
|
|
@@ -1004,6 +1220,7 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1004
1220
|
this.completed = false;
|
|
1005
1221
|
}
|
|
1006
1222
|
markIframeReady() {
|
|
1223
|
+
if (this.iframeReady) return;
|
|
1007
1224
|
this.iframeReady = true;
|
|
1008
1225
|
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
1009
1226
|
window.clearTimeout(this.iframeLoadTimer);
|
|
@@ -1248,6 +1465,17 @@ var LoginUI = class extends HostedFrameModal {
|
|
|
1248
1465
|
},
|
|
1249
1466
|
onMessage: (data, _container, event) => {
|
|
1250
1467
|
const isIframeEvent = event.source === this.iframe?.contentWindow;
|
|
1468
|
+
if (!isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE")) {
|
|
1469
|
+
logLoginWarn(
|
|
1470
|
+
"Login lifecycle event ignored: event.source does not match iframe contentWindow",
|
|
1471
|
+
{
|
|
1472
|
+
type: data.type,
|
|
1473
|
+
eventOrigin: event.origin,
|
|
1474
|
+
hasIframe: Boolean(this.iframe),
|
|
1475
|
+
hasIframeContentWindow: Boolean(this.iframe?.contentWindow)
|
|
1476
|
+
}
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1251
1479
|
if (isIframeEvent && (data.type === "LOGIN_READY" || data.type === "LOGIN_RESIZE") || data.type === "LOGIN_SUCCESS" || data.type === "LOGIN_ERROR") {
|
|
1252
1480
|
this.markIframeReady();
|
|
1253
1481
|
}
|
|
@@ -1382,6 +1610,406 @@ function createLoginUI() {
|
|
|
1382
1610
|
handleLoginCallbackIfPresent({ autoClose: false });
|
|
1383
1611
|
|
|
1384
1612
|
// src/client.ts
|
|
1613
|
+
var DEFAULT_PAYMENT_IFRAME_LOAD_TIMEOUT_MS = 8e3;
|
|
1614
|
+
var PAYMENT_UI_LOG_PREFIX = "[Youidian PaymentUI]";
|
|
1615
|
+
function hexToRgb(value) {
|
|
1616
|
+
const normalized = value.trim().replace(/^#/, "");
|
|
1617
|
+
if (!/^[0-9a-f]{3}([0-9a-f]{3})?$/i.test(normalized)) return null;
|
|
1618
|
+
const hex = normalized.length === 3 ? normalized.split("").map((char) => `${char}${char}`).join("") : normalized;
|
|
1619
|
+
const number = Number.parseInt(hex, 16);
|
|
1620
|
+
return {
|
|
1621
|
+
b: number & 255,
|
|
1622
|
+
g: number >> 8 & 255,
|
|
1623
|
+
r: number >> 16 & 255
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
function alphaColor(value, alpha) {
|
|
1627
|
+
const rgb = hexToRgb(value);
|
|
1628
|
+
if (!rgb)
|
|
1629
|
+
return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
|
|
1630
|
+
return `rgba(${rgb.r},${rgb.g},${rgb.b},${alpha})`;
|
|
1631
|
+
}
|
|
1632
|
+
function resolvePaymentTheme(options) {
|
|
1633
|
+
const primary = options?.theme?.primary || "#16a34a";
|
|
1634
|
+
const secondary = options?.theme?.secondary || "color-mix(in srgb, #16a34a 78%, white)";
|
|
1635
|
+
const foreground = options?.theme?.foreground || "#0f172a";
|
|
1636
|
+
const muted = options?.theme?.muted || "#64748b";
|
|
1637
|
+
const surface = options?.theme?.surface || "#ffffff";
|
|
1638
|
+
return {
|
|
1639
|
+
foreground,
|
|
1640
|
+
muted,
|
|
1641
|
+
primary,
|
|
1642
|
+
primary10: alphaColor(primary, 0.1),
|
|
1643
|
+
primary14: alphaColor(primary, 0.14),
|
|
1644
|
+
primary20: alphaColor(primary, 0.2),
|
|
1645
|
+
primary28: alphaColor(primary, 0.28),
|
|
1646
|
+
primary36: alphaColor(primary, 0.36),
|
|
1647
|
+
primary64: alphaColor(primary, 0.64),
|
|
1648
|
+
secondary,
|
|
1649
|
+
surface
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
function logPaymentInfo(message, details) {
|
|
1653
|
+
if (typeof console === "undefined") return;
|
|
1654
|
+
console.info(PAYMENT_UI_LOG_PREFIX, message, details || {});
|
|
1655
|
+
}
|
|
1656
|
+
function logPaymentWarn(message, details) {
|
|
1657
|
+
if (typeof console === "undefined") return;
|
|
1658
|
+
console.warn(PAYMENT_UI_LOG_PREFIX, message, details || {});
|
|
1659
|
+
}
|
|
1660
|
+
function getPaymentIframeLoadTimeoutMs(options) {
|
|
1661
|
+
const timeout = options?.iframeLoadTimeoutMs;
|
|
1662
|
+
if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
|
|
1663
|
+
return DEFAULT_PAYMENT_IFRAME_LOAD_TIMEOUT_MS;
|
|
1664
|
+
}
|
|
1665
|
+
return Math.max(0, timeout);
|
|
1666
|
+
}
|
|
1667
|
+
function isChinesePaymentLocale(locale) {
|
|
1668
|
+
return locale?.toLowerCase().startsWith("zh") || false;
|
|
1669
|
+
}
|
|
1670
|
+
function getPaymentFallbackText(options) {
|
|
1671
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1672
|
+
return {
|
|
1673
|
+
buttonText: options?.fallbackButtonText || (isChinese ? "\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00" : "Open in new page"),
|
|
1674
|
+
description: isChinese ? "\u5F53\u524D\u7F51\u7EDC\u53EF\u80FD\u8F83\u6162\uFF0C\u5EFA\u8BAE\u91CD\u65B0\u5C1D\u8BD5\u6216\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00\uFF0C\u4EE5\u83B7\u5F97\u66F4\u6D41\u7545\u7684\u652F\u4ED8\u4F53\u9A8C\u3002" : "Your network may be slow. Try again or open the payment page in a new page to continue.",
|
|
1675
|
+
retryText: options?.fallbackRetryText || (isChinese ? "\u91CD\u65B0\u5C1D\u8BD5" : "Try again"),
|
|
1676
|
+
title: isChinese ? "\u652F\u4ED8\u9875\u9762\u6253\u5F00\u8F83\u6162" : "Payment page is taking longer"
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
function getPaymentBrandText(options) {
|
|
1680
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1681
|
+
return {
|
|
1682
|
+
language: isChinese ? "zh" : "en",
|
|
1683
|
+
name: isChinese ? "\u4F18\u6613\u70B9" : "Youidian",
|
|
1684
|
+
subtitle: isChinese ? "\u5F00\u53D1\u8005\u670D\u52A1\u5E73\u53F0" : "Developer Service Platform"
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
function getPaymentBrandLoadingText(options) {
|
|
1688
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1689
|
+
return {
|
|
1690
|
+
language: isChinese ? "zh" : "en",
|
|
1691
|
+
name: isChinese ? "\u4F18\u6613\u70B9" : "Youidian",
|
|
1692
|
+
subtitle: isChinese ? "\u5F00\u53D1\u8005\u670D\u52A1\u4E2D\u53F0" : "Developer Service"
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
function getPaymentLoadingText(options) {
|
|
1696
|
+
const isChinese = isChinesePaymentLocale(options?.locale);
|
|
1697
|
+
return options?.loadingTitle || options?.loadingDescription || (isChinese ? "\u52A0\u8F7D\u4E2D..." : "Loading...");
|
|
1698
|
+
}
|
|
1699
|
+
function applyPaymentPanelStyle(panel, theme) {
|
|
1700
|
+
Object.assign(panel.style, {
|
|
1701
|
+
position: "absolute",
|
|
1702
|
+
inset: "0",
|
|
1703
|
+
display: "flex",
|
|
1704
|
+
alignItems: "center",
|
|
1705
|
+
justifyContent: "center",
|
|
1706
|
+
borderRadius: "28px",
|
|
1707
|
+
background: `linear-gradient(180deg, ${theme.surface} 0%, rgba(248,250,252,0.98) 100%)`,
|
|
1708
|
+
color: theme.foreground,
|
|
1709
|
+
padding: "28px 24px",
|
|
1710
|
+
textAlign: "center",
|
|
1711
|
+
zIndex: "1",
|
|
1712
|
+
boxShadow: "none",
|
|
1713
|
+
backdropFilter: "blur(16px)"
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
function createPaymentIcon(type) {
|
|
1717
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
1718
|
+
svg.setAttribute("viewBox", "0 0 24 24");
|
|
1719
|
+
svg.setAttribute("fill", "none");
|
|
1720
|
+
svg.setAttribute("aria-hidden", "true");
|
|
1721
|
+
Object.assign(svg.style, {
|
|
1722
|
+
display: "block",
|
|
1723
|
+
flex: "0 0 auto"
|
|
1724
|
+
});
|
|
1725
|
+
const paths = type === "external" ? [
|
|
1726
|
+
"M7 17L17 7",
|
|
1727
|
+
"M10 7H17V14",
|
|
1728
|
+
"M6.5 6.5H5.5A2.5 2.5 0 0 0 3 9V18.5A2.5 2.5 0 0 0 5.5 21H15A2.5 2.5 0 0 0 17.5 18.5V17.5"
|
|
1729
|
+
] : type === "refresh" ? [
|
|
1730
|
+
"M20 6V11H15",
|
|
1731
|
+
"M4 18V13H9",
|
|
1732
|
+
"M18.2 9A7 7 0 0 0 6.2 6.6L4 9",
|
|
1733
|
+
"M5.8 15A7 7 0 0 0 17.8 17.4L20 15"
|
|
1734
|
+
] : ["M12 7V12L15 14", "M21 12A9 9 0 1 1 3 12A9 9 0 0 1 21 12"];
|
|
1735
|
+
for (const value of paths) {
|
|
1736
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
1737
|
+
path.setAttribute("d", value);
|
|
1738
|
+
path.setAttribute("stroke", "currentColor");
|
|
1739
|
+
path.setAttribute("stroke-width", "2");
|
|
1740
|
+
path.setAttribute("stroke-linecap", "round");
|
|
1741
|
+
path.setAttribute("stroke-linejoin", "round");
|
|
1742
|
+
svg.appendChild(path);
|
|
1743
|
+
}
|
|
1744
|
+
return svg;
|
|
1745
|
+
}
|
|
1746
|
+
function createPaymentFallbackArtwork(theme) {
|
|
1747
|
+
const artwork = document.createElement("div");
|
|
1748
|
+
Object.assign(artwork.style, {
|
|
1749
|
+
height: "164px",
|
|
1750
|
+
margin: "0 auto 34px",
|
|
1751
|
+
position: "relative",
|
|
1752
|
+
width: "184px"
|
|
1753
|
+
});
|
|
1754
|
+
const wash = document.createElement("div");
|
|
1755
|
+
Object.assign(wash.style, {
|
|
1756
|
+
position: "absolute",
|
|
1757
|
+
left: "16px",
|
|
1758
|
+
top: "20px",
|
|
1759
|
+
width: "152px",
|
|
1760
|
+
height: "126px",
|
|
1761
|
+
borderRadius: "48% 52% 43% 57% / 54% 42% 58% 46%",
|
|
1762
|
+
background: `radial-gradient(circle at 48% 42%, ${theme.primary20}, ${theme.primary10} 52%, transparent 76%)`,
|
|
1763
|
+
filter: "blur(1px)",
|
|
1764
|
+
transform: "rotate(-10deg)"
|
|
1765
|
+
});
|
|
1766
|
+
const blob = document.createElement("div");
|
|
1767
|
+
Object.assign(blob.style, {
|
|
1768
|
+
position: "absolute",
|
|
1769
|
+
left: "26px",
|
|
1770
|
+
top: "28px",
|
|
1771
|
+
width: "132px",
|
|
1772
|
+
height: "116px",
|
|
1773
|
+
borderRadius: "42% 58% 53% 47% / 45% 39% 61% 55%",
|
|
1774
|
+
background: `linear-gradient(150deg, ${theme.primary14}, ${theme.primary10})`,
|
|
1775
|
+
boxShadow: `0 30px 64px ${theme.primary14}`,
|
|
1776
|
+
transform: "rotate(8deg)"
|
|
1777
|
+
});
|
|
1778
|
+
const tile = document.createElement("div");
|
|
1779
|
+
Object.assign(tile.style, {
|
|
1780
|
+
position: "absolute",
|
|
1781
|
+
left: "50%",
|
|
1782
|
+
top: "50%",
|
|
1783
|
+
transform: "translate(-50%, -50%) rotate(-4deg)",
|
|
1784
|
+
width: "112px",
|
|
1785
|
+
height: "106px",
|
|
1786
|
+
borderRadius: "38% 62% 50% 50% / 44% 43% 57% 56%",
|
|
1787
|
+
background: `linear-gradient(145deg, ${theme.primary}, ${theme.secondary})`,
|
|
1788
|
+
border: `1px solid ${theme.primary36}`,
|
|
1789
|
+
color: "#ffffff",
|
|
1790
|
+
display: "inline-flex",
|
|
1791
|
+
alignItems: "center",
|
|
1792
|
+
justifyContent: "center",
|
|
1793
|
+
boxShadow: `0 26px 54px ${theme.primary28}`
|
|
1794
|
+
});
|
|
1795
|
+
const icon = createPaymentIcon("slow");
|
|
1796
|
+
Object.assign(icon.style, {
|
|
1797
|
+
width: "52px",
|
|
1798
|
+
height: "52px",
|
|
1799
|
+
transform: "rotate(4deg)"
|
|
1800
|
+
});
|
|
1801
|
+
tile.appendChild(icon);
|
|
1802
|
+
artwork.appendChild(wash);
|
|
1803
|
+
artwork.appendChild(blob);
|
|
1804
|
+
artwork.appendChild(tile);
|
|
1805
|
+
return artwork;
|
|
1806
|
+
}
|
|
1807
|
+
function createPaymentBrandLoading(options, theme) {
|
|
1808
|
+
const brand = getPaymentBrandLoadingText(options);
|
|
1809
|
+
const wrapper = document.createElement("div");
|
|
1810
|
+
Object.assign(wrapper.style, {
|
|
1811
|
+
display: "flex",
|
|
1812
|
+
flexDirection: "column",
|
|
1813
|
+
alignItems: "center",
|
|
1814
|
+
justifyContent: "center",
|
|
1815
|
+
margin: "0 auto 16px"
|
|
1816
|
+
});
|
|
1817
|
+
wrapper.appendChild(
|
|
1818
|
+
createSdkBrandLogo({
|
|
1819
|
+
animated: true,
|
|
1820
|
+
brand,
|
|
1821
|
+
brandWidth: 292,
|
|
1822
|
+
copyWidth: 176,
|
|
1823
|
+
gap: 6,
|
|
1824
|
+
markMarginRight: -10,
|
|
1825
|
+
markSize: 112,
|
|
1826
|
+
nameSize: 39,
|
|
1827
|
+
subtitleMarginTop: 8,
|
|
1828
|
+
subtitleSize: 14,
|
|
1829
|
+
subtitleWeight: "700",
|
|
1830
|
+
theme,
|
|
1831
|
+
variant: "brand"
|
|
1832
|
+
})
|
|
1833
|
+
);
|
|
1834
|
+
return wrapper;
|
|
1835
|
+
}
|
|
1836
|
+
function createPaymentPlatformLogo(options, theme) {
|
|
1837
|
+
const brand = getPaymentBrandText(options);
|
|
1838
|
+
const wrapper = document.createElement("div");
|
|
1839
|
+
Object.assign(wrapper.style, {
|
|
1840
|
+
display: "flex",
|
|
1841
|
+
alignItems: "center",
|
|
1842
|
+
justifyContent: "center",
|
|
1843
|
+
margin: "0 auto 10px"
|
|
1844
|
+
});
|
|
1845
|
+
wrapper.appendChild(
|
|
1846
|
+
createSdkBrandLogo({
|
|
1847
|
+
brand,
|
|
1848
|
+
markSize: 48,
|
|
1849
|
+
nameSize: brand.language === "zh" ? 22 : 22,
|
|
1850
|
+
subtitleSize: brand.language === "zh" ? 9 : 9,
|
|
1851
|
+
theme
|
|
1852
|
+
})
|
|
1853
|
+
);
|
|
1854
|
+
return wrapper;
|
|
1855
|
+
}
|
|
1856
|
+
function createPaymentPanelContent() {
|
|
1857
|
+
const content = document.createElement("div");
|
|
1858
|
+
Object.assign(content.style, {
|
|
1859
|
+
display: "flex",
|
|
1860
|
+
flexDirection: "column",
|
|
1861
|
+
justifyContent: "center",
|
|
1862
|
+
maxWidth: "364px",
|
|
1863
|
+
minHeight: "100%",
|
|
1864
|
+
width: "100%"
|
|
1865
|
+
});
|
|
1866
|
+
return content;
|
|
1867
|
+
}
|
|
1868
|
+
function createPaymentPanelTitle(value, theme) {
|
|
1869
|
+
const title = document.createElement("div");
|
|
1870
|
+
title.textContent = value;
|
|
1871
|
+
Object.assign(title.style, {
|
|
1872
|
+
color: theme?.foreground || "#0f172a",
|
|
1873
|
+
fontSize: "24px",
|
|
1874
|
+
fontWeight: "900",
|
|
1875
|
+
lineHeight: "1.22",
|
|
1876
|
+
marginBottom: "16px"
|
|
1877
|
+
});
|
|
1878
|
+
return title;
|
|
1879
|
+
}
|
|
1880
|
+
function createPaymentPanelDescription(value, theme) {
|
|
1881
|
+
const description = document.createElement("div");
|
|
1882
|
+
description.textContent = value;
|
|
1883
|
+
Object.assign(description.style, {
|
|
1884
|
+
color: theme?.muted || "#64748b",
|
|
1885
|
+
fontSize: "14px",
|
|
1886
|
+
fontWeight: "600",
|
|
1887
|
+
lineHeight: "1.62",
|
|
1888
|
+
margin: "0 auto",
|
|
1889
|
+
maxWidth: "320px"
|
|
1890
|
+
});
|
|
1891
|
+
return description;
|
|
1892
|
+
}
|
|
1893
|
+
function createPaymentLoadingDescription(value, theme) {
|
|
1894
|
+
const description = document.createElement("div");
|
|
1895
|
+
description.textContent = value;
|
|
1896
|
+
Object.assign(description.style, {
|
|
1897
|
+
color: theme?.muted || "#64748b",
|
|
1898
|
+
fontSize: "14px",
|
|
1899
|
+
fontWeight: "500",
|
|
1900
|
+
lineHeight: "1.25",
|
|
1901
|
+
margin: "12px auto 0",
|
|
1902
|
+
maxWidth: "320px"
|
|
1903
|
+
});
|
|
1904
|
+
return description;
|
|
1905
|
+
}
|
|
1906
|
+
function createPaymentFallbackMessage(options) {
|
|
1907
|
+
const message = document.createElement("div");
|
|
1908
|
+
Object.assign(message.style, {
|
|
1909
|
+
margin: "0 auto",
|
|
1910
|
+
textAlign: "center"
|
|
1911
|
+
});
|
|
1912
|
+
message.appendChild(createPaymentFallbackArtwork(options.theme));
|
|
1913
|
+
message.appendChild(createPaymentPanelTitle(options.title, options.theme));
|
|
1914
|
+
message.appendChild(
|
|
1915
|
+
createPaymentPanelDescription(options.description, options.theme)
|
|
1916
|
+
);
|
|
1917
|
+
return message;
|
|
1918
|
+
}
|
|
1919
|
+
function createPaymentLoadingPanel(options) {
|
|
1920
|
+
const panel = document.createElement("div");
|
|
1921
|
+
const theme = resolvePaymentTheme(options);
|
|
1922
|
+
applyPaymentPanelStyle(panel, theme);
|
|
1923
|
+
const content = createPaymentPanelContent();
|
|
1924
|
+
content.appendChild(createPaymentBrandLoading(options, theme));
|
|
1925
|
+
content.appendChild(
|
|
1926
|
+
createPaymentLoadingDescription(getPaymentLoadingText(options), theme)
|
|
1927
|
+
);
|
|
1928
|
+
panel.appendChild(content);
|
|
1929
|
+
return panel;
|
|
1930
|
+
}
|
|
1931
|
+
function createPaymentButton(value, options) {
|
|
1932
|
+
const primary = options?.primary || false;
|
|
1933
|
+
const theme = options?.theme || resolvePaymentTheme();
|
|
1934
|
+
const button = document.createElement("button");
|
|
1935
|
+
button.type = "button";
|
|
1936
|
+
Object.assign(button.style, {
|
|
1937
|
+
width: "100%",
|
|
1938
|
+
height: "50px",
|
|
1939
|
+
borderRadius: "14px",
|
|
1940
|
+
border: primary ? `1px solid ${theme.primary}` : `1px solid ${theme.primary64}`,
|
|
1941
|
+
background: primary ? `linear-gradient(135deg, ${theme.primary}, ${theme.secondary})` : "#ffffff",
|
|
1942
|
+
color: primary ? "#ffffff" : theme.primary,
|
|
1943
|
+
cursor: "pointer",
|
|
1944
|
+
display: "inline-flex",
|
|
1945
|
+
alignItems: "center",
|
|
1946
|
+
justifyContent: "center",
|
|
1947
|
+
gap: "10px",
|
|
1948
|
+
fontSize: "15px",
|
|
1949
|
+
fontWeight: "800",
|
|
1950
|
+
marginTop: primary ? "12px" : "0",
|
|
1951
|
+
boxShadow: primary ? `0 14px 28px ${theme.primary20}` : "none"
|
|
1952
|
+
});
|
|
1953
|
+
if (options?.icon) {
|
|
1954
|
+
const icon = createPaymentIcon(options.icon);
|
|
1955
|
+
Object.assign(icon.style, {
|
|
1956
|
+
width: "17px",
|
|
1957
|
+
height: "17px"
|
|
1958
|
+
});
|
|
1959
|
+
button.appendChild(icon);
|
|
1960
|
+
}
|
|
1961
|
+
const label = document.createElement("span");
|
|
1962
|
+
label.textContent = value;
|
|
1963
|
+
button.appendChild(label);
|
|
1964
|
+
return button;
|
|
1965
|
+
}
|
|
1966
|
+
function createPaymentFallbackPanel(options) {
|
|
1967
|
+
const panel = document.createElement("div");
|
|
1968
|
+
const theme = resolvePaymentTheme(options.paymentOptions);
|
|
1969
|
+
applyPaymentPanelStyle(panel, theme);
|
|
1970
|
+
const content = createPaymentPanelContent();
|
|
1971
|
+
Object.assign(content.style, {
|
|
1972
|
+
justifyContent: "space-between"
|
|
1973
|
+
});
|
|
1974
|
+
const main = document.createElement("div");
|
|
1975
|
+
Object.assign(main.style, {
|
|
1976
|
+
display: "flex",
|
|
1977
|
+
flexDirection: "column",
|
|
1978
|
+
alignItems: "center",
|
|
1979
|
+
marginTop: "38px",
|
|
1980
|
+
width: "100%"
|
|
1981
|
+
});
|
|
1982
|
+
main.appendChild(
|
|
1983
|
+
createPaymentFallbackMessage({
|
|
1984
|
+
description: options.description,
|
|
1985
|
+
theme,
|
|
1986
|
+
title: options.title
|
|
1987
|
+
})
|
|
1988
|
+
);
|
|
1989
|
+
const actions = document.createElement("div");
|
|
1990
|
+
Object.assign(actions.style, {
|
|
1991
|
+
marginTop: "46px",
|
|
1992
|
+
width: "100%"
|
|
1993
|
+
});
|
|
1994
|
+
const retryButton = createPaymentButton(options.retryText, {
|
|
1995
|
+
icon: "refresh",
|
|
1996
|
+
theme
|
|
1997
|
+
});
|
|
1998
|
+
retryButton.onclick = options.onRetry;
|
|
1999
|
+
actions.appendChild(retryButton);
|
|
2000
|
+
const openButton = createPaymentButton(options.buttonText, {
|
|
2001
|
+
icon: "external",
|
|
2002
|
+
primary: true,
|
|
2003
|
+
theme
|
|
2004
|
+
});
|
|
2005
|
+
openButton.onclick = options.onOpen;
|
|
2006
|
+
actions.appendChild(openButton);
|
|
2007
|
+
main.appendChild(actions);
|
|
2008
|
+
content.appendChild(main);
|
|
2009
|
+
content.appendChild(createPaymentPlatformLogo(options.paymentOptions, theme));
|
|
2010
|
+
panel.appendChild(content);
|
|
2011
|
+
return panel;
|
|
2012
|
+
}
|
|
1385
2013
|
var PaymentUI = class extends HostedFrameModal {
|
|
1386
2014
|
constructor() {
|
|
1387
2015
|
super(...arguments);
|
|
@@ -1390,6 +2018,127 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1390
2018
|
__publicField(this, "activeOrderId", null);
|
|
1391
2019
|
__publicField(this, "paymentCompleted", false);
|
|
1392
2020
|
__publicField(this, "cancelRequestedOrderId", null);
|
|
2021
|
+
__publicField(this, "iframeFallbackPanel", null);
|
|
2022
|
+
__publicField(this, "iframeLoadingPanel", null);
|
|
2023
|
+
__publicField(this, "iframeLoadTimer", null);
|
|
2024
|
+
__publicField(this, "iframeReady", false);
|
|
2025
|
+
}
|
|
2026
|
+
cleanupPaymentFrameState() {
|
|
2027
|
+
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
2028
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
2029
|
+
}
|
|
2030
|
+
if (this.iframeFallbackPanel?.parentNode) {
|
|
2031
|
+
this.iframeFallbackPanel.parentNode.removeChild(this.iframeFallbackPanel);
|
|
2032
|
+
}
|
|
2033
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2034
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2035
|
+
}
|
|
2036
|
+
this.iframeFallbackPanel = null;
|
|
2037
|
+
this.iframeLoadingPanel = null;
|
|
2038
|
+
this.iframeLoadTimer = null;
|
|
2039
|
+
this.iframeReady = false;
|
|
2040
|
+
}
|
|
2041
|
+
markPaymentIframeReady() {
|
|
2042
|
+
if (this.iframeReady) return;
|
|
2043
|
+
this.iframeReady = true;
|
|
2044
|
+
if (typeof window !== "undefined" && this.iframeLoadTimer) {
|
|
2045
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
2046
|
+
this.iframeLoadTimer = null;
|
|
2047
|
+
}
|
|
2048
|
+
if (this.iframeFallbackPanel?.parentNode) {
|
|
2049
|
+
this.iframeFallbackPanel.parentNode.removeChild(this.iframeFallbackPanel);
|
|
2050
|
+
}
|
|
2051
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2052
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2053
|
+
}
|
|
2054
|
+
this.iframeFallbackPanel = null;
|
|
2055
|
+
this.iframeLoadingPanel = null;
|
|
2056
|
+
}
|
|
2057
|
+
showPaymentIframeLoading(container, options) {
|
|
2058
|
+
if (this.iframeLoadingPanel || this.iframeReady) return;
|
|
2059
|
+
const panel = createPaymentLoadingPanel(options);
|
|
2060
|
+
this.iframeLoadingPanel = panel;
|
|
2061
|
+
container.appendChild(panel);
|
|
2062
|
+
}
|
|
2063
|
+
openFallbackPaymentPage(finalUrl, options) {
|
|
2064
|
+
if (typeof window === "undefined") return;
|
|
2065
|
+
const popup = window.open(
|
|
2066
|
+
finalUrl,
|
|
2067
|
+
"youidian-payment-checkout",
|
|
2068
|
+
"popup=yes,width=480,height=760,resizable=yes,scrollbars=yes"
|
|
2069
|
+
);
|
|
2070
|
+
if (popup) {
|
|
2071
|
+
logPaymentInfo("Opened hosted checkout fallback page", {
|
|
2072
|
+
checkoutUrl: finalUrl
|
|
2073
|
+
});
|
|
2074
|
+
options?.onFallbackOpen?.(finalUrl);
|
|
2075
|
+
try {
|
|
2076
|
+
popup.focus();
|
|
2077
|
+
} catch {
|
|
2078
|
+
}
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
logPaymentWarn("Hosted checkout fallback popup was blocked", {
|
|
2082
|
+
checkoutUrl: finalUrl
|
|
2083
|
+
});
|
|
2084
|
+
options?.onFallbackBlocked?.(finalUrl);
|
|
2085
|
+
window.location.assign(finalUrl);
|
|
2086
|
+
}
|
|
2087
|
+
showPaymentIframeFallback(options) {
|
|
2088
|
+
if (this.iframeReady || this.iframeFallbackPanel) return;
|
|
2089
|
+
const { container, finalUrl, paymentOptions } = options;
|
|
2090
|
+
logPaymentWarn("Hosted checkout iframe did not report ready in time", {
|
|
2091
|
+
checkoutUrl: finalUrl
|
|
2092
|
+
});
|
|
2093
|
+
if (this.iframeLoadingPanel?.parentNode) {
|
|
2094
|
+
this.iframeLoadingPanel.parentNode.removeChild(this.iframeLoadingPanel);
|
|
2095
|
+
}
|
|
2096
|
+
this.iframeLoadingPanel = null;
|
|
2097
|
+
const fallbackText = getPaymentFallbackText(paymentOptions);
|
|
2098
|
+
const panel = createPaymentFallbackPanel({
|
|
2099
|
+
buttonText: fallbackText.buttonText,
|
|
2100
|
+
description: fallbackText.description,
|
|
2101
|
+
onOpen: () => {
|
|
2102
|
+
this.openFallbackPaymentPage(finalUrl, paymentOptions);
|
|
2103
|
+
},
|
|
2104
|
+
onRetry: () => {
|
|
2105
|
+
this.iframeFallbackPanel = null;
|
|
2106
|
+
if (panel.parentNode) {
|
|
2107
|
+
panel.parentNode.removeChild(panel);
|
|
2108
|
+
}
|
|
2109
|
+
this.iframeReady = false;
|
|
2110
|
+
this.showPaymentIframeLoading(container, paymentOptions);
|
|
2111
|
+
if (this.iframe) {
|
|
2112
|
+
this.iframe.src = finalUrl;
|
|
2113
|
+
}
|
|
2114
|
+
this.startPaymentIframeWatchdog({
|
|
2115
|
+
container,
|
|
2116
|
+
finalUrl,
|
|
2117
|
+
paymentOptions
|
|
2118
|
+
});
|
|
2119
|
+
},
|
|
2120
|
+
paymentOptions,
|
|
2121
|
+
retryText: fallbackText.retryText,
|
|
2122
|
+
title: fallbackText.title
|
|
2123
|
+
});
|
|
2124
|
+
this.iframeFallbackPanel = panel;
|
|
2125
|
+
container.appendChild(panel);
|
|
2126
|
+
paymentOptions?.onFallbackVisible?.();
|
|
2127
|
+
}
|
|
2128
|
+
startPaymentIframeWatchdog(options) {
|
|
2129
|
+
if (typeof window === "undefined") return;
|
|
2130
|
+
if (this.iframeLoadTimer) {
|
|
2131
|
+
window.clearTimeout(this.iframeLoadTimer);
|
|
2132
|
+
}
|
|
2133
|
+
const timeoutMs = getPaymentIframeLoadTimeoutMs(options.paymentOptions);
|
|
2134
|
+
if (timeoutMs === 0) {
|
|
2135
|
+
this.showPaymentIframeFallback(options);
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
this.iframeLoadTimer = window.setTimeout(() => {
|
|
2139
|
+
this.iframeLoadTimer = null;
|
|
2140
|
+
this.showPaymentIframeFallback(options);
|
|
2141
|
+
}, timeoutMs);
|
|
1393
2142
|
}
|
|
1394
2143
|
cancelHostedOrder(reason = "user_cancel", orderId) {
|
|
1395
2144
|
const targetOrderId = orderId || this.activeOrderId;
|
|
@@ -1432,6 +2181,7 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1432
2181
|
this.activeOrderId = null;
|
|
1433
2182
|
this.paymentCompleted = false;
|
|
1434
2183
|
this.cancelRequestedOrderId = null;
|
|
2184
|
+
this.cleanupPaymentFrameState();
|
|
1435
2185
|
if (typeof urlOrParams === "string") {
|
|
1436
2186
|
checkoutUrl = urlOrParams;
|
|
1437
2187
|
try {
|
|
@@ -1500,14 +2250,21 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1500
2250
|
checkoutUrl,
|
|
1501
2251
|
getAutoResolvedLocale(options?.locale)
|
|
1502
2252
|
);
|
|
1503
|
-
this.openHostedFrame(finalUrl, {
|
|
2253
|
+
const hostedFrame = this.openHostedFrame(finalUrl, {
|
|
1504
2254
|
allowedOrigin: options?.allowedOrigin,
|
|
2255
|
+
height: "min(680px, calc(100vh - 32px))",
|
|
1505
2256
|
onCloseButton: () => {
|
|
1506
2257
|
this.cancelHostedOrder("modal_close");
|
|
1507
2258
|
options?.onCancel?.(this.activeOrderId || void 0);
|
|
1508
2259
|
},
|
|
1509
|
-
onMessage: (data, container) => {
|
|
2260
|
+
onMessage: (data, container, event) => {
|
|
2261
|
+
const isIframeMessage = event.source === this.iframe?.contentWindow;
|
|
2262
|
+
if (isIframeMessage && (data.type === "PAYMENT_READY" || data.type === "PAYMENT_RESIZE" || data.type === "PAYMENT_STARTED")) {
|
|
2263
|
+
this.markPaymentIframeReady();
|
|
2264
|
+
}
|
|
1510
2265
|
switch (data.type) {
|
|
2266
|
+
case "PAYMENT_READY":
|
|
2267
|
+
break;
|
|
1511
2268
|
case "PAYMENT_STARTED":
|
|
1512
2269
|
if (data.orderId) {
|
|
1513
2270
|
this.activeOrderId = data.orderId;
|
|
@@ -1522,11 +2279,6 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1522
2279
|
options?.onCancel?.(data.orderId);
|
|
1523
2280
|
break;
|
|
1524
2281
|
case "PAYMENT_RESIZE":
|
|
1525
|
-
if (data.height) {
|
|
1526
|
-
const maxHeight = window.innerHeight * 0.9;
|
|
1527
|
-
const newHeight = Math.min(data.height, maxHeight);
|
|
1528
|
-
container.style.height = `${newHeight}px`;
|
|
1529
|
-
}
|
|
1530
2282
|
break;
|
|
1531
2283
|
case "PAYMENT_CLOSE":
|
|
1532
2284
|
this.cancelHostedOrder("payment_close", data.orderId);
|
|
@@ -1534,8 +2286,21 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1534
2286
|
options?.onClose?.();
|
|
1535
2287
|
break;
|
|
1536
2288
|
}
|
|
1537
|
-
}
|
|
2289
|
+
},
|
|
2290
|
+
width: "min(450px, 100%)"
|
|
1538
2291
|
});
|
|
2292
|
+
if (hostedFrame) {
|
|
2293
|
+
this.showPaymentIframeLoading(hostedFrame.container, options);
|
|
2294
|
+
this.startPaymentIframeWatchdog({
|
|
2295
|
+
container: hostedFrame.container,
|
|
2296
|
+
finalUrl,
|
|
2297
|
+
paymentOptions: options
|
|
2298
|
+
});
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
close() {
|
|
2302
|
+
super.close();
|
|
2303
|
+
this.cleanupPaymentFrameState();
|
|
1539
2304
|
}
|
|
1540
2305
|
/**
|
|
1541
2306
|
* Poll order status from integrator's API endpoint
|
|
@@ -1581,14 +2346,39 @@ var PaymentUI = class extends HostedFrameModal {
|
|
|
1581
2346
|
});
|
|
1582
2347
|
}
|
|
1583
2348
|
};
|
|
2349
|
+
var MessageUI = class {
|
|
2350
|
+
openWechatBinding(options) {
|
|
2351
|
+
const bindingUrl = options.bindingUrl?.trim();
|
|
2352
|
+
if (!bindingUrl) {
|
|
2353
|
+
throw new Error("bindingUrl is required");
|
|
2354
|
+
}
|
|
2355
|
+
if (options.displayMode === "popup") {
|
|
2356
|
+
const popup = window.open(
|
|
2357
|
+
bindingUrl,
|
|
2358
|
+
options.popupName || "youidian-wechat-message-binding",
|
|
2359
|
+
"width=480,height=720,noopener,noreferrer"
|
|
2360
|
+
);
|
|
2361
|
+
if (!popup) {
|
|
2362
|
+
window.location.href = bindingUrl;
|
|
2363
|
+
}
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
2366
|
+
window.location.href = bindingUrl;
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2369
|
+
function createMessageUI() {
|
|
2370
|
+
return new MessageUI();
|
|
2371
|
+
}
|
|
1584
2372
|
function createPaymentUI() {
|
|
1585
2373
|
return new PaymentUI();
|
|
1586
2374
|
}
|
|
1587
2375
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1588
2376
|
0 && (module.exports = {
|
|
1589
2377
|
LoginUI,
|
|
2378
|
+
MessageUI,
|
|
1590
2379
|
PaymentUI,
|
|
1591
2380
|
createLoginUI,
|
|
2381
|
+
createMessageUI,
|
|
1592
2382
|
createPaymentUI,
|
|
1593
2383
|
detectLoginEnvironment,
|
|
1594
2384
|
handleLoginCallbackIfPresent
|