|
| 1 | +# Solana Commerce Kit Store |
| 2 | + |
| 3 | +A Next.js e-commerce template demonstrating USDC payments on Solana using the Commerce Kit. |
| 4 | + |
| 5 | +## How It Works |
| 6 | + |
| 7 | +``` |
| 8 | +┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ |
| 9 | +│ Add items │ ──▶ │ Generate QR │ ──▶ │ Scan & Pay │ ──▶ │ Verified │ |
| 10 | +│ to cart │ │ with unique │ │ with any │ │ on-chain │ |
| 11 | +│ │ │ reference │ │ Solana │ │ │ |
| 12 | +└─────────────┘ └──────────────┘ │ wallet │ └──────────────┘ |
| 13 | + └─────────────┘ |
| 14 | +``` |
| 15 | + |
| 16 | +1. **Cart** - User adds products to their shopping cart |
| 17 | +2. **Checkout** - App generates a Solana Pay QR code with a unique reference address |
| 18 | +3. **Payment** - User scans the QR with any Solana wallet and sends USDC |
| 19 | +4. **Verification** - App polls the blockchain, finds the transaction by reference, and verifies the amount |
| 20 | + |
| 21 | +## Quick Start |
| 22 | + |
| 23 | +### 1. Install |
| 24 | + |
| 25 | +```bash |
| 26 | +pnpm install |
| 27 | +``` |
| 28 | + |
| 29 | +### 2. Configure |
| 30 | + |
| 31 | +Create `.env.local`: |
| 32 | + |
| 33 | +```bash |
| 34 | +# Required: Your Solana wallet address to receive payments |
| 35 | +NEXT_PUBLIC_MERCHANT_WALLET=<your-solana-wallet-address> |
| 36 | + |
| 37 | +# RPC endpoint (mainnet or devnet) |
| 38 | +NEXT_PUBLIC_RPC_URL=https://api.mainnet-beta.solana.com |
| 39 | + |
| 40 | +# Optional: USDC mint address (defaults to mainnet USDC) |
| 41 | +# Mainnet: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| 42 | +# Devnet: 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU |
| 43 | +# NEXT_PUBLIC_USDC_MINT=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| 44 | +``` |
| 45 | + |
| 46 | +### 3. Run |
| 47 | + |
| 48 | +```bash |
| 49 | +pnpm dev |
| 50 | +``` |
| 51 | + |
| 52 | +Open [http://localhost:3000](http://localhost:3000) |
| 53 | + |
| 54 | +## Solana Integration |
| 55 | + |
| 56 | +### Key Files |
| 57 | + |
| 58 | +| File | Purpose | |
| 59 | +| ------------------------------------------------------ | -------------------------------------------------------- | |
| 60 | +| `src/hooks/use-headless-checkout.ts` | Main payment hook - QR generation, polling, verification | |
| 61 | +| `src/components/checkout/headless-checkout-dialog.tsx` | Payment UI component | |
| 62 | +| `src/store/components/cart-drawer.tsx` | Cart with checkout integration | |
| 63 | + |
| 64 | +### Payment Flow (useHeadlessCheckout) |
| 65 | + |
| 66 | +```typescript |
| 67 | +// 1. Generate a unique reference keypair |
| 68 | +const referenceKeyPair = await generateKeyPair() |
| 69 | +const reference = await getAddressFromPublicKey(referenceKeyPair.publicKey) |
| 70 | + |
| 71 | +// 2. Create Solana Pay request with QR code |
| 72 | +const { url, qr } = await createSolanaPayRequest({ |
| 73 | + recipient: address(MERCHANT_WALLET), |
| 74 | + amount: BigInt(amountInMinorUnits), |
| 75 | + splToken: address(USDC_MINT), |
| 76 | + reference: reference, // This is how we track the payment |
| 77 | +}) |
| 78 | + |
| 79 | +// 3. Poll for transactions containing our reference |
| 80 | +const signatures = await rpc.getSignaturesForAddress(reference).send() |
| 81 | + |
| 82 | +// 4. Verify the payment on-chain |
| 83 | +const result = await verifyPayment(rpc, signature, expectedAmount, recipient, mint) |
| 84 | +``` |
| 85 | + |
| 86 | +### Dependencies |
| 87 | + |
| 88 | +| Package | Purpose | |
| 89 | +| --------------------------- | ---------------------------------------- | |
| 90 | +| `@solana-commerce/headless` | Payment requests, QR codes, verification | |
| 91 | +| `@solana/kit` | Key generation, address utilities | |
| 92 | +| `@solana/client` | RPC client for blockchain queries | |
| 93 | +| `@solana/react-hooks` | React hooks for Solana client | |
| 94 | + |
| 95 | +### Why These Packages? |
| 96 | + |
| 97 | +This template uses `@solana/kit` (the new Solana JavaScript SDK) instead of `@solana/web3.js`. Benefits: |
| 98 | + |
| 99 | +- **Smaller bundle** - Tree-shakeable, only import what you need |
| 100 | +- **Type-safe** - Better TypeScript support |
| 101 | +- **Modern** - Uses native BigInt, no polyfills needed |
| 102 | + |
| 103 | +## Project Structure |
| 104 | + |
| 105 | +``` |
| 106 | +src/ |
| 107 | +├── hooks/ |
| 108 | +│ ├── use-headless-checkout.ts # Payment flow hook |
| 109 | +│ └── use-purchase-history.ts # Transaction history |
| 110 | +├── components/ |
| 111 | +│ ├── checkout/ |
| 112 | +│ │ └── headless-checkout-dialog.tsx # Payment dialog |
| 113 | +│ └── wallet-ui.tsx # Wallet connect button |
| 114 | +├── store/ |
| 115 | +│ ├── components/ # Product grid, cart drawer |
| 116 | +│ ├── hooks/ # Cart, product selection |
| 117 | +│ └── providers/ # Cart context |
| 118 | +└── app/ |
| 119 | + └── page.tsx # Store home |
| 120 | +``` |
| 121 | + |
| 122 | +## Resources |
| 123 | + |
| 124 | +- [Solana Commerce Kit Docs](https://launch.solana.com/docs/commerce-kit) |
| 125 | +- [Solana Pay Specification](https://docs.solanapay.com) |
| 126 | +- [@solana/kit Documentation](https://github.com/solana-labs/solana-web3.js) |
| 127 | + |
| 128 | +## License |
| 129 | + |
| 130 | +Apache-2.0 |
0 commit comments