← All Projects
Vending Machine QR LCD
Python vending-machine payment prototype that creates single-use Razorpay QR codes, waits for signed payment confirmation, and triggers dispense only after webhook verification.
Python 3.14FastAPI and UvicornRazorpay Python SDK`python-dotenv`, `requests``uv` for dependency management
⚡ Stripe was not a good fit because of regional/invite constra…⚡ Razorpay test-mode QR flow does not create real `qr_code.cre…⚡ Webhook verification had to be realistic even before a publi…⚡ The software needed to stay hardware-ready without requiring…
Outcomes
- ●End-to-end payment-state control flow was validated without hardware.
- ●Demo script can show QR creation, waiting state, signed confirmation, and dispense gating.
- ●The architecture is ready for LCD display replacement and motor-control integration.
Portfolio Highlights
- →Built a FastAPI/Razorpay QR payment workflow for a vending-machine prototype, including signed webhook verification and dispense gating.
- →Designed a realistic test-mode simulator for Razorpay QR payments to validate production webhook logic before live account approval.
- →Structured the backend so LCD and motor hardware can be integrated without rewriting payment orchestration.
Snapshot
- Period: April 2026
- Source: `/Users/jose/Developer/work/hyperdynx/vending-machine-QR-LCD`
- Domain: IoT payment workflow, vending-machine backend, QR payments
- Status: Phase 1 validated; ready for live-payment and hardware integration
Portfolio Summary
This project validates the payment and control-flow core of a QR-enabled vending machine before integrating LCD and motor hardware. The app lets a user select an item, creates a fixed-amount Razorpay QR code, displays the hosted QR URL, blocks dispense while waiting for confirmation, verifies webhook-style events, and closes stale QR codes on timeout. Since Razorpay test-mode QR codes do not emit practical live UPI credit events, the project includes a signed local simulation endpoint that exercises the same verification path used in production.
Stack
- Python 3.14
- FastAPI and Uvicorn
- Razorpay Python SDK
- `python-dotenv`, `requests`
- `uv` for dependency management
- Render staging docs and webhook exposure notes
What I Built
- `VendingMachine` flow: product selection, QR creation, wait-for-payment, dispense.
- Razorpay QR integration using single-use, fixed-amount QR codes.
- Webhook server with real signature verification.
- Local signed simulation endpoint for test-mode validation.
- Environment-based test/live mode with simulator disabled in live mode.
- QR timeout handling that closes stale Razorpay QR codes after 300 seconds.
- Client demo notes explaining the exact test-mode vs live-mode behavior.
Key Decisions
- Used Razorpay QR Code API rather than Payment Links because fixed amount, single-use QR codes match physical vending semantics.
- Used `threading.Event` instead of `asyncio.Event` because FastAPI runs in a separate event loop/thread while the vending-machine flow is synchronous.
- Built `/webhook/simulate/{qr_id}` as the primary Phase 1 test path, signing a Razorpay-shaped payload with HMAC-SHA256.
- Separated test and live modes so simulated dispense cannot occur in live mode.
Development Timeline
- Created the pure-Python Phase 1 validation flow with FastAPI, Razorpay SDK, QR display, webhook server, and dispense gate.
- Added `devjourney.md` documenting decisions around QR API choice, webhook simulation, threading, and timeout behavior.
- Added live-mode support and Render staging webhook notes, then removed a billable Render blueprint to keep staging lightweight.
- Phase 1 validated: Razorpay QR flow and signed webhook simulation functional
- GoalPrepare hardware-ready architecture for deployment to physical vending machine controller