@seaverse/payment-sdk 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/dist/index.browser.js +694 -752
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +694 -752
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -11
- package/dist/index.js +694 -752
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.browser.js
CHANGED
|
@@ -2196,24 +2196,19 @@ class PaymentModal {
|
|
|
2196
2196
|
*
|
|
2197
2197
|
* 设计风格:深色卡片 + 清晰信息层次 + 渐变 CTA 按钮
|
|
2198
2198
|
*/
|
|
2199
|
-
/* ─── 设计 Token
|
|
2199
|
+
/* ─── 设计 Token(与 order-popups PendingPopup 一致) ─── */
|
|
2200
2200
|
const D = {
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
textWhite: '#
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
accentTealShadow: 'rgba(45, 212, 191, 0.35)',
|
|
2213
|
-
// 分隔线
|
|
2214
|
-
divider: 'rgba(255, 255, 255, 0.06)',
|
|
2215
|
-
// 圆角
|
|
2216
|
-
radiusCard: '20px',
|
|
2201
|
+
bgOverlay: 'rgba(0, 0, 0, 0.85)',
|
|
2202
|
+
bgCard: '#121212',
|
|
2203
|
+
bgCardBorder: 'rgba(44, 44, 46, 0.6)',
|
|
2204
|
+
bgSurface: '#1E1E1E',
|
|
2205
|
+
bgSurfaceHighlight: '#2A2A2E',
|
|
2206
|
+
borderSubtle: 'rgba(255, 255, 255, 0.05)',
|
|
2207
|
+
textWhite: '#FFFFFF',
|
|
2208
|
+
textMuted: '#A1A1AA',
|
|
2209
|
+
timerRed: '#EF4444',
|
|
2210
|
+
brandGreen: '#10B981',
|
|
2211
|
+
radiusCard: '24px',
|
|
2217
2212
|
radiusInner: '12px',
|
|
2218
2213
|
radiusBtn: '12px',
|
|
2219
2214
|
};
|
|
@@ -2275,27 +2270,30 @@ class RetentionModal {
|
|
|
2275
2270
|
*/
|
|
2276
2271
|
createModal() {
|
|
2277
2272
|
const { language, productName, purchaseAmount, bonusAmount, discountPrice } = this.options;
|
|
2278
|
-
const
|
|
2273
|
+
const lang = language ?? 'en';
|
|
2274
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
2279
2275
|
const t = isZh ? {
|
|
2280
2276
|
title: '你有一笔订单待支付',
|
|
2281
|
-
timePrefix: '请在',
|
|
2282
|
-
timeSuffix: '
|
|
2283
|
-
productLabel: '
|
|
2284
|
-
|
|
2285
|
-
|
|
2277
|
+
timePrefix: '请在 ',
|
|
2278
|
+
timeSuffix: ' 内支付,超时自动取消',
|
|
2279
|
+
productLabel: '商品',
|
|
2280
|
+
quantityLabel: '数量',
|
|
2281
|
+
priceLabel: '优惠价',
|
|
2282
|
+
bonusLabel: '奖励',
|
|
2286
2283
|
cancelBtn: '取消',
|
|
2287
2284
|
continueBtn: '继续支付',
|
|
2288
2285
|
} : {
|
|
2289
2286
|
title: 'You have a pending order',
|
|
2290
|
-
timePrefix: 'Please pay within',
|
|
2291
|
-
timeSuffix: '
|
|
2287
|
+
timePrefix: 'Please pay within ',
|
|
2288
|
+
timeSuffix: ', auto-cancelled if timeout',
|
|
2292
2289
|
productLabel: 'Product:',
|
|
2293
|
-
|
|
2290
|
+
quantityLabel: 'Quantity:',
|
|
2291
|
+
priceLabel: 'Price:',
|
|
2294
2292
|
bonusLabel: 'Bonus:',
|
|
2295
2293
|
cancelBtn: 'Cancel',
|
|
2296
|
-
continueBtn: '
|
|
2294
|
+
continueBtn: 'Pay Now',
|
|
2297
2295
|
};
|
|
2298
|
-
// ───
|
|
2296
|
+
// ─── 遮罩(与 order-popups 一致) ───
|
|
2299
2297
|
this.overlay = document.createElement('div');
|
|
2300
2298
|
this.overlay.id = 'retention-modal-overlay';
|
|
2301
2299
|
this.overlay.style.cssText = `
|
|
@@ -2303,137 +2301,130 @@ class RetentionModal {
|
|
|
2303
2301
|
display: flex; align-items: center; justify-content: center;
|
|
2304
2302
|
padding: 24px;
|
|
2305
2303
|
background: ${D.bgOverlay};
|
|
2306
|
-
backdrop-filter: blur(
|
|
2304
|
+
backdrop-filter: blur(8px);
|
|
2307
2305
|
animation: rm-fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
2308
2306
|
`;
|
|
2309
|
-
// ───
|
|
2307
|
+
// ─── 卡片(order-popups: bg-dark-card, rounded-[24px], border dark-border) ───
|
|
2310
2308
|
this.modal = document.createElement('div');
|
|
2311
2309
|
this.modal.style.cssText = `
|
|
2312
2310
|
position: relative;
|
|
2313
|
-
width: 90vw; max-width:
|
|
2311
|
+
width: 90vw; max-width: 500px; min-width: 420px;
|
|
2314
2312
|
border-radius: ${D.radiusCard};
|
|
2315
2313
|
background: ${D.bgCard};
|
|
2316
|
-
|
|
2314
|
+
border: 1px solid ${D.bgCardBorder};
|
|
2315
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
2316
|
+
padding: 24px;
|
|
2317
2317
|
animation: rm-slideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
2318
2318
|
overflow: hidden;
|
|
2319
2319
|
`;
|
|
2320
|
-
// ─── 构建 HTML ───
|
|
2320
|
+
// ─── 构建 HTML(与 order-popups PendingPopup + 图片布局一致) ───
|
|
2321
2321
|
this.modal.innerHTML = `
|
|
2322
|
-
<!--
|
|
2322
|
+
<!-- 关闭按钮(order-popups: top-5 right-5, rounded-full, text-dark-muted) -->
|
|
2323
2323
|
<button type="button" id="retention-modal-close-btn" style="
|
|
2324
|
-
position: absolute; top:
|
|
2325
|
-
display: flex; width:
|
|
2324
|
+
position: absolute; top: 20px; right: 20px; z-index: 10;
|
|
2325
|
+
display: flex; width: 40px; height: 40px;
|
|
2326
2326
|
align-items: center; justify-content: center;
|
|
2327
2327
|
border-radius: 50%;
|
|
2328
|
-
background:
|
|
2329
|
-
color:
|
|
2328
|
+
background: transparent;
|
|
2329
|
+
color: ${D.textMuted};
|
|
2330
2330
|
border: none; cursor: pointer;
|
|
2331
|
-
transition:
|
|
2331
|
+
transition: color 0.2s, background 0.2s;
|
|
2332
2332
|
">
|
|
2333
|
-
<svg width="
|
|
2334
|
-
<
|
|
2333
|
+
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2334
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
2335
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
2335
2336
|
</svg>
|
|
2336
2337
|
</button>
|
|
2337
2338
|
|
|
2338
|
-
<!--
|
|
2339
|
-
<div style="padding:
|
|
2340
|
-
<
|
|
2341
|
-
margin: 0 0
|
|
2342
|
-
font-size:
|
|
2339
|
+
<!-- 标题区域(order-popups: text-2xl font-bold, timer in red font-mono) -->
|
|
2340
|
+
<div style="padding: 16px 0 32px; text-align: center;">
|
|
2341
|
+
<h1 style="
|
|
2342
|
+
margin: 0 0 8px;
|
|
2343
|
+
font-size: 24px;
|
|
2343
2344
|
font-weight: 700;
|
|
2344
2345
|
color: ${D.textWhite};
|
|
2345
|
-
letter-spacing: -0.
|
|
2346
|
-
">${t.title}</
|
|
2346
|
+
letter-spacing: -0.02em;
|
|
2347
|
+
">${t.title}</h1>
|
|
2347
2348
|
<p style="
|
|
2348
2349
|
margin: 0;
|
|
2349
2350
|
font-size: 14px;
|
|
2350
|
-
color: ${D.
|
|
2351
|
-
|
|
2351
|
+
color: ${D.textMuted};
|
|
2352
|
+
display: flex;
|
|
2353
|
+
align-items: center;
|
|
2354
|
+
justify-content: center;
|
|
2355
|
+
flex-wrap: wrap;
|
|
2356
|
+
gap: 2px;
|
|
2352
2357
|
">
|
|
2353
|
-
${t.timePrefix}
|
|
2354
|
-
|
|
2355
|
-
color: ${D.accentRed};
|
|
2358
|
+
${t.timePrefix}<span id="countdown-display" style="
|
|
2359
|
+
color: ${D.timerRed};
|
|
2356
2360
|
font-weight: 700;
|
|
2357
2361
|
font-variant-numeric: tabular-nums;
|
|
2358
|
-
|
|
2359
|
-
|
|
2362
|
+
font-family: ui-monospace, monospace;
|
|
2363
|
+
">00:15:00</span>${t.timeSuffix}
|
|
2360
2364
|
</p>
|
|
2361
2365
|
</div>
|
|
2362
2366
|
|
|
2363
|
-
<!--
|
|
2364
|
-
<div style="
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
<div style="
|
|
2376
|
-
display: flex; align-items: center; justify-content: space-between;
|
|
2377
|
-
padding: 16px 20px;
|
|
2378
|
-
border-bottom: 1px solid ${D.divider};
|
|
2379
|
-
">
|
|
2380
|
-
<span style="font-size: 14px; color: ${D.textSecondary};">${t.productLabel}</span>
|
|
2381
|
-
<span style="font-size: 14px; font-weight: 600; color: ${D.textWhite};">${this.escapeHtml(productName)}</span>
|
|
2367
|
+
<!-- 订单详情卡片(order-popups: rounded-xl border border-white/5,上 part surface,下 part surfaceHighlight) -->
|
|
2368
|
+
<div style="
|
|
2369
|
+
border-radius: ${D.radiusInner};
|
|
2370
|
+
overflow: hidden;
|
|
2371
|
+
border: 1px solid ${D.borderSubtle};
|
|
2372
|
+
margin-bottom: 32px;
|
|
2373
|
+
">
|
|
2374
|
+
<!-- 上:Product + Quantity -->
|
|
2375
|
+
<div style="background: ${D.bgSurface}; padding: 20px; display: flex; flex-direction: column; gap: 16px;">
|
|
2376
|
+
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
|
2377
|
+
<span style="color: ${D.textMuted}; min-width: 64px;">${t.productLabel}</span>
|
|
2378
|
+
<span style="color: ${D.textWhite}; font-weight: 500; text-align: right; word-break: break-word;">${this.escapeHtml(productName)}</span>
|
|
2382
2379
|
</div>
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
display: flex; align-items: center; justify-content: space-between;
|
|
2387
|
-
padding: 16px 20px;
|
|
2388
|
-
border-bottom: 1px solid ${D.divider};
|
|
2389
|
-
">
|
|
2390
|
-
<span style="font-size: 14px; color: ${D.textSecondary};">${t.amountLabel}</span>
|
|
2391
|
-
<span style="font-size: 14px; font-weight: 600; color: ${D.textWhite};">${discountPrice}</span>
|
|
2380
|
+
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
|
2381
|
+
<span style="color: ${D.textMuted}; min-width: 64px;">${t.quantityLabel}</span>
|
|
2382
|
+
<span style="color: ${D.textWhite}; font-weight: 500; text-align: right;">${purchaseAmount.toLocaleString()}</span>
|
|
2392
2383
|
</div>
|
|
2393
|
-
|
|
2394
2384
|
${bonusAmount ? `
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
padding: 16px 20px;
|
|
2399
|
-
border-bottom: 1px solid ${D.divider};
|
|
2400
|
-
">
|
|
2401
|
-
<span style="font-size: 14px; color: ${D.textSecondary};">${t.bonusLabel}</span>
|
|
2402
|
-
<span style="font-size: 14px; font-weight: 600; color: ${D.textWhite};">${bonusAmount.toLocaleString()}</span>
|
|
2385
|
+
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
|
2386
|
+
<span style="color: ${D.textMuted}; min-width: 64px;">${t.bonusLabel}</span>
|
|
2387
|
+
<span style="color: ${D.textWhite}; font-weight: 500; text-align: right;">${bonusAmount.toLocaleString()}</span>
|
|
2403
2388
|
</div>
|
|
2404
2389
|
` : ''}
|
|
2405
|
-
|
|
2406
|
-
|
|
2390
|
+
</div>
|
|
2391
|
+
<!-- 下:Price(图片:大号绿色金额) -->
|
|
2392
|
+
<div style="
|
|
2393
|
+
background: ${D.bgSurfaceHighlight};
|
|
2394
|
+
padding: 20px;
|
|
2395
|
+
display: flex;
|
|
2396
|
+
justify-content: space-between;
|
|
2397
|
+
align-items: center;
|
|
2398
|
+
border-top: 1px solid ${D.borderSubtle};
|
|
2399
|
+
">
|
|
2400
|
+
<span style="font-size: 14px; color: ${D.textMuted}">${t.priceLabel}</span>
|
|
2401
|
+
<span style="font-size: 24px; font-weight: 700; color: ${D.brandGreen}; letter-spacing: 0.02em;">${this.escapeHtml(discountPrice)}</span>
|
|
2407
2402
|
</div>
|
|
2408
2403
|
</div>
|
|
2409
2404
|
|
|
2410
|
-
<!--
|
|
2411
|
-
<div style="display:
|
|
2405
|
+
<!-- 按钮组(order-popups: grid grid-cols-2 gap-4, Cancel=white/5 border, Pay=#10b981) -->
|
|
2406
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
|
2412
2407
|
<button type="button" id="retention-cancel-btn" style="
|
|
2413
|
-
flex: 1;
|
|
2414
2408
|
padding: 14px 20px;
|
|
2415
2409
|
border-radius: ${D.radiusBtn};
|
|
2416
|
-
border: 1px solid rgba(255,255,255,0.
|
|
2417
|
-
background:
|
|
2418
|
-
color: ${D.
|
|
2419
|
-
font-size:
|
|
2420
|
-
font-weight:
|
|
2410
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
2411
|
+
background: rgba(255,255,255,0.05);
|
|
2412
|
+
color: ${D.textMuted};
|
|
2413
|
+
font-size: 14px;
|
|
2414
|
+
font-weight: 500;
|
|
2421
2415
|
cursor: pointer;
|
|
2422
|
-
transition:
|
|
2416
|
+
transition: background 0.2s, color 0.2s, border-color 0.2s;
|
|
2423
2417
|
">${t.cancelBtn}</button>
|
|
2424
|
-
|
|
2425
2418
|
<button type="button" id="retention-continue-btn" style="
|
|
2426
|
-
flex: 1;
|
|
2427
2419
|
padding: 14px 20px;
|
|
2428
2420
|
border-radius: ${D.radiusBtn};
|
|
2429
2421
|
border: none;
|
|
2430
|
-
background: ${D.
|
|
2431
|
-
color: #
|
|
2432
|
-
font-size:
|
|
2422
|
+
background: ${D.brandGreen};
|
|
2423
|
+
color: #000000;
|
|
2424
|
+
font-size: 14px;
|
|
2433
2425
|
font-weight: 700;
|
|
2434
2426
|
cursor: pointer;
|
|
2435
|
-
transition:
|
|
2436
|
-
box-shadow: 0 4px 16px ${D.accentTealShadow};
|
|
2427
|
+
transition: box-shadow 0.2s, transform 0.1s;
|
|
2437
2428
|
">${t.continueBtn}</button>
|
|
2438
2429
|
</div>
|
|
2439
2430
|
`;
|
|
@@ -2468,20 +2459,20 @@ class RetentionModal {
|
|
|
2468
2459
|
}
|
|
2469
2460
|
|
|
2470
2461
|
#retention-modal-close-btn:hover {
|
|
2471
|
-
background: rgba(255,255,255,0.
|
|
2472
|
-
color: #
|
|
2473
|
-
transform: rotate(90deg);
|
|
2462
|
+
background: rgba(255,255,255,0.05) !important;
|
|
2463
|
+
color: #FFFFFF !important;
|
|
2474
2464
|
}
|
|
2475
2465
|
#retention-cancel-btn:hover {
|
|
2476
|
-
background: rgba(255,255,255,0.
|
|
2477
|
-
|
|
2466
|
+
background: rgba(255,255,255,0.1) !important;
|
|
2467
|
+
color: #FFFFFF !important;
|
|
2468
|
+
border-color: rgba(255,255,255,0.1) !important;
|
|
2478
2469
|
}
|
|
2479
2470
|
#retention-continue-btn:hover {
|
|
2480
|
-
box-shadow: 0
|
|
2481
|
-
transform:
|
|
2471
|
+
box-shadow: 0 0 20px rgba(16, 185, 129, 0.4) !important;
|
|
2472
|
+
transform: scale(1.02);
|
|
2482
2473
|
}
|
|
2483
2474
|
#retention-continue-btn:active {
|
|
2484
|
-
transform:
|
|
2475
|
+
transform: scale(0.98);
|
|
2485
2476
|
}
|
|
2486
2477
|
`;
|
|
2487
2478
|
document.head.appendChild(style);
|
|
@@ -2852,6 +2843,64 @@ class DropinPaymentModal {
|
|
|
2852
2843
|
}
|
|
2853
2844
|
}
|
|
2854
2845
|
|
|
2846
|
+
/**
|
|
2847
|
+
* 共享配置文件
|
|
2848
|
+
* Shared configuration for CreditPackageModal and GenericPackageModal
|
|
2849
|
+
*/
|
|
2850
|
+
/**
|
|
2851
|
+
* 环境配置映射表
|
|
2852
|
+
* SDK 根据 environment 参数自动选择对应的配置
|
|
2853
|
+
*/
|
|
2854
|
+
const ENVIRONMENT_CONFIGS = {
|
|
2855
|
+
development: {
|
|
2856
|
+
scriptUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.js',
|
|
2857
|
+
clientId: 'XF49NOfyZ54O16GujB0ptio2',
|
|
2858
|
+
orderApiUrl: 'https://payment.sg.seaverse.dev',
|
|
2859
|
+
walletApiUrl: 'https://wallet.sg.seaverse.dev',
|
|
2860
|
+
cssUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/public/style.css',
|
|
2861
|
+
},
|
|
2862
|
+
production: {
|
|
2863
|
+
scriptUrl: 'https://seaart-publish.sc-api.saconsole.com/payment-component/client.js',
|
|
2864
|
+
clientId: 'XF11ik3u5AJ16IyDI3hebq5',
|
|
2865
|
+
orderApiUrl: 'https://payment.seaverse.com',
|
|
2866
|
+
walletApiUrl: 'https://wallet.seaverse.com',
|
|
2867
|
+
cssUrl: 'https://seaart-publish.sc-api.saconsole.com/payment-component/public/style.css',
|
|
2868
|
+
},
|
|
2869
|
+
};
|
|
2870
|
+
/**
|
|
2871
|
+
* 响应式断点配置
|
|
2872
|
+
* Responsive breakpoints for grid layout
|
|
2873
|
+
*/
|
|
2874
|
+
const RESPONSIVE_BREAKPOINTS = {
|
|
2875
|
+
mobile: 768,
|
|
2876
|
+
tablet: 1200,
|
|
2877
|
+
laptop: 1400,
|
|
2878
|
+
desktop: Infinity,
|
|
2879
|
+
};
|
|
2880
|
+
/**
|
|
2881
|
+
* 网格列数配置
|
|
2882
|
+
* Grid columns for different screen sizes
|
|
2883
|
+
*/
|
|
2884
|
+
const GRID_COLUMNS = {
|
|
2885
|
+
mobile: 1,
|
|
2886
|
+
tablet: 2,
|
|
2887
|
+
laptop: 2,
|
|
2888
|
+
desktop: 4,
|
|
2889
|
+
};
|
|
2890
|
+
/**
|
|
2891
|
+
* SDK 初始化配置
|
|
2892
|
+
*/
|
|
2893
|
+
const SDK_CONFIG = {
|
|
2894
|
+
/** 默认脚本加载超时 (毫秒) */
|
|
2895
|
+
DEFAULT_SCRIPT_TIMEOUT: 10000,
|
|
2896
|
+
/** 默认 SDK 初始化超时 (毫秒) */
|
|
2897
|
+
DEFAULT_INIT_TIMEOUT: 30000,
|
|
2898
|
+
/** 默认最大重试次数 */
|
|
2899
|
+
DEFAULT_MAX_RETRIES: 1,
|
|
2900
|
+
/** 默认业务类型 (1=一次性购买, 2=订阅) */
|
|
2901
|
+
DEFAULT_BUSINESS_TYPE: 1,
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2855
2904
|
/**
|
|
2856
2905
|
* SeaartPaymentSDK
|
|
2857
2906
|
* 基于 SeaartPaymentComponent 的支付 SDK 封装
|
|
@@ -2888,22 +2937,22 @@ class SeaartPaymentSDK {
|
|
|
2888
2937
|
return;
|
|
2889
2938
|
}
|
|
2890
2939
|
console.log('[SeaartPaymentSDK] Initializing...', {
|
|
2891
|
-
scriptUrl: config.scriptUrl,
|
|
2892
|
-
clientId: config.clientId,
|
|
2940
|
+
scriptUrl: ENVIRONMENT_CONFIGS[config.environment].scriptUrl,
|
|
2941
|
+
clientId: ENVIRONMENT_CONFIGS[config.environment].clientId,
|
|
2893
2942
|
language: config.language,
|
|
2894
|
-
cssUrl: config.cssUrl,
|
|
2943
|
+
cssUrl: ENVIRONMENT_CONFIGS[config.environment].cssUrl,
|
|
2895
2944
|
});
|
|
2896
2945
|
try {
|
|
2897
2946
|
// 1. 并行加载 CSS 和 JavaScript
|
|
2898
2947
|
const loadTasks = [
|
|
2899
2948
|
ScriptLoader.loadSeaartPaymentComponent({
|
|
2900
|
-
scriptUrl: config.scriptUrl,
|
|
2949
|
+
scriptUrl: ENVIRONMENT_CONFIGS[config.environment].scriptUrl,
|
|
2901
2950
|
timeout: config.scriptTimeout || 10000,
|
|
2902
2951
|
}),
|
|
2903
2952
|
];
|
|
2904
2953
|
// 2. 如果提供了 CSS URL,则加载样式表
|
|
2905
|
-
if (config.cssUrl) {
|
|
2906
|
-
loadTasks.push(StylesheetLoader.loadPaymentStylesheet(config.cssUrl));
|
|
2954
|
+
if (ENVIRONMENT_CONFIGS[config.environment].cssUrl) {
|
|
2955
|
+
loadTasks.push(StylesheetLoader.loadPaymentStylesheet(ENVIRONMENT_CONFIGS[config.environment].cssUrl));
|
|
2907
2956
|
}
|
|
2908
2957
|
// 3. 等待所有资源加载完成
|
|
2909
2958
|
await Promise.all(loadTasks);
|
|
@@ -3294,64 +3343,6 @@ async function getCreditDetail(apiHost, authToken) {
|
|
|
3294
3343
|
}
|
|
3295
3344
|
}
|
|
3296
3345
|
|
|
3297
|
-
/**
|
|
3298
|
-
* 共享配置文件
|
|
3299
|
-
* Shared configuration for CreditPackageModal and GenericPackageModal
|
|
3300
|
-
*/
|
|
3301
|
-
/**
|
|
3302
|
-
* 环境配置映射表
|
|
3303
|
-
* SDK 根据 environment 参数自动选择对应的配置
|
|
3304
|
-
*/
|
|
3305
|
-
const ENVIRONMENT_CONFIGS = {
|
|
3306
|
-
development: {
|
|
3307
|
-
scriptUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/client.js',
|
|
3308
|
-
clientId: 'XF49NOfyZ54O16GujB0ptio2',
|
|
3309
|
-
orderApiUrl: 'https://payment.sg.seaverse.dev',
|
|
3310
|
-
walletApiUrl: 'https://wallet.sg.seaverse.dev',
|
|
3311
|
-
cssUrl: 'https://seaart-publish.sc-api-release.saconsole.com/payment-component/public/style.css',
|
|
3312
|
-
},
|
|
3313
|
-
production: {
|
|
3314
|
-
scriptUrl: 'https://seaart-publish.sc-api.saconsole.com/payment-component/client.js',
|
|
3315
|
-
clientId: 'prod_client_id',
|
|
3316
|
-
orderApiUrl: 'https://payment.seaverse.com',
|
|
3317
|
-
walletApiUrl: 'https://wallet.seaverse.com',
|
|
3318
|
-
cssUrl: 'https://seaart-publish.sc-api.saconsole.com/payment-component/public/style.css',
|
|
3319
|
-
},
|
|
3320
|
-
};
|
|
3321
|
-
/**
|
|
3322
|
-
* 响应式断点配置
|
|
3323
|
-
* Responsive breakpoints for grid layout
|
|
3324
|
-
*/
|
|
3325
|
-
const RESPONSIVE_BREAKPOINTS = {
|
|
3326
|
-
mobile: 768,
|
|
3327
|
-
tablet: 1200,
|
|
3328
|
-
laptop: 1400,
|
|
3329
|
-
desktop: Infinity,
|
|
3330
|
-
};
|
|
3331
|
-
/**
|
|
3332
|
-
* 网格列数配置
|
|
3333
|
-
* Grid columns for different screen sizes
|
|
3334
|
-
*/
|
|
3335
|
-
const GRID_COLUMNS = {
|
|
3336
|
-
mobile: 1,
|
|
3337
|
-
tablet: 2,
|
|
3338
|
-
laptop: 2,
|
|
3339
|
-
desktop: 4,
|
|
3340
|
-
};
|
|
3341
|
-
/**
|
|
3342
|
-
* SDK 初始化配置
|
|
3343
|
-
*/
|
|
3344
|
-
const SDK_CONFIG = {
|
|
3345
|
-
/** 默认脚本加载超时 (毫秒) */
|
|
3346
|
-
DEFAULT_SCRIPT_TIMEOUT: 10000,
|
|
3347
|
-
/** 默认 SDK 初始化超时 (毫秒) */
|
|
3348
|
-
DEFAULT_INIT_TIMEOUT: 30000,
|
|
3349
|
-
/** 默认最大重试次数 */
|
|
3350
|
-
DEFAULT_MAX_RETRIES: 1,
|
|
3351
|
-
/** 默认业务类型 (1=一次性购买, 2=订阅) */
|
|
3352
|
-
DEFAULT_BUSINESS_TYPE: 1,
|
|
3353
|
-
};
|
|
3354
|
-
|
|
3355
3346
|
/**
|
|
3356
3347
|
* 共享类型定义
|
|
3357
3348
|
* Shared types for CreditPackageModal and GenericPackageModal
|
|
@@ -3761,8 +3752,9 @@ class PurchaseSuccessModal {
|
|
|
3761
3752
|
*/
|
|
3762
3753
|
createModal() {
|
|
3763
3754
|
const { data, language } = this.options;
|
|
3764
|
-
const
|
|
3765
|
-
|
|
3755
|
+
const lang = language ?? 'en';
|
|
3756
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
3757
|
+
// 创建遮罩层(与 order-popups 一致:纯黑底)
|
|
3766
3758
|
this.overlay = document.createElement('div');
|
|
3767
3759
|
this.overlay.id = 'purchase-success-modal-overlay';
|
|
3768
3760
|
this.overlay.style.cssText = `
|
|
@@ -3773,21 +3765,24 @@ class PurchaseSuccessModal {
|
|
|
3773
3765
|
align-items: center;
|
|
3774
3766
|
justify-content: center;
|
|
3775
3767
|
padding: 20px;
|
|
3776
|
-
background: rgba(
|
|
3768
|
+
background: rgba(0, 0, 0, 0.85);
|
|
3777
3769
|
backdrop-filter: blur(8px);
|
|
3778
3770
|
animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
3779
3771
|
overflow: hidden;
|
|
3780
3772
|
`;
|
|
3781
|
-
//
|
|
3773
|
+
// 创建弹窗卡片(order-popups: dark-card #121212, rounded-[24px], border dark-border)
|
|
3782
3774
|
this.modal = document.createElement('div');
|
|
3783
3775
|
this.modal.style.cssText = `
|
|
3784
3776
|
position: relative;
|
|
3785
3777
|
width: 90vw;
|
|
3786
|
-
max-width:
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3778
|
+
max-width: 500px;
|
|
3779
|
+
min-width: 420px;
|
|
3780
|
+
border-radius: 24px;
|
|
3781
|
+
background: #121212;
|
|
3782
|
+
border: 1px solid rgba(44, 44, 46, 0.6);
|
|
3783
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
3790
3784
|
animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
3785
|
+
overflow: hidden;
|
|
3791
3786
|
`;
|
|
3792
3787
|
this.modal.innerHTML = this.getModalHTML(data, isZh);
|
|
3793
3788
|
this.overlay.appendChild(this.modal);
|
|
@@ -3806,211 +3801,121 @@ class PurchaseSuccessModal {
|
|
|
3806
3801
|
message: '感谢您的购买。您的积分已成功添加到账户中。',
|
|
3807
3802
|
packLabel: '套餐名称',
|
|
3808
3803
|
creditsLabel: '积分数量',
|
|
3809
|
-
amountLabel: '支付金额'
|
|
3810
|
-
badge: '已支付',
|
|
3811
|
-
} : {
|
|
3804
|
+
amountLabel: '支付金额'} : {
|
|
3812
3805
|
title: 'Purchase Successful!',
|
|
3813
3806
|
subtitle: 'Your credits have been added',
|
|
3814
3807
|
greeting: 'Hi there,',
|
|
3815
3808
|
message: 'Thank you for your purchase. Your credits have been successfully added to your account.',
|
|
3816
3809
|
packLabel: 'Package',
|
|
3817
3810
|
creditsLabel: 'Credits',
|
|
3818
|
-
amountLabel: 'Amount'
|
|
3819
|
-
badge: 'PAID',
|
|
3820
|
-
};
|
|
3811
|
+
amountLabel: 'Amount'};
|
|
3821
3812
|
const currency = getCurrencySymbol(data.currency || 'USD');
|
|
3813
|
+
const creditsText = isZh ? `${data.credits.toLocaleString()} 积分` : `${data.credits.toLocaleString()} Credits`;
|
|
3822
3814
|
return `
|
|
3823
|
-
<!--
|
|
3815
|
+
<!-- 关闭按钮(order-popups: top-5 right-5, rounded-full, text-dark-muted, hover:bg-white/5) -->
|
|
3824
3816
|
<button
|
|
3825
3817
|
type="button"
|
|
3826
3818
|
id="success-modal-close-btn"
|
|
3827
3819
|
style="
|
|
3828
3820
|
position: absolute;
|
|
3829
|
-
top:
|
|
3830
|
-
right:
|
|
3821
|
+
top: 20px;
|
|
3822
|
+
right: 20px;
|
|
3831
3823
|
z-index: 10;
|
|
3832
3824
|
display: flex;
|
|
3833
|
-
width:
|
|
3834
|
-
height:
|
|
3825
|
+
width: 40px;
|
|
3826
|
+
height: 40px;
|
|
3835
3827
|
align-items: center;
|
|
3836
3828
|
justify-content: center;
|
|
3837
3829
|
border-radius: 50%;
|
|
3838
|
-
background:
|
|
3839
|
-
color:
|
|
3830
|
+
background: transparent;
|
|
3831
|
+
color: #A1A1AA;
|
|
3840
3832
|
border: none;
|
|
3841
3833
|
cursor: pointer;
|
|
3842
|
-
transition:
|
|
3834
|
+
transition: color 0.2s, background 0.2s;
|
|
3843
3835
|
"
|
|
3844
3836
|
>
|
|
3845
|
-
<svg width="
|
|
3846
|
-
<
|
|
3837
|
+
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3838
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
3839
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
3847
3840
|
</svg>
|
|
3848
3841
|
</button>
|
|
3849
3842
|
|
|
3850
|
-
<!--
|
|
3843
|
+
<!-- 成功状态与标题(与图片一致:大号绿色勾 + 紧凑布局) -->
|
|
3851
3844
|
<div style="
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3845
|
+
display: flex;
|
|
3846
|
+
flex-direction: column;
|
|
3847
|
+
align-items: center;
|
|
3855
3848
|
text-align: center;
|
|
3849
|
+
padding: 32px 24px 24px;
|
|
3856
3850
|
">
|
|
3857
|
-
<!-- Success Icon -->
|
|
3851
|
+
<!-- Success Icon:绿色实心圆 + 白色勾 -->
|
|
3858
3852
|
<div style="
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3853
|
+
width: 72px;
|
|
3854
|
+
height: 72px;
|
|
3855
|
+
margin-bottom: 20px;
|
|
3862
3856
|
animation: scaleIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
3863
3857
|
">
|
|
3864
|
-
<svg width="
|
|
3865
|
-
<circle cx="
|
|
3866
|
-
<
|
|
3867
|
-
<path d="M28 40L36 48L52 32" stroke="#10B981" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
|
|
3858
|
+
<svg width="72" height="72" viewBox="0 0 72 72" fill="none">
|
|
3859
|
+
<circle cx="36" cy="36" r="36" fill="#52AD5F"/>
|
|
3860
|
+
<path d="M22 36 L32 46 L50 26" stroke="#FFFFFF" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3868
3861
|
</svg>
|
|
3869
3862
|
</div>
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
margin: 0 0 6px;
|
|
3874
|
-
font-size: 24px;
|
|
3863
|
+
<h1 style="
|
|
3864
|
+
margin: 0 0 12px;
|
|
3865
|
+
font-size: 28px;
|
|
3875
3866
|
font-weight: 700;
|
|
3876
|
-
color:
|
|
3877
|
-
|
|
3878
|
-
">${texts.title}</
|
|
3879
|
-
|
|
3880
|
-
<!-- Subtitle -->
|
|
3867
|
+
color: #FFFFFF;
|
|
3868
|
+
letter-spacing: 0.02em;
|
|
3869
|
+
">${texts.title}</h1>
|
|
3881
3870
|
<p style="
|
|
3882
3871
|
margin: 0;
|
|
3883
|
-
font-size:
|
|
3884
|
-
color:
|
|
3885
|
-
animation: fadeInUp 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.3s backwards;
|
|
3872
|
+
font-size: 16px;
|
|
3873
|
+
color: #A1A1AA;
|
|
3886
3874
|
">${texts.subtitle}</p>
|
|
3887
3875
|
</div>
|
|
3888
3876
|
|
|
3889
|
-
<!--
|
|
3890
|
-
<div style="
|
|
3891
|
-
|
|
3877
|
+
<!-- 详情卡片(order-popups: bg-dark-surface/50, rounded-xl, border border-white/5) -->
|
|
3878
|
+
<div style="
|
|
3879
|
+
margin: 0 24px 24px;
|
|
3880
|
+
padding: 20px;
|
|
3881
|
+
border-radius: 12px;
|
|
3882
|
+
background: rgba(30, 30, 30, 0.5);
|
|
3883
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
3884
|
+
">
|
|
3885
|
+
<!-- 问候语(border-b border-white/10) -->
|
|
3892
3886
|
<div style="
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
background: #1e293b;
|
|
3897
|
-
animation: fadeInUp 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.4s backwards;
|
|
3887
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
|
3888
|
+
padding-bottom: 16px;
|
|
3889
|
+
margin-bottom: 16px;
|
|
3898
3890
|
">
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
color: #10B981;
|
|
3913
|
-
">
|
|
3914
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none">
|
|
3915
|
-
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="currentColor" opacity="0.3" />
|
|
3916
|
-
<path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
3917
|
-
<path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
3918
|
-
</svg>
|
|
3919
|
-
<span style="
|
|
3920
|
-
font-size: 15px;
|
|
3921
|
-
font-weight: 600;
|
|
3922
|
-
">SeaVerse</span>
|
|
3923
|
-
</div>
|
|
3924
|
-
<div style="
|
|
3925
|
-
border-radius: 9999px;
|
|
3926
|
-
border: 1px solid rgba(168, 85, 247, 0.3);
|
|
3927
|
-
background: rgba(168, 85, 247, 0.1);
|
|
3928
|
-
padding: 4px 12px;
|
|
3929
|
-
font-size: 11px;
|
|
3930
|
-
font-weight: 500;
|
|
3931
|
-
color: #a855f7;
|
|
3932
|
-
">${texts.badge}</div>
|
|
3933
|
-
</div>
|
|
3891
|
+
<h2 style="
|
|
3892
|
+
margin: 0 0 8px;
|
|
3893
|
+
font-size: 18px;
|
|
3894
|
+
font-weight: 600;
|
|
3895
|
+
color: #FFFFFF;
|
|
3896
|
+
">${texts.greeting}</h2>
|
|
3897
|
+
<p style="
|
|
3898
|
+
margin: 0;
|
|
3899
|
+
font-size: 14px;
|
|
3900
|
+
line-height: 1.6;
|
|
3901
|
+
color: #A1A1AA;
|
|
3902
|
+
">${texts.message}</p>
|
|
3903
|
+
</div>
|
|
3934
3904
|
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
<p style="
|
|
3941
|
-
margin: 0 0 8px;
|
|
3942
|
-
font-size: 13px;
|
|
3943
|
-
font-weight: 600;
|
|
3944
|
-
color: rgba(255, 255, 255, 0.9);
|
|
3945
|
-
">${texts.greeting}</p>
|
|
3946
|
-
<p style="
|
|
3947
|
-
margin: 0;
|
|
3948
|
-
font-size: 12px;
|
|
3949
|
-
line-height: 1.6;
|
|
3950
|
-
color: rgba(255, 255, 255, 0.7);
|
|
3951
|
-
">${texts.message}</p>
|
|
3905
|
+
<!-- 套餐/积分/金额行(order-popups: space-y-4, label muted, value white/right, amount 绿色) -->
|
|
3906
|
+
<div style="display: flex; flex-direction: column; gap: 16px;">
|
|
3907
|
+
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
|
3908
|
+
<span style="color: #A1A1AA;">${texts.packLabel}</span>
|
|
3909
|
+
<span style="color: #FFFFFF; font-weight: 500; text-align: right;">${this.escapeHtml(data.packName)}</span>
|
|
3952
3910
|
</div>
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
">
|
|
3959
|
-
<
|
|
3960
|
-
|
|
3961
|
-
align-items: center;
|
|
3962
|
-
justify-content: space-between;
|
|
3963
|
-
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
3964
|
-
padding: 12px 0;
|
|
3965
|
-
">
|
|
3966
|
-
<span style="
|
|
3967
|
-
font-size: 12px;
|
|
3968
|
-
font-weight: 500;
|
|
3969
|
-
color: rgba(255, 255, 255, 0.6);
|
|
3970
|
-
">${texts.packLabel}</span>
|
|
3971
|
-
<span style="
|
|
3972
|
-
font-size: 13px;
|
|
3973
|
-
font-weight: 600;
|
|
3974
|
-
color: rgba(255, 255, 255, 0.95);
|
|
3975
|
-
">${this.escapeHtml(data.packName)}</span>
|
|
3976
|
-
</div>
|
|
3977
|
-
<div style="
|
|
3978
|
-
display: flex;
|
|
3979
|
-
align-items: center;
|
|
3980
|
-
justify-content: space-between;
|
|
3981
|
-
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
3982
|
-
padding: 12px 0;
|
|
3983
|
-
">
|
|
3984
|
-
<span style="
|
|
3985
|
-
font-size: 12px;
|
|
3986
|
-
font-weight: 500;
|
|
3987
|
-
color: rgba(255, 255, 255, 0.6);
|
|
3988
|
-
">${texts.creditsLabel}</span>
|
|
3989
|
-
<span style="
|
|
3990
|
-
font-size: 13px;
|
|
3991
|
-
font-weight: 600;
|
|
3992
|
-
color: rgba(255, 255, 255, 0.95);
|
|
3993
|
-
">${data.credits.toLocaleString()} Credits</span>
|
|
3994
|
-
</div>
|
|
3995
|
-
<div style="
|
|
3996
|
-
display: flex;
|
|
3997
|
-
align-items: center;
|
|
3998
|
-
justify-content: space-between;
|
|
3999
|
-
background: linear-gradient(to right, rgba(16, 185, 129, 0.05), transparent);
|
|
4000
|
-
margin: 0 -16px;
|
|
4001
|
-
padding: 12px 16px;
|
|
4002
|
-
">
|
|
4003
|
-
<span style="
|
|
4004
|
-
font-size: 12px;
|
|
4005
|
-
font-weight: 500;
|
|
4006
|
-
color: rgba(255, 255, 255, 0.6);
|
|
4007
|
-
">${texts.amountLabel}</span>
|
|
4008
|
-
<span style="
|
|
4009
|
-
font-size: 16px;
|
|
4010
|
-
font-weight: 600;
|
|
4011
|
-
color: #10B981;
|
|
4012
|
-
">${currency}${this.escapeHtml(data.amount)}</span>
|
|
4013
|
-
</div>
|
|
3911
|
+
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
|
|
3912
|
+
<span style="color: #A1A1AA;">${texts.creditsLabel}</span>
|
|
3913
|
+
<span style="color: #FFFFFF; font-weight: 500; text-align: right;">${creditsText}</span>
|
|
3914
|
+
</div>
|
|
3915
|
+
<div style="height: 1px; background: rgba(255, 255, 255, 0.1); margin: 4px 0;"></div>
|
|
3916
|
+
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 4px;">
|
|
3917
|
+
<span style="font-size: 14px; color: #A1A1AA;">${texts.amountLabel}</span>
|
|
3918
|
+
<span style="font-size: 20px; font-weight: 700; color: #10B981; letter-spacing: 0.02em;">${currency}${this.escapeHtml(data.amount)}</span>
|
|
4014
3919
|
</div>
|
|
4015
3920
|
</div>
|
|
4016
3921
|
</div>
|
|
@@ -4089,9 +3994,8 @@ class PurchaseSuccessModal {
|
|
|
4089
3994
|
}
|
|
4090
3995
|
|
|
4091
3996
|
#success-modal-close-btn:hover {
|
|
4092
|
-
background: rgba(255, 255, 255, 0.
|
|
4093
|
-
color:
|
|
4094
|
-
transform: rotate(90deg);
|
|
3997
|
+
background: rgba(255, 255, 255, 0.05) !important;
|
|
3998
|
+
color: #FFFFFF !important;
|
|
4095
3999
|
}
|
|
4096
4000
|
`;
|
|
4097
4001
|
document.head.appendChild(style);
|
|
@@ -4274,6 +4178,7 @@ class BasePackageModal {
|
|
|
4274
4178
|
console.log(`[${this.constructor.name}] Using environment:`, config.environment);
|
|
4275
4179
|
// 3. Initialize SeaartPaymentSDK
|
|
4276
4180
|
await SeaartPaymentSDK.getInstance().init({
|
|
4181
|
+
environment: config.environment,
|
|
4277
4182
|
scriptUrl: finalConfig.scriptUrl,
|
|
4278
4183
|
clientId: finalConfig.clientId,
|
|
4279
4184
|
language: this.language,
|
|
@@ -5141,8 +5046,9 @@ class PaymentVerificationModal {
|
|
|
5141
5046
|
* 创建弹窗元素
|
|
5142
5047
|
*/
|
|
5143
5048
|
createModal() {
|
|
5144
|
-
const
|
|
5145
|
-
|
|
5049
|
+
const lang = this.options.language ?? 'en';
|
|
5050
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
5051
|
+
// 遮罩(与 PurchaseSuccessModal 一致)
|
|
5146
5052
|
this.overlay = document.createElement('div');
|
|
5147
5053
|
this.overlay.id = 'payment-verification-modal-overlay';
|
|
5148
5054
|
this.overlay.style.cssText = `
|
|
@@ -5153,20 +5059,21 @@ class PaymentVerificationModal {
|
|
|
5153
5059
|
align-items: center;
|
|
5154
5060
|
justify-content: center;
|
|
5155
5061
|
padding: 20px;
|
|
5156
|
-
background: rgba(
|
|
5157
|
-
backdrop-filter: blur(
|
|
5158
|
-
animation: fadeIn 0.
|
|
5062
|
+
background: rgba(0, 0, 0, 0.85);
|
|
5063
|
+
backdrop-filter: blur(8px);
|
|
5064
|
+
animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
5159
5065
|
overflow: hidden;
|
|
5160
5066
|
`;
|
|
5161
|
-
//
|
|
5067
|
+
// 弹窗卡片(PurchaseSuccessModal 风格)
|
|
5162
5068
|
this.modal = document.createElement('div');
|
|
5163
5069
|
this.modal.style.cssText = `
|
|
5164
5070
|
position: relative;
|
|
5165
5071
|
width: 90vw;
|
|
5166
|
-
max-width:
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5072
|
+
max-width: 500px;
|
|
5073
|
+
min-width: 420px;
|
|
5074
|
+
border-radius: 24px;
|
|
5075
|
+
background: #121212;
|
|
5076
|
+
border: 1px solid rgba(44, 44, 46, 0.6);
|
|
5170
5077
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
5171
5078
|
animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
5172
5079
|
overflow: hidden;
|
|
@@ -5184,52 +5091,50 @@ class PaymentVerificationModal {
|
|
|
5184
5091
|
const texts = this.getTexts(isZh);
|
|
5185
5092
|
const paymentType = this.options.paymentMethodName || 'Debit/Credit Card';
|
|
5186
5093
|
return `
|
|
5187
|
-
<!--
|
|
5094
|
+
<!-- 关闭按钮(与 PurchaseSuccessModal 一致) -->
|
|
5188
5095
|
<button
|
|
5189
5096
|
type="button"
|
|
5190
5097
|
id="verification-modal-close-btn"
|
|
5191
5098
|
style="
|
|
5192
5099
|
position: absolute;
|
|
5193
|
-
top:
|
|
5194
|
-
right:
|
|
5100
|
+
top: 20px;
|
|
5101
|
+
right: 20px;
|
|
5195
5102
|
z-index: 10;
|
|
5196
5103
|
display: flex;
|
|
5197
|
-
width:
|
|
5198
|
-
height:
|
|
5104
|
+
width: 40px;
|
|
5105
|
+
height: 40px;
|
|
5199
5106
|
align-items: center;
|
|
5200
5107
|
justify-content: center;
|
|
5201
5108
|
border-radius: 50%;
|
|
5202
|
-
background:
|
|
5203
|
-
color:
|
|
5109
|
+
background: transparent;
|
|
5110
|
+
color: #A1A1AA;
|
|
5204
5111
|
border: none;
|
|
5205
5112
|
cursor: pointer;
|
|
5206
|
-
transition:
|
|
5113
|
+
transition: color 0.2s, background 0.2s;
|
|
5207
5114
|
"
|
|
5208
5115
|
>
|
|
5209
|
-
<svg width="
|
|
5210
|
-
<
|
|
5116
|
+
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
5117
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
5118
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
5211
5119
|
</svg>
|
|
5212
5120
|
</button>
|
|
5213
5121
|
|
|
5214
5122
|
<!-- 内容区域 -->
|
|
5215
|
-
<div style="padding:
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
margin: 0 0 12px;
|
|
5123
|
+
<div style="padding: 24px 24px 24px;">
|
|
5124
|
+
<h1 style="
|
|
5125
|
+
margin: 0 0 8px;
|
|
5219
5126
|
font-size: 24px;
|
|
5220
5127
|
font-weight: 700;
|
|
5221
|
-
color: #
|
|
5128
|
+
color: #FFFFFF;
|
|
5222
5129
|
text-align: center;
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
">${texts.title} ${paymentType}</h2>
|
|
5130
|
+
letter-spacing: -0.02em;
|
|
5131
|
+
">${texts.title} ${paymentType}</h1>
|
|
5226
5132
|
|
|
5227
|
-
<!-- 提示文本 -->
|
|
5228
5133
|
<p style="
|
|
5229
5134
|
margin: 0 0 20px;
|
|
5230
|
-
font-size:
|
|
5135
|
+
font-size: 14px;
|
|
5231
5136
|
line-height: 1.6;
|
|
5232
|
-
color:
|
|
5137
|
+
color: #A1A1AA;
|
|
5233
5138
|
text-align: center;
|
|
5234
5139
|
">${texts.message}</p>
|
|
5235
5140
|
|
|
@@ -5238,16 +5143,19 @@ class PaymentVerificationModal {
|
|
|
5238
5143
|
position: relative;
|
|
5239
5144
|
margin: 0 0 24px;
|
|
5240
5145
|
min-height: 56px;
|
|
5146
|
+
padding: 16px;
|
|
5147
|
+
border-radius: 12px;
|
|
5148
|
+
background: rgba(30, 30, 30, 0.5);
|
|
5149
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
5241
5150
|
">
|
|
5242
5151
|
<p style="
|
|
5243
5152
|
margin: 0;
|
|
5244
5153
|
font-size: 13px;
|
|
5245
5154
|
line-height: 1.7;
|
|
5246
|
-
color:
|
|
5155
|
+
color: #A1A1AA;
|
|
5247
5156
|
text-align: center;
|
|
5248
5157
|
">${texts.helpText}</p>
|
|
5249
5158
|
|
|
5250
|
-
<!-- 加载状态遮罩(默认隐藏,Processing 时显示) -->
|
|
5251
5159
|
<div id="verification-loading-overlay" style="
|
|
5252
5160
|
display: none;
|
|
5253
5161
|
position: absolute;
|
|
@@ -5255,71 +5163,47 @@ class PaymentVerificationModal {
|
|
|
5255
5163
|
align-items: center;
|
|
5256
5164
|
justify-content: center;
|
|
5257
5165
|
gap: 12px;
|
|
5258
|
-
background: rgba(
|
|
5259
|
-
backdrop-filter: blur(
|
|
5260
|
-
border-radius:
|
|
5166
|
+
background: rgba(18, 18, 18, 0.92);
|
|
5167
|
+
backdrop-filter: blur(4px);
|
|
5168
|
+
border-radius: 12px;
|
|
5261
5169
|
">
|
|
5262
5170
|
<div id="verification-spinner" style="
|
|
5263
5171
|
width: 24px;
|
|
5264
5172
|
height: 24px;
|
|
5265
|
-
border: 3px solid rgba(
|
|
5266
|
-
border-top-color: #
|
|
5173
|
+
border: 3px solid rgba(16, 185, 129, 0.25);
|
|
5174
|
+
border-top-color: #10B981;
|
|
5267
5175
|
border-radius: 50%;
|
|
5268
5176
|
animation: verificationSpin 0.8s linear infinite;
|
|
5269
5177
|
flex-shrink: 0;
|
|
5270
5178
|
"></div>
|
|
5271
|
-
<span style="
|
|
5272
|
-
font-size: 14px;
|
|
5273
|
-
color: rgba(255, 255, 255, 0.8);
|
|
5274
|
-
white-space: nowrap;
|
|
5275
|
-
">${texts.checkingStatus}</span>
|
|
5179
|
+
<span style="font-size: 14px; color: #A1A1AA; white-space: nowrap;">${texts.checkingStatus}</span>
|
|
5276
5180
|
</div>
|
|
5277
5181
|
</div>
|
|
5278
5182
|
|
|
5279
|
-
<!--
|
|
5280
|
-
<div style="
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
>${texts.
|
|
5303
|
-
|
|
5304
|
-
<!-- Complete Payment / Processing 按钮 -->
|
|
5305
|
-
<button
|
|
5306
|
-
type="button"
|
|
5307
|
-
id="verification-complete-btn"
|
|
5308
|
-
style="
|
|
5309
|
-
flex: 1;
|
|
5310
|
-
max-width: 240px;
|
|
5311
|
-
height: 48px;
|
|
5312
|
-
border-radius: 10px;
|
|
5313
|
-
border: none;
|
|
5314
|
-
background: linear-gradient(135deg, #0d9488 0%, #3b82f6 100%);
|
|
5315
|
-
color: white;
|
|
5316
|
-
font-size: 15px;
|
|
5317
|
-
font-weight: 600;
|
|
5318
|
-
cursor: pointer;
|
|
5319
|
-
transition: all 0.2s;
|
|
5320
|
-
box-shadow: 0 4px 12px rgba(13, 148, 136, 0.3);
|
|
5321
|
-
"
|
|
5322
|
-
>${texts.completeButton}</button>
|
|
5183
|
+
<!-- 按钮组(与 PurchaseSuccessModal 一致) -->
|
|
5184
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
|
5185
|
+
<button type="button" id="verification-cancel-btn" style="
|
|
5186
|
+
padding: 14px 20px;
|
|
5187
|
+
border-radius: 12px;
|
|
5188
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
5189
|
+
background: rgba(255,255,255,0.05);
|
|
5190
|
+
color: #A1A1AA;
|
|
5191
|
+
font-size: 14px;
|
|
5192
|
+
font-weight: 500;
|
|
5193
|
+
cursor: pointer;
|
|
5194
|
+
transition: background 0.2s, color 0.2s, border-color 0.2s;
|
|
5195
|
+
">${texts.cancelButton}</button>
|
|
5196
|
+
<button type="button" id="verification-complete-btn" style="
|
|
5197
|
+
padding: 14px 20px;
|
|
5198
|
+
border-radius: 12px;
|
|
5199
|
+
border: none;
|
|
5200
|
+
background: #10B981;
|
|
5201
|
+
color: #000000;
|
|
5202
|
+
font-size: 14px;
|
|
5203
|
+
font-weight: 700;
|
|
5204
|
+
cursor: pointer;
|
|
5205
|
+
transition: box-shadow 0.2s, transform 0.1s;
|
|
5206
|
+
">${texts.completeButton}</button>
|
|
5323
5207
|
</div>
|
|
5324
5208
|
</div>
|
|
5325
5209
|
`;
|
|
@@ -5397,24 +5281,23 @@ class PaymentVerificationModal {
|
|
|
5397
5281
|
}
|
|
5398
5282
|
|
|
5399
5283
|
#verification-modal-close-btn:hover {
|
|
5400
|
-
background: rgba(255, 255, 255, 0.
|
|
5401
|
-
color:
|
|
5402
|
-
transform: rotate(90deg);
|
|
5284
|
+
background: rgba(255, 255, 255, 0.05) !important;
|
|
5285
|
+
color: #FFFFFF !important;
|
|
5403
5286
|
}
|
|
5404
5287
|
|
|
5405
5288
|
#verification-cancel-btn:hover {
|
|
5406
|
-
background: rgba(255, 255, 255, 0.
|
|
5407
|
-
|
|
5289
|
+
background: rgba(255, 255, 255, 0.1) !important;
|
|
5290
|
+
color: #FFFFFF !important;
|
|
5291
|
+
border-color: rgba(255, 255, 255, 0.1) !important;
|
|
5408
5292
|
}
|
|
5409
5293
|
|
|
5410
5294
|
#verification-complete-btn:hover {
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
transform: translateY(-1px);
|
|
5295
|
+
box-shadow: 0 0 20px rgba(16, 185, 129, 0.4) !important;
|
|
5296
|
+
transform: scale(1.02);
|
|
5414
5297
|
}
|
|
5415
5298
|
|
|
5416
5299
|
#verification-complete-btn:active {
|
|
5417
|
-
transform:
|
|
5300
|
+
transform: scale(0.98);
|
|
5418
5301
|
}
|
|
5419
5302
|
`;
|
|
5420
5303
|
document.head.appendChild(style);
|
|
@@ -5493,7 +5376,8 @@ class PaymentVerificationModal {
|
|
|
5493
5376
|
// 更新按钮文本为 Processing...
|
|
5494
5377
|
const completeBtn = document.getElementById('verification-complete-btn');
|
|
5495
5378
|
if (completeBtn) {
|
|
5496
|
-
const
|
|
5379
|
+
const lang = this.options.language ?? 'en';
|
|
5380
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
5497
5381
|
completeBtn.textContent = isZh ? '处理中...' : 'Processing...';
|
|
5498
5382
|
completeBtn.style.pointerEvents = 'none';
|
|
5499
5383
|
completeBtn.style.opacity = '0.85';
|
|
@@ -5511,7 +5395,8 @@ class PaymentVerificationModal {
|
|
|
5511
5395
|
// 恢复按钮文本
|
|
5512
5396
|
const completeBtn = document.getElementById('verification-complete-btn');
|
|
5513
5397
|
if (completeBtn) {
|
|
5514
|
-
const
|
|
5398
|
+
const lang = this.options.language ?? 'en';
|
|
5399
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
5515
5400
|
completeBtn.textContent = isZh ? '我已完成支付' : 'I\'ve Completed Payment';
|
|
5516
5401
|
completeBtn.style.pointerEvents = '';
|
|
5517
5402
|
completeBtn.style.opacity = '';
|
|
@@ -5635,8 +5520,9 @@ class PaymentFailedModal {
|
|
|
5635
5520
|
*/
|
|
5636
5521
|
createModal() {
|
|
5637
5522
|
const { language } = this.options;
|
|
5638
|
-
const
|
|
5639
|
-
|
|
5523
|
+
const lang = language ?? 'en';
|
|
5524
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
5525
|
+
// 遮罩(与 PurchaseSuccessModal 一致)
|
|
5640
5526
|
this.overlay = document.createElement('div');
|
|
5641
5527
|
this.overlay.id = 'payment-failed-modal-overlay';
|
|
5642
5528
|
this.overlay.style.cssText = `
|
|
@@ -5647,20 +5533,21 @@ class PaymentFailedModal {
|
|
|
5647
5533
|
align-items: center;
|
|
5648
5534
|
justify-content: center;
|
|
5649
5535
|
padding: 20px;
|
|
5650
|
-
background: rgba(
|
|
5651
|
-
backdrop-filter: blur(
|
|
5652
|
-
animation: fadeIn 0.
|
|
5536
|
+
background: rgba(0, 0, 0, 0.85);
|
|
5537
|
+
backdrop-filter: blur(8px);
|
|
5538
|
+
animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
5653
5539
|
overflow: hidden;
|
|
5654
5540
|
`;
|
|
5655
|
-
//
|
|
5541
|
+
// 弹窗卡片(PurchaseSuccessModal 风格:dark-card #121212, rounded 24px)
|
|
5656
5542
|
this.modal = document.createElement('div');
|
|
5657
5543
|
this.modal.style.cssText = `
|
|
5658
5544
|
position: relative;
|
|
5659
5545
|
width: 90vw;
|
|
5660
|
-
max-width:
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5546
|
+
max-width: 500px;
|
|
5547
|
+
min-width: 420px;
|
|
5548
|
+
border-radius: 24px;
|
|
5549
|
+
background: #121212;
|
|
5550
|
+
border: 1px solid rgba(44, 44, 46, 0.6);
|
|
5664
5551
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
5665
5552
|
animation: slideInUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
5666
5553
|
overflow: hidden;
|
|
@@ -5683,58 +5570,62 @@ class PaymentFailedModal {
|
|
|
5683
5570
|
const hasDetails = !!this.options.details;
|
|
5684
5571
|
const hasRetry = !!this.options.onRetry;
|
|
5685
5572
|
return `
|
|
5686
|
-
<!--
|
|
5573
|
+
<!-- 关闭按钮(与 PurchaseSuccessModal 一致) -->
|
|
5687
5574
|
<button
|
|
5688
5575
|
type="button"
|
|
5689
5576
|
id="failed-modal-close-btn"
|
|
5690
5577
|
style="
|
|
5691
5578
|
position: absolute;
|
|
5692
|
-
top:
|
|
5693
|
-
right:
|
|
5579
|
+
top: 20px;
|
|
5580
|
+
right: 20px;
|
|
5694
5581
|
z-index: 10;
|
|
5695
5582
|
display: flex;
|
|
5696
|
-
width:
|
|
5697
|
-
height:
|
|
5583
|
+
width: 40px;
|
|
5584
|
+
height: 40px;
|
|
5698
5585
|
align-items: center;
|
|
5699
5586
|
justify-content: center;
|
|
5700
5587
|
border-radius: 50%;
|
|
5701
|
-
background:
|
|
5702
|
-
color:
|
|
5588
|
+
background: transparent;
|
|
5589
|
+
color: #A1A1AA;
|
|
5703
5590
|
border: none;
|
|
5704
5591
|
cursor: pointer;
|
|
5705
|
-
transition:
|
|
5592
|
+
transition: color 0.2s, background 0.2s;
|
|
5706
5593
|
"
|
|
5707
5594
|
>
|
|
5708
|
-
<svg width="
|
|
5709
|
-
<
|
|
5595
|
+
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
5596
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
5597
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
5710
5598
|
</svg>
|
|
5711
5599
|
</button>
|
|
5712
5600
|
|
|
5713
|
-
<!--
|
|
5714
|
-
<div style="padding:
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
margin: 0 0 12px;
|
|
5601
|
+
<!-- 标题与消息 -->
|
|
5602
|
+
<div style="padding: 24px 24px 0;">
|
|
5603
|
+
<h1 style="
|
|
5604
|
+
margin: 0 0 8px;
|
|
5718
5605
|
font-size: 24px;
|
|
5719
5606
|
font-weight: 700;
|
|
5720
|
-
color: #
|
|
5607
|
+
color: #FFFFFF;
|
|
5721
5608
|
text-align: center;
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
">${this.escapeHtml(title)}</h2>
|
|
5725
|
-
|
|
5726
|
-
<!-- 消息 -->
|
|
5609
|
+
letter-spacing: -0.02em;
|
|
5610
|
+
">${this.escapeHtml(title)}</h1>
|
|
5727
5611
|
<p style="
|
|
5728
|
-
margin: 0 0
|
|
5729
|
-
font-size:
|
|
5612
|
+
margin: 0 0 24px;
|
|
5613
|
+
font-size: 14px;
|
|
5730
5614
|
line-height: 1.6;
|
|
5731
|
-
color:
|
|
5615
|
+
color: #A1A1AA;
|
|
5732
5616
|
text-align: center;
|
|
5733
5617
|
">${this.escapeHtml(this.options.message)}</p>
|
|
5618
|
+
</div>
|
|
5734
5619
|
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5620
|
+
<!-- 详情展开/折叠(放入内卡片风格) -->
|
|
5621
|
+
${hasDetails ? `
|
|
5622
|
+
<div style="margin: 0 24px 24px;">
|
|
5623
|
+
<div style="
|
|
5624
|
+
padding: 20px;
|
|
5625
|
+
border-radius: 12px;
|
|
5626
|
+
background: rgba(30, 30, 30, 0.5);
|
|
5627
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
5628
|
+
">
|
|
5738
5629
|
<button
|
|
5739
5630
|
type="button"
|
|
5740
5631
|
id="failed-modal-details-toggle"
|
|
@@ -5744,15 +5635,15 @@ class PaymentFailedModal {
|
|
|
5744
5635
|
align-items: center;
|
|
5745
5636
|
justify-content: center;
|
|
5746
5637
|
gap: 8px;
|
|
5747
|
-
padding: 10px;
|
|
5638
|
+
padding: 10px 12px;
|
|
5748
5639
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
5749
|
-
border-radius:
|
|
5640
|
+
border-radius: 8px;
|
|
5750
5641
|
background: rgba(255, 255, 255, 0.03);
|
|
5751
|
-
color:
|
|
5642
|
+
color: #A1A1AA;
|
|
5752
5643
|
font-size: 13px;
|
|
5753
5644
|
font-weight: 500;
|
|
5754
5645
|
cursor: pointer;
|
|
5755
|
-
transition:
|
|
5646
|
+
transition: background 0.2s, color 0.2s, border-color 0.2s;
|
|
5756
5647
|
"
|
|
5757
5648
|
>
|
|
5758
5649
|
<span id="failed-modal-details-toggle-text">${detailsToggleText}</span>
|
|
@@ -5771,91 +5662,69 @@ class PaymentFailedModal {
|
|
|
5771
5662
|
<div style="
|
|
5772
5663
|
margin-top: 12px;
|
|
5773
5664
|
padding: 16px;
|
|
5774
|
-
border-radius:
|
|
5775
|
-
background: rgba(239, 68, 68, 0.
|
|
5776
|
-
border: 1px solid rgba(239, 68, 68, 0.
|
|
5665
|
+
border-radius: 8px;
|
|
5666
|
+
background: rgba(239, 68, 68, 0.06);
|
|
5667
|
+
border: 1px solid rgba(239, 68, 68, 0.12);
|
|
5777
5668
|
">
|
|
5778
5669
|
<pre style="
|
|
5779
5670
|
margin: 0;
|
|
5780
|
-
font-family: ui-monospace,
|
|
5671
|
+
font-family: ui-monospace, monospace;
|
|
5781
5672
|
font-size: 12px;
|
|
5782
5673
|
line-height: 1.6;
|
|
5783
|
-
color:
|
|
5674
|
+
color: #A1A1AA;
|
|
5784
5675
|
white-space: pre-wrap;
|
|
5785
5676
|
word-break: break-word;
|
|
5786
5677
|
">${this.escapeHtml(this.options.details || '')}</pre>
|
|
5787
5678
|
</div>
|
|
5788
5679
|
</div>
|
|
5789
5680
|
</div>
|
|
5790
|
-
` : ''}
|
|
5791
|
-
|
|
5792
|
-
<!-- 按钮组 -->
|
|
5793
|
-
<div style="
|
|
5794
|
-
display: flex;
|
|
5795
|
-
gap: 16px;
|
|
5796
|
-
justify-content: center;
|
|
5797
|
-
">
|
|
5798
|
-
${hasRetry ? `
|
|
5799
|
-
<!-- 关闭按钮(有重试时) -->
|
|
5800
|
-
<button
|
|
5801
|
-
type="button"
|
|
5802
|
-
id="failed-modal-close-bottom-btn"
|
|
5803
|
-
style="
|
|
5804
|
-
flex: 1;
|
|
5805
|
-
max-width: 240px;
|
|
5806
|
-
height: 48px;
|
|
5807
|
-
border-radius: 10px;
|
|
5808
|
-
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
5809
|
-
background: transparent;
|
|
5810
|
-
color: rgba(255, 255, 255, 0.8);
|
|
5811
|
-
font-size: 15px;
|
|
5812
|
-
font-weight: 500;
|
|
5813
|
-
cursor: pointer;
|
|
5814
|
-
transition: all 0.2s;
|
|
5815
|
-
"
|
|
5816
|
-
>${closeText}</button>
|
|
5817
|
-
|
|
5818
|
-
<!-- 重试按钮 -->
|
|
5819
|
-
<button
|
|
5820
|
-
type="button"
|
|
5821
|
-
id="failed-modal-retry-btn"
|
|
5822
|
-
style="
|
|
5823
|
-
flex: 1;
|
|
5824
|
-
max-width: 240px;
|
|
5825
|
-
height: 48px;
|
|
5826
|
-
border-radius: 10px;
|
|
5827
|
-
border: none;
|
|
5828
|
-
background: linear-gradient(135deg, #0d9488 0%, #3b82f6 100%);
|
|
5829
|
-
color: white;
|
|
5830
|
-
font-size: 15px;
|
|
5831
|
-
font-weight: 600;
|
|
5832
|
-
cursor: pointer;
|
|
5833
|
-
transition: all 0.2s;
|
|
5834
|
-
box-shadow: 0 4px 12px rgba(13, 148, 136, 0.3);
|
|
5835
|
-
"
|
|
5836
|
-
>${retryText}</button>
|
|
5837
|
-
` : `
|
|
5838
|
-
<!-- 关闭按钮(无重试时,居中显示) -->
|
|
5839
|
-
<button
|
|
5840
|
-
type="button"
|
|
5841
|
-
id="failed-modal-close-bottom-btn"
|
|
5842
|
-
style="
|
|
5843
|
-
flex: 0;
|
|
5844
|
-
min-width: 160px;
|
|
5845
|
-
max-width: 240px;
|
|
5846
|
-
height: 48px;
|
|
5847
|
-
border-radius: 10px;
|
|
5848
|
-
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
5849
|
-
background: transparent;
|
|
5850
|
-
color: rgba(255, 255, 255, 0.8);
|
|
5851
|
-
font-size: 15px;
|
|
5852
|
-
font-weight: 500;
|
|
5853
|
-
cursor: pointer;
|
|
5854
|
-
transition: all 0.2s;
|
|
5855
|
-
"
|
|
5856
|
-
>${closeText}</button>
|
|
5857
|
-
`}
|
|
5858
5681
|
</div>
|
|
5682
|
+
` : '<div style="margin-bottom: 24px;"></div>'}
|
|
5683
|
+
|
|
5684
|
+
<!-- 按钮组(与 PurchaseSuccessModal / RetentionModal 一致) -->
|
|
5685
|
+
<div style="display: grid; grid-template-columns: ${hasRetry ? '1fr 1fr' : '1fr'}; gap: 16px; padding: 0 24px 24px; justify-items: center;">
|
|
5686
|
+
${hasRetry ? `
|
|
5687
|
+
<button type="button" id="failed-modal-close-bottom-btn" style="
|
|
5688
|
+
width: 100%;
|
|
5689
|
+
max-width: 240px;
|
|
5690
|
+
padding: 14px 20px;
|
|
5691
|
+
border-radius: 12px;
|
|
5692
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
5693
|
+
background: rgba(255,255,255,0.05);
|
|
5694
|
+
color: #A1A1AA;
|
|
5695
|
+
font-size: 14px;
|
|
5696
|
+
font-weight: 500;
|
|
5697
|
+
cursor: pointer;
|
|
5698
|
+
transition: background 0.2s, color 0.2s, border-color 0.2s;
|
|
5699
|
+
">${closeText}</button>
|
|
5700
|
+
<button type="button" id="failed-modal-retry-btn" style="
|
|
5701
|
+
width: 100%;
|
|
5702
|
+
max-width: 240px;
|
|
5703
|
+
padding: 14px 20px;
|
|
5704
|
+
border-radius: 12px;
|
|
5705
|
+
border: none;
|
|
5706
|
+
background: #10B981;
|
|
5707
|
+
color: #000000;
|
|
5708
|
+
font-size: 14px;
|
|
5709
|
+
font-weight: 700;
|
|
5710
|
+
cursor: pointer;
|
|
5711
|
+
transition: box-shadow 0.2s, transform 0.1s;
|
|
5712
|
+
">${retryText}</button>
|
|
5713
|
+
` : `
|
|
5714
|
+
<button type="button" id="failed-modal-close-bottom-btn" style="
|
|
5715
|
+
min-width: 160px;
|
|
5716
|
+
max-width: 240px;
|
|
5717
|
+
padding: 14px 20px;
|
|
5718
|
+
border-radius: 12px;
|
|
5719
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
5720
|
+
background: rgba(255,255,255,0.05);
|
|
5721
|
+
color: #A1A1AA;
|
|
5722
|
+
font-size: 14px;
|
|
5723
|
+
font-weight: 500;
|
|
5724
|
+
cursor: pointer;
|
|
5725
|
+
transition: background 0.2s, color 0.2s, border-color 0.2s;
|
|
5726
|
+
">${closeText}</button>
|
|
5727
|
+
`}
|
|
5859
5728
|
</div>
|
|
5860
5729
|
`;
|
|
5861
5730
|
}
|
|
@@ -5902,30 +5771,29 @@ class PaymentFailedModal {
|
|
|
5902
5771
|
}
|
|
5903
5772
|
|
|
5904
5773
|
#failed-modal-close-btn:hover {
|
|
5905
|
-
background: rgba(255, 255, 255, 0.
|
|
5906
|
-
color:
|
|
5907
|
-
transform: rotate(90deg);
|
|
5774
|
+
background: rgba(255, 255, 255, 0.05) !important;
|
|
5775
|
+
color: #FFFFFF !important;
|
|
5908
5776
|
}
|
|
5909
5777
|
|
|
5910
5778
|
#failed-modal-details-toggle:hover {
|
|
5911
5779
|
background: rgba(255, 255, 255, 0.06) !important;
|
|
5912
|
-
border-color: rgba(255, 255, 255, 0.
|
|
5913
|
-
color:
|
|
5780
|
+
border-color: rgba(255, 255, 255, 0.15) !important;
|
|
5781
|
+
color: #FFFFFF !important;
|
|
5914
5782
|
}
|
|
5915
5783
|
|
|
5916
5784
|
#failed-modal-close-bottom-btn:hover {
|
|
5917
|
-
background: rgba(255, 255, 255, 0.
|
|
5918
|
-
|
|
5785
|
+
background: rgba(255, 255, 255, 0.1) !important;
|
|
5786
|
+
color: #FFFFFF !important;
|
|
5787
|
+
border-color: rgba(255, 255, 255, 0.1) !important;
|
|
5919
5788
|
}
|
|
5920
5789
|
|
|
5921
5790
|
#failed-modal-retry-btn:hover {
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
transform: translateY(-1px);
|
|
5791
|
+
box-shadow: 0 0 20px rgba(16, 185, 129, 0.4) !important;
|
|
5792
|
+
transform: scale(1.02);
|
|
5925
5793
|
}
|
|
5926
5794
|
|
|
5927
5795
|
#failed-modal-retry-btn:active {
|
|
5928
|
-
transform:
|
|
5796
|
+
transform: scale(0.98);
|
|
5929
5797
|
}
|
|
5930
5798
|
`;
|
|
5931
5799
|
document.head.appendChild(style);
|
|
@@ -5978,7 +5846,8 @@ class PaymentFailedModal {
|
|
|
5978
5846
|
* 切换详情展开/折叠
|
|
5979
5847
|
*/
|
|
5980
5848
|
toggleDetails() {
|
|
5981
|
-
const
|
|
5849
|
+
const lang = this.options.language ?? 'en';
|
|
5850
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
5982
5851
|
const detailsToggleText = isZh ? '查看详情' : 'View Details';
|
|
5983
5852
|
const detailsHideText = isZh ? '隐藏详情' : 'Hide Details';
|
|
5984
5853
|
this.detailsExpanded = !this.detailsExpanded;
|
|
@@ -8509,16 +8378,6 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8509
8378
|
this.isFetchingPackages = false;
|
|
8510
8379
|
}
|
|
8511
8380
|
}
|
|
8512
|
-
/**
|
|
8513
|
-
* Parse purchase limit string to day_limit number
|
|
8514
|
-
* Example: "Daily limit: 1" => 1
|
|
8515
|
-
*/
|
|
8516
|
-
parsePurchaseLimit(limit) {
|
|
8517
|
-
if (!limit)
|
|
8518
|
-
return 0;
|
|
8519
|
-
const match = limit.match(/\d+/);
|
|
8520
|
-
return match ? parseInt(match[0]) : 0;
|
|
8521
|
-
}
|
|
8522
8381
|
/**
|
|
8523
8382
|
* 覆盖 BasePackageModal 的 handlePaymentFlow 方法
|
|
8524
8383
|
* 使用 PaymentCheckoutModal 替代旧的 DropinPaymentModal
|
|
@@ -8653,6 +8512,7 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8653
8512
|
if (modalElement) {
|
|
8654
8513
|
modalElement.style.background = '#0a0a0f';
|
|
8655
8514
|
modalElement.style.border = '1px solid rgba(255, 255, 255, 0.1)';
|
|
8515
|
+
modalElement.style.borderRadius = '24px';
|
|
8656
8516
|
}
|
|
8657
8517
|
// Modify title style
|
|
8658
8518
|
const titleElement = document.querySelector('.payment-modal-title');
|
|
@@ -8663,6 +8523,31 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8663
8523
|
titleElement.style.padding = '32px 32px 0 32px';
|
|
8664
8524
|
titleElement.style.marginBottom = '16px';
|
|
8665
8525
|
titleElement.style.letterSpacing = '-0.01em';
|
|
8526
|
+
titleElement.style.display = 'none'; // Hide default title, we use custom header in renderContent
|
|
8527
|
+
}
|
|
8528
|
+
// Add responsive styles for cards
|
|
8529
|
+
if (!document.getElementById('credit-package-responsive-styles')) {
|
|
8530
|
+
const style = document.createElement('style');
|
|
8531
|
+
style.id = 'credit-package-responsive-styles';
|
|
8532
|
+
style.textContent = `
|
|
8533
|
+
@media (max-width: 768px) {
|
|
8534
|
+
.credit-pack-card-container {
|
|
8535
|
+
width: 100% !important;
|
|
8536
|
+
max-width: 320px;
|
|
8537
|
+
margin: 0 auto;
|
|
8538
|
+
}
|
|
8539
|
+
.credit-pack-card {
|
|
8540
|
+
width: 100% !important;
|
|
8541
|
+
height: 260px !important;
|
|
8542
|
+
}
|
|
8543
|
+
.payment-modal {
|
|
8544
|
+
width: 95vw !important;
|
|
8545
|
+
max-height: 90vh !important;
|
|
8546
|
+
overflow-y: auto !important;
|
|
8547
|
+
}
|
|
8548
|
+
}
|
|
8549
|
+
`;
|
|
8550
|
+
document.head.appendChild(style);
|
|
8666
8551
|
}
|
|
8667
8552
|
// Modify close button color and add hover animation
|
|
8668
8553
|
const closeButton = document.querySelector('.payment-modal-close');
|
|
@@ -8695,7 +8580,8 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8695
8580
|
if (!container) {
|
|
8696
8581
|
throw new Error('Modal content container not found');
|
|
8697
8582
|
}
|
|
8698
|
-
const
|
|
8583
|
+
const lang = this.language ?? 'en';
|
|
8584
|
+
const isZh = lang === 'zh' || lang === 'zh-TW';
|
|
8699
8585
|
const styles = this.getResponsiveStyles();
|
|
8700
8586
|
container.innerHTML = `
|
|
8701
8587
|
<div style="
|
|
@@ -8705,10 +8591,10 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8705
8591
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
8706
8592
|
">
|
|
8707
8593
|
<!-- Credit Packs - credit package purchase title -->
|
|
8708
|
-
<div style="margin: 0 auto ${
|
|
8594
|
+
<div style="margin: 0 auto ${styles.headerMargin}; max-width: 80rem; text-align: center;">
|
|
8709
8595
|
<h3 style="
|
|
8710
8596
|
margin-bottom: ${this.SPACING.xs};
|
|
8711
|
-
font-size:
|
|
8597
|
+
font-size: ${styles.titleFontSize};
|
|
8712
8598
|
font-weight: 700;
|
|
8713
8599
|
color: ${this.COLORS.text.primary};
|
|
8714
8600
|
letter-spacing: -0.02em;
|
|
@@ -8716,11 +8602,11 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8716
8602
|
${isZh ? '需要更多积分?' : 'Need More Credits?'}
|
|
8717
8603
|
</h3>
|
|
8718
8604
|
<p style="
|
|
8719
|
-
font-size:
|
|
8605
|
+
font-size: ${styles.subtitleFontSize};
|
|
8720
8606
|
color: ${this.COLORS.text.secondary};
|
|
8721
8607
|
line-height: 1.6;
|
|
8722
8608
|
">
|
|
8723
|
-
${isZh ? '随时购买永久积分包' : '
|
|
8609
|
+
${isZh ? '随时购买永久积分包' : 'Get credits (Valid for all platform products)'}
|
|
8724
8610
|
</p>
|
|
8725
8611
|
</div>
|
|
8726
8612
|
|
|
@@ -8728,7 +8614,8 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8728
8614
|
<div style="
|
|
8729
8615
|
display: grid;
|
|
8730
8616
|
grid-template-columns: ${styles.packGridColumns};
|
|
8731
|
-
gap:
|
|
8617
|
+
gap: ${styles.gridGap};
|
|
8618
|
+
justify-items: center;
|
|
8732
8619
|
">
|
|
8733
8620
|
${this.getPackages().map((pkg, index) => this.renderPackageCard(pkg, index)).join('')}
|
|
8734
8621
|
</div>
|
|
@@ -8743,30 +8630,55 @@ class CreditPackageModal extends BasePackageModal {
|
|
|
8743
8630
|
*/
|
|
8744
8631
|
getResponsiveStyles() {
|
|
8745
8632
|
const isMobile = window.matchMedia('(max-width: 768px)').matches;
|
|
8746
|
-
const isTablet = window.matchMedia('(max-width:
|
|
8633
|
+
const isTablet = window.matchMedia('(max-width: 1024px)').matches;
|
|
8747
8634
|
const isLaptop = window.matchMedia('(max-width: 1400px)').matches;
|
|
8748
8635
|
let computeColumns = 5;
|
|
8749
8636
|
let packColumns = 4;
|
|
8750
8637
|
let padding = '0 60px 60px';
|
|
8638
|
+
let titleSize = '32px';
|
|
8639
|
+
let subtitleSize = '16px';
|
|
8640
|
+
let headerMargin = this.SPACING.lg;
|
|
8641
|
+
let gridGap = '24px';
|
|
8751
8642
|
if (isMobile) {
|
|
8752
8643
|
computeColumns = 1;
|
|
8753
8644
|
packColumns = 1;
|
|
8754
|
-
padding = '0
|
|
8645
|
+
padding = '0 16px 32px';
|
|
8646
|
+
titleSize = '24px';
|
|
8647
|
+
subtitleSize = '14px';
|
|
8648
|
+
headerMargin = this.SPACING.md;
|
|
8649
|
+
gridGap = '16px';
|
|
8755
8650
|
}
|
|
8756
8651
|
else if (isTablet) {
|
|
8757
8652
|
computeColumns = 2;
|
|
8758
8653
|
packColumns = 2;
|
|
8759
|
-
padding = '0
|
|
8654
|
+
padding = '0 32px 48px';
|
|
8655
|
+
titleSize = '28px';
|
|
8656
|
+
subtitleSize = '15px';
|
|
8657
|
+
headerMargin = this.SPACING.md;
|
|
8658
|
+
gridGap = '20px';
|
|
8760
8659
|
}
|
|
8761
8660
|
else if (isLaptop) {
|
|
8762
8661
|
computeColumns = 3;
|
|
8763
|
-
packColumns =
|
|
8764
|
-
padding = '0
|
|
8662
|
+
packColumns = 3;
|
|
8663
|
+
padding = '0 48px 60px';
|
|
8664
|
+
titleSize = '32px';
|
|
8665
|
+
subtitleSize = '16px';
|
|
8666
|
+
headerMargin = this.SPACING.lg;
|
|
8667
|
+
gridGap = '24px';
|
|
8668
|
+
}
|
|
8669
|
+
// Adjust columns based on package count if small
|
|
8670
|
+
const packageCount = this.getPackages().length;
|
|
8671
|
+
if (!isMobile && packageCount < packColumns) {
|
|
8672
|
+
packColumns = packageCount;
|
|
8765
8673
|
}
|
|
8766
8674
|
return {
|
|
8767
8675
|
containerPadding: padding,
|
|
8768
8676
|
computeGridColumns: `repeat(${computeColumns}, 1fr)`,
|
|
8769
8677
|
packGridColumns: `repeat(${packColumns}, 1fr)`,
|
|
8678
|
+
titleFontSize: titleSize,
|
|
8679
|
+
subtitleFontSize: subtitleSize,
|
|
8680
|
+
headerMargin: headerMargin,
|
|
8681
|
+
gridGap: gridGap,
|
|
8770
8682
|
};
|
|
8771
8683
|
}
|
|
8772
8684
|
/**
|
|
@@ -8922,8 +8834,8 @@ class GenericPackageModal extends BasePackageModal {
|
|
|
8922
8834
|
if (!container) {
|
|
8923
8835
|
throw new Error('Modal content container not found');
|
|
8924
8836
|
}
|
|
8925
|
-
|
|
8926
|
-
container.innerHTML =
|
|
8837
|
+
const cardsHtml = this.options.packages.map((pkg, index) => this.renderPackageCard(pkg, index)).join('');
|
|
8838
|
+
container.innerHTML = `<div style="display:flex;flex-wrap:wrap;justify-content:center;gap:24px;padding:0;">${cardsHtml}</div>`;
|
|
8927
8839
|
// Attach event listeners
|
|
8928
8840
|
this.attachEventListeners(container);
|
|
8929
8841
|
}
|
|
@@ -9018,199 +8930,229 @@ class GenericPackageModal extends BasePackageModal {
|
|
|
9018
8930
|
};
|
|
9019
8931
|
}
|
|
9020
8932
|
/**
|
|
9021
|
-
* Render package card
|
|
8933
|
+
* Render package card (Credits.html / 参考图一比一风格)
|
|
9022
8934
|
*/
|
|
9023
8935
|
renderPackageCard(pkg, index) {
|
|
9024
8936
|
const hasBonus = pkg.bonus_credits && parseInt(pkg.bonus_credits) > 0;
|
|
9025
|
-
const hasBonusPercentage = pkg.bonus_percentage && pkg.bonus_percentage > 0;
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
8937
|
+
const hasBonusPercentage = pkg.bonus_percentage != null && pkg.bonus_percentage > 0;
|
|
8938
|
+
const baseNum = this.formatNumber(pkg.base_credits || pkg.credits);
|
|
8939
|
+
const bonusNum = hasBonus ? this.formatNumber(pkg.bonus_credits) : '';
|
|
8940
|
+
const originalPrice = pkg.original_price;
|
|
8941
|
+
const svgClose = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
|
|
8942
|
+
const svgZap = '<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>';
|
|
8943
|
+
const svgCheck = '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>';
|
|
8944
|
+
const svgSparkles = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"></path></svg>';
|
|
9031
8945
|
return `
|
|
9032
8946
|
<div
|
|
9033
8947
|
data-package-id="${pkg.id}"
|
|
8948
|
+
class="generic-package-card"
|
|
9034
8949
|
style="
|
|
9035
8950
|
position: relative;
|
|
9036
8951
|
display: flex;
|
|
9037
8952
|
flex-direction: column;
|
|
9038
|
-
justify-content: center;
|
|
9039
8953
|
align-items: center;
|
|
9040
|
-
gap: 48px;
|
|
9041
|
-
border-radius: 16px;
|
|
9042
|
-
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
9043
|
-
background: #000000;
|
|
9044
|
-
padding: 80px 60px;
|
|
9045
8954
|
text-align: center;
|
|
9046
|
-
cursor: pointer;
|
|
9047
|
-
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
9048
8955
|
width: 100%;
|
|
9049
|
-
|
|
8956
|
+
max-width: 384px;
|
|
8957
|
+
min-width: 340px;
|
|
8958
|
+
margin: 0 auto;
|
|
9050
8959
|
box-sizing: border-box;
|
|
8960
|
+
border-radius: 24px;
|
|
8961
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
8962
|
+
background: #171717;
|
|
8963
|
+
padding: 40px 32px 32px;
|
|
8964
|
+
overflow: hidden;
|
|
9051
8965
|
"
|
|
9052
|
-
onmouseover="this.style.borderColor='rgba(255, 255, 255, 0.2)';"
|
|
9053
|
-
onmouseout="this.style.borderColor='rgba(255, 255, 255, 0.1)';"
|
|
9054
8966
|
>
|
|
9055
|
-
<!--
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
">
|
|
9069
|
-
${packageTitle}
|
|
9070
|
-
</div>
|
|
9071
|
-
` : ''}
|
|
8967
|
+
<!-- Background Ambient Glow (参考图中部绿色光晕) -->
|
|
8968
|
+
<div style="
|
|
8969
|
+
position: absolute;
|
|
8970
|
+
bottom: 25%;
|
|
8971
|
+
right: 25%;
|
|
8972
|
+
width: 240px;
|
|
8973
|
+
height: 240px;
|
|
8974
|
+
background: rgba(6, 182, 212, 0.1);
|
|
8975
|
+
border-radius: 50%;
|
|
8976
|
+
filter: blur(100px);
|
|
8977
|
+
pointer-events: none;
|
|
8978
|
+
z-index: 0;
|
|
8979
|
+
"></div>
|
|
9072
8980
|
|
|
9073
|
-
<!-- Close button
|
|
8981
|
+
<!-- Close button (右上角圆形按钮) -->
|
|
9074
8982
|
<button
|
|
8983
|
+
type="button"
|
|
9075
8984
|
onclick="this.closest('[data-package-id]').dispatchEvent(new CustomEvent('close-modal', { bubbles: true }));"
|
|
9076
8985
|
style="
|
|
9077
8986
|
position: absolute;
|
|
9078
|
-
top:
|
|
9079
|
-
right:
|
|
9080
|
-
width:
|
|
9081
|
-
height:
|
|
8987
|
+
top: 16px;
|
|
8988
|
+
right: 16px;
|
|
8989
|
+
width: 34px;
|
|
8990
|
+
height: 34px;
|
|
9082
8991
|
border-radius: 50%;
|
|
9083
8992
|
border: none;
|
|
9084
|
-
background: rgba(255, 255, 255, 0.
|
|
9085
|
-
color: rgba(255, 255, 255, 0.
|
|
8993
|
+
background: rgba(255, 255, 255, 0.05);
|
|
8994
|
+
color: rgba(255, 255, 255, 0.4);
|
|
9086
8995
|
cursor: pointer;
|
|
9087
8996
|
display: flex;
|
|
9088
8997
|
align-items: center;
|
|
9089
8998
|
justify-content: center;
|
|
9090
|
-
font-size: 20px;
|
|
9091
|
-
line-height: 1;
|
|
9092
8999
|
transition: all 0.2s;
|
|
9093
|
-
z-index:
|
|
9000
|
+
z-index: 10;
|
|
9094
9001
|
"
|
|
9095
|
-
onmouseover="this.style.background='rgba(255,
|
|
9096
|
-
onmouseout="this.style.background='rgba(255,
|
|
9097
|
-
>
|
|
9098
|
-
×
|
|
9099
|
-
</button>
|
|
9002
|
+
onmouseover="this.style.background='rgba(255,255,255,0.1)'; this.style.color='#FFFFFF';"
|
|
9003
|
+
onmouseout="this.style.background='rgba(255,255,255,0.05)'; this.style.color='rgba(255,255,255,0.4)';"
|
|
9004
|
+
>${svgClose}</button>
|
|
9100
9005
|
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9006
|
+
<div style="position: relative; z-index: 1; width: 100%; display: flex; flex-direction: column; align-items: center;">
|
|
9007
|
+
<!-- Value badge: +N% EXTRA VALUE (深色底, 金色边框) -->
|
|
9008
|
+
${hasBonusPercentage ? `
|
|
9009
|
+
<div style="
|
|
9010
|
+
display: inline-flex;
|
|
9011
|
+
align-items: center;
|
|
9012
|
+
gap: 6px;
|
|
9013
|
+
margin-bottom: 24px;
|
|
9014
|
+
padding: 4px 12px;
|
|
9015
|
+
border-radius: 9999px;
|
|
9016
|
+
background: rgba(249, 176, 22, 0.1);
|
|
9017
|
+
border: 1px solid rgba(249, 176, 22, 0.2);
|
|
9018
|
+
color: #F9B016;
|
|
9019
|
+
font-size: 12px;
|
|
9020
|
+
font-weight: 700;
|
|
9021
|
+
box-shadow: 0 0 15px rgba(249, 176, 22, 0.1);
|
|
9022
|
+
">
|
|
9023
|
+
<span style="display:inline-flex;">${svgZap}</span>
|
|
9024
|
+
<span>+${pkg.bonus_percentage}% EXTRA VALUE</span>
|
|
9025
|
+
</div>
|
|
9026
|
+
` : '<div style="height:16px;"></div>'}
|
|
9027
|
+
|
|
9028
|
+
<!-- Main credits: 巨大白字 + CREDITS -->
|
|
9029
|
+
<div style="margin-bottom: 0;">
|
|
9030
|
+
<span style="
|
|
9031
|
+
display: block;
|
|
9032
|
+
font-size: 60px;
|
|
9033
|
+
line-height: 1;
|
|
9034
|
+
font-weight: 800;
|
|
9035
|
+
color: #FFFFFF;
|
|
9036
|
+
letter-spacing: -0.05em;
|
|
9037
|
+
filter: drop-shadow(0 20px 30px rgba(0,0,0,0.5));
|
|
9038
|
+
">${baseNum}</span>
|
|
9039
|
+
<span style="
|
|
9040
|
+
display: block;
|
|
9041
|
+
margin-top: 4px;
|
|
9042
|
+
font-size: 14px;
|
|
9043
|
+
font-weight: 500;
|
|
9044
|
+
color: #A3A3A3;
|
|
9045
|
+
letter-spacing: 0.1em;
|
|
9046
|
+
text-transform: uppercase;
|
|
9047
|
+
">CREDITS</span>
|
|
9118
9048
|
</div>
|
|
9119
|
-
` : ''}
|
|
9120
9049
|
|
|
9121
|
-
|
|
9122
|
-
<div style="
|
|
9123
|
-
display: flex;
|
|
9124
|
-
flex-direction: column;
|
|
9125
|
-
align-items: center;
|
|
9126
|
-
justify-content: center;
|
|
9127
|
-
gap: 0;
|
|
9128
|
-
width: 100%;
|
|
9129
|
-
margin-top: 60px;
|
|
9130
|
-
">
|
|
9050
|
+
<!-- Separator: 渐变线 + 加号 (缩短线条长度) -->
|
|
9131
9051
|
<div style="
|
|
9132
9052
|
display: flex;
|
|
9133
|
-
align-items:
|
|
9053
|
+
align-items: center;
|
|
9134
9054
|
justify-content: center;
|
|
9135
9055
|
gap: 12px;
|
|
9136
|
-
|
|
9056
|
+
width: 100%;
|
|
9057
|
+
margin: 12px 0;
|
|
9058
|
+
opacity: 0.4;
|
|
9137
9059
|
">
|
|
9138
|
-
|
|
9139
|
-
<span style="
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
font-weight: 400;
|
|
9143
|
-
color: white;
|
|
9144
|
-
letter-spacing: -0.04em;
|
|
9145
|
-
white-space: nowrap;
|
|
9146
|
-
">
|
|
9147
|
-
${this.formatNumber(pkg.base_credits || pkg.credits)}
|
|
9148
|
-
</span>
|
|
9149
|
-
|
|
9150
|
-
<!-- credits text -->
|
|
9151
|
-
<span style="
|
|
9152
|
-
font-size: 52px;
|
|
9153
|
-
line-height: 1;
|
|
9154
|
-
font-weight: 400;
|
|
9155
|
-
color: white;
|
|
9156
|
-
letter-spacing: -0.04em;
|
|
9157
|
-
white-space: nowrap;
|
|
9158
|
-
">
|
|
9159
|
-
credits
|
|
9160
|
-
</span>
|
|
9060
|
+
<span style="width: 40px; height: 1px; background: linear-gradient(to right, transparent, #FFFFFF);"></span>
|
|
9061
|
+
<span style="color: #FFFFFF; font-size: 18px; font-weight: 300; line-height: 1;">+</span>
|
|
9062
|
+
<span style="width: 40px; height: 1px; background: linear-gradient(to left, transparent, #FFFFFF);"></span>
|
|
9063
|
+
</div>
|
|
9161
9064
|
|
|
9162
|
-
|
|
9163
|
-
|
|
9065
|
+
<!-- Bonus credits: 绿色数字 + BONUS CREDITS -->
|
|
9066
|
+
${hasBonus ? `
|
|
9067
|
+
<div style="margin-bottom: 32px; position: relative;">
|
|
9068
|
+
<div style="position: absolute; inset: -16px; background: rgba(34, 197, 94, 0.1); filter: blur(20px); border-radius: 50%;"></div>
|
|
9164
9069
|
<span style="
|
|
9165
|
-
|
|
9070
|
+
display: block;
|
|
9071
|
+
position: relative;
|
|
9072
|
+
font-size: 36px;
|
|
9166
9073
|
line-height: 1;
|
|
9167
|
-
font-weight:
|
|
9168
|
-
color:
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9074
|
+
font-weight: 700;
|
|
9075
|
+
color: transparent;
|
|
9076
|
+
background: linear-gradient(to bottom, #86EFAC, #22C55E);
|
|
9077
|
+
-webkit-background-clip: text;
|
|
9078
|
+
background-clip: text;
|
|
9079
|
+
">${bonusNum}</span>
|
|
9080
|
+
<div style="display:inline-flex;position: relative;align-items:center;gap:6px;margin-top:4px;">
|
|
9081
|
+
<span style="display:inline-flex;color:#4ADE80;">${svgSparkles}</span>
|
|
9082
|
+
<span style="font-size:14px;font-weight:600;color:#4ADE80;letter-spacing:0.05em;text-transform:uppercase;">Bonus Credits</span>
|
|
9083
|
+
</div>
|
|
9084
|
+
</div>
|
|
9085
|
+
` : '<div style="height:32px;"></div>'}
|
|
9086
|
+
|
|
9087
|
+
<!-- Validity badge (深色小胶囊) -->
|
|
9088
|
+
<div style="
|
|
9089
|
+
display: inline-flex;
|
|
9090
|
+
align-items: center;
|
|
9091
|
+
gap: 6px;
|
|
9092
|
+
margin-bottom: 32px;
|
|
9093
|
+
padding: 6px 12px;
|
|
9094
|
+
border-radius: 8px;
|
|
9095
|
+
background: rgba(255, 255, 255, 0.05);
|
|
9096
|
+
color: #737373;
|
|
9097
|
+
font-size: 12px;
|
|
9098
|
+
">
|
|
9099
|
+
<span style="display:inline-flex;">${svgCheck}</span>
|
|
9100
|
+
<span>Valid for all platform products</span>
|
|
9175
9101
|
</div>
|
|
9176
|
-
</div>
|
|
9177
9102
|
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9103
|
+
<!-- CTA Button (渐变大按钮, 右侧带价格深色块) -->
|
|
9104
|
+
<button
|
|
9105
|
+
data-package-button="${pkg.id}"
|
|
9106
|
+
type="button"
|
|
9107
|
+
style="
|
|
9108
|
+
width: 100%;
|
|
9109
|
+
border: none;
|
|
9110
|
+
border-radius: 16px;
|
|
9111
|
+
padding: 4px 4px 4px 24px;
|
|
9112
|
+
background: linear-gradient(to right, #34D399, #06B6D4);
|
|
9113
|
+
color: #171717;
|
|
9114
|
+
font-size: 18px;
|
|
9115
|
+
font-weight: 700;
|
|
9116
|
+
cursor: pointer;
|
|
9117
|
+
display: flex;
|
|
9118
|
+
align-items: center;
|
|
9119
|
+
justify-content: space-between;
|
|
9120
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
9121
|
+
box-sizing: border-box;
|
|
9122
|
+
position: relative;
|
|
9123
|
+
overflow: hidden;
|
|
9124
|
+
"
|
|
9125
|
+
onmouseover="this.style.transform='scale(1.02)';"
|
|
9126
|
+
onmouseout="this.style.transform='scale(1)';"
|
|
9127
|
+
onmousedown="this.style.transform='scale(0.98)';"
|
|
9128
|
+
>
|
|
9129
|
+
<!-- Hover Shine Effect -->
|
|
9130
|
+
<div style="
|
|
9131
|
+
position: absolute;
|
|
9132
|
+
top: 0;
|
|
9133
|
+
left: -100%;
|
|
9134
|
+
height: 100%;
|
|
9135
|
+
width: 100%;
|
|
9136
|
+
background: linear-gradient(to right, transparent, rgba(255,255,255,0.3), transparent);
|
|
9137
|
+
transform: skewX(-20deg);
|
|
9138
|
+
transition: left 0.5s;
|
|
9139
|
+
" onmouseover="this.style.left='100%'" onmouseout="this.style.left='-100%'"></div>
|
|
9188
9140
|
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
cursor: pointer;
|
|
9205
|
-
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
9206
|
-
box-shadow: 0 4px 20px rgba(0, 255, 136, 0.35);
|
|
9207
|
-
letter-spacing: 0.01em;
|
|
9208
|
-
"
|
|
9209
|
-
onmouseover="this.style.background='linear-gradient(135deg, #00ff88 0%, #00f2fe 100%)'; this.style.boxShadow='0 6px 28px rgba(0, 255, 136, 0.5)'; this.style.transform='translateY(-2px) scale(1.02)';"
|
|
9210
|
-
onmouseout="this.style.background='linear-gradient(135deg, #00ff88 0%, #00f2fe 100%)'; this.style.boxShadow='0 4px 20px rgba(0, 255, 136, 0.35)'; this.style.transform='translateY(0) scale(1)';"
|
|
9211
|
-
>
|
|
9212
|
-
Buy $ ${pkg.price}
|
|
9213
|
-
</button>
|
|
9141
|
+
<span>Unlock Now</span>
|
|
9142
|
+
<div style="
|
|
9143
|
+
display: flex;
|
|
9144
|
+
align-items: center;
|
|
9145
|
+
gap: 8px;
|
|
9146
|
+
background: rgba(0, 0, 0, 0.2);
|
|
9147
|
+
padding: 10px 10px;
|
|
9148
|
+
border-radius: 8px;
|
|
9149
|
+
backdrop-filter: blur(4px);
|
|
9150
|
+
">
|
|
9151
|
+
${originalPrice ? `<span style="font-size:14px;font-weight:700;color:rgba(255, 255, 255, 0.6);text-decoration:line-through;">$${originalPrice}</span>` : ''}
|
|
9152
|
+
<span style="font-size:16px;font-weight:600;color:#FFFFFF;">$${pkg.price}</span>
|
|
9153
|
+
</div>
|
|
9154
|
+
</button>
|
|
9155
|
+
</div>
|
|
9214
9156
|
</div>
|
|
9215
9157
|
`;
|
|
9216
9158
|
}
|