Jose Gibson
← 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 constraRazorpay test-mode QR flow does not create real `qr_code.creWebhook verification had to be realistic even before a publiThe 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

  1. Created the pure-Python Phase 1 validation flow with FastAPI, Razorpay SDK, QR display, webhook server, and dispense gate.
  2. Added `devjourney.md` documenting decisions around QR API choice, webhook simulation, threading, and timeout behavior.
  3. Added live-mode support and Render staging webhook notes, then removed a billable Render blueprint to keep staging lightweight.
  4. Phase 1 validated: Razorpay QR flow and signed webhook simulation functional
  5. GoalPrepare hardware-ready architecture for deployment to physical vending machine controller