Skip to content
Shahab Hassan
All projects

Practice digital bankingWeb Development · 2025

YouthPay

A practice digital bank for young people, with real banking flows and no real money.

The YouthPay marketing page beside a long transaction history, account balances and a Bitcoin wallet
01Overview

Overview

YouthPay is a digital bank that behaves exactly like a real one, except no real money moves through it. It was built for an international client as a learning tool for young people. They get accounts, balances, transfers and a crypto wallet, and use all of it the way an adult uses their banking app, with nothing at stake. Every screen, every step and every confirmation mirrors what a professional banking product does, so the habits carry straight over to the real thing.

Each user holds three balances: a checking account, a savings account and a Bitcoin wallet. They can move money four ways. They can send it to another person by email address or phone number, the way Zelle works. They can move it between their own checking and savings. They can send an external transfer to another bank, filling in the recipient's bank name, account details and address. And they can send Bitcoin to an outside wallet address.

Every one of those is a step by step flow that ends the same way: a code arrives by email, and nothing moves until it is typed in. That is deliberate on both sides. Learning to expect a confirmation step is one of the habits the product exists to teach, and it is also the right way to build it. Until that code comes back, the transfer sits on the user's record as a pending item rather than as a half applied balance change, so closing the tab halfway through never leaves money in the wrong place. Code resends are capped at three in five minutes.

The dashboard shows all three balances at a glance, recent activity with a different icon per kind of transaction, quick links to the main actions, and the people they have sent money to most recently. The Bitcoin balance is priced against a live feed that refreshes every ten minutes, and the price at the moment of each crypto transaction is stored alongside it, so the history stays accurate even as the market moves. A full transaction list covers every type, colour coded for money coming in and money going out, with a status on each one.

Nobody gets in on their own, which is what keeps it a controlled environment. A signup lands in a pending queue with the applicant's details, and an admin has to approve it before the account works. From the admin panel an operator can suspend an account, add transactions by hand including Bitcoin buys and sells at a chosen price, look through every transaction on the platform, and read a log of every login with its address, time and device.

The part that makes it a product rather than one organisation's app is the white label layer. From a settings page an operator sets the site name, support contact, social links, logo, transfer service logo, account icon styles and the legal pages, plus one primary colour. That colour is expanded into a full nine shade palette at runtime and written as browser level style variables, so saving the settings rebrands every screen at once, with no code change and no redeploy. Another school or organisation can be running their own branded version in minutes.

Underneath it is a Next.js app in TypeScript with MongoDB behind it, passwords hashed with bcrypt, and deliberately separate sign in mechanisms for users and admins so an admin session cannot be lifted out of browser storage. It ships as a Docker image and is self hosted on a private server behind NGINX with a security certificate, deployed through Dokploy, which leaves the client relying on no third party service. Around 20 pages, 21 routes and 7 data models in total.

02Features22

Features

  • A full digital bank that behaves like the real thing, with no real money involved
  • Three balances per user: a checking account, a savings account and a Bitcoin wallet
  • Send money to another person by email address or phone number
  • Move money between your own checking and savings accounts
  • Send an external transfer to another bank with full recipient details
  • Send Bitcoin to an outside wallet address at the live rate
  • Every transfer confirmed by a code emailed to the user before anything moves
  • Step by step transfer screens with a review of the details before you commit
  • Dashboard with all three balances, recent activity and frequent recipients
  • Full transaction history, colour coded for money in and money out
  • Bitcoin balance valued against a live price that refreshes every ten minutes
  • Account numbers, routing numbers and open dates shown on each account
  • Profile page for updating your details and changing your password
  • Password recovery by a code sent to your registered email
  • New signups wait in a queue until an admin approves them
  • Admins can suspend and reactivate any account at any time
  • Admins can add transactions by hand, including Bitcoin buys and sells
  • A log of every login with its address, time and device
  • Rebrand the whole platform from one settings page: name, logo, colours, legal pages
  • One chosen colour expands into a nine shade palette across every screen
  • Animated marketing landing page driven by the same settings
  • Self hosted with Docker behind NGINX with a security certificate
03Challenges & solutions7

Challenges and solutions

  1. 01
    Challenge

    The product had to feel like a real bank to be worth learning from, while never touching real money.

    Solution

    Built every flow to full banking standard, multi step transfers, emailed confirmation codes, pending states, statements and login audit logs, and kept balances as platform figures an admin controls. The experience is realistic while the risk is zero.

  2. 02
    Challenge

    A transfer that is half applied when someone closes the tab is a real money bug.

    Solution

    Staged every transfer as a pending object on the user record with its own verification code, and only moved balances once the emailed code came back. An abandoned transfer expires as data and never touches a balance.

  3. 03
    Challenge

    The client wanted to rebrand the whole platform without a developer.

    Solution

    Moved every branding value into a settings document and served it from an endpoint that every page reads on load. The primary colour is expanded into nine shades at runtime and written as CSS custom properties, so one save changes the entire look with no deploy.

  4. 04
    Challenge

    Anyone could sign up, and a learning environment for young people cannot work that way.

    Solution

    Split registration into a pending collection kept separate from real users. The applicant verifies their email, then waits, and only an explicit admin approval creates the actual account.

  5. 05
    Challenge

    Four different transfer types would have meant four nearly identical flows that slowly drift apart.

    Solution

    Built one step wizard pattern, select, enter the amount, review, verify by code, result, and reused it across all four transfer types, with only the middle step differing.

  6. 06
    Challenge

    Users and admins needed separate sessions that could not be confused with each other.

    Solution

    Kept them on different mechanisms. Users authenticate with a JWT the client sends as a bearer token, admins use an HTTP only cookie session, so an admin session cannot be lifted out of browser storage.

  7. 07
    Challenge

    Bitcoin balances are meaningless without a current price, but polling on every render would hammer the feed.

    Solution

    Fetched the price on a ten minute interval and recalculated the dollar value from the cached figure, and stored the price at the time of every crypto transaction so history stays accurate as the market moves.


04The product13 screens

YouthPay screens