This guide will help you set up and deploy the complete PYUSD invoice generation and payment system.
- Frontend: React + TypeScript + Vite + TailwindCSS + RainbowKit
- Blockchain: Ethereum Sepolia testnet
- Smart Contract: Invoice Factory pattern with PYUSD integration
- Payment Flow: Direct peer-to-peer PYUSD transfers
- Node.js (v18 or higher)
- npm or yarn
- MetaMask or compatible Web3 wallet
- Sepolia ETH for gas fees
- PYUSD on Sepolia for testing payments
npm installEdit src/utils/constants.ts and update the contract addresses:
export const CONTRACTS = {
// Get PYUSD Sepolia address from official documentation
PYUSD: "0x[PYUSD_SEPOLIA_ADDRESS]",
// Deploy your InvoiceFactory contract and update this
INVOICE_FACTORY: "0x[YOUR_DEPLOYED_CONTRACT_ADDRESS]",
} as const;Edit src/main.tsx and replace the placeholder project ID:
const config = getDefaultConfig({
appName: "PYUSD Invoice System",
projectId: "YOUR_WALLETCONNECT_PROJECT_ID", // Get from https://cloud.walletconnect.com
chains: [sepolia, mainnet, polygon, optimism, arbitrum, base],
ssr: true,
});npm run devThe app will be available at http://localhost:5173
The contract is located at contracts/InvoiceManager.sol. Deploy it with the PYUSD Sepolia address as constructor parameter.
Constructor Parameters:
_pyusd: PYUSD token contract address on Sepolia
After deployment, verify your contract on Sepolia Etherscan for transparency.
Update the INVOICE_FACTORY address in src/utils/constants.ts with your deployed contract address.
- Check PayPal's official documentation for Sepolia PYUSD faucet
- Or bridge from mainnet if available
- Form validation with proper error handling
- On-chain storage via smart contract
- Automatic payment link generation
- QR code generation for mobile payments
- PYUSD balance validation
- Automatic approval flow handling
- Real-time transaction status updates
- Mobile-responsive payment interface
- User invoice history dashboard
- Payment status tracking
- Copy payment links functionality
- Filter by payment status
- Responsive design for all screen sizes
- QR code scanning for mobile wallets
- Touch-friendly interface
- Connect wallet with RainbowKit
- Fill out invoice form (org name, description, amount, due date)
- Submit transaction to create invoice on-chain
- Get shareable payment link and QR code
- Visit payment link (
/pay/:invoiceId) - View invoice details
- Connect wallet
- Approve PYUSD spending (if needed)
- Complete payment transaction
- Receive confirmation
- Visit history page (
/history) - View all created invoices
- Check payment status
- Copy payment links
- Filter by status
src/
βββ components/
β βββ InvoiceCreator.tsx # Invoice creation form
β βββ InvoiceHistory.tsx # Invoice management dashboard
β βββ PaymentPage.tsx # Payment processing interface
β βββ QRGenerator.tsx # QR code component
β βββ StatusBadge.tsx # Payment status indicators
βββ hooks/
β βββ useInvoiceContract.ts # Invoice contract interactions
β βββ usePYUSDContract.ts # PYUSD token interactions
β βββ useInvoiceData.ts # Data fetching and caching
βββ utils/
β βββ constants.ts # Contract addresses and ABIs
β βββ contractHelpers.ts # Contract utility functions
β βββ formatters.ts # Formatting utilities
βββ pages/
β βββ Home.tsx # Landing page with invoice creation
β βββ History.tsx # Invoice management page
β βββ PayPage.tsx # Payment processing page
βββ App.tsx # Main app with routing
- Wagmi: React hooks for Ethereum
- Viem: TypeScript Ethereum library
- RainbowKit: Wallet connection UI
- TanStack Query: Data fetching and caching
- React Router: Client-side routing
- QRCode: QR code generation
- TailwindCSS: Utility-first CSS framework
Create a .env.local file for any sensitive configuration:
VITE_WALLETCONNECT_PROJECT_ID=your_project_id_here
VITE_PYUSD_CONTRACT_ADDRESS=0x...
VITE_INVOICE_FACTORY_ADDRESS=0x...- Wallet connection works
- Invoice creation form validation
- Invoice creation transaction
- Payment link generation
- QR code generation
- Payment page loads correctly
- PYUSD balance checking
- Approval transaction flow
- Payment transaction flow
- Invoice history loading
- Status updates after payment
- Mobile responsiveness
- Happy Path: Create invoice β Share link β Pay invoice β Verify payment
- Insufficient Balance: Try to pay with insufficient PYUSD
- Expired Invoice: Try to pay an expired invoice
- Already Paid: Try to pay an already paid invoice
- Wrong Network: Try to use on wrong network
PYUSD uses 6 decimals, not 18 like ETH. Make sure all amount calculations use the correct decimals.
The contract is optimized for gas efficiency:
- Minimal storage usage
- Efficient data structures
- Direct transfers without holding funds
- Contract doesn't hold funds (direct peer-to-peer transfers)
- Input validation on both frontend and contract
- Proper error handling for all edge cases
The app is fully responsive and optimized for mobile:
- Touch-friendly buttons and forms
- QR code scanning support
- Mobile wallet integration
- Responsive table layouts
"Invoice not found"
- Check if the invoice ID is correct
- Verify the contract address is correct
- Ensure you're on the right network (Sepolia)
"Insufficient allowance"
- The approval transaction may have failed
- Try the approval step again
- Check PYUSD balance
"Transaction failed"
- Check gas settings
- Verify network connection
- Ensure sufficient ETH for gas
QR codes not generating
- Check browser console for errors
- Ensure the qrcode library is installed
- Verify the URL format is correct
- Check browser console for errors
- Verify network and contract addresses
- Test with small amounts first
- Check Sepolia Etherscan for transaction details
npm run buildThe built files in dist/ can be deployed to any static hosting service.
Set these in your hosting platform:
VITE_WALLETCONNECT_PROJECT_ID- Any other environment-specific variables
This project is built for ETHGlobal hackathon purposes. Please check individual dependencies for their licenses.