@directcryptopay/sdk 0.1.0 → 0.2.1
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 +202 -256
- package/dist/{add-KF4m4jFK.js → add-sji6scSD.js} +1 -1
- package/dist/{all-wallets-D6NAjQgX.js → all-wallets-B4H-890E.js} +1 -1
- package/dist/{app-store-D7TTn-EO.js → app-store-Z433s97G.js} +1 -1
- package/dist/{apple-DjX2E2hE.js → apple-b8Lxj7nb.js} +1 -1
- package/dist/{arrow-bottom-C0YrNJYB.js → arrow-bottom-M9oWWo_9.js} +1 -1
- package/dist/{arrow-bottom-circle-Dlxvx_XG.js → arrow-bottom-circle-N9c4CXY1.js} +1 -1
- package/dist/{arrow-left-x8_-lUyK.js → arrow-left-Dw8AKfwf.js} +1 -1
- package/dist/{arrow-right-BTZybj80.js → arrow-right-DwLQZSC_.js} +1 -1
- package/dist/{arrow-top-LzH7iLCp.js → arrow-top-zhUjkBe1.js} +1 -1
- package/dist/{bank-23jp-IV_.js → bank-CbQdnILK.js} +1 -1
- package/dist/{browser-EjoorDid.js → browser-xAqNwt7z.js} +1 -1
- package/dist/{card-DGgWwtwC.js → card-Dr1QBmWp.js} +1 -1
- package/dist/{ccip-BMANewTU.js → ccip-BIGqktC1.js} +6 -6
- package/dist/{checkmark-B1qcQhBo.js → checkmark-BhT1dTgG.js} +1 -1
- package/dist/{checkmark-bold-Cyc4IEEJ.js → checkmark-bold-CPB29wqQ.js} +1 -1
- package/dist/{chevron-bottom-ClHs08rB.js → chevron-bottom-BhNyx2II.js} +1 -1
- package/dist/{chevron-left-O8h_551_.js → chevron-left-CGuEjQlY.js} +1 -1
- package/dist/{chevron-right-DP3xpyIA.js → chevron-right-CvIRRsqZ.js} +1 -1
- package/dist/{chevron-top-CuwkBUs9.js → chevron-top-RSzCqjBd.js} +1 -1
- package/dist/{chrome-store-zfT_aJ3R.js → chrome-store-Cs8dAgs0.js} +1 -1
- package/dist/{clock-DHZqivIS.js → clock-fhZO5otC.js} +1 -1
- package/dist/{close-Cp9rNAw4.js → close-BPuztrdR.js} +1 -1
- package/dist/{coinPlaceholder-U7-T1KKQ.js → coinPlaceholder-C8X2i7Kh.js} +1 -1
- package/dist/{compass-Ds5-PRSR.js → compass-WMc5huk0.js} +1 -1
- package/dist/{copy-Jg4HdIMf.js → copy-DVAeT17y.js} +1 -1
- package/dist/core/api.d.ts +10 -1
- package/dist/core/wallet.d.ts +23 -2
- package/dist/{cursor-DmMevduB.js → cursor-BJ4YLXfy.js} +1 -1
- package/dist/{cursor-transparent-Dn9-1SV8.js → cursor-transparent-DN2fLQN4.js} +1 -1
- package/dist/dcp-sdk.umd.js +603 -603
- package/dist/dcp.d.ts +11 -1
- package/dist/{desktop-C4udXXlZ.js → desktop-6avxisBw.js} +1 -1
- package/dist/{disconnect-wd1BYLxt.js → disconnect-AReVI8Gk.js} +1 -1
- package/dist/{discord-DthxuCAP.js → discord-CxrI30BZ.js} +1 -1
- package/dist/{email-B3jSnUFE.js → email-B8dIIaay.js} +24 -24
- package/dist/{embedded-wallet-CJHmoBI2.js → embedded-wallet-C_5hF7rM.js} +24 -24
- package/dist/{etherscan-Cjp4xfMW.js → etherscan-BnAy8cIF.js} +1 -1
- package/dist/{exclamation-triangle-CRNR5WOy.js → exclamation-triangle-Bu7nHwx9.js} +1 -1
- package/dist/{extension-Cydk0mZt.js → extension-F0LIhvcf.js} +1 -1
- package/dist/{external-link-CuPTAoq9.js → external-link-CP6phyaM.js} +1 -1
- package/dist/{facebook-CghqXmdf.js → facebook-BtQ-Io2y.js} +1 -1
- package/dist/{farcaster-BREqMX4y.js → farcaster-BmaN1ugd.js} +1 -1
- package/dist/{filters-Dn_Ys7ew.js → filters-DpEwoOmy.js} +1 -1
- package/dist/{github-C-A7JmIY.js → github-q7qO9V-b.js} +1 -1
- package/dist/{google-CCdM_naE.js → google-DH_ZE8bW.js} +1 -1
- package/dist/{hashTypedData-D2Qmzscs.js → hashTypedData-ZH9ZnWu3.js} +6 -6
- package/dist/{help-circle-DIH4vyj3.js → help-circle-BAQVmKas.js} +1 -1
- package/dist/{id-DkJ0gBuy.js → id-Cj68Zwgo.js} +1 -1
- package/dist/{if-defined-BciplFKz.js → if-defined-CNte9B3N.js} +89 -89
- package/dist/{image-qMjyiXM0.js → image-BKJDw6N-.js} +1 -1
- package/dist/{index-BpXOsxzU.js → index-5mp7WkhV.js} +2 -2
- package/dist/{index-CX60z_g2.js → index-7toZMdtG.js} +32 -32
- package/dist/{index-CMPIqsB1.js → index-B1uKzdvN.js} +3 -3
- package/dist/{index-eW8y-mXH.js → index-BHFZVF-b.js} +3 -3
- package/dist/{index-DiHImG4L.js → index-BJ7cbG3N.js} +12400 -11573
- package/dist/{index-CqVegmN4.js → index-BKwa5JSA.js} +10 -10
- package/dist/{index-D-IzHD_8.js → index-BP4B9VUt.js} +2 -2
- package/dist/{index-DmOMXRG1.js → index-BVdzXHpO.js} +11 -11
- package/dist/{index-B2iDt0TJ.js → index-BYND0GJ9.js} +2 -2
- package/dist/{index-lbhz9evJ.js → index-BaJ0zEbh.js} +2 -2
- package/dist/{index-B7K86vWu.js → index-BdSIrl-R.js} +38 -38
- package/dist/{index-C4BX3QW8.js → index-Bh0MPFwP.js} +3 -3
- package/dist/{index-BBkcvSiY.js → index-Bsh7_qTp.js} +53 -53
- package/dist/{index-DoSYqTQg.js → index-BwnXTNNg.js} +3 -3
- package/dist/{index-Ij6XA6_4.js → index-C0kPDbg_.js} +2 -2
- package/dist/{index-fxzIDZsb.js → index-CKikVKe2.js} +2 -2
- package/dist/{index-SzyBYfzA.js → index-CPTcEPbD.js} +1582 -1881
- package/dist/{index-C27dwOyE.js → index-ChVh0Hkp.js} +3 -3
- package/dist/{index-CwB_qRfM.js → index-Cle_NnnS.js} +6 -6
- package/dist/{index-CUdQyyFn.js → index-CmWdvIFT.js} +2 -2
- package/dist/{index-1adX-Fit.js → index-D2AMA8Bu.js} +2 -2
- package/dist/{index-CTYngdl0.js → index-D5r0iSq4.js} +1 -1
- package/dist/index-D6h-qfpt.js +276 -0
- package/dist/{index-CppCc1n8.js → index-DAUM8CO4.js} +2 -2
- package/dist/{index-DtCsAVBg.js → index-DGjZW6uR.js} +2 -2
- package/dist/{index-CxOF7GqE.js → index-DQe94z7X.js} +3 -3
- package/dist/{index-AvC0IGDl.js → index-DTo6w99t.js} +101 -101
- package/dist/{index-B5zkXsLJ.js → index-DYdXjap2.js} +9 -9
- package/dist/{index-BdjxQs66.js → index-DceCxNV5.js} +5 -5
- package/dist/{index-Da8oZh8H.js → index-DobBVPe4.js} +14 -14
- package/dist/{index-DRNiFv9I.js → index-Dy4NyE6l.js} +7 -7
- package/dist/{index-Bijd4_Ns.js → index-Uw9cSw0q.js} +3 -3
- package/dist/{index-DpHXq5_E.js → index-f3LXSfM5.js} +6 -6
- package/dist/{index--3Zp0jAb.js → index-qiuyrukh.js} +2 -2
- package/dist/{index-CuiyMA8F.js → index-zddvaohA.js} +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{info-DMIGgjkL.js → info-RfPsmroW.js} +1 -1
- package/dist/{info-circle-CJuIKZSx.js → info-circle-DFKHB_ZN.js} +1 -1
- package/dist/{lightbulb-qFT6WEWV.js → lightbulb-B-Bykj9X.js} +1 -1
- package/dist/{localBatchGatewayRequest-CsMVMFBc.js → localBatchGatewayRequest-CjGcn5nM.js} +1 -1
- package/dist/{mail-DoYgQvOt.js → mail-mBAgGuw5.js} +1 -1
- package/dist/{mobile-URtsh7o-.js → mobile-Dhh3ndkf.js} +1 -1
- package/dist/{more-DoQd10TF.js → more-D1h7UTvg.js} +1 -1
- package/dist/{network-placeholder-BBA2Ue6C.js → network-placeholder-Dqynvc-t.js} +1 -1
- package/dist/{nftPlaceholder-C9RXWz9k.js → nftPlaceholder-Df7MW4MM.js} +1 -1
- package/dist/{off-YcuDQczT.js → off-BmG3cHTX.js} +1 -1
- package/dist/{onramp-BfqDIx4o.js → onramp-C401Aenb.js} +46 -46
- package/dist/{parseSignature-280HB24T.js → parseSignature-S8VEpRHC.js} +967 -1222
- package/dist/{play-store-sFaloG_r.js → play-store-4q1fzL_P.js} +1 -1
- package/dist/{plus-l0wekSht.js → plus-603Gs3yG.js} +1 -1
- package/dist/{qr-code-CihrUU4G.js → qr-code-Dgwhf6M1.js} +1 -1
- package/dist/{receive-dfY1Cu-g.js → receive-CYXbbEUR.js} +10 -10
- package/dist/{recycle-horizontal-nXu6YaPw.js → recycle-horizontal-Bu8zZ563.js} +1 -1
- package/dist/{ref-huAzXCX0.js → ref-DpmKRWBK.js} +2 -2
- package/dist/{refresh-D2ZbVeNC.js → refresh-BMZFu0mu.js} +1 -1
- package/dist/{reown-logo-BMaTMJmc.js → reown-logo-BXph7ThY.js} +1 -1
- package/dist/{search-YVM9q3J-.js → search-Cm_V42Y_.js} +1 -1
- package/dist/{secp256k1-DPQgTBwQ.js → secp256k1-C0iX1TUr.js} +19 -19
- package/dist/{secp256k1-BrysY3Sv.js → secp256k1-DOQBqE4Z.js} +1 -1
- package/dist/{send-BwQZPKxI.js → send-BSMYxDuP.js} +1 -1
- package/dist/{send-GyetMVu1.js → send-C8EeIzRB.js} +20 -20
- package/dist/{socials-B0W91J9k.js → socials-DQrHQajs.js} +15 -15
- package/dist/{swapHorizontal-Dy_oQEkp.js → swapHorizontal-98rnJewS.js} +1 -1
- package/dist/{swapHorizontalBold-C4JpaMpc.js → swapHorizontalBold-C299FjEt.js} +1 -1
- package/dist/{swapHorizontalMedium-D5NuVZFh.js → swapHorizontalMedium-Cqm6i4WJ.js} +1 -1
- package/dist/{swapHorizontalRoundedBold-Bq4P2MCj.js → swapHorizontalRoundedBold-De7hFfqZ.js} +1 -1
- package/dist/{swapVertical-CVQ8Mg03.js → swapVertical-DSL75l8L.js} +1 -1
- package/dist/{swaps-CA04SSdK.js → swaps-BuTNp65Y.js} +24 -24
- package/dist/{telegram-BP4SgW_L.js → telegram-cJP7hgUb.js} +1 -1
- package/dist/{three-dots-BJYGJ-dQ.js → three-dots-DHnEh28O.js} +1 -1
- package/dist/{transactions-Bq-98Tsg.js → transactions-DujFkB-M.js} +3 -3
- package/dist/{twitch-DTATWo9M.js → twitch-CR2iGcBo.js} +1 -1
- package/dist/{twitterIcon-D5UWPInb.js → twitterIcon-E5TAQjOn.js} +1 -1
- package/dist/types.d.ts +60 -0
- package/dist/ui/Modal.d.ts +3 -3
- package/dist/ui/index.d.ts +2 -2
- package/dist/{verify-Byvj8Wi1.js → verify-DEukUJp0.js} +1 -1
- package/dist/{verify-filled-B40taNm0.js → verify-filled-BXsx1i_p.js} +1 -1
- package/dist/{w3m-modal-HV6SE74G.js → w3m-modal-Bm7BqVng.js} +40 -40
- package/dist/{wallet-Cp-6Kk88.js → wallet-CzyyvdrT.js} +1 -1
- package/dist/{wallet-placeholder-C3juwA9o.js → wallet-placeholder-BrcmyGEe.js} +1 -1
- package/dist/{walletconnect-CRkIiLCx.js → walletconnect-BSYogWiE.js} +1 -1
- package/dist/{warning-circle-DtvCLwG4.js → warning-circle-Cgp2BW3m.js} +1 -1
- package/dist/{x-Cqyx5eCt.js → x-BJinLpTw.js} +1 -1
- package/package.json +1 -1
- package/dist/index-B2-vKLd8.js +0 -276
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @directcryptopay/sdk
|
|
2
2
|
|
|
3
|
-
Official
|
|
3
|
+
Official SDK for DirectCryptoPay — accept crypto payments directly to your wallet. Non-custodial, multi-chain, developer-first.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
- **Non-custodial** — Funds go directly from customer wallet to yours
|
|
8
|
+
- **Multi-chain** — Ethereum, Polygon, BNB Chain, Base, Arbitrum, Optimism (mainnet + testnet)
|
|
9
|
+
- **Shadow DOM isolation** — Payment modal won't interfere with your app's styles or state
|
|
10
|
+
- **WalletConnect support** — MetaMask, Rabby, WalletConnect, and 300+ wallets via Reown AppKit
|
|
11
|
+
- **Two payment modes** — Tool-based (pre-configured) or Integration-based (dynamic amounts)
|
|
12
|
+
- **TypeScript-first** — Full type safety with exported types
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
@@ -22,335 +23,280 @@ yarn add @directcryptopay/sdk
|
|
|
22
23
|
|
|
23
24
|
## Quick Start
|
|
24
25
|
|
|
25
|
-
###
|
|
26
|
+
### 1. Initialize the SDK
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
import { DirectCryptoPay } from '@directcryptopay/sdk';
|
|
29
|
-
|
|
30
|
-
const dcp = new DirectCryptoPay({
|
|
31
|
-
baseURL: 'https://test-api.directcryptopay.com',
|
|
32
|
-
apiKey: process.env.DCP_API_KEY!,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const intent = await dcp.createPaymentIntent({
|
|
36
|
-
amount: 49.99,
|
|
37
|
-
currency: 'USD',
|
|
38
|
-
metadata: {
|
|
39
|
-
order_id: 'ORD-123',
|
|
40
|
-
customer_email: 'customer@example.com'
|
|
41
|
-
},
|
|
42
|
-
idempotencyKey: crypto.randomUUID(), // Recommended
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
console.log(intent.id); // pi_abc123...
|
|
46
|
-
console.log(intent.recipient); // 0x1234...
|
|
47
|
-
console.log(intent.amount_wei); // "50000000000000000"
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Server-side: Verify Webhook
|
|
28
|
+
Call `DCP.init()` once when your app loads. You need a [Reown project ID](https://cloud.reown.com) (free) for WalletConnect support.
|
|
51
29
|
|
|
52
30
|
```typescript
|
|
53
|
-
import {
|
|
54
|
-
|
|
55
|
-
export async function POST(req: Request) {
|
|
56
|
-
const rawBody = await req.text();
|
|
57
|
-
const signature = req.headers.get('x-dcp-signature') ?? '';
|
|
58
|
-
|
|
59
|
-
const isValid = await verifyWebhookSignature({
|
|
60
|
-
rawBody,
|
|
61
|
-
signatureHeader: signature,
|
|
62
|
-
secret: process.env.DCP_WEBHOOK_SECRET!,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
if (!isValid) {
|
|
66
|
-
return new Response('Invalid signature', { status: 400 });
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const event = JSON.parse(rawBody);
|
|
70
|
-
|
|
71
|
-
if (event.event === 'payment.succeeded') {
|
|
72
|
-
// Handle payment success
|
|
73
|
-
console.log('Payment confirmed:', event.data.id);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return new Response('OK', { status: 200 });
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## API Reference
|
|
81
|
-
|
|
82
|
-
### `DirectCryptoPay`
|
|
83
|
-
|
|
84
|
-
Main SDK class for interacting with DirectCryptoPay API.
|
|
31
|
+
import { DCP } from '@directcryptopay/sdk';
|
|
85
32
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
const dcp = new DirectCryptoPay({
|
|
90
|
-
baseURL: string; // e.g., 'https://api.directcryptopay.com'
|
|
91
|
-
apiKey: string; // Your server-side API key
|
|
92
|
-
fetch?: typeof fetch; // Optional: custom fetch (for testing)
|
|
33
|
+
DCP.init({
|
|
34
|
+
projectId: 'your-reown-project-id', // Free at cloud.reown.com
|
|
93
35
|
});
|
|
94
36
|
```
|
|
95
37
|
|
|
96
|
-
|
|
38
|
+
### 2. Accept a payment
|
|
97
39
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
Create a new payment intent.
|
|
40
|
+
**Option A: Payment Tool** (pre-configured amount, token, and chain)
|
|
101
41
|
|
|
102
42
|
```typescript
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
43
|
+
DCP.pay({
|
|
44
|
+
toolId: 'your-tool-id', // From Dashboard > Payment Tools > Get Code
|
|
45
|
+
callbacks: {
|
|
46
|
+
onSuccess: (data) => {
|
|
47
|
+
console.log('Payment confirmed:', data);
|
|
48
|
+
},
|
|
49
|
+
onError: (error) => {
|
|
50
|
+
console.error('Payment failed:', error);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
109
53
|
});
|
|
110
54
|
```
|
|
111
55
|
|
|
112
|
-
**
|
|
113
|
-
|
|
114
|
-
##### `declareTx(input)`
|
|
115
|
-
|
|
116
|
-
Declare a blockchain transaction for a payment intent.
|
|
56
|
+
**Option B: Integration** (dynamic amount, token selector)
|
|
117
57
|
|
|
118
58
|
```typescript
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
59
|
+
DCP.Payment({
|
|
60
|
+
integrationId: 'your-integration-id',
|
|
61
|
+
amount_usd: '49.99',
|
|
62
|
+
callbacks: {
|
|
63
|
+
onSuccess: (data) => {
|
|
64
|
+
console.log('Paid:', data.txHash);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
123
67
|
});
|
|
124
68
|
```
|
|
125
69
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
##### `getIntentStatus(intentId)`
|
|
129
|
-
|
|
130
|
-
Get current status of a payment intent.
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
const intent = await dcp.getIntentStatus('pi_abc123');
|
|
134
|
-
console.log(intent.status); // 'created' | 'pending' | 'paid' | 'failed' | 'expired'
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Returns:** `Promise<Intent>`
|
|
70
|
+
## API Reference
|
|
138
71
|
|
|
139
|
-
|
|
72
|
+
### `DCP.init(config)`
|
|
140
73
|
|
|
141
|
-
|
|
74
|
+
Initialize the SDK. Must be called once before `pay()` or `Payment()`.
|
|
142
75
|
|
|
143
76
|
```typescript
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
77
|
+
DCP.init({
|
|
78
|
+
projectId: string; // Required — Reown/WalletConnect project ID
|
|
79
|
+
apiUrl?: string; // Default: 'https://api.directcryptopay.com'
|
|
80
|
+
defaultChainId?: number; // Default chain for wallet connection
|
|
81
|
+
gasWarningThreshold?: number; // Gas warning % threshold (default: 15)
|
|
82
|
+
env?: 'test' | 'prod'; // Environment hint
|
|
150
83
|
});
|
|
151
|
-
|
|
152
|
-
console.log('Payment confirmed:', confirmedIntent.tx_hash);
|
|
153
84
|
```
|
|
154
85
|
|
|
155
|
-
|
|
156
|
-
**Throws:** If payment fails, expires, or times out
|
|
157
|
-
|
|
158
|
-
##### `listPaymentIntents(options?)`
|
|
86
|
+
### `DCP.pay(options)`
|
|
159
87
|
|
|
160
|
-
|
|
88
|
+
Open the payment modal for a pre-configured Payment Tool. The tool defines the amount, accepted tokens, and target chain.
|
|
161
89
|
|
|
162
90
|
```typescript
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
91
|
+
DCP.pay({
|
|
92
|
+
toolId: string; // Required — Payment Tool ID
|
|
93
|
+
amountUsd?: number; // Override USD amount (for donations)
|
|
94
|
+
token?: string; // Pre-select token symbol
|
|
95
|
+
chainId?: number; // Pre-select chain
|
|
96
|
+
metadata?: Record<string, string>; // Custom metadata
|
|
97
|
+
callbacks?: PaymentCallbacks; // Event handlers
|
|
167
98
|
});
|
|
168
99
|
```
|
|
169
100
|
|
|
170
|
-
|
|
101
|
+
### `DCP.Payment(options)`
|
|
171
102
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
Verify HMAC-SHA256 webhook signature (timing-safe).
|
|
103
|
+
Open the payment modal for an Integration-based payment. Use this for dynamic amounts (carts, subscriptions, per-user pricing).
|
|
175
104
|
|
|
176
105
|
```typescript
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
106
|
+
DCP.Payment({
|
|
107
|
+
integrationId: string; // Required — Integration public ID
|
|
108
|
+
amount_usd?: string; // Amount in USD (e.g., '49.99')
|
|
109
|
+
amount?: string | number; // OR amount in token units (not both)
|
|
110
|
+
currency?: string; // Pre-select token (skips selector if set)
|
|
111
|
+
chainId?: number; // Pre-select chain
|
|
112
|
+
metadata?: Record<string, any>; // Custom metadata
|
|
113
|
+
callbacks?: PaymentCallbacks; // Event handlers
|
|
182
114
|
});
|
|
183
115
|
```
|
|
184
116
|
|
|
185
|
-
**
|
|
117
|
+
> **Note:** Provide either `amount_usd` or `amount`, not both.
|
|
186
118
|
|
|
187
|
-
|
|
119
|
+
### Callbacks
|
|
188
120
|
|
|
189
|
-
All
|
|
121
|
+
All callbacks are optional.
|
|
190
122
|
|
|
191
123
|
```typescript
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### `Intent`
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
interface Intent {
|
|
206
|
-
id: string;
|
|
207
|
-
chain_id: ChainId;
|
|
208
|
-
recipient: `0x${string}`;
|
|
209
|
-
amount_wei: string;
|
|
210
|
-
currency: string;
|
|
211
|
-
amount: number;
|
|
212
|
-
expires_at: string;
|
|
213
|
-
status: PaymentStatus;
|
|
214
|
-
signature: string;
|
|
215
|
-
asset_type: 'native' | 'erc20';
|
|
216
|
-
token_address?: `0x${string}`;
|
|
217
|
-
tx_hash?: `0x${string}`;
|
|
218
|
-
confirmed_at?: string;
|
|
124
|
+
interface PaymentCallbacks {
|
|
125
|
+
onOpen?: () => void; // Modal opened
|
|
126
|
+
onClose?: () => void; // Modal closed
|
|
127
|
+
onStatus?: (status: PaymentStatus) => void; // Status updates
|
|
128
|
+
onTxSubmitted?: (txHash: string) => void; // Transaction sent to chain
|
|
129
|
+
onSuccess?: (data: any) => void; // Payment confirmed
|
|
130
|
+
onCancel?: () => void; // User cancelled
|
|
131
|
+
onError?: (error: Error) => void; // Error occurred
|
|
219
132
|
}
|
|
220
133
|
```
|
|
221
134
|
|
|
222
|
-
###
|
|
135
|
+
### Payment Status
|
|
136
|
+
|
|
137
|
+
Real-time status updates via `onStatus`:
|
|
223
138
|
|
|
224
139
|
```typescript
|
|
225
|
-
type PaymentStatus =
|
|
140
|
+
type PaymentStatus =
|
|
141
|
+
| { type: 'fetching_tool_data' }
|
|
142
|
+
| { type: 'fetching_token_balances' }
|
|
143
|
+
| { type: 'awaiting_token_selection' }
|
|
144
|
+
| { type: 'creating_payment_intent' }
|
|
145
|
+
| { type: 'estimating_gas' }
|
|
146
|
+
| { type: 'gas_estimated'; estimate: GasEstimate }
|
|
147
|
+
| { type: 'awaiting_wallet_connection' }
|
|
148
|
+
| { type: 'wallet_connected'; address: string }
|
|
149
|
+
| { type: 'awaiting_signature' }
|
|
150
|
+
| { type: 'transaction_submitted'; txHash: string }
|
|
151
|
+
| { type: 'confirming'; txHash: string; confirmations: number }
|
|
152
|
+
| { type: 'verifying'; txHash: string; paymentId: string }
|
|
153
|
+
| { type: 'confirmed'; txHash: string; paymentId?: string }
|
|
154
|
+
| { type: 'failed'; error: Error }
|
|
155
|
+
| { type: 'rejected' }
|
|
156
|
+
| { type: 'cancelled' };
|
|
226
157
|
```
|
|
227
158
|
|
|
228
|
-
##
|
|
159
|
+
## Framework Examples
|
|
229
160
|
|
|
230
|
-
### Next.js
|
|
161
|
+
### Next.js (App Router)
|
|
231
162
|
|
|
232
|
-
|
|
233
|
-
// app/api/dcp/create-intent/route.ts
|
|
234
|
-
import { DirectCryptoPay } from '@directcryptopay/sdk';
|
|
163
|
+
**1. Create a provider:**
|
|
235
164
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
});
|
|
165
|
+
```tsx
|
|
166
|
+
// components/DCPProvider.tsx
|
|
167
|
+
'use client';
|
|
240
168
|
|
|
241
|
-
|
|
242
|
-
|
|
169
|
+
import { useEffect } from 'react';
|
|
170
|
+
import { DCP } from '@directcryptopay/sdk';
|
|
243
171
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
172
|
+
export function DCPProvider({ children }: { children: React.ReactNode }) {
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
DCP.init({
|
|
175
|
+
projectId: 'your-reown-project-id'
|
|
176
|
+
});
|
|
177
|
+
}, []);
|
|
249
178
|
|
|
250
|
-
return
|
|
179
|
+
return <>{children}</>;
|
|
251
180
|
}
|
|
252
181
|
```
|
|
253
182
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
// app/api/dcp/webhook/route.ts
|
|
258
|
-
import { verifyWebhookSignature } from '@directcryptopay/sdk';
|
|
183
|
+
**2. Wrap your layout:**
|
|
259
184
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
185
|
+
```tsx
|
|
186
|
+
// app/layout.tsx
|
|
187
|
+
import { DCPProvider } from '@/components/DCPProvider';
|
|
263
188
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const event = JSON.parse(rawBody);
|
|
275
|
-
|
|
276
|
-
switch (event.event) {
|
|
277
|
-
case 'payment.succeeded':
|
|
278
|
-
// Handle success
|
|
279
|
-
break;
|
|
280
|
-
case 'payment.failed':
|
|
281
|
-
// Handle failure
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
189
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
190
|
+
return (
|
|
191
|
+
<html lang="en">
|
|
192
|
+
<body>
|
|
193
|
+
<DCPProvider>{children}</DCPProvider>
|
|
194
|
+
</body>
|
|
195
|
+
</html>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
284
199
|
|
|
285
|
-
|
|
200
|
+
**3. Create a pay button:**
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
// components/PayButton.tsx
|
|
204
|
+
'use client';
|
|
205
|
+
|
|
206
|
+
import { useState } from 'react';
|
|
207
|
+
import { DCP } from '@directcryptopay/sdk';
|
|
208
|
+
|
|
209
|
+
export function PayButton({ toolId, label = 'Pay with Crypto' }: {
|
|
210
|
+
toolId: string;
|
|
211
|
+
label?: string;
|
|
212
|
+
}) {
|
|
213
|
+
const [status, setStatus] = useState<string | null>(null);
|
|
214
|
+
|
|
215
|
+
const handlePay = () => {
|
|
216
|
+
setStatus('pending');
|
|
217
|
+
DCP.pay({
|
|
218
|
+
toolId,
|
|
219
|
+
callbacks: {
|
|
220
|
+
onSuccess: (data) => {
|
|
221
|
+
setStatus('confirmed');
|
|
222
|
+
console.log('Payment confirmed:', data);
|
|
223
|
+
},
|
|
224
|
+
onError: (error) => {
|
|
225
|
+
setStatus('failed');
|
|
226
|
+
console.error('Payment failed:', error);
|
|
227
|
+
},
|
|
228
|
+
onClose: () => setStatus(null),
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<button onClick={handlePay} disabled={status === 'pending'}>
|
|
235
|
+
{status === 'confirmed' ? 'Payment Confirmed!' :
|
|
236
|
+
status === 'pending' ? 'Processing...' : label}
|
|
237
|
+
</button>
|
|
238
|
+
);
|
|
286
239
|
}
|
|
287
240
|
```
|
|
288
241
|
|
|
289
|
-
###
|
|
242
|
+
### Vanilla JavaScript
|
|
290
243
|
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const dcp = new DirectCryptoPay({
|
|
295
|
-
baseURL: 'https://api.directcryptopay.com',
|
|
296
|
-
apiKey: env.DCP_API_KEY,
|
|
297
|
-
});
|
|
244
|
+
```html
|
|
245
|
+
<script type="module">
|
|
246
|
+
import { DCP } from 'https://unpkg.com/@directcryptopay/sdk/dist/index.js';
|
|
298
247
|
|
|
299
|
-
|
|
300
|
-
amount: 99.99,
|
|
301
|
-
currency: 'USD',
|
|
302
|
-
});
|
|
248
|
+
DCP.init({ projectId: 'your-reown-project-id' });
|
|
303
249
|
|
|
304
|
-
|
|
305
|
-
|
|
250
|
+
document.getElementById('pay-btn').addEventListener('click', () => {
|
|
251
|
+
DCP.pay({
|
|
252
|
+
toolId: 'your-tool-id',
|
|
253
|
+
callbacks: {
|
|
254
|
+
onSuccess: (data) => alert('Payment confirmed!'),
|
|
255
|
+
onError: (error) => alert('Payment failed: ' + error.message),
|
|
256
|
+
}
|
|
306
257
|
});
|
|
307
|
-
}
|
|
308
|
-
|
|
258
|
+
});
|
|
259
|
+
</script>
|
|
309
260
|
```
|
|
310
261
|
|
|
311
|
-
##
|
|
262
|
+
## Supported Networks
|
|
312
263
|
|
|
313
|
-
|
|
264
|
+
| Network | Chain ID | Type |
|
|
265
|
+
|---------|----------|------|
|
|
266
|
+
| Ethereum | 1 | Mainnet |
|
|
267
|
+
| Polygon | 137 | Mainnet |
|
|
268
|
+
| BNB Chain | 56 | Mainnet |
|
|
269
|
+
| Base | 8453 | Mainnet |
|
|
270
|
+
| Arbitrum One | 42161 | Mainnet |
|
|
271
|
+
| Optimism | 10 | Mainnet |
|
|
272
|
+
| Sepolia | 11155111 | Testnet |
|
|
273
|
+
| Polygon Amoy | 80002 | Testnet |
|
|
274
|
+
| BNB Testnet | 97 | Testnet |
|
|
275
|
+
| Base Sepolia | 84532 | Testnet |
|
|
276
|
+
| Arbitrum Sepolia | 421614 | Testnet |
|
|
277
|
+
| Optimism Sepolia | 11155420 | Testnet |
|
|
314
278
|
|
|
315
|
-
|
|
316
|
-
2. **Use environment variables** for API keys and secrets
|
|
317
|
-
3. **Use HTTPS in production**
|
|
318
|
-
4. **Use idempotency keys** to prevent duplicate payments
|
|
319
|
-
5. **Validate payment amounts** server-side before fulfillment
|
|
279
|
+
## Security
|
|
320
280
|
|
|
321
|
-
|
|
281
|
+
The frontend callbacks (`onSuccess`, `onError`) are for **UX purposes only** — updating your UI when a payment completes. For production apps, always verify payments server-side using [webhooks](https://docs.directcryptopay.com).
|
|
322
282
|
|
|
323
|
-
|
|
324
|
-
2. **Never trust client-side payment amounts**
|
|
325
|
-
3. **Never skip signature verification** on webhooks
|
|
326
|
-
4. **Never hardcode secrets** in source code
|
|
283
|
+
DirectCryptoPay is non-custodial: transactions go directly from the customer's wallet to your wallet address. No funds are held by DirectCryptoPay at any point.
|
|
327
284
|
|
|
328
285
|
## Testing
|
|
329
286
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
- Node.js 16+ (with `globalThis.crypto`)
|
|
333
|
-
- Deno
|
|
334
|
-
- Cloudflare Workers
|
|
335
|
-
- Vercel Edge Functions
|
|
336
|
-
- Modern browsers
|
|
337
|
-
|
|
338
|
-
### Test Networks
|
|
339
|
-
|
|
340
|
-
- **Sepolia** (Ethereum) - chainId: 11155111
|
|
341
|
-
- **Polygon Amoy** - chainId: 80002
|
|
342
|
-
- **BSC Testnet** - chainId: 97
|
|
343
|
-
|
|
344
|
-
### Get Test Tokens
|
|
287
|
+
Both testnet and mainnet are available on every account from day one. Test with:
|
|
345
288
|
|
|
346
|
-
- Sepolia ETH
|
|
347
|
-
- Sepolia USDC
|
|
289
|
+
- **Sepolia ETH:** [sepoliafaucet.com](https://sepoliafaucet.com)
|
|
290
|
+
- **Sepolia USDC:** [faucet.circle.com](https://faucet.circle.com)
|
|
348
291
|
|
|
349
|
-
##
|
|
292
|
+
## Links
|
|
350
293
|
|
|
351
|
-
- **
|
|
352
|
-
- **
|
|
353
|
-
- **
|
|
294
|
+
- **Website:** [directcryptopay.com](https://directcryptopay.com)
|
|
295
|
+
- **Dashboard:** [directcryptopay.com/dashboard](https://directcryptopay.com/dashboard)
|
|
296
|
+
- **Documentation:** [docs.directcryptopay.com](https://docs.directcryptopay.com)
|
|
297
|
+
- **API Docs:** [api.directcryptopay.com/api/docs](https://api.directcryptopay.com/api/docs)
|
|
298
|
+
- **Discord:** [discord.com/invite/PPdJNkXh](https://discord.com/invite/PPdJNkXh)
|
|
299
|
+
- **GitHub:** [github.com/directcryptopay](https://github.com/directcryptopay)
|
|
354
300
|
|
|
355
301
|
## License
|
|
356
302
|
|