Inspiration

My friends and I go out together all the time: nights out, game nights, birthdays, and dinners. There's always someone who picks up the tab, and then comes the hard part: figuring out who had what, who owes how much, and who's already paid.

On a big night out it's never just one bill. It's dinner, then drinks, then dessert. By the end of the night nobody remembers who paid for what or who ordered which items. Someone ends up digging through receipts and group texts, doing the math, and chasing people for weeks to get their money back.

We built Split It Up to settle the bill the moment it's paid: snap the receipt, share a link, and everyone pays for exactly what they had, right there at the table. No spreadsheets, no reminders, no awkward "hey, you still owe me." Just friends, square before the night is over.

What it does

  1. Snap the receipt. The host takes a photo, and Google Gemini reads every line item, tax, and tip in seconds. It cleans up cryptic names ("CHKN SAND" → "Chicken Sandwich") and splits quantity lines like "2 × Huevos Rancheros $39" into separate items so two people can each claim one.
  2. Check and share. The host fixes anything the AI misread, picks a tip (15 / 18 / 20%), and gets a share link plus a QR code.
  3. Friends tap what they had. Each friend opens the link on their phone, enters their name, and taps their items, with no app or account needed. Shared something? Take ½, ⅓, or ¼ of it.
  4. Everyone pays their exact share: their items plus their proportional share of tax and tip, paid with PayPal or Venmo through PayPal Checkout.
  5. The host watches it fill up live. The host dashboard updates every few seconds: who's paid, what's left, and items greyed out once they're covered.

How we built it

  • PayPal Orders v2 REST API: the server creates an order for each friend's exact share, then captures it after they approve.
  • PayPal JavaScript SDK (Smart Buttons): the checkout on the bill page, with Venmo enabled alongside PayPal.
  • Google Gemini 3.5 Flash (@google/genai): reads the receipt photo and returns structured JSON with merchant, line items, tax, tip, and total. If the main model is busy, the server automatically retries with Gemini 3.5 Flash-Lite, so scanning keeps working during a demo.
  • Node.js + Express: API server and static hosting.
  • Plain HTML, CSS, and JavaScript: mobile-first, no framework, no build step. Photos are resized in the browser before upload.
  • AG Grid Community for the item tables and qrcode-generator for the share-link QR codes.
  • Render hosts the live demo.

Keeping the money correct. All money is integer cents on the server. The browser only sends your name and which items you picked, never a price or total, so editing the page can't change what you pay. Tax and tip are prorated by your share of the subtotal. Every item is divided into 12 "units", so ½ = 6, ⅓ = 4, and ¼ = 3 always add up exactly with whole numbers and no floating-point drift. A payment is recorded only after PayPal returns COMPLETED and the captured amount matches the share exactly.

Challenges we ran into

  • Reading real receipts. Receipts are abbreviated, crumpled, and inconsistent. We used JSON-only responses from Gemini, expanded abbreviations, split quantity lines, and gave the host a review step to fix anything the AI got wrong before sharing.
  • Splits that always add up. Mixing ½, ⅓, and ¼ shares with fractions led to rounding drift and items that looked "almost" fully claimed. Switching to 12 whole units per item made over-claiming impossible and the math exact.
  • Two people paying for the same item at once. A friend could be in the PayPal popup while someone else pays for the same item. We validate claims when the order is created and again right before capture. If the item was taken in the meantime, the friend is told and not charged.
  • Model availability. The AI model sometimes returned "busy" errors under load, so we added an automatic fallback to Flash-Lite.
  • Phone photos. Large images and iPhone HEIC files made uploads hang silently at first. We added in-browser resizing, a raw-file fallback, and clear on-screen errors.

Accomplishments that we're proud of

  • A complete, deployed flow in about a day: photo → AI-itemized bill → share link and QR → real sandbox PayPal payments → live host dashboard.
  • Payment logic we can stand behind: server-calculated shares, exact 12-unit splits, double validation, and amount-matched captures.
  • Friends need no download and no sign-up, just a link and the PayPal account they already have.
  • A live demo judges can try right now on their own phone.

What we learned

  • How PayPal Checkout works end to end: OAuth tokens, creating and capturing orders, and how one integration covers PayPal, Venmo, Pay Later, and cards.
  • How to get dependable structured data out of a vision model, and why AI output still needs a human review step and validation before money depends on it.
  • Payment fundamentals: keep secrets on the server, never trust amounts from the browser, use integer cents, and handle race conditions between create and capture.

What's next for Split It Up

  • Natural-language claiming: type "I had the latte and split the hashbrowns with Sam" and Gemini ticks the boxes for you.
  • Pay the host directly with PayPal's payee field, so money goes straight to whoever fronted the bill.
  • Whole-night tabs: group dinner, drinks, and dessert into one night out with a single settle-up per person.
  • Reminders for anyone who hasn't paid yet.
  • A real database so bills last forever.

Built With

Share this project:

Updates

Submission history