cppay-sdk 0.0.2-beta.2 → 0.0.2-beta.21

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/react.js ADDED
@@ -0,0 +1,586 @@
1
+ import { a as payment_dialog_default, i as injectStyle, n as metamask_default, o as __toESM, r as require_browser, t as walletconnect_default } from "./walletconnect-B0L70Mgc.js";
2
+ import { t as cppay_default } from "./cppay-BcCDwXlg.js";
3
+ import { EMPTY, defer, timer } from "rxjs";
4
+ import { expand, retry, switchMap, tap, timeout } from "rxjs/operators";
5
+ import { createWalletClient, custom, parseUnits } from "viem";
6
+ import { arbitrum, base, bsc, mainnet, optimism, polygon } from "viem/chains";
7
+ import EthereumProvider from "@walletconnect/ethereum-provider";
8
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ var import_browser = /* @__PURE__ */ __toESM(require_browser(), 1), PaymentDialog_default = React.memo(({ open: e, onClose: t, apikey: r, plain: i, orderId: l, amount: u, intervalDays: d, onExpired: we, onSuccess: f, onFailed: p, onError: m }) => {
11
+ let h = useMemo(() => new cppay_default(r), [r]), [g, _] = useState("select"), [v, y] = useState(!1), [b, x] = useState([]), [S, C] = useState(""), [w, T] = useState(""), [E, D] = useState(""), [O, k] = useState(""), [A, j] = useState(!1), [M, N] = useState(null), P = useRef(null), F = useRef(null), I = useMemo(() => b.find((e) => e.chain === S), [b, S]), L = useMemo(() => I?.tokens || [], [I]), R = useMemo(() => L.find((e) => e.symbol === w), [L, w]), z = (e) => [
12
+ "USDT",
13
+ "USDC",
14
+ "BUSD",
15
+ "DAI",
16
+ "TUSD",
17
+ "USDD",
18
+ "FDUSD"
19
+ ].includes(e.toUpperCase()) ? 2 : 6, B = (e) => ({
20
+ ETH: mainnet,
21
+ BSC: bsc,
22
+ Polygon: polygon,
23
+ Arbitrum: arbitrum,
24
+ Optimism: optimism,
25
+ Base: base
26
+ })[e] || mainnet, V = (e, t) => {
27
+ let n = parseFloat(e);
28
+ return isNaN(n) ? "0" : n.toFixed(t).replace(/\.?0+$/, "");
29
+ }, H = useMemo(() => {
30
+ if (!w || !R) return "0";
31
+ let e = parseFloat(R.price);
32
+ if (isNaN(e) || e === 0) return "0";
33
+ let t = z(w);
34
+ return V((parseFloat(u) / e).toFixed(t), t);
35
+ }, [
36
+ u,
37
+ w,
38
+ R
39
+ ]), U = async () => {
40
+ try {
41
+ y(!0);
42
+ let e = await h.getSupportedChains();
43
+ x(e), e.length > 0 && C(e[0].chain);
44
+ } catch (e) {
45
+ m?.(e);
46
+ } finally {
47
+ y(!1);
48
+ }
49
+ }, W = async (e) => {
50
+ try {
51
+ if (j(!0), e === "metamask") {
52
+ if (typeof window < "u" && window.ethereum?.isMetaMask) {
53
+ let e = await window.ethereum.request({ method: "eth_requestAccounts" });
54
+ if (e && e.length > 0) {
55
+ k(e[0]), N("metamask");
56
+ return;
57
+ }
58
+ }
59
+ throw Error("请安装 MetaMask 扩展");
60
+ }
61
+ if (e === "walletconnect") {
62
+ let e = await EthereumProvider.init({
63
+ projectId: "8d2e1854d3f1782e45aa15fbd8938894",
64
+ chains: [1],
65
+ showQrModal: !0,
66
+ optionalChains: [
67
+ 56,
68
+ 137,
69
+ 42161,
70
+ 10,
71
+ 8453
72
+ ],
73
+ methods: [
74
+ "eth_sendTransaction",
75
+ "eth_signTransaction",
76
+ "eth_sign",
77
+ "personal_sign",
78
+ "eth_signTypedData"
79
+ ],
80
+ events: ["chainChanged", "accountsChanged"],
81
+ metadata: {
82
+ name: "Cppay",
83
+ description: "Cppay Payment Gateway",
84
+ url: typeof window < "u" ? window.location.origin : "https://cppay.com",
85
+ icons: ["https://cppay.com/icon.png"]
86
+ },
87
+ rpcMap: {
88
+ 1: "https://ethereum.publicnode.com",
89
+ 56: "https://bsc-dataseed.binance.org",
90
+ 137: "https://polygon-rpc.com",
91
+ 42161: "https://arb1.arbitrum.io/rpc",
92
+ 10: "https://mainnet.optimism.io",
93
+ 8453: "https://mainnet.base.org"
94
+ }
95
+ });
96
+ await e.enable();
97
+ let t = await e.request({ method: "eth_accounts" });
98
+ t && t.length > 0 && (k(t[0]), N("walletconnect"), P.current = e);
99
+ }
100
+ } catch (e) {
101
+ console.error("钱包连接失败:", e), m?.(e);
102
+ } finally {
103
+ j(!1);
104
+ }
105
+ }, G = async (e) => {
106
+ let t;
107
+ if (t = M === "walletconnect" ? P.current : window.ethereum, t) try {
108
+ await t.request({
109
+ method: "wallet_switchEthereumChain",
110
+ params: [{ chainId: `0x${e.toString(16)}` }]
111
+ });
112
+ } catch (e) {
113
+ throw e.code === 4902 ? Error("请在钱包中添加该网络") : e;
114
+ }
115
+ }, K = async () => {
116
+ if (!(!O || !Y.current || !R)) try {
117
+ y(!0);
118
+ let e = Y.current, t = B(S);
119
+ await G(I.chainId);
120
+ let n = createWalletClient({
121
+ account: O,
122
+ chain: t,
123
+ transport: custom(M === "walletconnect" ? P.current : window.ethereum)
124
+ });
125
+ if (R.address) {
126
+ let t = await n.writeContract({
127
+ address: R.address,
128
+ abi: [{
129
+ name: "transfer",
130
+ type: "function",
131
+ stateMutability: "nonpayable",
132
+ inputs: [{
133
+ name: "to",
134
+ type: "address"
135
+ }, {
136
+ name: "amount",
137
+ type: "uint256"
138
+ }],
139
+ outputs: [{ type: "bool" }]
140
+ }],
141
+ functionName: "transfer",
142
+ args: [e.receiveAddress, parseUnits(e.paymentAmount, R.decimals)],
143
+ chain: null
144
+ });
145
+ console.log("转账交易哈希:", t);
146
+ } else {
147
+ let t = await n.sendTransaction({
148
+ to: e.receiveAddress,
149
+ value: parseUnits(e.paymentAmount, R.decimals),
150
+ chain: null
151
+ });
152
+ console.log("转账交易哈希:", t);
153
+ }
154
+ Z(e.paymentId);
155
+ } catch (e) {
156
+ console.error("钱包支付失败:", e), m?.(e);
157
+ } finally {
158
+ y(!1);
159
+ }
160
+ }, q = async () => {
161
+ if (!(!O || !Y.current || !R)) try {
162
+ y(!0);
163
+ let e = Y.current, t = B(S);
164
+ await G(I.chainId);
165
+ let n = createWalletClient({
166
+ account: O,
167
+ chain: t,
168
+ transport: custom(M === "walletconnect" ? P.current : window.ethereum)
169
+ });
170
+ if (!R.address) throw Error("订阅支付不支持原生代币");
171
+ let r = await n.writeContract({
172
+ address: R.address,
173
+ abi: [{
174
+ name: "approve",
175
+ type: "function",
176
+ stateMutability: "nonpayable",
177
+ inputs: [{
178
+ name: "spender",
179
+ type: "address"
180
+ }, {
181
+ name: "amount",
182
+ type: "uint256"
183
+ }],
184
+ outputs: [{ type: "bool" }]
185
+ }],
186
+ functionName: "approve",
187
+ args: [e.spenderAddress, parseUnits(e.approveAmount, R.decimals)],
188
+ chain: null
189
+ });
190
+ console.log("授权交易哈希:", r), Z(e.subscriptionId);
191
+ } catch (e) {
192
+ console.error("钱包授权失败:", e), m?.(e);
193
+ } finally {
194
+ y(!1);
195
+ }
196
+ }, J = async () => {
197
+ if (!O) {
198
+ m?.(/* @__PURE__ */ Error("请先连接钱包"));
199
+ return;
200
+ }
201
+ i === "one-time" ? await K() : i === "subscription" && await q();
202
+ }, Y = useRef(null), X = async () => {
203
+ if (!(!S || !w)) try {
204
+ y(!0);
205
+ let e = "";
206
+ i === "one-time" ? (Y.current = await h.createOnetimePayment({
207
+ paymentChain: S,
208
+ paymentToken: w,
209
+ orderId: l,
210
+ amount: H
211
+ }), e = `${S.toLowerCase()}:${Y.current.receiveAddress}?amount=${Y.current.paymentAmount}`) : i === "subscription" && (Y.current = await h.createSubscriptionPayment({
212
+ paymentChain: S,
213
+ paymentToken: w,
214
+ orderId: l,
215
+ amountOfUsd: H,
216
+ intervalDays: d || 30
217
+ }), e = `${S.toLowerCase()}:${Y.current.spenderAddress}?amount=${Y.current.approveAmount}`), _("payment"), D(await import_browser.toDataURL(e, {
218
+ width: 200,
219
+ margin: 2,
220
+ errorCorrectionLevel: "H"
221
+ }));
222
+ } catch (e) {
223
+ m?.(e);
224
+ } finally {
225
+ y(!1);
226
+ }
227
+ }, Te = async () => {
228
+ if (Y.current) try {
229
+ y(!0), i === "one-time" ? Z(Y.current.paymentId) : i === "subscription" && Z(Y.current.subscriptionId);
230
+ } catch (e) {
231
+ console.error("支付状态检查错误:", e), m?.(e), y(!1);
232
+ }
233
+ }, Z = (e) => {
234
+ let t = () => defer(() => i === "subscription" ? h.checkSubscriptionPaymentStatus({ subscriptionId: e }) : h.checkOnetimePaymentStatus({ paymentId: e })).pipe(timeout(15e3), retry({
235
+ count: 3,
236
+ delay: 2e3
237
+ }));
238
+ F.current?.unsubscribe(), F.current = t().pipe(expand((e) => e.status === "pending" ? timer(2e3).pipe(switchMap(() => t())) : EMPTY), tap((e) => {
239
+ e.status === "expired" && (y(!1), we?.(e)), e.status === "paid" && (y(!1), _("success"), f?.(e)), e.status === "failed" && (y(!1), p?.(e)), e.status === "approved" && (y(!1), _("success"), f?.(e));
240
+ })).subscribe({ error: (e) => {
241
+ console.error("支付状态检查错误:", e), y(!1), m?.(e);
242
+ } });
243
+ }, Q = async () => {
244
+ if (!Y.current) return;
245
+ let e = i === "subscription" ? Y.current.spenderAddress : Y.current.receiveAddress;
246
+ e && await navigator.clipboard.writeText(e);
247
+ }, $ = () => {
248
+ v || (t(), setTimeout(() => {
249
+ _("select"), Y.current = null;
250
+ }, 300));
251
+ };
252
+ return useEffect(() => {
253
+ e && b.length === 0 && U();
254
+ }, [e]), useEffect(() => {
255
+ L.length > 0 && T(L[0].symbol);
256
+ }, [L]), useEffect(() => () => {
257
+ F.current?.unsubscribe();
258
+ }, []), e ? /* @__PURE__ */ jsx("div", {
259
+ className: "_cppay-overlay",
260
+ onClick: (e) => e.target === e.currentTarget && !v && $(),
261
+ children: /* @__PURE__ */ jsxs("div", {
262
+ className: "_cppay-dialog",
263
+ children: [/* @__PURE__ */ jsxs("div", {
264
+ className: "_cppay-header",
265
+ children: [/* @__PURE__ */ jsx("h2", {
266
+ className: "_cppay-title",
267
+ children: g === "select" ? "选择支付方式" : "完成支付"
268
+ }), /* @__PURE__ */ jsx("button", {
269
+ onClick: $,
270
+ disabled: v,
271
+ className: "_cppay-close-btn",
272
+ children: /* @__PURE__ */ jsx("svg", {
273
+ fill: "none",
274
+ stroke: "currentColor",
275
+ viewBox: "0 0 24 24",
276
+ children: /* @__PURE__ */ jsx("path", {
277
+ strokeLinecap: "round",
278
+ strokeLinejoin: "round",
279
+ strokeWidth: 2,
280
+ d: "M6 18L18 6M6 6l12 12"
281
+ })
282
+ })
283
+ })]
284
+ }), /* @__PURE__ */ jsx("div", {
285
+ className: "_cppay-content",
286
+ children: g === "success" ? /* @__PURE__ */ jsxs("div", {
287
+ style: {
288
+ textAlign: "center",
289
+ padding: "2rem 0"
290
+ },
291
+ children: [
292
+ /* @__PURE__ */ jsx("div", {
293
+ style: {
294
+ fontSize: "64px",
295
+ marginBottom: "1rem"
296
+ },
297
+ children: "✅"
298
+ }),
299
+ /* @__PURE__ */ jsx("h3", {
300
+ style: {
301
+ fontSize: "1.5rem",
302
+ fontWeight: 600,
303
+ color: "#10b981",
304
+ margin: "0 0 0.5rem 0"
305
+ },
306
+ children: i === "subscription" ? "授权成功!" : "支付成功!"
307
+ }),
308
+ /* @__PURE__ */ jsx("p", {
309
+ style: {
310
+ color: "#6b7280",
311
+ margin: 0
312
+ },
313
+ children: i === "subscription" ? "订阅已激活" : "交易已完成"
314
+ })
315
+ ]
316
+ }) : g === "select" ? /* @__PURE__ */ jsxs("div", { children: [
317
+ /* @__PURE__ */ jsxs("div", {
318
+ className: "_cppay-section",
319
+ children: [/* @__PURE__ */ jsx("label", {
320
+ className: "_cppay-label",
321
+ children: "支付网络"
322
+ }), /* @__PURE__ */ jsx("div", {
323
+ className: "_cppay-grid",
324
+ children: b.map((e) => /* @__PURE__ */ jsxs("button", {
325
+ onClick: () => C(e.chain),
326
+ className: `_cppay-select-btn ${S === e.chain ? "_cppay-selected" : ""}`,
327
+ children: [e.icon && /* @__PURE__ */ jsx("img", {
328
+ src: e.icon,
329
+ alt: e.chain
330
+ }), /* @__PURE__ */ jsx("span", { children: e.chain })]
331
+ }, e.chain))
332
+ })]
333
+ }),
334
+ /* @__PURE__ */ jsxs("div", {
335
+ className: "_cppay-section",
336
+ children: [/* @__PURE__ */ jsx("label", {
337
+ className: "_cppay-label",
338
+ children: "支付代币"
339
+ }), /* @__PURE__ */ jsx("div", {
340
+ className: "_cppay-grid",
341
+ children: L.map((e) => /* @__PURE__ */ jsxs("button", {
342
+ onClick: () => T(e.symbol),
343
+ className: `_cppay-select-btn ${w === e.symbol ? "_cppay-selected" : ""}`,
344
+ children: [e.icon && /* @__PURE__ */ jsx("img", {
345
+ src: e.icon,
346
+ alt: e.symbol
347
+ }), /* @__PURE__ */ jsx("span", { children: e.symbol })]
348
+ }, e.symbol))
349
+ })]
350
+ }),
351
+ /* @__PURE__ */ jsx("div", {
352
+ className: "_cppay-section",
353
+ children: /* @__PURE__ */ jsx("div", {
354
+ className: "_cppay-price-box",
355
+ children: /* @__PURE__ */ jsxs("div", {
356
+ className: "_cppay-price-row",
357
+ children: [/* @__PURE__ */ jsx("span", {
358
+ className: "_cppay-price-label",
359
+ children: "支付金额"
360
+ }), /* @__PURE__ */ jsxs("div", {
361
+ className: "_cppay-price-amount",
362
+ children: [/* @__PURE__ */ jsxs("div", {
363
+ className: "_cppay-price-main",
364
+ children: [
365
+ H,
366
+ " ",
367
+ w
368
+ ]
369
+ }), /* @__PURE__ */ jsxs("div", {
370
+ className: "_cppay-price-sub",
371
+ children: ["≈ $", u]
372
+ })]
373
+ })]
374
+ })
375
+ })
376
+ }),
377
+ /* @__PURE__ */ jsx("div", {
378
+ className: "_cppay-section",
379
+ children: /* @__PURE__ */ jsx("button", {
380
+ onClick: X,
381
+ disabled: !S || !w || v,
382
+ className: "_cppay-btn _cppay-btn-primary",
383
+ children: v ? "处理中..." : "继续支付"
384
+ })
385
+ })
386
+ ] }) : /* @__PURE__ */ jsxs("div", { children: [
387
+ /* @__PURE__ */ jsx("div", {
388
+ className: "_cppay-qr-container",
389
+ children: /* @__PURE__ */ jsx("div", {
390
+ className: "_cppay-qr-code",
391
+ children: E && /* @__PURE__ */ jsx("img", {
392
+ src: E,
393
+ alt: "Payment QR Code",
394
+ style: {
395
+ width: "160px",
396
+ height: "160px",
397
+ display: "block"
398
+ }
399
+ })
400
+ })
401
+ }),
402
+ /* @__PURE__ */ jsxs("div", {
403
+ className: "_cppay-section",
404
+ children: [
405
+ /* @__PURE__ */ jsxs("div", {
406
+ className: "_cppay-info-box",
407
+ children: [/* @__PURE__ */ jsx("div", {
408
+ className: "_cppay-info-label",
409
+ children: i === "subscription" ? "授权金额" : "支付金额"
410
+ }), /* @__PURE__ */ jsx("div", {
411
+ className: "_cppay-info-value",
412
+ children: i === "subscription" ? `${V(Y.current.approveAmount, z(w))} ${w}` : `${V(Y.current.paymentAmount, z(w))} ${w}`
413
+ })]
414
+ }),
415
+ /* @__PURE__ */ jsxs("div", {
416
+ className: "_cppay-info-box",
417
+ children: [/* @__PURE__ */ jsx("div", {
418
+ className: "_cppay-info-label",
419
+ children: i === "subscription" ? "授权合约地址" : "支付地址"
420
+ }), /* @__PURE__ */ jsxs("div", {
421
+ className: "_cppay-address-row",
422
+ children: [/* @__PURE__ */ jsx("code", { children: i === "subscription" ? Y.current.spenderAddress : Y.current.receiveAddress }), /* @__PURE__ */ jsx("button", {
423
+ onClick: Q,
424
+ className: "_cppay-copy-btn",
425
+ title: "复制地址",
426
+ children: /* @__PURE__ */ jsx("svg", {
427
+ fill: "none",
428
+ stroke: "currentColor",
429
+ viewBox: "0 0 24 24",
430
+ children: /* @__PURE__ */ jsx("path", {
431
+ strokeLinecap: "round",
432
+ strokeLinejoin: "round",
433
+ strokeWidth: 2,
434
+ d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
435
+ })
436
+ })
437
+ })]
438
+ })]
439
+ }),
440
+ i === "subscription" && /* @__PURE__ */ jsxs("div", {
441
+ className: "_cppay-info-box",
442
+ style: {
443
+ background: "#fff3cd",
444
+ borderColor: "#ffc107"
445
+ },
446
+ children: [/* @__PURE__ */ jsx("div", {
447
+ className: "_cppay-info-label",
448
+ style: { color: "#856404" },
449
+ children: "📌 订阅说明"
450
+ }), /* @__PURE__ */ jsx("div", {
451
+ className: "_cppay-info-value",
452
+ style: {
453
+ fontSize: "12px",
454
+ color: "#856404"
455
+ },
456
+ children: "订阅支付需要授权代币给合约地址,系统将按周期自动扣款。授权后无需每次手动支付。"
457
+ })]
458
+ })
459
+ ]
460
+ }),
461
+ /* @__PURE__ */ jsx("div", {
462
+ className: "_cppay-section",
463
+ children: O ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
464
+ onClick: J,
465
+ disabled: v,
466
+ className: "_cppay-btn _cppay-btn-primary",
467
+ children: v ? i === "subscription" ? "授权中..." : "支付中..." : i === "subscription" ? "💳 钱包授权" : "💳 钱包支付"
468
+ }), /* @__PURE__ */ jsxs("div", {
469
+ style: {
470
+ textAlign: "center",
471
+ marginTop: "8px",
472
+ fontSize: "12px",
473
+ color: "#666"
474
+ },
475
+ children: [
476
+ "已连接: ",
477
+ O.slice(0, 6),
478
+ "...",
479
+ O.slice(-4)
480
+ ]
481
+ })] }) : /* @__PURE__ */ jsxs("div", {
482
+ style: {
483
+ display: "flex",
484
+ flexDirection: "row",
485
+ gap: "0.5rem",
486
+ justifyContent: "center"
487
+ },
488
+ children: [/* @__PURE__ */ jsxs("button", {
489
+ onClick: () => W("metamask"),
490
+ disabled: A,
491
+ className: "_cppay-btn _cppay-btn-secondary",
492
+ style: {
493
+ display: "flex",
494
+ alignItems: "center",
495
+ justifyContent: "center",
496
+ gap: "0.5rem",
497
+ padding: "0.5rem 1rem",
498
+ fontSize: "14px",
499
+ flex: "1"
500
+ },
501
+ children: [/* @__PURE__ */ jsx("img", {
502
+ src: metamask_default,
503
+ alt: "MetaMask",
504
+ style: {
505
+ width: "20px",
506
+ height: "20px"
507
+ }
508
+ }), /* @__PURE__ */ jsx("span", { children: "MetaMask" })]
509
+ }), /* @__PURE__ */ jsxs("button", {
510
+ onClick: () => W("walletconnect"),
511
+ disabled: A,
512
+ className: "_cppay-btn _cppay-btn-secondary",
513
+ style: {
514
+ display: "flex",
515
+ alignItems: "center",
516
+ justifyContent: "center",
517
+ gap: "0.5rem",
518
+ padding: "0.5rem 1rem",
519
+ fontSize: "14px",
520
+ flex: "1"
521
+ },
522
+ children: [/* @__PURE__ */ jsx("img", {
523
+ src: walletconnect_default,
524
+ alt: "WalletConnect",
525
+ style: {
526
+ width: "20px",
527
+ height: "20px"
528
+ }
529
+ }), /* @__PURE__ */ jsx("span", { children: "WalletConnect" })]
530
+ })]
531
+ })
532
+ }),
533
+ /* @__PURE__ */ jsx("div", {
534
+ className: "_cppay-section",
535
+ children: /* @__PURE__ */ jsx("button", {
536
+ onClick: Te,
537
+ disabled: v,
538
+ className: "_cppay-btn _cppay-btn-primary",
539
+ children: v ? "检查中..." : "我已完成支付"
540
+ })
541
+ }),
542
+ /* @__PURE__ */ jsx("div", {
543
+ className: "_cppay-section",
544
+ children: /* @__PURE__ */ jsx("button", {
545
+ onClick: () => _("select"),
546
+ disabled: v,
547
+ className: "_cppay-btn _cppay-btn-text",
548
+ children: "更改支付方式"
549
+ })
550
+ })
551
+ ] })
552
+ })]
553
+ })
554
+ }) : null;
555
+ }), CppayContext = createContext(null);
556
+ const CppayProvider = ({ apikey: e, children: t }) => {
557
+ let [n, r] = useState(!1), [i, a] = useState(null), o = useCallback((e) => {
558
+ a(e), r(!0);
559
+ }, []), s = useCallback(() => {
560
+ r(!1);
561
+ }, []), Ce = useCallback((e) => {
562
+ i?.onSuccess?.(e), r(!1);
563
+ }, [i]), c = useCallback((e) => {
564
+ i?.onError?.(e);
565
+ }, [i]);
566
+ return /* @__PURE__ */ jsxs(CppayContext.Provider, {
567
+ value: { showPayment: o },
568
+ children: [t, i && /* @__PURE__ */ jsx(PaymentDialog_default, {
569
+ open: n,
570
+ onClose: s,
571
+ apikey: e,
572
+ plain: i.plain,
573
+ orderId: i.orderId,
574
+ amount: i.amount,
575
+ intervalDays: i.intervalDays,
576
+ onSuccess: Ce,
577
+ onError: c
578
+ })]
579
+ });
580
+ }, useCppayPayment = () => {
581
+ let e = useContext(CppayContext);
582
+ if (!e) throw Error("useCppayPayment must be used within CppayProvider");
583
+ return e;
584
+ };
585
+ injectStyle(payment_dialog_default);
586
+ export { CppayProvider, PaymentDialog_default as PaymentDialog, useCppayPayment };
package/dist/vue.cjs ADDED
@@ -0,0 +1 @@
1
+ const e=require(`./walletconnect-B_n5YF-h.cjs`),t=require(`./cppay-DnxPUyM2.cjs`);let n=require(`vue`),r=require(`rxjs`),i=require(`rxjs/operators`),a=require(`viem`),o=require(`viem/chains`),s=require(`@walletconnect/ethereum-provider`);s=e.o(s);var ee=e.o(e.r(),1),te={class:`_cppay-dialog`},ne={class:`_cppay-header`},re={class:`_cppay-title`},ie=[`disabled`],ae={class:`_cppay-content`},oe={key:0,style:{"text-align":`center`,padding:`2rem 0`}},c={style:{"font-size":`1.5rem`,"font-weight":`600`,color:`#10b981`,margin:`0 0 0.5rem 0`}},se={style:{color:`#6b7280`,margin:`0`}},ce={key:1},le={class:`_cppay-section`},ue={class:`_cppay-grid`},de=[`onClick`],fe=[`src`,`alt`],pe={class:`_cppay-section`},me={class:`_cppay-grid`},he=[`onClick`],ge=[`src`,`alt`],_e={class:`_cppay-section`},ve={class:`_cppay-price-box`},ye={class:`_cppay-price-row`},be={class:`_cppay-price-amount`},xe={class:`_cppay-price-main`},Se={class:`_cppay-price-sub`},Ce={class:`_cppay-section`},we=[`disabled`],Te={key:2},Ee={class:`_cppay-qr-container`},De={class:`_cppay-qr-code`},l=[`src`],u={class:`_cppay-section`},d={class:`_cppay-info-box`},f={class:`_cppay-info-label`},p={class:`_cppay-info-value`},m={class:`_cppay-info-box`},h={class:`_cppay-info-label`},g={class:`_cppay-address-row`},_={key:0,class:`_cppay-info-box`,style:{background:`#fff3cd`,"border-color":`#ffc107`}},v={class:`_cppay-section`},y={key:0,style:{display:`flex`,"flex-direction":`row`,gap:`0.5rem`,"justify-content":`center`}},b=[`disabled`],x=[`src`],S=[`disabled`],C=[`src`],w={key:1},T=[`disabled`],E={style:{"text-align":`center`,"margin-top":`8px`,"font-size":`12px`,color:`#666`}},Oe={class:`_cppay-section`},ke=[`disabled`],Ae={class:`_cppay-section`},je=[`disabled`],D=(0,n.defineComponent)({__name:`PaymentDialog`,props:{modelValue:{type:Boolean},apikey:{},orderId:{},amount:{},plain:{default:`one-time`},intervalDays:{default:30}},emits:[`update:modelValue`,`success`,`error`],setup(D,{emit:O}){let k=D,A=O,j=new t.t(k.apikey),M=(0,n.ref)(`select`),N=(0,n.ref)(!1),P=(0,n.ref)([]),F=(0,n.ref)(``),I=(0,n.ref)(``),L=(0,n.ref)(null),R=(0,n.ref)(``),z=(0,n.ref)(``),B=(0,n.ref)(!1),V=(0,n.ref)(!0),H=(0,n.ref)(null),U=(0,n.ref)(null),W=(0,n.ref)(null),G=(0,n.computed)(()=>P.value.find(e=>e.chain===F.value)),K=(0,n.computed)(()=>G.value?.tokens||[]),q=(0,n.computed)(()=>K.value.find(e=>e.symbol===I.value)),Me=e=>[`USDT`,`USDC`,`BUSD`,`DAI`,`TUSD`,`USDD`,`FDUSD`].includes(e.toUpperCase())?2:6,Ne=(e,t)=>{let n=parseFloat(e);return isNaN(n)?`0`:n.toFixed(t).replace(/\.?0+$/,``)},J=(0,n.computed)(()=>{if(!I.value||!q.value)return`0`;let e=parseFloat(q.value.price);if(isNaN(e)||e===0)return`0`;let t=Me(I.value);return Ne((parseFloat(k.amount)/e).toFixed(t),t)}),Pe=()=>{L.value&&(N.value=!0,k.plain===`one-time`?$(L.value.paymentId):k.plain===`subscription`&&$(L.value.subscriptionId))},Y=()=>{N.value||(A(`update:modelValue`,!1),setTimeout(()=>{M.value=`select`,L.value=null},300))},Fe=async()=>{try{N.value=!0,P.value=await j.getSupportedChains(),P.value.length>0&&(F.value=P.value[0].chain)}catch(e){A(`error`,e)}finally{N.value=!1}},X=e=>({ETH:o.mainnet,BSC:o.bsc,Polygon:o.polygon,Arbitrum:o.arbitrum,Optimism:o.optimism,Base:o.base})[e]||o.mainnet,Z=async e=>{try{if(B.value=!0,e===`metamask`){if(typeof window<`u`&&window.ethereum?.isMetaMask){let e=await window.ethereum.request({method:`eth_requestAccounts`});if(e&&e.length>0){z.value=e[0],H.value=`metamask`,V.value=!1;return}}throw Error(`请安装 MetaMask 扩展`)}if(e===`walletconnect`){let e=await s.default.init({projectId:`8d2e1854d3f1782e45aa15fbd8938894`,chains:[1],showQrModal:!0,optionalChains:[56,137,42161,10,8453],methods:[`eth_sendTransaction`,`eth_signTransaction`,`eth_sign`,`personal_sign`,`eth_signTypedData`],events:[`chainChanged`,`accountsChanged`],metadata:{name:`Cppay`,description:`Cppay Payment Gateway`,url:typeof window<`u`?window.location.origin:`https://cppay.com`,icons:[`https://cppay.com/icon.png`]},rpcMap:{1:`https://ethereum.publicnode.com`,56:`https://bsc-dataseed.binance.org`,137:`https://polygon-rpc.com`,42161:`https://arb1.arbitrum.io/rpc`,10:`https://mainnet.optimism.io`,8453:`https://mainnet.base.org`}});await e.enable();let t=await e.request({method:`eth_accounts`});t&&t.length>0&&(z.value=t[0],H.value=`walletconnect`,U.value=e,V.value=!1)}}catch(e){console.error(`钱包连接失败:`,e),A(`error`,e)}finally{B.value=!1}},Q=async e=>{let t;if(t=H.value===`walletconnect`?U.value:window.ethereum,t)try{await t.request({method:`wallet_switchEthereumChain`,params:[{chainId:`0x${e.toString(16)}`}]})}catch(e){throw e.code===4902?Error(`请在钱包中添加该网络`):e}},Ie=async()=>{if(!(!z.value||!L.value||!q.value))try{N.value=!0;let e=L.value,t=X(F.value);await Q(G.value.chainId);let n=(0,a.createWalletClient)({account:z.value,chain:t,transport:(0,a.custom)(H.value===`walletconnect`?U.value:window.ethereum)});if(q.value.address){let t=await n.writeContract({address:q.value.address,abi:[{name:`transfer`,type:`function`,stateMutability:`nonpayable`,inputs:[{name:`to`,type:`address`},{name:`amount`,type:`uint256`}],outputs:[{type:`bool`}]}],functionName:`transfer`,args:[e.receiveAddress,(0,a.parseUnits)(e.paymentAmount,q.value.decimals)],chain:null});console.log(`转账交易哈希:`,t)}else{let t=await n.sendTransaction({to:e.receiveAddress,value:(0,a.parseUnits)(e.paymentAmount,q.value.decimals),chain:null});console.log(`转账交易哈希:`,t)}$(e.paymentId)}catch(e){console.error(`钱包支付失败:`,e),A(`error`,e)}finally{N.value=!1}},Le=async()=>{if(!(!z.value||!L.value||!q.value))try{N.value=!0;let e=L.value,t=X(F.value);await Q(G.value.chainId);let n=(0,a.createWalletClient)({account:z.value,chain:t,transport:(0,a.custom)(H.value===`walletconnect`?U.value:window.ethereum)});if(!q.value.address)throw Error(`订阅支付不支持原生代币`);let r=await n.writeContract({address:q.value.address,abi:[{name:`approve`,type:`function`,stateMutability:`nonpayable`,inputs:[{name:`spender`,type:`address`},{name:`amount`,type:`uint256`}],outputs:[{type:`bool`}]}],functionName:`approve`,args:[e.receiveAddress,(0,a.parseUnits)(e.paymentAmount,q.value.decimals)],chain:null});console.log(`授权交易哈希:`,r),$(e.paymentId)}catch(e){console.error(`钱包授权失败:`,e),A(`error`,e)}finally{N.value=!1}},Re=async()=>{if(!z.value){V.value=!0;return}k.plain===`one-time`?await Ie():k.plain===`subscription`&&await Le()},ze=async()=>{if(!(!F.value||!I.value))try{N.value=!0;let e;k.plain===`one-time`?e=await j.createPayment(`one-time`,{paymentChain:F.value,paymentToken:I.value,orderId:k.orderId,amount:J.value}):k.plain===`subscription`&&(e=await j.createPayment(`subscription`,{paymentChain:F.value,paymentToken:I.value,orderId:k.orderId,amountOfUsd:J.value,intervalDays:k.intervalDays||30})),L.value={paymentId:e.paymentId||e.subscriptionId,paymentAmount:e.paymentAmount||e.approveAmount,receiveAddress:e.receiveAddress||e.spenderAddress||``};let t=`${F.value.toLowerCase()}:${L.value.receiveAddress}?amount=${L.value.paymentAmount}`;R.value=await ee.toDataURL(t,{width:200,margin:2,errorCorrectionLevel:`H`}),M.value=`payment`}catch(e){A(`error`,e)}finally{N.value=!1}},$=e=>{let t=()=>(0,r.defer)(()=>k.plain===`subscription`?j.checkSubscriptionPaymentStatus({subscriptionId:e}):j.checkOnetimePaymentStatus({paymentId:e})).pipe((0,i.timeout)(15e3),(0,i.retry)({count:3,delay:2e3}));W.value?.unsubscribe(),W.value=t().pipe((0,i.expand)(e=>e.status===`pending`?(0,r.timer)(2e3).pipe((0,i.switchMap)(()=>t())):r.EMPTY),(0,i.tap)(e=>{e.status===`expired`&&(N.value=!1),e.status===`paid`&&(N.value=!1,M.value=`success`,A(`success`,e)),e.status===`failed`&&(N.value=!1),e.status===`approved`&&(N.value=!1,M.value=`success`,A(`success`,e))})).subscribe({error:e=>{console.error(`支付状态检查错误:`,e),N.value=!1,A(`error`,e)}})},Be=async()=>{L.value?.receiveAddress&&await navigator.clipboard.writeText(L.value.receiveAddress)};return(0,n.watch)(()=>k.modelValue,e=>{e&&P.value.length===0&&Fe()}),(0,n.watch)(F,()=>{K.value.length>0&&(I.value=K.value[0].symbol)}),(0,n.watch)(M,e=>{e===`payment`&&L.value&&$(L.value.paymentId)}),(0,n.onUnmounted)(()=>{W.value?.unsubscribe()}),(t,r)=>((0,n.openBlock)(),(0,n.createBlock)(n.Teleport,{to:`body`},[(0,n.createVNode)(n.Transition,{name:`_cppay-fade`},{default:(0,n.withCtx)(()=>[D.modelValue?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,{key:0,class:`_cppay-overlay`,onClick:r[3]||=(0,n.withModifiers)(e=>!N.value&&Y(),[`self`])},[(0,n.createElementVNode)(`div`,te,[(0,n.createElementVNode)(`div`,ne,[(0,n.createElementVNode)(`h2`,re,(0,n.toDisplayString)(M.value===`select`?`选择支付方式`:M.value===`success`?`支付结果`:`完成支付`),1),(0,n.createElementVNode)(`button`,{onClick:Y,class:`_cppay-close-btn`,disabled:N.value},[...r[4]||=[(0,n.createElementVNode)(`svg`,{fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[(0,n.createElementVNode)(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M6 18L18 6M6 6l12 12`})],-1)]],8,ie)]),(0,n.createElementVNode)(`div`,ae,[M.value===`success`?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,oe,[r[5]||=(0,n.createElementVNode)(`div`,{style:{"font-size":`64px`,"margin-bottom":`1rem`}},`✅`,-1),(0,n.createElementVNode)(`h3`,c,(0,n.toDisplayString)(k.plain===`subscription`?`授权成功!`:`支付成功!`),1),(0,n.createElementVNode)(`p`,se,(0,n.toDisplayString)(k.plain===`subscription`?`订阅已激活`:`交易已完成`),1)])):(0,n.createCommentVNode)(``,!0),M.value===`select`?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,ce,[(0,n.createElementVNode)(`div`,le,[r[6]||=(0,n.createElementVNode)(`label`,{class:`_cppay-label`},`支付网络`,-1),(0,n.createElementVNode)(`div`,ue,[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(P.value,e=>((0,n.openBlock)(),(0,n.createElementBlock)(`button`,{key:e.chain,onClick:t=>F.value=e.chain,class:(0,n.normalizeClass)([`_cppay-select-btn`,F.value===e.chain?`_cppay-selected`:``])},[e.icon?((0,n.openBlock)(),(0,n.createElementBlock)(`img`,{key:0,src:e.icon,alt:e.chain},null,8,fe)):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`span`,null,(0,n.toDisplayString)(e.chain),1)],10,de))),128))])]),(0,n.createElementVNode)(`div`,pe,[r[7]||=(0,n.createElementVNode)(`label`,{class:`_cppay-label`},`支付代币`,-1),(0,n.createElementVNode)(`div`,me,[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(K.value,e=>((0,n.openBlock)(),(0,n.createElementBlock)(`button`,{key:e.symbol,onClick:t=>I.value=e.symbol,class:(0,n.normalizeClass)([`_cppay-select-btn`,I.value===e.symbol?`_cppay-selected`:``])},[e.icon?((0,n.openBlock)(),(0,n.createElementBlock)(`img`,{key:0,src:e.icon,alt:e.symbol},null,8,ge)):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`span`,null,(0,n.toDisplayString)(e.symbol),1)],10,he))),128))])]),(0,n.createElementVNode)(`div`,_e,[(0,n.createElementVNode)(`div`,ve,[(0,n.createElementVNode)(`div`,ye,[r[8]||=(0,n.createElementVNode)(`span`,{class:`_cppay-price-label`},`支付金额`,-1),(0,n.createElementVNode)(`div`,be,[(0,n.createElementVNode)(`div`,xe,(0,n.toDisplayString)(J.value)+` `+(0,n.toDisplayString)(I.value),1),(0,n.createElementVNode)(`div`,Se,`≈ $`+(0,n.toDisplayString)(D.amount),1)])])])]),(0,n.createElementVNode)(`div`,Ce,[(0,n.createElementVNode)(`button`,{onClick:ze,disabled:!F.value||!I.value||N.value,class:`_cppay-btn _cppay-btn-primary`},(0,n.toDisplayString)(N.value?`处理中...`:`继续支付`),9,we)])])):M.value===`payment`&&L.value?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,Te,[(0,n.createElementVNode)(`div`,Ee,[(0,n.createElementVNode)(`div`,De,[R.value?((0,n.openBlock)(),(0,n.createElementBlock)(`img`,{key:0,src:R.value,alt:`QR Code`,style:{width:`160px`,height:`160px`,display:`block`}},null,8,l)):(0,n.createCommentVNode)(``,!0)])]),(0,n.createElementVNode)(`div`,u,[(0,n.createElementVNode)(`div`,d,[(0,n.createElementVNode)(`div`,f,(0,n.toDisplayString)(k.plain===`subscription`?`授权金额`:`支付金额`),1),(0,n.createElementVNode)(`div`,p,(0,n.toDisplayString)(L.value.paymentAmount)+` `+(0,n.toDisplayString)(I.value),1)]),(0,n.createElementVNode)(`div`,m,[(0,n.createElementVNode)(`div`,h,(0,n.toDisplayString)(k.plain===`subscription`?`授权合约地址`:`支付地址`),1),(0,n.createElementVNode)(`div`,g,[(0,n.createElementVNode)(`code`,null,(0,n.toDisplayString)(L.value.receiveAddress),1),(0,n.createElementVNode)(`button`,{onClick:Be,class:`_cppay-copy-btn`,title:`复制地址`},[...r[9]||=[(0,n.createElementVNode)(`svg`,{fill:`none`,stroke:`currentColor`,viewBox:`0 0 24 24`},[(0,n.createElementVNode)(`path`,{"stroke-linecap":`round`,"stroke-linejoin":`round`,"stroke-width":`2`,d:`M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z`})],-1)]])])]),k.plain===`subscription`?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,_,[...r[10]||=[(0,n.createElementVNode)(`div`,{class:`_cppay-info-label`,style:{color:`#856404`}},`📌 订阅说明`,-1),(0,n.createElementVNode)(`div`,{class:`_cppay-info-value`,style:{"font-size":`12px`,color:`#856404`}},` 订阅支付需要授权代币给合约地址,系统将按周期自动扣款。授权后无需每次手动支付。 `,-1)]])):(0,n.createCommentVNode)(``,!0)]),(0,n.createElementVNode)(`div`,v,[z.value?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,w,[(0,n.createElementVNode)(`button`,{onClick:Re,disabled:N.value,class:`_cppay-btn _cppay-btn-primary`},(0,n.toDisplayString)(N.value?D.plain===`subscription`?`授权中...`:`支付中...`:D.plain===`subscription`?`💳 钱包授权`:`💳 钱包支付`),9,T),(0,n.createElementVNode)(`div`,E,` 已连接: `+(0,n.toDisplayString)(z.value.slice(0,6))+`...`+(0,n.toDisplayString)(z.value.slice(-4)),1)])):((0,n.openBlock)(),(0,n.createElementBlock)(`div`,y,[(0,n.createElementVNode)(`button`,{onClick:r[0]||=()=>Z(`metamask`),disabled:B.value,class:`_cppay-btn _cppay-btn-secondary`,style:{display:`flex`,"align-items":`center`,"justify-content":`center`,gap:`0.5rem`,padding:`0.5rem 1rem`,"font-size":`14px`,flex:`1`}},[(0,n.createElementVNode)(`img`,{src:(0,n.unref)(e.n),alt:`MetaMask`,style:{width:`20px`,height:`20px`}},null,8,x),r[11]||=(0,n.createElementVNode)(`span`,null,`MetaMask`,-1)],8,b),(0,n.createElementVNode)(`button`,{onClick:r[1]||=()=>Z(`walletconnect`),disabled:B.value,class:`_cppay-btn _cppay-btn-secondary`,style:{display:`flex`,"align-items":`center`,"justify-content":`center`,gap:`0.5rem`,padding:`0.5rem 1rem`,"font-size":`14px`,flex:`1`}},[(0,n.createElementVNode)(`img`,{src:(0,n.unref)(e.t),alt:`WalletConnect`,style:{width:`20px`,height:`20px`}},null,8,C),r[12]||=(0,n.createElementVNode)(`span`,null,`WalletConnect`,-1)],8,S)]))]),(0,n.createElementVNode)(`div`,Oe,[(0,n.createElementVNode)(`button`,{onClick:Pe,disabled:N.value,class:`_cppay-btn _cppay-btn-primary`},(0,n.toDisplayString)(N.value?`检查中...`:`我已完成支付`),9,ke)]),(0,n.createElementVNode)(`div`,Ae,[(0,n.createElementVNode)(`button`,{onClick:r[2]||=e=>M.value=`select`,disabled:N.value,class:`_cppay-btn _cppay-btn-text`},` 更改支付方式 `,8,je)])])):(0,n.createCommentVNode)(``,!0)])])])):(0,n.createCommentVNode)(``,!0)]),_:1})]))}}),O=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},k=O(D,[[`__scopeId`,`data-v-1a5fedf2`]]),A=(0,n.ref)({apikey:``,open:!1,options:null});const j=e=>{A.value.options=e,A.value.open=!0};var M=()=>{A.value.open=!1},N=e=>{A.value.options?.onSuccess?.(e),A.value.open=!1},P=e=>{A.value.options?.onError?.(e)};const F={install(e,t){if(!t?.apikey)throw Error(`Cppay plugin requires an apikey`);A.value.apikey=t.apikey,e.config.globalProperties.$showPayment=j;let r=document.createElement(`div`);document.body.appendChild(r),(0,n.createApp)({setup(){return()=>A.value.options?(0,n.h)(k,{modelValue:A.value.open,"onUpdate:modelValue":e=>{A.value.open=e,e||M()},apikey:A.value.apikey,plain:A.value.options.plain,orderId:A.value.options.orderId,amount:A.value.options.amount,intervalDays:A.value.options.intervalDays,onSuccess:N,onError:P}):null}}).mount(r)}},I=()=>{if(!A.value.apikey)throw Error(`useCppayPayment must be used after installing CppayPlugin`);return{showPayment:j}};e.i(e.a),exports.CppayPlugin=F,exports.PaymentDialog=k,exports.showPayment=j,exports.useCppayPayment=I;