cppay-sdk 0.0.2-beta.9 → 0.0.2

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 CHANGED
@@ -1,3 +1,631 @@
1
- # cppay-sdk
1
+ # CPPay SDK
2
2
 
3
- This is a payment sdk
3
+ CPPay SDK 是一个支持多链加密货币支付的前端 SDK,支持一次性支付和订阅支付。
4
+
5
+ ## 📦 安装
6
+
7
+ ```bash
8
+ npm install cppay-sdk
9
+ # 或
10
+ yarn add cppay-sdk
11
+ # 或
12
+ pnpm add cppay-sdk
13
+ ```
14
+
15
+ ## 🚀 快速开始
16
+
17
+ ### React 使用
18
+
19
+ #### 方式一:使用 Provider + Hook(推荐)
20
+
21
+ 这是最灵活的方式,适合需要在多个组件中调用支付功能的场景。
22
+
23
+ **1. 配置 Provider**
24
+
25
+ ```tsx
26
+ // App.tsx
27
+ import { CppayProvider } from "cppay-sdk/react";
28
+
29
+ function App() {
30
+ return (
31
+ <CppayProvider>
32
+ <YourApp />
33
+ </CppayProvider>
34
+ );
35
+ }
36
+ ```
37
+
38
+ **2. 使用 Hook 调用支付**
39
+
40
+ ```tsx
41
+ // PaymentButton.tsx
42
+ import { useCppayPayment } from "cppay-sdk/react";
43
+
44
+ function PaymentButton() {
45
+ const { showPayment, closePayment } = useCppayPayment();
46
+
47
+ const handlePay = () => {
48
+ showPayment({
49
+ apikey: "your-api-key",
50
+ plain: "instant", // instant | 'subscription'
51
+ orderId: "ORD-0000001",
52
+ amount: "100", // USD
53
+ onSuccess: (order) => {
54
+ console.log("支付成功", order);
55
+ },
56
+ onError: (error) => {
57
+ console.error("支付失败", error);
58
+ },
59
+ onExpired: (order) => {
60
+ console.log("支付已过期", order);
61
+ },
62
+ onFailed: (order) => {
63
+ console.log("支付失败", order);
64
+ },
65
+ });
66
+ };
67
+
68
+ return <button onClick={handlePay}>支付</button>;
69
+ }
70
+ ```
71
+
72
+ #### 方式二:使用 PaymentDialog 组件
73
+
74
+ 适合需要手动控制弹框显示隐藏的场景。
75
+
76
+ ```tsx
77
+ import { useState } from "react";
78
+ import { PaymentDialog } from "cppay-sdk/react";
79
+
80
+ function App() {
81
+ const [open, setOpen] = useState(false);
82
+
83
+ return (
84
+ <>
85
+ <button onClick={() => setOpen(true)}>支付</button>
86
+
87
+ <PaymentDialog
88
+ open={open}
89
+ onClose={() => setOpen(false)}
90
+ apikey="your-api-key"
91
+ plain="instant"
92
+ orderId="order-123"
93
+ amount="100"
94
+ onSuccess={(order) => {
95
+ console.log("支付成功", order);
96
+ setOpen(false);
97
+ }}
98
+ onError={(error) => {
99
+ console.error("支付失败", error);
100
+ }}
101
+ />
102
+ </>
103
+ );
104
+ }
105
+ ```
106
+
107
+ #### 方式三:使用 PaymentContent 组件
108
+
109
+ 适合需要自定义页面布局,不使用弹框的场景。
110
+
111
+ ```tsx
112
+ import { PaymentContent } from "cppay-sdk/react";
113
+
114
+ function PaymentPage() {
115
+ return (
116
+ <div className="payment-page">
117
+ <h1>支付页面</h1>
118
+ <PaymentContent
119
+ apikey="your-api-key"
120
+ plain="instant"
121
+ orderId="order-123"
122
+ amount="100"
123
+ onSuccess={(order) => {
124
+ console.log("支付成功", order);
125
+ }}
126
+ onError={(error) => {
127
+ console.error("支付失败", error);
128
+ }}
129
+ />
130
+ </div>
131
+ );
132
+ }
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Vue 使用
138
+
139
+ #### 方式一:使用 Plugin + Composable(推荐)
140
+
141
+ **1. 安装插件**
142
+
143
+ ```typescript
144
+ // main.ts
145
+ import { createApp } from "vue";
146
+ import App from "./App.vue";
147
+ import { CppayPlugin } from "cppay-sdk/vue";
148
+
149
+ const app = createApp(App);
150
+
151
+ app.use(CppayPlugin);
152
+
153
+ app.mount("#app");
154
+ ```
155
+
156
+ **2. 使用 Composable 调用支付**
157
+
158
+ ```vue
159
+ <script setup lang="ts">
160
+ import { useCppayPayment } from "cppay-sdk/vue";
161
+
162
+ const { showPayment, closePayment } = useCppayPayment();
163
+
164
+ const handlePay = () => {
165
+ showPayment({
166
+ apikey: "your-api-key",
167
+ plain: "instant",
168
+ orderId: "order-123",
169
+ amount: "100",
170
+ onSuccess: (order) => {
171
+ console.log("支付成功", order);
172
+ },
173
+ onError: (error) => {
174
+ console.error("支付失败", error);
175
+ },
176
+ });
177
+ };
178
+ </script>
179
+
180
+ <template>
181
+ <button @click="handlePay">支付</button>
182
+ </template>
183
+ ```
184
+
185
+ **3. 或使用全局方法**
186
+
187
+ ```vue
188
+ <script setup lang="ts">
189
+ import { getCurrentInstance } from "vue";
190
+
191
+ const instance = getCurrentInstance();
192
+
193
+ const handlePay = () => {
194
+ instance?.proxy?.$showPayment({
195
+ apikey: "your-api-key",
196
+ plain: "instant",
197
+ orderId: "order-123",
198
+ amount: "100",
199
+ onSuccess: (order) => {
200
+ console.log("支付成功", order);
201
+ },
202
+ });
203
+ };
204
+ </script>
205
+
206
+ <template>
207
+ <button @click="handlePay">支付</button>
208
+ </template>
209
+ ```
210
+
211
+ #### 方式二:使用 PaymentDialog 组件
212
+
213
+ ```vue
214
+ <script setup lang="ts">
215
+ import { ref } from "vue";
216
+ import { PaymentDialog } from "cppay-sdk/vue";
217
+
218
+ const dialogOpen = ref(false);
219
+
220
+ const handleSuccess = (order: any) => {
221
+ console.log("支付成功", order);
222
+ dialogOpen.value = false;
223
+ };
224
+ </script>
225
+
226
+ <template>
227
+ <button @click="dialogOpen = true">支付</button>
228
+
229
+ <PaymentDialog
230
+ v-model="dialogOpen"
231
+ apikey="your-api-key"
232
+ plain="instant"
233
+ order-id="order-123"
234
+ amount="100"
235
+ @success="handleSuccess"
236
+ @error="(error) => console.error(error)"
237
+ />
238
+ </template>
239
+ ```
240
+
241
+ #### 方式三:使用 PaymentContent 组件
242
+
243
+ ```vue
244
+ <script setup lang="ts">
245
+ import { PaymentContent } from "cppay-sdk/vue";
246
+
247
+ const handleSuccess = (order: any) => {
248
+ console.log("支付成功", order);
249
+ };
250
+ </script>
251
+
252
+ <template>
253
+ <div class="payment-page">
254
+ <h1>支付页面</h1>
255
+ <PaymentContent
256
+ apikey="your-api-key"
257
+ plain="instant"
258
+ order-id="order-123"
259
+ amount="100"
260
+ @success="handleSuccess"
261
+ @error="(error) => console.error(error)"
262
+ />
263
+ </div>
264
+ </template>
265
+ ```
266
+
267
+ ---
268
+
269
+ ## 🔧 直接使用 API(不使用组件)
270
+
271
+ 如果你不想使用我们提供的 UI 组件,可以直接调用底层 API 来实现自定义的支付流程。
272
+
273
+ ### 安装和初始化
274
+
275
+ ```typescript
276
+ import Cppay from "cppay-sdk";
277
+
278
+ // 使用 API Key 初始化
279
+ const cppay = new Cppay("your-api-key");
280
+ ```
281
+
282
+ ### 1. 获取支持的链和代币
283
+
284
+ ```typescript
285
+ const chains = await cppay.getSupportedChains();
286
+
287
+ console.log(chains);
288
+ // [
289
+ // {
290
+ // chain: 'Ethereum',
291
+ // chainId: 1,
292
+ // icon: 'https://...',
293
+ // tokens: [
294
+ // {
295
+ // symbol: 'USDT',
296
+ // decimals: 6,
297
+ // address: '0x...',
298
+ // icon: 'https://...',
299
+ // price: '1.00'
300
+ // },
301
+ // // ...
302
+ // ]
303
+ // },
304
+ // // ...
305
+ // ]
306
+ ```
307
+
308
+ ### 2. 创建一次性支付
309
+
310
+ ```typescript
311
+ const paymentInfo = await cppay.createOnetimePayment({
312
+ paymentChain: "Ethereum",
313
+ paymentToken: "USDT",
314
+ orderId: "order-123",
315
+ amount: "0.0001", // Token Amount
316
+ remark: "商品购买",
317
+ });
318
+
319
+ console.log(paymentInfo);
320
+ // {
321
+ // orderId: 'order-123',
322
+ // paymentId: 'pay-xxx',
323
+ // paymentAmount: '0.0001',
324
+ // paymentChain: 'Ethereum',
325
+ // paymentToken: 'USDT',
326
+ // receiveAddress: '0x...',
327
+ // expireAt: 1234567890
328
+ // }
329
+ ```
330
+
331
+ ### 3. 创建订阅支付
332
+
333
+ ```typescript
334
+ const subscriptionInfo = await cppay.createSubscriptionPayment({
335
+ paymentChain: "BSC",
336
+ paymentToken: "USDT",
337
+ orderId: "subscription-123",
338
+ amountOfUsd: "9.99",
339
+ intervalDays: 30,
340
+ });
341
+
342
+ console.log(subscriptionInfo);
343
+ // {
344
+ // orderId: 'subscription-123',
345
+ // subscriptionId: 'sub-xxx',
346
+ // approveAmount: '299.70',
347
+ // spenderAddress: '0x...',
348
+ // expireAt: 1234567890,
349
+ // paymentChain: 'BSC',
350
+ // paymentToken: 'USDT',
351
+ // amountOfUsd: '9.99',
352
+ // intervalDays: 30
353
+ // }
354
+ ```
355
+
356
+ ### 4. 查询支付状态
357
+
358
+ ```typescript
359
+ // 查询一次性支付状态
360
+ const status = await cppay.checkOnetimePaymentStatus({
361
+ paymentId: "pay-xxx",
362
+ });
363
+
364
+ console.log(status);
365
+ // {
366
+ // orderId: 'order-123',
367
+ // paymentId: 'pay-xxx',
368
+ // status: 'paid', // 'pending' | 'paid' | 'expired' | 'failed'
369
+ // chain: 'Ethereum',
370
+ // token: 'USDT',
371
+ // baseAmount: '100',
372
+ // payAmount: '100.00',
373
+ // receiveAddress: '0x...',
374
+ // expireAt: 1234567890
375
+ // }
376
+
377
+ // 查询订阅支付状态
378
+ const subscriptionStatus = await cppay.checkSubscriptionPaymentStatus({
379
+ subscriptionId: "sub-xxx",
380
+ });
381
+
382
+ console.log(subscriptionStatus);
383
+ // {
384
+ // orderId: 'subscription-123',
385
+ // subscriptionId: 'sub-xxx',
386
+ // status: 'approved', // 'pending' | 'approved' | 'expired' | 'failed'
387
+ // chain: 'BSC',
388
+ // token: 'USDT',
389
+ // approvedAddress: '0x...',
390
+ // txHash: '0x...',
391
+ // approveAmount: '299.70',
392
+ // amountOfUsd: '9.99',
393
+ // expireAt: 1234567890
394
+ // }
395
+ ```
396
+
397
+ ### 完整的自定义支付流程示例
398
+
399
+ ```typescript
400
+ import Cppay from "cppay-sdk";
401
+
402
+ const cppay = new Cppay("your-api-key", undefined);
403
+
404
+ async function customPaymentFlow() {
405
+ try {
406
+ // 1. 获取支持的链和代币
407
+ const chains = await cppay.getSupportedChains();
408
+ console.log("支持的链:", chains);
409
+
410
+ // 2. 用户选择链和代币
411
+ const selectedChain = "Ethereum";
412
+ const selectedToken = "USDT";
413
+
414
+ // 3. 创建支付
415
+ const paymentInfo = await cppay.createOnetimePayment({
416
+ paymentChain: selectedChain,
417
+ paymentToken: selectedToken,
418
+ orderId: `order-${Date.now()}`,
419
+ amount: "0.1",
420
+ // remark: "商品购买",
421
+ });
422
+
423
+ console.log("支付信息:", paymentInfo);
424
+ console.log("请向地址转账:", paymentInfo.receiveAddress);
425
+ console.log("金额:", paymentInfo.paymentAmount);
426
+
427
+ // 4. 轮询检查支付状态
428
+ const checkPayment = setInterval(async () => {
429
+ const status = await cppay.checkOnetimePaymentStatus({
430
+ paymentId: paymentInfo.paymentId,
431
+ });
432
+
433
+ console.log("支付状态:", status.status);
434
+
435
+ if (status.status === "paid") {
436
+ console.log("支付成功!");
437
+ clearInterval(checkPayment);
438
+ } else if (status.status === "expired" || status.status === "failed") {
439
+ console.log("支付失败或过期");
440
+ clearInterval(checkPayment);
441
+ }
442
+ }, 3000); // 每3秒检查一次
443
+ } catch (error) {
444
+ console.error("支付流程错误:", error);
445
+ }
446
+ }
447
+
448
+ customPaymentFlow();
449
+ ```
450
+
451
+ ---
452
+
453
+ ## 📖 API 参数说明
454
+
455
+ ### 通用参数
456
+
457
+ | 参数 | 类型 | 必填 | 说明 |
458
+ | -------------- | ----------------------------- | ---- | ------------------------------------------------------- |
459
+ | `apikey` | `string` | 是 | API 密钥. |
460
+ | `plain` | `'instant' \| 'subscription'` | 是 | 支付类型:`instant` 一次性支付,`subscription` 订阅支付 |
461
+ | `orderId` | `string` | 是 | 订单 ID(唯一标识) |
462
+ | `amount` | `string` | 是 | 支付金额(USD) |
463
+ | `intervalDays` | `number` | 否 | 订阅间隔天数(订阅支付时必填) |
464
+ | `remark` | `string` | 否 | 备注信息 |
465
+ | `locale` | `'en' \| 'zh-CN'` | 否 | 语言设置,默认 `'en'` |
466
+
467
+ ### 回调函数
468
+
469
+ | 回调 | 参数类型 | 说明 |
470
+ | ----------- | ----------------- | ------------ |
471
+ | `onSuccess` | `(order) => void` | 支付成功回调 |
472
+ | `onError` | `(error) => void` | 支付错误回调 |
473
+ | `onExpired` | `(order) => void` | 支付过期回调 |
474
+ | `onFailed` | `(order) => void` | 支付失败回调 |
475
+
476
+ ### PaymentDialog 特有参数(React)
477
+
478
+ | 参数 | 类型 | 必填 | 说明 |
479
+ | --------- | ------------ | ---- | ----------------- |
480
+ | `open` | `boolean` | 是 | 控制弹框显示/隐藏 |
481
+ | `onClose` | `() => void` | 是 | 关闭弹框回调 |
482
+
483
+ ### PaymentDialog 特有参数(Vue)
484
+
485
+ | 参数 | 类型 | 必填 | 说明 |
486
+ | ------------------------ | --------- | ---- | ----------------- |
487
+ | `v-model` / `modelValue` | `boolean` | 是 | 控制弹框显示/隐藏 |
488
+
489
+ ---
490
+
491
+ ## 🎨 自定义插槽(Slots)
492
+
493
+ 组件支持自定义插槽,可以替换默认的 UI 展示。
494
+
495
+ ### React 示例
496
+
497
+ ```tsx
498
+ <PaymentDialog
499
+ open={open}
500
+ onClose={() => setOpen(false)}
501
+ apikey="your-api-key"
502
+ plain="instant"
503
+ orderId="order-123"
504
+ amount="100"
505
+ Slots={{
506
+ Success: ({ paymentInfo }) => (
507
+ <div>
508
+ <h2>支付成功!</h2>
509
+ <p>订单号: {paymentInfo.orderId}</p>
510
+ </div>
511
+ ),
512
+ Error: ({ paymentInfo }) => (
513
+ <div>
514
+ <h2>支付出错</h2>
515
+ <p>请稍后重试</p>
516
+ </div>
517
+ ),
518
+ }}
519
+ />
520
+ ```
521
+
522
+ ### 可用插槽
523
+
524
+ - `ChooseTop`: 选择支付方式页面顶部内容
525
+ - `ChooseBottom`: 选择支付方式页面底部内容
526
+ - `Success`: 支付成功页面
527
+ - `Expired`: 支付过期页面
528
+ - `Failed`: 支付失败页面
529
+ - `Error`: 支付错误页面
530
+
531
+ ---
532
+
533
+ ## 🌍 支持的链和代币
534
+
535
+ SDK 支持多个主流区块链网络:
536
+
537
+ - **Ethereum**(以太坊)
538
+ - **BSC**(币安智能链)
539
+ - **Polygon**(马蹄链)
540
+ - **Tron**(波场)
541
+ - **Solana**(索拉纳)
542
+
543
+ 支持的代币:
544
+
545
+ - USDT
546
+ - USDC
547
+ - ETH
548
+ - BNB
549
+ - TRX
550
+ - SOL
551
+
552
+ 具体支持的链和代币可通过 `getSupportedChains()` API 动态获取。
553
+
554
+ ---
555
+
556
+ ## 📝 类型定义
557
+
558
+ ```typescript
559
+ // 支付类型
560
+ type PaymentPlain = "instant" | "subscription";
561
+
562
+ // 支付状态
563
+ type PaymentStatus = "pending" | "paid" | "expired" | "failed";
564
+
565
+ // 订阅支付状态
566
+ type SubscriptionPaymentStatus = "pending" | "approved" | "expired" | "failed";
567
+
568
+ // 一次性支付信息
569
+ interface OnetimePaymentInfo {
570
+ orderId: string;
571
+ paymentId: string;
572
+ paymentAmount: string;
573
+ paymentChain: string;
574
+ paymentToken: string;
575
+ receiveAddress: string;
576
+ expireAt: number;
577
+ }
578
+
579
+ // 订阅支付信息
580
+ interface SubscriptionPaymentInfo {
581
+ orderId: string;
582
+ subscriptionId: string;
583
+ approveAmount: string;
584
+ spenderAddress: string;
585
+ expireAt: number;
586
+ paymentChain: string;
587
+ paymentToken: string;
588
+ amountOfUsd: string;
589
+ intervalDays: number;
590
+ }
591
+
592
+ // 链信息
593
+ interface ChainInfo {
594
+ chain: string;
595
+ chainId: number;
596
+ icon?: string;
597
+ tokens: TokenInfo[];
598
+ }
599
+
600
+ // 代币信息
601
+ interface TokenInfo {
602
+ symbol: string;
603
+ decimals: number;
604
+ address: string;
605
+ icon?: string;
606
+ price: string;
607
+ }
608
+ ```
609
+
610
+ ---
611
+
612
+ ## ⚠️ 注意事项
613
+
614
+ 1. **API Key 安全性**:请勿在前端代码中直接暴露 API Key,建议使用环境变量或后端代理。
615
+ 2. **支付轮询**:使用组件时会自动轮询支付状态,直接使用 API 时需要自行实现轮询逻辑。
616
+ 3. **订阅支付**:订阅支付需要用户授权代币使用权限,首次支付会有两笔交易(授权 + 支付)。
617
+ 4. **过期时间**:支付订单有过期时间限制,请在 `expireAt` 之前完成支付。
618
+
619
+ ---
620
+
621
+ ## 🔗 相关链接
622
+
623
+ - [官方文档](https://docs.cppay.io)
624
+ - [API 参考](https://api.cppay.io/docs)
625
+ - [示例项目](https://github.com/cppay/examples)
626
+
627
+ ---
628
+
629
+ ## 📄 License
630
+
631
+ MIT License