Inspiration
Splitting a group bill means a calculator, an argument about who had the wine, and weeks of “did you pay me yet?”. I wanted to turn that into one smooth flow where the money actually moves, not just a number on a screen.
What it does
SplitSnap turns a photo of a receipt into PayPal payment links for everyone at the table. Upload a receipt photo. Google Gemini reads the items, quantities, prices, tax and tip. Add the people at the table. Choose who pays for each item. Every item is split equally between everyone by default, or you can pick specific people. Selecting nobody means the item is not charged. SplitSnap calculates each person’s exact share, with tax and tip split in proportion to what they ordered. It creates one PayPal payment link per person. When someone pays, the app captures the payment and their row turns to “paid” live.
How I built it
PayPal: the Orders v2 API in the sandbox. POST /v2/checkout/orders creates one order per person for their exact share, and POST /v2/checkout/orders/{id}/capture settles it when the payer returns to the app. Idempotency keys prevent duplicate orders and captures. AI: the Google Gemini API (free tier, vision) reads the receipt photo and returns structured JSON, which the app validates. Exact maths: all amounts are integer cents, split with the largest-remainder method, so shares always add up to the bill. Stack: Node.js with no dependencies, a plain HTML and JavaScript front end, hosted on Render’s free tier. Unit tests cover the split maths.
Challenges
Making the shares add up exactly to the cent, including when tax and tip are split in proportion. Deciding what an item with nobody selected means. I ended up with three explicit states per item: Everyone, specific people, or nobody. Handling the PayPal approve-then-capture flow so the live status updates correctly.
Accomplishments
A working end-to-end flow from a receipt photo to real sandbox PayPal payments, with a hosted demo and open-source code.
What I learned
How the PayPal Orders API fits together (create, approve, capture), how to get reliable structured data out of a vision model, and why money should always be handled in integer cents.
What’s next
Real multi-currency support, a database so bills survive restarts, PayPal webhooks for more reliable payment confirmation, and sending the links by message directly.
Tools used (AI and PayPal)
Google Gemini API (vision): reads receipt photos into structured data. PayPal Orders v2 (sandbox): creates and captures one payment per person. Render: hosting.
Built With
- css
- google-gemini
- html
- javascript
- node.js
- paypal