SplitPal: Devpost submission

Copy each part into the matching Devpost field.

Elevator pitch (under 180 characters)

Pay anywhere with PayPal and your budget files itself. AI asks only when unsure, covers overspends from a common pool, and splits bills so you budget only your share.

About the project (Markdown)

## Inspiration

We all pay with a tap now: a phone wallet at the checkout, a card, a PayPal button online. Budgeting hasn't caught up. Budget apps want you to file every purchase by hand, or they guess at categories a week later, when nobody remembers what "MKTPL*4417" was. Splitting apps are worse: a $60 dinner you split four ways still shows up as $60 of *your* spending.

We wanted budgeting to happen **at the moment you pay**, inside PayPal, where the money actually moves.

## What it does

SplitPal turns every PayPal purchase into a budgeting decision that mostly makes itself.

- **Files purchases as they happen.** Phone-wallet taps, card swipes and online payments reach SplitPal from PayPal. Each one lands in a bucket (Grocery, Transportation, Entertainment, Subscriptions, Self-care, Travel), and a live notification tells you: *"Phone wallet ยท $12.00 at City Parking Garage. From Transportation, $121.80 left."*
- **Asks only when it has to.** Gemini returns a bucket *and* whether it's confident. A marketplace that sells everything gets one tap: choose a bucket or the Common pool. Tick *Always use this bucket* and SplitPal never asks about that merchant again.
- **Catches overspending at checkout.** If Grocery has $35 left and you spend $50, it asks right away: take the $15 from your Common pool, go over budget, or use a different bucket.
- **Budgets your share, not the bill.** Split a purchase equally or by typing *"Ana had the lobster so she pays 40%"*, and your bucket counts only your part. If you'd covered an overspend from the Common pool, the part you no longer need flows back automatically.
- **Gets you paid back through PayPal.** A weekly report shows what each friend owes, with an AI recap. One click sends an itemized **PayPal invoice**, and debts settle with **PayPal Checkout** straight to a friend's PayPal account.

## How we built it

- **PayPal sandbox APIs**
  - **OAuth 2.0** client credentials.
  - **Transaction Search** pulls account activity. A background sync checks it every few minutes and sends each new expense through the purchase pipeline.
  - **Orders v2** plus the **JavaScript SDK** for settle-ups paid directly to a friend (`payee.email_address`).
  - **Invoicing v2** to create, send and track itemized payment requests.
- **Google Gemini** (`gemini-3.5-flash`) with JSON-schema **structured outputs** on every call:
  - `pickBucket` returns `{bucket_id, confident, category, reason}`. The `confident` flag *is* the "ask only when unsure" feature.
  - Categorizing imported transactions, parsing plain-English split instructions, and writing the weekly recap and payment-request messages.
- **Live updates** with server-sent events, so a purchase pops up on every open screen, including your phone.
- **Node.js + Express**, a plain HTML/CSS/JS frontend with no build step, a JSON-file store, and `node --test` unit tests.

**Design rule: the AI decides, code does the money.** Gemini only picks buckets and people. Every amount is integer cents, and splits use largest-remainder rounding so shares always add up exactly:

$$\sum_{i} \text{share}_i = \text{total}$$

A top-up from the Common pool only counts for what the bucket still needs:

$$\text{top-up}_{\text{effective}} = \min\big(\text{approved},\ \max(0,\ \text{spent} - \text{budgeted})\big)$$

## Challenges we ran into

- **Knowing when to ask.** Always asking is annoying; never asking files things wrong. A confidence field in the structured output, plus remembering answers per merchant, gave us both.
- **Messy merchant names.** `CORNER FRESH MKT #0421` and `Corner Fresh Mkt` have to be the same merchant, so names are normalized before SplitPal remembers them.
- **Budgets that change after the fact.** A purchase can be split days after you covered its overspend. Instead of storing a fixed transfer, SplitPal re-computes how much of each top-up is still needed, so the Common pool is always right.
- **Real time from a sandbox.** You can't tap a phone against the sandbox, so purchases from Transaction Search sync and from the in-app simulator go through the exact same pipeline.
- **AI limits.** Overload errors are retried with backoff, daily-limit errors fail fast, and without AI the app falls back to category and merchant-name matching.

## Accomplishments that we're proud of

- A purchase goes from tap to bucket to notification with **zero typing**.
- After one answer, SplitPal stops asking about that merchant.
- Splitting and budgeting finally agree: a $60 dinner for four costs your bucket $15.

## What we learned

The best AI feature here is the one that knows its limits. Making Gemini say *"I'm not sure"* in a typed field turned a guessing budget app into one people can trust.

## What's next for SplitPal

- Real-time card authorization events from PayPal instead of polling.
- Lock-screen push notifications for the "which bucket?" question.
- Shared group budgets for trips and households.
- Recurring splits for rent and utilities.
- Voice based split instructions to the AI

Built with (tags, max 25)

paypal, paypal-rest-api, paypal-transaction-search, paypal-orders-api, paypal-invoicing, paypal-javascript-sdk, oauth2, gemini, google-gemini-api, structured-outputs, node.js, express.js, javascript, html5, css3, server-sent-events, json, render

"Try it out" links

Source code: https://github.com/Muthuvisali/splitpal demo: https://splitpal-7xk6.onrender.com/

Image gallery

  1. 1-budget-filed.png: a phone-wallet tap filed automatically, with a live notification.
  2. 2-activity.png: PayPal activity tagged with buckets and categories.
  3. 3-split.png: Split the transaction with group of people
  4. 4-report.png: the spending report and per-friend payment requests.

Video

https://youtu.be/Z8Db5hLjeYI

Built With

Share this project:

Updates