Digitalise Agency

flask-online-shop

Flask Online Shop

A demo of an online shop: nine planet-themed products, sign-up, login, and checkout through Stripe, the payment service, in practice mode, so no real money moves. The point was building every piece a real store needs, including scrambling stored passwords. Two bugs turned up: a login that would have let anybody into anybody else's account once a second person registered, and a displayed price the checkout would not have charged.

Solo

Solo work by our founder, Salman Adnan.

Checkout Orbit: a shopper's path drawn as an orbit. Products circle past, the chosen ones drop into the cart, and the gold thread is the checkout that turns that cart into a paid order. Live and interactive: drag it to orbit, scroll or pinch to zoom. Open full screen
The real Flask Online Shop product grid.
Live local run, public storefront view.
9planets in the catalog
4flows verified end to end

Overview

A small e-commerce demo built with Flask: browse a nine-planet product catalog, create an account, log in, and pay through Stripe Checkout in test mode.

This is a self-contained exercise in wiring up the parts a real online store needs: session-based auth with hashed passwords, a SQLite-backed user table, and a hosted payment flow, without pulling in a framework that hides how any of it works.

Key features

  • Product cards (image, name, price, description, "Buy" button) rendered from a single planet catalog, nine in total, looped from one Jinja list instead of nine copy-pasted markup blocks.
  • A shared header/nav on every page that reflects the actual session state, plus a consistent dark/light color scheme across the storefront, auth pages, and result pages.
  • Login and registration pages styled as a single card with inline validation error messages for a wrong password, an unknown email, or mismatched passwords on signup.
  • Account creation and login with bcrypt-hashed passwords stored in SQLite.
  • Stripe Checkout session creation per purchase, with distinct success and cancel pages.
  • The displayed price for every planet is derived from the same dict sent to Stripe, so the two numbers can't drift apart.

Verification

The app installs cleanly in a fresh virtualenv and boots with the Flask dev server. GET / returns HTTP 200 and renders nine product cards. A full register-then-login-then-logout flow was driven end to end with a requests session against the running server, including the wrong-password and unregistered-email error paths. POST /create-checkout-session was hit directly and reaches Stripe's API, failing only on the missing key, which confirms the route is wired correctly up to the point a real key is required. A full Stripe payment end to end was not verified here since that needs a real test-mode secret key this environment doesn't have.

Tech stack

  • Python
  • Flask
  • Flask-SQLAlchemy
  • bcrypt
  • Stripe SDK
  • SQLite

A challenge worth noting

The original login check found the submitted email, then always compared the password against user id 1's hash regardless of who was logging in. With exactly one seeded user this happens to work; with a second account it lets any password through as long as it matches user 1's hash. Fixed by looking up the row for the submitted email and checking against that row's own hash. A separate bug hid in plain sight in the catalog itself: the template hardcoded Uranus at $69,420, but the dict actually sent to Stripe priced it at $42,069. Every other planet's hardcoded price happened to agree with its Stripe amount, so this only surfaced by cross-checking each one by hand; the fix derives the displayed price from the same dict the checkout session uses, so the two figures can't diverge again.

Book a call

Let's talk about what you're building.

Pick a slot below. No forms, no back-and-forth emails.