split

Inspiration

My inspiration for split came from repeatedly trying to divide grocery runs and restaurant bills with friends. Groceries can include personal items, shared staples, and different quantities. Restaurant bills add individual orders, shared appetizers, tax, tip, and discounts. When those two situations overlap, like buying groceries for a group meal and ordering a few extra dishes, the number of possible combinations gets messy very quickly.

Existing splitting apps can handle parts of this problem, but I found it tedious to ask everyone to download another app just to use one feature. Without an app, using a calculator means constantly switching between the receipt, percentages, and several running totals. For anything more complicated, I would end up opening Google Sheets and building a temporary spreadsheet for a task that should only take a few minutes.

That frustration shaped the core idea: make bill splitting browser-based, easy to access, and useful without requiring every participant to install an app or create an account. One organizer should be able to scan the receipt and assign the items, while everyone else opens a secure link and sees a private, itemized explanation of exactly what they owe. AI can remove the manual data-entry burden, but deterministic server-side code should remain responsible for the final money math.

The broader product vision is to connect each participant’s verified share directly to an e-transfer flow. That would reduce the risk of sending money to the wrong email address or selecting the wrong contact. The organizer could rotate a participant’s secure link when needed and send it through whatever contact method they already use with that person. The current MVP implements rotating private links and simulated payment states; direct e-transfer integration is a planned next step rather than a live payment feature today.

What it does

split turns a receipt image into a complete bill-splitting workflow:

  1. An organizer takes a photo or uploads a receipt.
  2. Gemini extracts the merchant, items, adjustments, tax, tip, and total into a strict schema.
  3. split flags uncertain or non-reconciling fields for human review instead of silently guessing.
  4. The organizer assigns items to one person, splits them equally, uses custom quantities or weights, or shares them across the whole group.
  5. The server calculates every participant’s exact total and exposes any one-cent rounding adjustment.
  6. The organizer publishes private, expiring guest links. Each participant sees only their own itemized share.
  7. Participants can ask questions, submit an item dispute, and simulate a pending, paid, or failed payment state. No real money moves and no banking credentials are collected.

The repository also includes a prepared North Market walkthrough, so judges can explore the complete product without configuring external services. A separate live path connects Auth0, MongoDB Atlas, Gemini, and Backboard for the full organizer workflow.

How we built it

split is a full-stack Next.js 16 application written in TypeScript and React 19, with the App Router providing both the interface and typed API routes. Tailwind CSS 4 and a project-specific design system create a responsive organizer flow, private guest views, and a public demo experience.

Receipt images are type-checked, size- and pixel-limited, normalized with Sharp, and stored privately in MongoDB GridFS. Gemini performs vision extraction with a JSON-schema-constrained response. Zod then validates the structure, and server-side semantic checks verify that the receipt actually reconciles. An exact known demo receipt has a clearly labeled deterministic fallback; an unknown failed receipt opens a blank manual-review path rather than inventing data.

All financial values are represented as integer cents. For a pool of cents (P), participant weights (w_i), and total weight (W = \sum_j w_j), split.ai begins with:

$$ q_i = \frac{|P|w_i}{W} $$

It assigns (\lfloor q_i \rfloor) cents first, then distributes the remaining cents to the largest fractional remainders using a stable participant order. The final invariant is:

$$ \sum_i a_i = P $$

BigInt intermediates prevent precision loss, and the same allocation method handles positive charges and negative discounts. The resulting calculation snapshot is canonicalized and hashed, which makes recalculation and stale-revision detection predictable.

MongoDB Atlas stores bills, participants, assignments, calculations, payment requests, disputes, rate limits, and append-only audit entries. Multi-document financial changes use transactions and optimistic revision checks. Auth0 protects organizer actions. Guest URLs contain random 32-byte credentials; only their hashes are stored, and exchanging a link creates a participant-scoped HttpOnly session.

Backboard powers four advisory workflows, Receipt Review, Split Verification, Payment Explanation, and Dispute Resolution. These agents receive minimized context and can explain or recommend, but they never change totals or authorize a payment. Each workflow has a deterministic local fallback, and provider-created ephemeral threads are deleted on a best-effort basis.

Challenges we ran into

Making AI useful without making it authoritative

Receipt photos are messy: text can be blurry, totals can be cropped, and line items can be ambiguous. The challenge was not merely extracting text; it was designing a boundary where AI accelerates review without becoming the source of financial truth. Strict schemas, confidence signals, reconciliation checks, and an explicit manual-review state keep the organizer in control.

Guaranteeing that every cent has an owner

Naive floating-point division eventually creates a missing or duplicated cent. Shared items, proportional tax and tip, signed discounts, and custom quantities make the edge cases multiply quickly. Integer arithmetic plus Hamilton’s largest-remainder method produced a deterministic result whose participant totals always equal the receipt total.

Preserving privacy through the whole workflow

An organizer needs the complete bill, but a guest should see only their own share. That required more than hiding UI elements: owner-scoped APIs, allow-listed guest response shapes, hashed and revocable tokens, expiring sessions, same-origin mutation checks, and rate limits all had to agree on the same boundary.

Correcting a bill after it has been shared

A dispute can change several participants’ totals at once. Silently editing an already published bill would leave old links pointing at stale amounts. split.ai handles the safe case transactionally: validate the dispute, reassign the item, recalculate the bill, supersede the previous payment requests, issue replacement links, and append an audit record.

Building a demo that stays judgeable

Live AI, identity, and database services make the product realistic, but they also make a hackathon demo fragile. The prepared public walkthrough mirrors the full flow with canonical data, while the live organizer path demonstrates the real integrations. That separation keeps the core experience available without pretending the sample path is a live transaction.

Accomplishments that we’re proud of

  • Every calculation is server-authoritative, exact to the cent, and accompanied by a visible rounding trace.
  • The same product supports individual, equal, custom-weight, quantity-based, and whole-group assignments.
  • Private participant links expose an itemized explanation without leaking the rest of the bill.
  • A dispute can drive a transactional reassignment, recalculation, link supersession, and audit trail.
  • Four AI-assisted workflows improve review and explanation while remaining advisory-only.
  • The zero-configuration walkthrough and the cloud-backed organizer flow coexist without blurring their boundaries.
  • The repository currently passes 70 unit tests across calculation, payment-state, dispute-policy, schema, adapter, and client-contract behavior, along with linting and TypeScript checks.

What we learned

The biggest lesson was that AI and deterministic software are strongest at different parts of the problem. AI is valuable at the fuzzy edge, reading a photo, identifying uncertainty, and explaining supplied information. Exact allocation, authorization, state transitions, and audit history belong in conventional, testable code.

We also learned that graceful degradation is part of product design, not just error handling. A fallback must be visible, bounded, and unable to manufacture unknown data. Similarly, privacy is clearest when it is reflected in data contracts and server queries rather than left to the interface.

Finally, “exact to the cent” is as much a communication challenge as a mathematical one. Showing the receipt rows, tax, tip, adjustments, and rounding trace makes a correct answer feel trustworthy.

What’s next for split

  • Deploy the live workflow with production monitoring, backups, and a deliberate receipt-retention policy.
  • Add email, SMS, or contact-sharing delivery for private links and payment reminders.
  • Expand dispute tools for shared items and receipt-level corrections while preserving organizer approval.
  • Add collaborative item claiming so participants can help assign a large receipt in real time.
  • Improve extraction evaluation across a wider range of merchants, layouts, lighting conditions, and supported currencies.
  • Add an opt-in e-transfer integration that carries the verified participant amount and intended recipient into the payment flow, while keeping final confirmation with the sender and adding safeguards against the wrong email address or contact.

Built With

Share this project:

Updates