💡 Inspiration
We wanted to make crypto payments as simple as scanning a QR code. Existing Web3 checkouts are often slow or confusing — especially for small vendors who just want to receive a quick Solana payment without writing smart contracts or setting up complicated APIs. So we built PayLite, a lightweight Solana QR checkout that anyone can deploy, even on a Raspberry Pi or a free VPS.
⚙️ What it does
PayLite lets a merchant instantly generate a Solana QR code that customers can scan and pay using the Phantom Wallet app.
Phantom Sign-In → merchants connect and verify ownership of their wallet.
Generate Checkout → choose an amount, click “Generate QR,” and get a shareable QR.
Scan & Pay → customers scan with Phantom’s in-app QR scanner; the wallet pre-fills the recipient address.
Auto Confirm + Audio Alert → PayLite polls the Solana Devnet for incoming transactions and plays a “payment received” sound when funds land.
Everything happens client-to-wallet — no custodial servers, no private keys.
🧱 How we built it
Frontend
HTML + Bootstrap 5 for responsive UI
Vanilla JavaScript (ES6) for Phantom Wallet connection & message signing
bs58.js for base58 encoding
HTML5 Audio for success notification
Backend
Python 3 / Flask 3.0 web server
Flask-CORS for cross-origin wallet requests
PyNaCl to verify Phantom-signed login messages
qrcode + Pillow to generate checkout QRs
requests to call Solana RPC (getSignaturesForAddress, getTransaction, etc.)
python-dotenv for environment configuration (MERCHANT_PUBLIC_KEY, SOLANA_RPC)
Blockchain
Solana Devnet RPC endpoint (with optional Helius/Alchemy/QuickNode fallback)
Simple in-memory order tracking (ORDERS dict) and session store
Extras
Auto-polling every 3 seconds until payment confirmed
Fallback merchant address from .env if Phantom not signed in
Deployable via Vultr Docker or any simple Flask server
🚧 Challenges we ran into
RPC Timeouts: Devnet endpoints sometimes hang for 20 + seconds, delaying confirmation. We added shorter timeouts and retries.
Phantom Scanner: Some QR formats (with amount pre-filled) triggered “Send Error”. We fixed this by using a clean solana:
URI.Session Persistence: Keeping the Phantom login session active between routes required careful CORS and cookie handling.
Latency: Polling every 3 seconds while avoiding blocked threads took tuning of Flask’s request timeouts.
🏆 Accomplishments that we’re proud of
Built a fully working crypto checkout without any smart-contract code.
Integrated Sign-In With Solana securely using real signature verification.
Designed a clean, Bootstrap UI with real-time updates and success sound.
Debugged full stack (Flask ↔ Phantom ↔ Solana RPC) end-to-end in one weekend.
📚 What we learned
How Solana’s JSON-RPC works under the hood (getTransaction, getSignatureStatuses).
How Phantom Wallet handles message signing and QR URIs.
How to manage sessions and authentication without a traditional database.
How to make a lightweight blockchain dApp feel like a normal web checkout.
🚀 What's next for PayLite
Instant confirmations via webhooks or a Solana indexer (Helius, Shyft, SolanaFM).
Multi-token support (USDC-SPL, BONK, etc.).
Merchant dashboard to track sales history.
Mobile PWA version so sellers can generate checkouts directly on their phone.
Mainnet launch with on-chain analytics and NFT receipts.
Built With
- flask
- html
- javascript
- phantom-wallet
- python
- sol
- solana

Log in or sign up for Devpost to join the conversation.