2026
My Mom Marathon's Fundraiser
How I built my first payment-enabled website from scratch

Overview
My mom called me one day and told me she needed my help. She said she got a bib for the 2027 TCS London Marathon and told me the only way to do so was by donating a lump sum contribution to her charity of choice, Get Kids Going!, so there was no way to do proper fundraising through her charity's website. She needed my help creating a website for her marathon fundraising campaign, both to reimburse her for her initial contribution and to raise more funds beyond her initial goal. I told her I would take a stab at it, but in all honesty, I had never created a website that was able to support transactions within it.
Challenge
I had a strong idea of what I wanted the end product to look like: a very personalized user experience that walks through my mom's why for running the marathon and raising money for Get Kids Going! I also wanted to display her progress towards her goal and a wall of recent donations with optional messages. This was going to require a database setup as well as some kind of reputable payment integration, so I was going to be building the most full stack website I've built to date. I spent a good amount of time researching databases and payment integrations. The options I considered for payment were Stripe Checkout, PayPal, and Venmo. I ultimately chose Stripe Checkout for its ease of integration and robust webhook support. For databases, I considered Supabase, Firebase, and MongoDB. Supabase is the open-source standard for SQL with built-in authentication and storage with real-time sync capabilities, whereas Firebase is the industry standard when it comes to mobile apps. I ultimately landed on Supabase after learning about the pros and cons of each option.
Approach
The goal with the architecture design was to never attempt to store a user's sensitive credit card information, obviously. I used Vercel for my server, which I am seeing being used more and more due to the accessible nature of being able to build and deploy for free. When a user submits a donation, it hits a create-checkout-session route that writes a pending donation row and then hands them off to Stripe's own hosted Checkout page where they actually pay. Payment happens entirely within Stripe, and the donor gets redirected back to the website at the /thank-you page afterward. Stripe fires a signed webhook, which verifies the payment and updates the donation status from pending to completed. Supabase Postgres serves as the single source of truth holding all of the donor / donation information, with one row per payment attempt and a log of processed Stripe event ids. One thing I am proud of with the database design was the choices to store campaign information as a table, which provides the flexibility to extend this website to a fundraising page for multiple different marathons if my Mom continues to run them and raise money for various charities. I thought about making a charities table if I wanted to one day show how much money she has raised for each charity across different races. I ultimately opted not to do this because (1) I am not confident this site will be used for her other fundraising needs and (2) charities really only come with a few pieces of information: name and URL. The donations table and campaign_totals table are among the most important for rendering the "Recent Supporters" wall and progress bar, respectively. The images below show more detailed information about the architecture design and schema design that I used to build this website.


Impact
Honestly, this project sparked a lot of joy for me. It was incredibly rewarding to see my mom successfully raise funds for her charity through a platform I built from scratch. I spent about 8-10 hours working on it (while jet-lagged after my flight home from Europe), but I also spent $0 for the infrastructure powering this website, which far exceeded my expectations. I am most proud of testing each aspect of functionality rigorously such that it worked flawlessly as of the first deployment and real donation!

Previous
← Penciv