@quantabit/payment-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1502 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var antd = require('antd');
5
+ var icons = require('@ant-design/icons');
6
+ var sdkConfig = require('@quantabit/sdk-config');
7
+
8
+ function _extends() {
9
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
10
+ for (var e = 1; e < arguments.length; e++) {
11
+ var t = arguments[e];
12
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
13
+ }
14
+ return n;
15
+ }, _extends.apply(null, arguments);
16
+ }
17
+
18
+ function PricingCard({
19
+ name,
20
+ price,
21
+ period = '/mo',
22
+ description,
23
+ features = [],
24
+ cta = 'Get Started',
25
+ popular = false,
26
+ onSelect,
27
+ className = ''
28
+ }) {
29
+ return /*#__PURE__*/React.createElement("div", {
30
+ className: `qpay-card ${popular ? 'qpay-popular' : ''} ${className}`,
31
+ style: {
32
+ padding: 28,
33
+ borderRadius: 16,
34
+ border: popular ? '2px solid #3b82f6' : '1px solid #e4e4e7',
35
+ background: '#fff',
36
+ position: 'relative',
37
+ boxShadow: popular ? '0 8px 32px rgba(59,130,246,0.12)' : 'none',
38
+ transition: 'all 0.3s'
39
+ }
40
+ }, popular && /*#__PURE__*/React.createElement("span", {
41
+ style: {
42
+ position: 'absolute',
43
+ top: -12,
44
+ left: '50%',
45
+ transform: 'translateX(-50%)',
46
+ background: '#3b82f6',
47
+ color: '#fff',
48
+ fontSize: 11,
49
+ fontWeight: 700,
50
+ padding: '3px 12px',
51
+ borderRadius: 20
52
+ }
53
+ }, "Most Popular"), /*#__PURE__*/React.createElement("div", {
54
+ style: {
55
+ fontSize: 18,
56
+ fontWeight: 700,
57
+ color: '#18181b'
58
+ }
59
+ }, name), description && /*#__PURE__*/React.createElement("div", {
60
+ style: {
61
+ fontSize: 13,
62
+ color: '#71717a',
63
+ marginTop: 4
64
+ }
65
+ }, description), /*#__PURE__*/React.createElement("div", {
66
+ style: {
67
+ marginTop: 16,
68
+ marginBottom: 16
69
+ }
70
+ }, /*#__PURE__*/React.createElement("span", {
71
+ style: {
72
+ fontSize: 36,
73
+ fontWeight: 800,
74
+ color: '#18181b'
75
+ }
76
+ }, price), /*#__PURE__*/React.createElement("span", {
77
+ style: {
78
+ fontSize: 14,
79
+ color: '#a1a1aa'
80
+ }
81
+ }, period)), /*#__PURE__*/React.createElement("ul", {
82
+ style: {
83
+ listStyle: 'none',
84
+ padding: 0,
85
+ margin: '0 0 20px',
86
+ display: 'flex',
87
+ flexDirection: 'column',
88
+ gap: 8
89
+ }
90
+ }, features.map((f, i) => /*#__PURE__*/React.createElement("li", {
91
+ key: i,
92
+ style: {
93
+ display: 'flex',
94
+ alignItems: 'center',
95
+ gap: 8,
96
+ fontSize: 13,
97
+ color: '#3f3f46'
98
+ }
99
+ }, /*#__PURE__*/React.createElement("svg", {
100
+ width: "16",
101
+ height: "16",
102
+ viewBox: "0 0 24 24",
103
+ fill: "none",
104
+ stroke: f.included !== false ? '#22c55e' : '#d4d4d8',
105
+ strokeWidth: "2"
106
+ }, /*#__PURE__*/React.createElement("polyline", {
107
+ points: "20 6 9 17 4 12"
108
+ })), /*#__PURE__*/React.createElement("span", {
109
+ style: {
110
+ opacity: f.included === false ? 0.5 : 1
111
+ }
112
+ }, typeof f === 'string' ? f : f.text)))), /*#__PURE__*/React.createElement("button", {
113
+ onClick: () => onSelect?.(name),
114
+ style: {
115
+ width: '100%',
116
+ padding: '10px',
117
+ borderRadius: 8,
118
+ border: 'none',
119
+ background: popular ? '#3b82f6' : '#18181b',
120
+ color: '#fff',
121
+ fontSize: 14,
122
+ fontWeight: 600,
123
+ cursor: 'pointer',
124
+ transition: 'all 0.2s'
125
+ }
126
+ }, cta));
127
+ }
128
+
129
+ function PricingTable({
130
+ plans = [],
131
+ onSelect,
132
+ columns = 3,
133
+ className = ''
134
+ }) {
135
+ return /*#__PURE__*/React.createElement("div", {
136
+ className: `qpay-table ${className}`,
137
+ style: {
138
+ display: 'grid',
139
+ gridTemplateColumns: `repeat(${Math.min(columns, plans.length)}, 1fr)`,
140
+ gap: 20,
141
+ alignItems: 'start'
142
+ }
143
+ }, plans.map((plan, i) => /*#__PURE__*/React.createElement(PricingCard, _extends({
144
+ key: plan.name || i
145
+ }, plan, {
146
+ onSelect: onSelect
147
+ }))));
148
+ }
149
+
150
+ /**
151
+ * Payment SDK - 国际化 i18n
152
+ */
153
+
154
+ const SUPPORTED_LANGUAGES = ['en', 'zh', 'ja', 'ko'];
155
+ const messages = {
156
+ zh: {
157
+ 'pay.checkout': '结算',
158
+ 'pay.total': '合计',
159
+ 'pay.subtotal': '小计',
160
+ 'pay.orderSummary': '订单明细',
161
+ 'pay.discount': '折扣',
162
+ 'pay.tax': '税费',
163
+ 'pay.processing': '处理中...',
164
+ 'pay.proceedToCheckout': '前往支付',
165
+ // 充值相关
166
+ 'enterValidAmount': '请输入有效的金额',
167
+ 'recharge': '充值',
168
+ 'createOrderFailed': '创建订单失败',
169
+ 'networkError': '网络错误,请稍后重试',
170
+ 'paymentConfirmFailed': '支付确认失败',
171
+ 'rechargeSuccessful': '充值成功',
172
+ 'rechargeSuccessMsg': '已成功充值 {amount} {currency}',
173
+ 'paymentProcessing': '支付处理中',
174
+ 'orderNo': '订单号',
175
+ 'waitingForPayment': '等待支付...',
176
+ 'simulatePaySuccess': '模拟支付成功',
177
+ 'rechargeAmount': '充值金额',
178
+ 'paymentMethod': '支付方式',
179
+ 'confirmRecharge': '确认充值',
180
+ 'walletRecharge': '钱包充值',
181
+ // 支付方式
182
+ 'method.card': '信用卡/借记卡',
183
+ 'method.cardDesc': '支持 Visa, MasterCard 等',
184
+ 'method.paypal': 'PayPal',
185
+ 'method.paypalDesc': '快速安全的结算方式',
186
+ 'method.crypto': '加密货币',
187
+ 'methodCrypto': '加密货币',
188
+ 'method.cryptoDesc': '使用 Web3 钱包支付',
189
+ 'method.alipay': '支付宝',
190
+ 'methodAlipay': '支付宝',
191
+ 'method.alipayDesc': '支付宝快捷支付',
192
+ 'method.wechat': '微信支付',
193
+ 'methodWechat': '微信支付',
194
+ 'method.wechatDesc': '微信快捷支付',
195
+ 'method.apple': 'Apple Pay',
196
+ 'method.appleDesc': '苹果设备快捷支付',
197
+ 'method.google': 'Google Pay',
198
+ 'method.googleDesc': '安卓设备快捷支付',
199
+ 'method.selected': '已选择的支付方式'
200
+ },
201
+ en: {
202
+ 'pay.checkout': 'Checkout',
203
+ 'pay.total': 'Total',
204
+ 'pay.subtotal': 'Subtotal',
205
+ 'pay.orderSummary': 'Order Summary',
206
+ 'pay.discount': 'Discount',
207
+ 'pay.tax': 'Tax',
208
+ 'pay.processing': 'Processing...',
209
+ 'pay.proceedToCheckout': 'Proceed to Checkout',
210
+ // Recharge
211
+ 'enterValidAmount': 'Please enter a valid amount',
212
+ 'recharge': 'Recharge',
213
+ 'createOrderFailed': 'Failed to create order',
214
+ 'networkError': 'Network error, please try again',
215
+ 'paymentConfirmFailed': 'Failed to confirm payment',
216
+ 'rechargeSuccessful': 'Recharge Successful',
217
+ 'rechargeSuccessMsg': 'Successfully recharged {amount} {currency}',
218
+ 'paymentProcessing': 'Payment Processing',
219
+ 'orderNo': 'Order No',
220
+ 'waitingForPayment': 'Waiting for payment...',
221
+ 'simulatePaySuccess': 'Simulate Payment Success',
222
+ 'rechargeAmount': 'Recharge Amount',
223
+ 'paymentMethod': 'Payment Method',
224
+ 'confirmRecharge': 'Confirm Recharge',
225
+ 'walletRecharge': 'Wallet Recharge',
226
+ // Payment Methods
227
+ 'method.card': 'Credit Card',
228
+ 'method.cardDesc': 'Visa, MasterCard, etc.',
229
+ 'method.paypal': 'PayPal',
230
+ 'method.paypalDesc': 'Fast & secure checkout',
231
+ 'method.crypto': 'Crypto',
232
+ 'methodCrypto': 'Crypto',
233
+ 'method.cryptoDesc': 'Pay with Web3 wallet',
234
+ 'method.alipay': 'Alipay',
235
+ 'methodAlipay': 'Alipay',
236
+ 'method.alipayDesc': 'Alipay quick pay',
237
+ 'method.wechat': 'WeChat Pay',
238
+ 'methodWechat': 'WeChat Pay',
239
+ 'method.wechatDesc': 'WeChat quick pay',
240
+ 'method.apple': 'Apple Pay',
241
+ 'method.appleDesc': 'Quick pay on Apple devices',
242
+ 'method.google': 'Google Pay',
243
+ 'method.googleDesc': 'Quick pay on Android',
244
+ 'method.selected': 'Selected payment method'
245
+ },
246
+ ja: {
247
+ 'pay.checkout': 'チェックアウト',
248
+ 'pay.total': '合計',
249
+ 'pay.subtotal': '小計',
250
+ 'pay.orderSummary': '注文の概要',
251
+ 'pay.discount': '割引',
252
+ 'pay.tax': '税金',
253
+ 'pay.processing': '処理中...',
254
+ 'pay.proceedToCheckout': '支払いに進む',
255
+ // Recharge
256
+ 'enterValidAmount': '有効な金額を入力してください',
257
+ 'recharge': 'チャージ',
258
+ 'createOrderFailed': '注文の作成に失敗しました',
259
+ 'networkError': 'ネットワークエラーです。後でもう一度お試しください',
260
+ 'paymentConfirmFailed': '支払いの確認に失敗しました',
261
+ 'rechargeSuccessful': 'チャージ成功',
262
+ 'rechargeSuccessMsg': '{amount} {currency}のチャージに成功しました',
263
+ 'paymentProcessing': '支払い処理中',
264
+ 'orderNo': '注文番号',
265
+ 'waitingForPayment': '支払いを待っています...',
266
+ 'simulatePaySuccess': '支払いの成功をシミュレート',
267
+ 'rechargeAmount': 'チャージ金額',
268
+ 'paymentMethod': '支払い方法',
269
+ 'confirmRecharge': 'チャージを確認',
270
+ 'walletRecharge': 'ウォレットチャージ',
271
+ // Payment Methods
272
+ 'method.card': 'クレジットカード',
273
+ 'method.cardDesc': 'Visa、MasterCardなど',
274
+ 'method.paypal': 'PayPal',
275
+ 'method.paypalDesc': '迅速で安全な支払い',
276
+ 'method.crypto': '暗号通貨',
277
+ 'methodCrypto': '暗号通貨',
278
+ 'method.cryptoDesc': 'Web3ウォレットで支払う',
279
+ 'method.alipay': 'Alipay',
280
+ 'methodAlipay': 'Alipay',
281
+ 'method.alipayDesc': 'Alipayクイックペイ',
282
+ 'method.wechat': 'WeChat Pay',
283
+ 'methodWechat': 'WeChat Pay',
284
+ 'method.wechatDesc': 'WeChatクイックペイ',
285
+ 'method.apple': 'Apple Pay',
286
+ 'method.appleDesc': 'Appleデバイスでクイックペイ',
287
+ 'method.google': 'Google Pay',
288
+ 'method.googleDesc': 'Androidデバイスでクイックペイ',
289
+ 'method.selected': '選択された支払い方法'
290
+ },
291
+ ko: {
292
+ 'pay.checkout': '결제',
293
+ 'pay.total': '합계',
294
+ 'pay.subtotal': '소계',
295
+ 'pay.orderSummary': '주문 요약',
296
+ 'pay.discount': '할인',
297
+ 'pay.tax': '세금',
298
+ 'pay.processing': '처리 중...',
299
+ 'pay.proceedToCheckout': '결제 진행',
300
+ // Recharge
301
+ 'enterValidAmount': '유효한 금액을 입력하세요',
302
+ 'recharge': '충전',
303
+ 'createOrderFailed': '주문 생성 실패',
304
+ 'networkError': '네트워크 오류, 나중에 다시 시도하세요',
305
+ 'paymentConfirmFailed': '결제 확인 실패',
306
+ 'rechargeSuccessful': '충전 성공',
307
+ 'rechargeSuccessMsg': '{amount} {currency} 충전이 완료되었습니다',
308
+ 'paymentProcessing': '결제 처리 중',
309
+ 'orderNo': '주문 번호',
310
+ 'waitingForPayment': '결제 대기 중...',
311
+ 'simulatePaySuccess': '결제 성공 시뮬레이션',
312
+ 'rechargeAmount': '충전 금액',
313
+ 'paymentMethod': '결제 수단',
314
+ 'confirmRecharge': '충전 확인',
315
+ 'walletRecharge': '지갑 충전',
316
+ // Payment Methods
317
+ 'method.card': '신용카드',
318
+ 'method.cardDesc': 'Visa, MasterCard 등',
319
+ 'method.paypal': 'PayPal',
320
+ 'method.paypalDesc': '빠르고 안전한 결제',
321
+ 'method.crypto': '암호화폐',
322
+ 'methodCrypto': '암호화폐',
323
+ 'method.cryptoDesc': 'Web3 지갑으로 결제',
324
+ 'method.alipay': 'Alipay',
325
+ 'methodAlipay': 'Alipay',
326
+ 'method.alipayDesc': 'Alipay 빠른 결제',
327
+ 'method.wechat': 'WeChat Pay',
328
+ 'methodWechat': 'WeChat Pay',
329
+ 'method.wechatDesc': 'WeChat 빠른 결제',
330
+ 'method.apple': 'Apple Pay',
331
+ 'method.appleDesc': 'Apple 기기에서 빠른 결제',
332
+ 'method.google': 'Google Pay',
333
+ 'method.googleDesc': 'Android 기기에서 빠른 결제',
334
+ 'method.selected': '선택한 결제 수단'
335
+ }
336
+ };
337
+ let currentLang = 'zh';
338
+ function setLanguage(l) {
339
+ if (SUPPORTED_LANGUAGES.includes(l)) currentLang = l;
340
+ }
341
+ function getLanguage() {
342
+ return currentLang;
343
+ }
344
+ function t(key, params) {
345
+ const msgs = messages[currentLang] || messages.zh;
346
+ let text = msgs[key] || messages.en[key] || key;
347
+ if (params) {
348
+ Object.keys(params).forEach(k => {
349
+ text = text.replace(new RegExp(`\\{${k}\\}`, 'g'), params[k]);
350
+ });
351
+ }
352
+ return text;
353
+ }
354
+
355
+ /**
356
+ * Payment SDK - PaymentMethodSelector
357
+ * 高品质支付方式选择器
358
+ */
359
+ function PaymentMethodSelector({
360
+ methods = ['card', 'paypal', 'crypto'],
361
+ value,
362
+ onChange,
363
+ className = ''
364
+ }) {
365
+ const ICONS = {
366
+ card: '💳',
367
+ paypal: '🅿️',
368
+ crypto: '₿',
369
+ alipay: '🔷',
370
+ wechat: '💬',
371
+ apple: '🍎',
372
+ google: 'G'
373
+ };
374
+ return /*#__PURE__*/React.createElement("div", {
375
+ className: `qpay-methods ${className}`,
376
+ style: {
377
+ display: 'flex',
378
+ flexDirection: 'column',
379
+ gap: '16px'
380
+ }
381
+ }, methods.map(key => {
382
+ const icon = ICONS[key] || '💰';
383
+ const label = t(`method.${key}`);
384
+ const desc = t(`method.${key}Desc`) || t('method.selected');
385
+ const active = value === key;
386
+ return /*#__PURE__*/React.createElement("button", {
387
+ key: key,
388
+ onClick: () => onChange?.(key),
389
+ style: {
390
+ display: 'flex',
391
+ alignItems: 'center',
392
+ gap: '16px',
393
+ padding: '20px',
394
+ borderRadius: '24px',
395
+ border: active ? '1px solid rgba(59, 130, 246, 0.8)' : '1px solid rgba(255, 255, 255, 0.4)',
396
+ background: active ? 'rgba(255, 255, 255, 0.85)' : 'rgba(255, 255, 255, 0.6)',
397
+ backdropFilter: 'blur(24px)',
398
+ WebkitBackdropFilter: 'blur(24px)',
399
+ cursor: 'pointer',
400
+ textAlign: 'left',
401
+ transition: 'all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
402
+ boxShadow: active ? '0 15px 35px -5px rgba(59, 130, 246, 0.15), inset 0 0 0 1px rgba(255, 255, 255, 0.8)' : '0 10px 30px -10px rgba(0,0,0,0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.5)',
403
+ outline: 'none'
404
+ },
405
+ onMouseEnter: e => {
406
+ if (!active) {
407
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.75)';
408
+ e.currentTarget.style.transform = 'translateY(-2px)';
409
+ e.currentTarget.style.boxShadow = '0 15px 35px -10px rgba(0,0,0,0.08), inset 0 0 0 1px rgba(255, 255, 255, 0.8)';
410
+ }
411
+ },
412
+ onMouseLeave: e => {
413
+ if (!active) {
414
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.6)';
415
+ e.currentTarget.style.transform = 'none';
416
+ e.currentTarget.style.boxShadow = '0 10px 30px -10px rgba(0,0,0,0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.5)';
417
+ }
418
+ }
419
+ }, /*#__PURE__*/React.createElement("div", {
420
+ style: {
421
+ width: '48px',
422
+ height: '48px',
423
+ borderRadius: '16px',
424
+ background: 'rgba(255, 255, 255, 0.9)',
425
+ display: 'flex',
426
+ alignItems: 'center',
427
+ justifyContent: 'center',
428
+ fontSize: '24px',
429
+ boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
430
+ }
431
+ }, icon), /*#__PURE__*/React.createElement("div", {
432
+ style: {
433
+ display: 'flex',
434
+ flexDirection: 'column',
435
+ gap: '4px',
436
+ flex: 1
437
+ }
438
+ }, /*#__PURE__*/React.createElement("span", {
439
+ style: {
440
+ fontWeight: active ? 800 : 700,
441
+ color: '#0F172A',
442
+ fontSize: '16px',
443
+ letterSpacing: '-0.01em'
444
+ }
445
+ }, label), /*#__PURE__*/React.createElement("span", {
446
+ style: {
447
+ fontSize: '13px',
448
+ color: '#64748B',
449
+ fontWeight: 500
450
+ }
451
+ }, desc)), /*#__PURE__*/React.createElement("div", {
452
+ style: {
453
+ width: '28px',
454
+ height: '28px',
455
+ borderRadius: '50%',
456
+ border: active ? '8px solid #3B82F6' : '2px solid rgba(148, 163, 184, 0.5)',
457
+ background: '#fff',
458
+ transition: 'all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
459
+ marginLeft: 'auto',
460
+ boxShadow: active ? '0 4px 12px rgba(59, 130, 246, 0.3)' : 'none'
461
+ }
462
+ }));
463
+ }));
464
+ }
465
+
466
+ function CheckoutSummary({
467
+ items = [],
468
+ subtotal,
469
+ discount,
470
+ tax,
471
+ total,
472
+ currency = '$',
473
+ onCheckout,
474
+ loading = false,
475
+ className = ''
476
+ }) {
477
+ return /*#__PURE__*/React.createElement("div", {
478
+ className: `qpay-summary ${className}`,
479
+ style: {
480
+ padding: 24,
481
+ borderRadius: 16,
482
+ border: '1px solid #e4e4e7',
483
+ background: '#fafafa'
484
+ }
485
+ }, /*#__PURE__*/React.createElement("h3", {
486
+ style: {
487
+ fontSize: 16,
488
+ fontWeight: 700,
489
+ margin: '0 0 16px'
490
+ }
491
+ }, "Order Summary"), /*#__PURE__*/React.createElement("div", {
492
+ style: {
493
+ display: 'flex',
494
+ flexDirection: 'column',
495
+ gap: 8
496
+ }
497
+ }, items.map((item, i) => /*#__PURE__*/React.createElement("div", {
498
+ key: i,
499
+ style: {
500
+ display: 'flex',
501
+ justifyContent: 'space-between',
502
+ fontSize: 13
503
+ }
504
+ }, /*#__PURE__*/React.createElement("span", {
505
+ style: {
506
+ color: '#3f3f46'
507
+ }
508
+ }, item.name, item.qty > 1 && ` × ${item.qty}`), /*#__PURE__*/React.createElement("span", {
509
+ style: {
510
+ fontWeight: 500
511
+ }
512
+ }, currency, item.price)))), /*#__PURE__*/React.createElement("div", {
513
+ style: {
514
+ borderTop: '1px solid #e4e4e7',
515
+ marginTop: 12,
516
+ paddingTop: 12,
517
+ display: 'flex',
518
+ flexDirection: 'column',
519
+ gap: 6,
520
+ fontSize: 13
521
+ }
522
+ }, subtotal != null && /*#__PURE__*/React.createElement("div", {
523
+ style: {
524
+ display: 'flex',
525
+ justifyContent: 'space-between'
526
+ }
527
+ }, /*#__PURE__*/React.createElement("span", {
528
+ style: {
529
+ color: '#71717a'
530
+ }
531
+ }, "Subtotal"), /*#__PURE__*/React.createElement("span", null, currency, subtotal)), discount != null && /*#__PURE__*/React.createElement("div", {
532
+ style: {
533
+ display: 'flex',
534
+ justifyContent: 'space-between'
535
+ }
536
+ }, /*#__PURE__*/React.createElement("span", {
537
+ style: {
538
+ color: '#22c55e'
539
+ }
540
+ }, "Discount"), /*#__PURE__*/React.createElement("span", {
541
+ style: {
542
+ color: '#22c55e'
543
+ }
544
+ }, "-", currency, discount)), tax != null && /*#__PURE__*/React.createElement("div", {
545
+ style: {
546
+ display: 'flex',
547
+ justifyContent: 'space-between'
548
+ }
549
+ }, /*#__PURE__*/React.createElement("span", {
550
+ style: {
551
+ color: '#71717a'
552
+ }
553
+ }, "Tax"), /*#__PURE__*/React.createElement("span", null, currency, tax)), /*#__PURE__*/React.createElement("div", {
554
+ style: {
555
+ display: 'flex',
556
+ justifyContent: 'space-between',
557
+ fontSize: 16,
558
+ fontWeight: 700,
559
+ borderTop: '1px solid #e4e4e7',
560
+ paddingTop: 12,
561
+ marginTop: 4
562
+ }
563
+ }, /*#__PURE__*/React.createElement("span", null, "Total"), /*#__PURE__*/React.createElement("span", null, currency, total))), onCheckout && /*#__PURE__*/React.createElement("button", {
564
+ onClick: onCheckout,
565
+ disabled: loading,
566
+ style: {
567
+ width: '100%',
568
+ marginTop: 16,
569
+ padding: '12px',
570
+ borderRadius: 10,
571
+ border: 'none',
572
+ background: '#18181b',
573
+ color: '#fff',
574
+ fontSize: 14,
575
+ fontWeight: 600,
576
+ cursor: 'pointer'
577
+ }
578
+ }, loading ? 'Processing...' : 'Checkout'));
579
+ }
580
+
581
+ /**
582
+ * Payment SDK - API 客户端
583
+ * 支付系统后端接口封装
584
+ *
585
+ * 使用 BaseApiClient 基类简化代码
586
+ */
587
+
588
+
589
+ /**
590
+ * 支付 API 客户端
591
+ */
592
+ class PaymentApiClient extends sdkConfig.BaseApiClient {
593
+ constructor(config = {}) {
594
+ super('/api/payment', config);
595
+ }
596
+
597
+ // ============ 支付方式 ============
598
+
599
+ /**
600
+ * 获取可用支付方式
601
+ * @param {Object} orderInfo - 订单信息
602
+ */
603
+ async getPaymentMethods(orderInfo = {}) {
604
+ return this.post('/methods', orderInfo);
605
+ }
606
+
607
+ /**
608
+ * 获取已绑定的支付方式
609
+ */
610
+ async getSavedPaymentMethods() {
611
+ return this.get('/methods/saved');
612
+ }
613
+
614
+ /**
615
+ * 添加支付方式
616
+ * @param {Object} paymentMethod - 支付方式数据
617
+ */
618
+ async addPaymentMethod(paymentMethod) {
619
+ return this.post('/methods/add', paymentMethod);
620
+ }
621
+
622
+ /**
623
+ * 删除支付方式
624
+ * @param {string} methodId - 支付方式 ID
625
+ */
626
+ async removePaymentMethod(methodId) {
627
+ return this.delete(`/methods/${methodId}`);
628
+ }
629
+
630
+ /**
631
+ * 设置默认支付方式
632
+ * @param {string} methodId - 支付方式 ID
633
+ */
634
+ async setDefaultPaymentMethod(methodId) {
635
+ return this.post(`/methods/${methodId}/default`);
636
+ }
637
+
638
+ // ============ 支付操作 ============
639
+
640
+ /**
641
+ * 创建支付订单
642
+ * @param {Object} data - 支付数据
643
+ */
644
+ async createPayment(data) {
645
+ return this.post('/create', data);
646
+ }
647
+
648
+ /**
649
+ * 获取支付信息
650
+ * @param {string} paymentId - 支付 ID
651
+ */
652
+ async getPayment(paymentId) {
653
+ return this.get(`/${paymentId}`);
654
+ }
655
+
656
+ /**
657
+ * 确认支付
658
+ * @param {string} paymentId - 支付 ID
659
+ * @param {Object} paymentData - 支付数据
660
+ */
661
+ async confirmPayment(paymentId, paymentData) {
662
+ return this.post(`/${paymentId}/confirm`, paymentData);
663
+ }
664
+
665
+ /**
666
+ * 取消支付
667
+ * @param {string} paymentId - 支付 ID
668
+ */
669
+ async cancelPayment(paymentId) {
670
+ return this.post(`/${paymentId}/cancel`);
671
+ }
672
+
673
+ /**
674
+ * 查询支付状态
675
+ * @param {string} paymentId - 支付 ID
676
+ */
677
+ async getPaymentStatus(paymentId) {
678
+ return this.get(`/${paymentId}/status`);
679
+ }
680
+
681
+ // ============ 退款 ============
682
+
683
+ /**
684
+ * 申请退款
685
+ * @param {string} paymentId - 支付 ID
686
+ * @param {Object} refundData - 退款数据
687
+ */
688
+ async requestRefund(paymentId, refundData) {
689
+ return this.post(`/${paymentId}/refund`, refundData);
690
+ }
691
+
692
+ /**
693
+ * 获取退款状态
694
+ * @param {string} refundId - 退款 ID
695
+ */
696
+ async getRefundStatus(refundId) {
697
+ return this.get(`/refunds/${refundId}`);
698
+ }
699
+
700
+ /**
701
+ * 获取退款列表
702
+ * @param {Object} params - 查询参数
703
+ */
704
+ async getRefunds(params = {}) {
705
+ return this.get('/refunds', params);
706
+ }
707
+
708
+ // ============ 支付记录 ============
709
+
710
+ /**
711
+ * 获取支付记录
712
+ * @param {Object} params - 查询参数
713
+ */
714
+ async getPaymentHistory(params = {}) {
715
+ return this.get('/history', params);
716
+ }
717
+
718
+ /**
719
+ * 获取支付统计
720
+ * @param {Object} params - 统计参数
721
+ */
722
+ async getPaymentStats(params = {}) {
723
+ return this.get('/stats', params);
724
+ }
725
+
726
+ // ============ 第三方支付 ============
727
+
728
+ /**
729
+ * 获取微信支付参数
730
+ * @param {string} paymentId - 支付 ID
731
+ */
732
+ async getWechatPayParams(paymentId) {
733
+ return this.get(`/${paymentId}/wechat/params`);
734
+ }
735
+
736
+ /**
737
+ * 获取支付宝支付参数
738
+ * @param {string} paymentId - 支付 ID
739
+ */
740
+ async getAlipayParams(paymentId) {
741
+ return this.get(`/${paymentId}/alipay/params`);
742
+ }
743
+
744
+ /**
745
+ * 获取 Apple Pay 参数
746
+ * @param {string} paymentId - 支付 ID
747
+ */
748
+ async getApplePayParams(paymentId) {
749
+ return this.get(`/${paymentId}/applepay/params`);
750
+ }
751
+
752
+ // ============ 加密货币支付 ============
753
+
754
+ /**
755
+ * 获取加密货币支付地址
756
+ * @param {string} paymentId - 支付 ID
757
+ * @param {string} currency - 币种
758
+ */
759
+ async getCryptoPaymentAddress(paymentId, currency) {
760
+ return this.get(`/${paymentId}/crypto/address`, {
761
+ currency
762
+ });
763
+ }
764
+
765
+ /**
766
+ * 确认加密货币支付
767
+ * @param {string} paymentId - 支付 ID
768
+ * @param {string} txHash - 交易哈希
769
+ */
770
+ async confirmCryptoPayment(paymentId, txHash) {
771
+ return this.post(`/${paymentId}/crypto/confirm`, {
772
+ tx_hash: txHash
773
+ });
774
+ }
775
+
776
+ // ============ 平台支付同步 (QuantaBit) ============
777
+
778
+ /**
779
+ * 同步支付结果到 QuantaBit
780
+ * 平台支付完成后调用,将支付信息同步到 QuantaBit 中台
781
+ * @param {Object} data - 支付同步数据
782
+ * @param {string} data.app_id - 来源应用 ID
783
+ * @param {string} data.app_order_id - 应用内订单 ID
784
+ * @param {string} data.payment_method - 支付方式
785
+ * @param {number} data.amount - 支付金额
786
+ * @param {string} [data.status] - 支付状态(默认 'success')
787
+ * @param {string} [data.user_did] - 用户 DID
788
+ * @param {string} [data.title] - 订单标题
789
+ */
790
+ async syncPaymentToQbitDid(data) {
791
+ const baseURL = this.config?.qbitDidApiUrl || (this.baseURL.includes('/api/payment') ? this.baseURL.replace('/api/payment', '') : this.baseURL);
792
+ return this.post('/platform-orders/sync-payment', data, {
793
+ baseURL
794
+ });
795
+ }
796
+
797
+ /**
798
+ * 同步交易流水到 QuantaBit
799
+ * @param {Object} data - 交易数据
800
+ * @param {string} data.app_id - 应用 ID
801
+ * @param {string} data.tx_type - 交易类型
802
+ * @param {number} data.amount - 金额
803
+ * @param {string} data.title - 交易标题
804
+ * @param {string} [data.user_did] - 用户 DID
805
+ */
806
+ async syncTransactionToQbitDid(data) {
807
+ const baseURL = this.config?.qbitDidApiUrl || (this.baseURL.includes('/api/payment') ? this.baseURL.replace('/api/payment', '') : this.baseURL);
808
+ return this.post('/platform-orders/sync-transaction', data, {
809
+ baseURL
810
+ });
811
+ }
812
+
813
+ /**
814
+ * 扣减用户 QuantaBit 积分
815
+ * 用于支付时抵扣积分
816
+ * @param {Object} data - 扣减数据
817
+ * @param {string} data.app_id - 应用 ID
818
+ * @param {number} data.points - 积分数量
819
+ * @param {string} [data.user_did] - 用户 DID
820
+ * @param {string} [data.order_id] - 关联订单 ID
821
+ * @param {string} [data.reason] - 扣减原因
822
+ */
823
+ async deductQbitDidPoints(data) {
824
+ const baseURL = this.config?.qbitDidApiUrl || (this.baseURL.includes('/api/payment') ? this.baseURL.replace('/api/payment', '') : this.baseURL);
825
+ return this.post('/platform-orders/deduct-points', data, {
826
+ baseURL
827
+ });
828
+ }
829
+
830
+ /**
831
+ * 获取用户 QuantaBit 积分余额
832
+ * @param {string} userDid - 用户 DID
833
+ */
834
+ async getQbitDidPointsBalance(userDid) {
835
+ const baseURL = this.config?.qbitDidApiUrl || (this.baseURL.includes('/api/payment') ? this.baseURL.replace('/api/payment', '') : this.baseURL);
836
+ return this.get('/modules/points/balance', {
837
+ did: userDid
838
+ }, {
839
+ baseURL
840
+ });
841
+ }
842
+
843
+ /**
844
+ * 获取用户 QuantaBit 代币余额
845
+ * @param {string} userDid - 用户 DID
846
+ * @param {string} [tokenSymbol] - 代币符号
847
+ */
848
+ async getQbitDidTokenBalance(userDid, tokenSymbol) {
849
+ const baseURL = this.config?.qbitDidApiUrl || (this.baseURL.includes('/api/payment') ? this.baseURL.replace('/api/payment', '') : this.baseURL);
850
+ return this.get('/modules/tokens/balance', {
851
+ did: userDid,
852
+ symbol: tokenSymbol
853
+ }, {
854
+ baseURL
855
+ });
856
+ }
857
+
858
+ /**
859
+ * 综合支付并同步到 QuantaBit
860
+ * 一次调用完成:本地支付 + QuantaBit 同步
861
+ * @param {Object} paymentData - 支付数据
862
+ * @param {Object} syncOptions - 同步选项
863
+ */
864
+ async payAndSync(paymentData, syncOptions = {}) {
865
+ // 1. 执行本地支付
866
+ const paymentResult = await this.createPayment(paymentData);
867
+
868
+ // 2. 如果支付成功,自动同步到 QuantaBit
869
+ if (paymentResult.success || paymentResult.status === 'success') {
870
+ try {
871
+ await this.syncPaymentToQbitDid({
872
+ app_id: syncOptions.app_id || 'default',
873
+ app_order_id: paymentData.order_id,
874
+ payment_method: paymentData.payment_method,
875
+ amount: paymentData.amount,
876
+ status: 'success',
877
+ user_did: syncOptions.user_did,
878
+ title: syncOptions.title || paymentData.title
879
+ });
880
+ paymentResult.qbit_did_synced = true;
881
+ } catch (syncError) {
882
+ // 同步失败不影响支付结果,但记录错误
883
+ console.warn('[PaymentSDK] QuantaBit 同步失败:', syncError);
884
+ paymentResult.qbit_did_synced = false;
885
+ paymentResult.qbit_did_sync_error = syncError.message;
886
+ }
887
+ }
888
+ return paymentResult;
889
+ }
890
+
891
+ // ============ 余额查询 ============
892
+
893
+ /**
894
+ * 获取用户余额
895
+ * @returns {Promise<{amount: number, points: number}>}
896
+ */
897
+ async getBalance() {
898
+ return this.get('/balance');
899
+ }
900
+
901
+ // ============ 余额支付 ============
902
+
903
+ /**
904
+ * 使用余额支付
905
+ * @param {string} orderId - 订单 ID
906
+ * @param {string} password - 支付密码
907
+ */
908
+ async payWithBalance(orderId, password) {
909
+ return this.post(`/${orderId}/pay-with-balance`, {
910
+ password
911
+ });
912
+ }
913
+
914
+ // ============ 充值 ============
915
+
916
+ /**
917
+ * 创建充值订单
918
+ * @param {Object} data - 充值数据
919
+ * @param {number} data.amount - 充值金额
920
+ * @param {string} data.method - 充值方式
921
+ */
922
+ async createRecharge(data) {
923
+ return this.post('/recharge', data);
924
+ }
925
+
926
+ // ============ 兼容别名(供 PaymentContext 调用) ============
927
+
928
+ /** @alias getPaymentMethods */
929
+ async getAvailableMethods(params) {
930
+ return this.getPaymentMethods(params);
931
+ }
932
+
933
+ /** @alias createPayment */
934
+ async create(data) {
935
+ return this.createPayment(data);
936
+ }
937
+
938
+ /** @alias getPaymentStatus */
939
+ async checkStatus(paymentId) {
940
+ return this.getPaymentStatus(paymentId);
941
+ }
942
+
943
+ /** @alias cancelPayment */
944
+ async cancel(paymentId) {
945
+ return this.cancelPayment(paymentId);
946
+ }
947
+
948
+ // ============ 隐私合规 (PCI DSS + GDPR) ============
949
+
950
+ /**
951
+ * 导出用户支付数据 — GDPR 第20条
952
+ * 导出匿名化的支付记录(不含完整卡号/密码)
953
+ * @returns {Promise<object>} 匿名化的支付数据
954
+ */
955
+ async exportPaymentData() {
956
+ try {
957
+ const history = await this.getPaymentHistory({
958
+ page_size: 100
959
+ });
960
+ const methods = await this.getSavedPaymentMethods();
961
+ return {
962
+ exportDate: new Date().toISOString(),
963
+ format: 'QBit Payment Export (GDPR Art. 20)',
964
+ note: 'Card numbers are masked per PCI DSS requirements',
965
+ paymentHistory: history?.data?.items?.map(tx => ({
966
+ ...tx,
967
+ // 支付密码和卡号不导出
968
+ card_number: tx.card_number ? `****${tx.card_number.slice(-4)}` : undefined,
969
+ password: undefined,
970
+ cvv: undefined
971
+ })) || [],
972
+ savedMethods: methods?.data?.map(m => ({
973
+ id: m.id,
974
+ type: m.type,
975
+ lastFour: m.last_four || m.card_number?.slice(-4),
976
+ expiry: m.expiry,
977
+ isDefault: m.is_default
978
+ })) || []
979
+ };
980
+ } catch (e) {
981
+ return {
982
+ error: e.message,
983
+ exportDate: new Date().toISOString()
984
+ };
985
+ }
986
+ }
987
+
988
+ /**
989
+ * 获取隐私数据声明
990
+ */
991
+ getDataDisclosure() {
992
+ return {
993
+ sdk: '@quantabit/payment-sdk',
994
+ privacyLevel: 'functional',
995
+ consentRequired: false,
996
+ collected: [{
997
+ type: 'payment_methods',
998
+ description: 'Saved payment methods (masked)',
999
+ retention: 'Until deletion',
1000
+ encrypted: true
1001
+ }, {
1002
+ type: 'transaction_history',
1003
+ description: 'Payment records',
1004
+ retention: '5 years (legal requirement)'
1005
+ }, {
1006
+ type: 'billing_address',
1007
+ description: 'Billing details (if provided)',
1008
+ retention: 'Until deletion'
1009
+ }, {
1010
+ type: 'points_balance',
1011
+ description: 'QBit points and token balances',
1012
+ retention: 'Active'
1013
+ }],
1014
+ compliance: ['PCI DSS Level 1', 'GDPR Art. 20 (export)', 'AML/KYT'],
1015
+ gdprCapabilities: ['export'],
1016
+ note: 'Card numbers are never stored in full; only last 4 digits retained per PCI DSS.'
1017
+ };
1018
+ }
1019
+ }
1020
+
1021
+ // 创建默认实例
1022
+ const paymentApi = new PaymentApiClient();
1023
+
1024
+ /**
1025
+ * Payment SDK - RechargeModal 组件
1026
+ * 钱包充值弹窗
1027
+ *
1028
+ * 使用 i18n 国际化,不依赖 Tailwind CSS
1029
+ */
1030
+
1031
+ const {
1032
+ Text,
1033
+ Title
1034
+ } = antd.Typography;
1035
+ const PAYMENT_METHODS = [{
1036
+ id: "alipay",
1037
+ nameKey: "methodAlipay",
1038
+ icon: /*#__PURE__*/React.createElement(icons.AlipayCircleFilled, {
1039
+ style: {
1040
+ color: "#1677FF",
1041
+ fontSize: '24px'
1042
+ }
1043
+ })
1044
+ }, {
1045
+ id: "wechat",
1046
+ nameKey: "methodWechat",
1047
+ icon: /*#__PURE__*/React.createElement(icons.WechatFilled, {
1048
+ style: {
1049
+ color: "#52C41A",
1050
+ fontSize: '24px'
1051
+ }
1052
+ })
1053
+ }, {
1054
+ id: "crypto",
1055
+ nameKey: "methodCrypto",
1056
+ icon: /*#__PURE__*/React.createElement(icons.DollarCircleFilled, {
1057
+ style: {
1058
+ color: "#F7B500",
1059
+ fontSize: '24px'
1060
+ }
1061
+ })
1062
+ }];
1063
+ const RechargeModal = ({
1064
+ visible,
1065
+ onCancel,
1066
+ onSuccess,
1067
+ userId,
1068
+ initialAmount = 100,
1069
+ currency = "XWIN"
1070
+ }) => {
1071
+ const [amount, setAmount] = React.useState(initialAmount);
1072
+ const [method, setMethod] = React.useState("alipay");
1073
+ const [loading, setLoading] = React.useState(false);
1074
+ const [step, setStep] = React.useState("select"); // select, paying, success
1075
+ const [paymentData, setPaymentData] = React.useState(null);
1076
+ React.useEffect(() => {
1077
+ if (visible) {
1078
+ setStep("select");
1079
+ setAmount(initialAmount);
1080
+ setPaymentData(null);
1081
+ }
1082
+ }, [visible, initialAmount]);
1083
+ const handleRecharge = async () => {
1084
+ if (amount <= 0) {
1085
+ try {
1086
+ const {
1087
+ message
1088
+ } = await import('antd');
1089
+ message.warning(t('enterValidAmount'));
1090
+ } catch {
1091
+ alert(t('enterValidAmount'));
1092
+ }
1093
+ return;
1094
+ }
1095
+ setLoading(true);
1096
+ try {
1097
+ const res = await paymentApi.createPayment({
1098
+ user_id: userId,
1099
+ amount,
1100
+ currency,
1101
+ payment_method: method,
1102
+ order_type: "recharge",
1103
+ description: `${t('recharge')} ${amount} ${currency}`
1104
+ });
1105
+ if (res.code === 0 || res.success) {
1106
+ setPaymentData(res.data);
1107
+ setStep("paying");
1108
+ if (method === "mock" || method === "wallet") {
1109
+ handleSuccess();
1110
+ }
1111
+ } else {
1112
+ try {
1113
+ const {
1114
+ message
1115
+ } = await import('antd');
1116
+ message.error(res.data?.msg || t('createOrderFailed'));
1117
+ } catch {
1118
+ alert(t('createOrderFailed'));
1119
+ }
1120
+ }
1121
+ } catch (error) {
1122
+ console.error(error);
1123
+ try {
1124
+ const {
1125
+ message
1126
+ } = await import('antd');
1127
+ message.error(t('networkError'));
1128
+ } catch {
1129
+ alert(t('networkError'));
1130
+ }
1131
+ } finally {
1132
+ setLoading(false);
1133
+ }
1134
+ };
1135
+ const handleSuccess = () => {
1136
+ setStep("success");
1137
+ if (onSuccess) onSuccess(amount);
1138
+ setTimeout(() => {
1139
+ onCancel();
1140
+ }, 3000);
1141
+ };
1142
+ const handleMockPay = async () => {
1143
+ setLoading(true);
1144
+ try {
1145
+ await paymentApi.confirmPayment(paymentData.payment_no || paymentData.id, {
1146
+ status: 'success'
1147
+ });
1148
+ handleSuccess();
1149
+ } catch (e) {
1150
+ try {
1151
+ const {
1152
+ message
1153
+ } = await import('antd');
1154
+ message.error(t('paymentConfirmFailed'));
1155
+ } catch {
1156
+ alert(t('paymentConfirmFailed'));
1157
+ }
1158
+ } finally {
1159
+ setLoading(false);
1160
+ }
1161
+ };
1162
+ const getMethodName = m => t(m.nameKey) || m.id;
1163
+ const renderContent = () => {
1164
+ // ============ 充值成功 ============
1165
+ if (step === "success") {
1166
+ return /*#__PURE__*/React.createElement("div", {
1167
+ style: {
1168
+ textAlign: 'center',
1169
+ padding: '40px 20px',
1170
+ animation: 'fadeIn 0.5s'
1171
+ }
1172
+ }, /*#__PURE__*/React.createElement(icons.CheckCircleFilled, {
1173
+ style: {
1174
+ fontSize: 72,
1175
+ color: "#52C41A",
1176
+ marginBottom: '24px',
1177
+ animation: 'scaleIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)'
1178
+ }
1179
+ }), /*#__PURE__*/React.createElement("h2", {
1180
+ style: {
1181
+ fontSize: '24px',
1182
+ fontWeight: 800,
1183
+ color: '#0F172A',
1184
+ marginBottom: '8px'
1185
+ }
1186
+ }, t('rechargeSuccessful')), /*#__PURE__*/React.createElement("p", {
1187
+ style: {
1188
+ fontSize: '15px',
1189
+ color: '#64748B'
1190
+ }
1191
+ }, t('rechargeSuccessMsg', {
1192
+ amount,
1193
+ currency
1194
+ })));
1195
+ }
1196
+
1197
+ // ============ 等待支付 ============
1198
+ if (step === "paying") {
1199
+ return /*#__PURE__*/React.createElement("div", {
1200
+ style: {
1201
+ padding: '20px',
1202
+ textAlign: 'center',
1203
+ animation: 'fadeIn 0.3s'
1204
+ }
1205
+ }, /*#__PURE__*/React.createElement("h3", {
1206
+ style: {
1207
+ fontSize: '20px',
1208
+ fontWeight: 700,
1209
+ color: '#0F172A',
1210
+ marginBottom: '8px'
1211
+ }
1212
+ }, t('paymentProcessing')), /*#__PURE__*/React.createElement("div", {
1213
+ style: {
1214
+ fontSize: '13px',
1215
+ color: '#94A3B8',
1216
+ marginBottom: '32px'
1217
+ }
1218
+ }, t('orderNo'), ": ", paymentData?.order_no), /*#__PURE__*/React.createElement("div", {
1219
+ style: {
1220
+ background: 'rgba(241, 245, 249, 0.5)',
1221
+ border: '1px solid rgba(226, 232, 240, 0.8)',
1222
+ borderRadius: '24px',
1223
+ padding: '32px',
1224
+ marginBottom: '32px',
1225
+ display: 'flex',
1226
+ flexDirection: 'column',
1227
+ alignItems: 'center'
1228
+ }
1229
+ }, /*#__PURE__*/React.createElement("div", {
1230
+ style: {
1231
+ fontSize: '48px',
1232
+ fontWeight: 800,
1233
+ color: '#0F172A',
1234
+ lineHeight: 1,
1235
+ marginBottom: '16px'
1236
+ }
1237
+ }, amount, " ", /*#__PURE__*/React.createElement("span", {
1238
+ style: {
1239
+ fontSize: '20px',
1240
+ color: '#64748B'
1241
+ }
1242
+ }, currency)), /*#__PURE__*/React.createElement("div", {
1243
+ style: {
1244
+ display: 'flex',
1245
+ alignItems: 'center',
1246
+ gap: '8px',
1247
+ background: '#fff',
1248
+ padding: '8px 16px',
1249
+ borderRadius: '100px',
1250
+ boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
1251
+ }
1252
+ }, PAYMENT_METHODS.find(m => m.id === method)?.icon, /*#__PURE__*/React.createElement("span", {
1253
+ style: {
1254
+ fontSize: '15px',
1255
+ fontWeight: 600,
1256
+ color: '#334155'
1257
+ }
1258
+ }, getMethodName(PAYMENT_METHODS.find(m => m.id === method))))), /*#__PURE__*/React.createElement("div", {
1259
+ style: {
1260
+ display: 'flex',
1261
+ flexDirection: 'column',
1262
+ gap: '24px',
1263
+ alignItems: 'center'
1264
+ }
1265
+ }, /*#__PURE__*/React.createElement(antd.Spin, {
1266
+ tip: t('waitingForPayment'),
1267
+ size: "large"
1268
+ }), /*#__PURE__*/React.createElement("button", {
1269
+ onClick: handleMockPay,
1270
+ style: {
1271
+ background: 'transparent',
1272
+ border: 'none',
1273
+ color: '#3B82F6',
1274
+ fontSize: '14px',
1275
+ fontWeight: 600,
1276
+ cursor: 'pointer',
1277
+ textDecoration: 'underline'
1278
+ }
1279
+ }, t('simulatePaySuccess'))));
1280
+ }
1281
+
1282
+ // ============ 选择金额和方式 ============
1283
+ return /*#__PURE__*/React.createElement("div", {
1284
+ style: {
1285
+ display: 'flex',
1286
+ flexDirection: 'column',
1287
+ gap: '32px',
1288
+ padding: '10px 0'
1289
+ }
1290
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
1291
+ style: {
1292
+ fontSize: '16px',
1293
+ fontWeight: 700,
1294
+ color: '#0F172A',
1295
+ marginBottom: '16px'
1296
+ }
1297
+ }, t('rechargeAmount'), " (", currency, ")"), /*#__PURE__*/React.createElement("div", {
1298
+ style: {
1299
+ display: 'grid',
1300
+ gridTemplateColumns: 'repeat(4, 1fr)',
1301
+ gap: '12px',
1302
+ marginBottom: '16px'
1303
+ }
1304
+ }, [100, 500, 1000, 5000].map(val => /*#__PURE__*/React.createElement("div", {
1305
+ key: val,
1306
+ onClick: () => setAmount(val),
1307
+ style: {
1308
+ padding: '16px 0',
1309
+ textAlign: 'center',
1310
+ borderRadius: '16px',
1311
+ cursor: 'pointer',
1312
+ fontSize: '16px',
1313
+ fontWeight: 600,
1314
+ transition: 'all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
1315
+ border: amount === val ? '1px solid rgba(59, 130, 246, 0.8)' : '1px solid rgba(255, 255, 255, 0.4)',
1316
+ background: amount === val ? 'rgba(255, 255, 255, 0.9)' : 'rgba(255, 255, 255, 0.6)',
1317
+ backdropFilter: 'blur(16px)',
1318
+ WebkitBackdropFilter: 'blur(16px)',
1319
+ color: amount === val ? '#2563EB' : '#475569',
1320
+ boxShadow: amount === val ? '0 10px 20px -5px rgba(59, 130, 246, 0.2), inset 0 0 0 1px rgba(255,255,255,0.8)' : '0 4px 12px rgba(0,0,0,0.02), inset 0 0 0 1px rgba(255,255,255,0.5)'
1321
+ },
1322
+ onMouseEnter: e => {
1323
+ if (amount !== val) {
1324
+ e.currentTarget.style.transform = 'translateY(-2px)';
1325
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.8)';
1326
+ }
1327
+ },
1328
+ onMouseLeave: e => {
1329
+ if (amount !== val) {
1330
+ e.currentTarget.style.transform = 'none';
1331
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.6)';
1332
+ }
1333
+ }
1334
+ }, val))), /*#__PURE__*/React.createElement(antd.InputNumber, {
1335
+ style: {
1336
+ width: "100%",
1337
+ borderRadius: '16px',
1338
+ background: 'rgba(241, 245, 249, 0.5)'
1339
+ },
1340
+ size: "large",
1341
+ value: amount,
1342
+ onChange: setAmount,
1343
+ prefix: /*#__PURE__*/React.createElement(icons.DollarOutlined, {
1344
+ style: {
1345
+ color: '#94A3B8'
1346
+ }
1347
+ }),
1348
+ min: 1
1349
+ })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
1350
+ style: {
1351
+ fontSize: '16px',
1352
+ fontWeight: 700,
1353
+ color: '#0F172A',
1354
+ marginBottom: '16px'
1355
+ }
1356
+ }, t('paymentMethod')), /*#__PURE__*/React.createElement("div", {
1357
+ style: {
1358
+ display: 'flex',
1359
+ flexDirection: 'column',
1360
+ gap: '12px'
1361
+ }
1362
+ }, PAYMENT_METHODS.map(m => /*#__PURE__*/React.createElement("div", {
1363
+ key: m.id,
1364
+ onClick: () => setMethod(m.id),
1365
+ style: {
1366
+ display: 'flex',
1367
+ alignItems: 'center',
1368
+ padding: '16px',
1369
+ borderRadius: '20px',
1370
+ cursor: 'pointer',
1371
+ border: method === m.id ? '1px solid rgba(59, 130, 246, 0.8)' : '1px solid rgba(255, 255, 255, 0.4)',
1372
+ background: method === m.id ? 'rgba(255, 255, 255, 0.85)' : 'rgba(255, 255, 255, 0.6)',
1373
+ backdropFilter: 'blur(16px)',
1374
+ WebkitBackdropFilter: 'blur(16px)',
1375
+ transition: 'all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
1376
+ boxShadow: method === m.id ? '0 10px 25px -5px rgba(59, 130, 246, 0.15), inset 0 0 0 1px rgba(255,255,255,0.8)' : '0 4px 12px rgba(0,0,0,0.02), inset 0 0 0 1px rgba(255,255,255,0.5)'
1377
+ },
1378
+ onMouseEnter: e => {
1379
+ if (method !== m.id) {
1380
+ e.currentTarget.style.transform = 'translateY(-2px)';
1381
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.8)';
1382
+ }
1383
+ },
1384
+ onMouseLeave: e => {
1385
+ if (method !== m.id) {
1386
+ e.currentTarget.style.transform = 'none';
1387
+ e.currentTarget.style.background = 'rgba(255, 255, 255, 0.6)';
1388
+ }
1389
+ }
1390
+ }, /*#__PURE__*/React.createElement("div", {
1391
+ style: {
1392
+ width: '40px',
1393
+ height: '40px',
1394
+ background: 'rgba(255,255,255,0.9)',
1395
+ borderRadius: '12px',
1396
+ display: 'flex',
1397
+ alignItems: 'center',
1398
+ justifyContent: 'center',
1399
+ boxShadow: '0 2px 8px rgba(0,0,0,0.05)'
1400
+ }
1401
+ }, m.icon), /*#__PURE__*/React.createElement("div", {
1402
+ style: {
1403
+ marginLeft: '16px',
1404
+ flex: 1,
1405
+ fontSize: '16px',
1406
+ fontWeight: 600,
1407
+ color: '#0F172A'
1408
+ }
1409
+ }, getMethodName(m)), /*#__PURE__*/React.createElement("div", {
1410
+ style: {
1411
+ width: '24px',
1412
+ height: '24px',
1413
+ borderRadius: '50%',
1414
+ border: method === m.id ? '7px solid #3B82F6' : '2px solid rgba(148, 163, 184, 0.5)',
1415
+ background: '#fff',
1416
+ transition: 'all 0.2s',
1417
+ boxShadow: method === m.id ? '0 4px 8px rgba(59, 130, 246, 0.2)' : 'none'
1418
+ }
1419
+ }))))), /*#__PURE__*/React.createElement("button", {
1420
+ onClick: handleRecharge,
1421
+ disabled: loading,
1422
+ style: {
1423
+ width: '100%',
1424
+ padding: '16px',
1425
+ borderRadius: '16px',
1426
+ border: 'none',
1427
+ background: 'linear-gradient(135deg, #1E293B 0%, #0F172A 100%)',
1428
+ color: '#fff',
1429
+ fontSize: '16px',
1430
+ fontWeight: 700,
1431
+ cursor: loading ? 'not-allowed' : 'pointer',
1432
+ opacity: loading ? 0.8 : 1,
1433
+ display: 'flex',
1434
+ alignItems: 'center',
1435
+ justifyContent: 'center',
1436
+ gap: '8px',
1437
+ boxShadow: '0 10px 25px -5px rgba(15, 23, 42, 0.3)',
1438
+ transition: 'all 0.2s'
1439
+ },
1440
+ onMouseEnter: e => {
1441
+ if (!loading) {
1442
+ e.currentTarget.style.transform = 'translateY(-2px)';
1443
+ e.currentTarget.style.boxShadow = '0 15px 35px -5px rgba(15, 23, 42, 0.4)';
1444
+ }
1445
+ },
1446
+ onMouseLeave: e => {
1447
+ if (!loading) {
1448
+ e.currentTarget.style.transform = 'none';
1449
+ e.currentTarget.style.boxShadow = '0 10px 25px -5px rgba(15, 23, 42, 0.3)';
1450
+ }
1451
+ }
1452
+ }, /*#__PURE__*/React.createElement(icons.WalletFilled, null), loading ? t('pay.processing') : t('confirmRecharge')));
1453
+ };
1454
+ return /*#__PURE__*/React.createElement(antd.Modal, {
1455
+ open: visible,
1456
+ onCancel: onCancel,
1457
+ footer: null,
1458
+ width: 480,
1459
+ destroyOnClose: true,
1460
+ styles: {
1461
+ content: {
1462
+ padding: '32px',
1463
+ borderRadius: '32px',
1464
+ background: 'rgba(255, 255, 255, 0.9)',
1465
+ backdropFilter: 'blur(24px)',
1466
+ boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)'
1467
+ },
1468
+ header: {
1469
+ background: 'transparent',
1470
+ marginBottom: '24px'
1471
+ },
1472
+ mask: {
1473
+ backdropFilter: 'blur(8px)',
1474
+ background: 'rgba(15, 23, 42, 0.4)'
1475
+ }
1476
+ },
1477
+ title: /*#__PURE__*/React.createElement("div", {
1478
+ style: {
1479
+ fontSize: '24px',
1480
+ fontWeight: 800,
1481
+ color: '#0F172A'
1482
+ }
1483
+ }, t('walletRecharge'))
1484
+ }, /*#__PURE__*/React.createElement("style", null, `
1485
+ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
1486
+ @keyframes scaleIn { from { transform: scale(0.5); opacity: 0; } to { transform: scale(1); opacity: 1; } }
1487
+ `), renderContent());
1488
+ };
1489
+
1490
+ exports.CheckoutSummary = CheckoutSummary;
1491
+ exports.PaymentApiClient = PaymentApiClient;
1492
+ exports.PaymentMethodSelector = PaymentMethodSelector;
1493
+ exports.PricingCard = PricingCard;
1494
+ exports.PricingTable = PricingTable;
1495
+ exports.RechargeModal = RechargeModal;
1496
+ exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
1497
+ exports.getLanguage = getLanguage;
1498
+ exports.messages = messages;
1499
+ exports.paymentApi = paymentApi;
1500
+ exports.setLanguage = setLanguage;
1501
+ exports.t = t;
1502
+ //# sourceMappingURL=index.cjs.map