Online Shop - Flask + Bitcoin SV Micro-Store

An eCommerce app with BSV micropayments, secure downloads, and a Flask architecture

Posted by CM-WebDev on November 14, 2025

Project Overview

The goal was to go beyond the typical course demo and build something that looks and behaves like a realistic micro-store:

  • Product catalog for BSV-themed T-shirt designs (PNG/ZIP files).
  • Session-based shopping cart with quantity controls and removal.
  • Checkout flow that converts stable USD prices into live BSV amounts.
  • On-chain payment step with 2-hour order expiry and status tracking.
  • User accounts, order history, and download entitlements.
  • Basic admin area to review orders and manage products.

Core Technologies

  • Backend: Python 3.10, Flask, Flask-Login, Flask-Mail
  • Database: SQLite + SQLAlchemy ORM
  • Frontend: Jinja2 templates, Bootstrap 5 (dark mode)
  • Payments: Custom BSV PaymentProvider abstraction, WhatsOnChain API
  • Config: .env and Config class for secrets and environment settings

Technical Execution & Architecture

The app is structured as a proper Flask package with blueprints for auth, catalog, cart, checkout, and admin. This keeps routes and templates separated by feature and makes the project easier to extend.

Data is modelled with a small, focused set of SQLAlchemy models:

  • User – authentication, admin flag, relationships to orders and downloads.
  • Product – digital T-shirt metadata, USD pricing, file path.
  • Order / OrderItem – immutable snapshot of what was purchased.
  • Payment – BSV address, amount, TXID, status, timestamps.
  • DownloadEntitlement – one record per purchased product, with secure token and expiry.

This separation lets the store support things like multiple payments per order, per-item downloads, and a future migration to a different payment rail without rewriting the rest of the app.

BSV Payment Flow & Provider Abstraction

Instead of wiring the app directly to a single wallet or custodial gateway, I implemented a dedicated PaymentProvider layer:

  • OnChainPaymentProvider takes an Order, fetches a real BSV/USD rate, and returns a fixed BSV amount.
  • Each payment uses a configured BSV receiving address and stores the amount, status, and timestamps.
  • Payments expire automatically after two hours if they are not confirmed.
  • TX verification is done against the WhatsOnChain API, checking address and amount before marking a payment as paid.

Because everything talks to the provider interface, the app is ready for future implementations (for example a BRC-100 wallet service or a dedicated HandCash/Babbage integration) without touching the cart, order, or delivery logic.

Secure Digital Delivery

Once a payment is confirmed, the app:

  1. Creates DownloadEntitlement records for each purchased product.
  2. Generates a cryptographically random download token per entitlement.
  3. Sends the user an email with a secure, tokenised download link.
  4. Serves the actual file from an internal app/downloads directory via Flask, not a public URL.

Download links are tied to the authenticated user, can expire, and track download count, which is a pattern easily reused for other digital products.

Key Features & Technical Highlights

  • Clean, blueprint-based Flask structure suitable for a real portfolio project.
  • Session cart with adjustable quantities and automatic totals in USD and BSV.
  • Two-hour payment window with visible expiry status on the payment page.
  • Admin views for orders and products, gated behind an is_admin flag.
  • Environment-driven configuration (SECRET_KEY, DB URI, BSV address, API keys, mail settings).
  • Separation between business logic (orders, entitlements) and infrastructure (payment provider, mailer, explorer API).

Demonstrated Skill Set

From an engineering perspective, this project shows experience with:

  • Designing and implementing a small, coherent web application architecture.
  • Working with authentication, authorization, and user roles in Flask.
  • Integrating a blockchain payment flow in a way that stays wallet-agnostic and future-proof.
  • Designing database models that capture real business concepts (orders, payments, entitlements) rather than just “tables for the UI”.
  • Balancing course constraints with professional best practices suitable for production-style work.

Overall, this micro-store is a compact example of how I approach payment-enabled web applications: focus on clear boundaries, stable abstractions, and a path to evolve the stack as the product grows.