Skip to content

Repository files navigation

SplitIt 💸

Scan a receipt, split it with friends, and pay — all from your phone.

SplitIt is a cross-platform mobile app that turns the awkward "who owes what" moment into a few taps. Snap a photo of a restaurant or bar receipt and an AI vision model extracts every line item; invite friends to a live splitting session; assign items to people; and settle up through real payment rails — including a SplitIt virtual card you can add to Apple Wallet.

Built with React Native (Expo) + a Node/Express backend on Google Cloud Run, with AI receipt parsing, real-time multiplayer sessions, biometric auth, and card issuing.


Table of contents


Features

  • 📷 AI receipt scanning — Point your camera at a receipt. An OpenAI vision model first verifies it is a receipt, then extracts the restaurant name, line items, quantities, prices, add-ons/modifiers, tax, subtotal, total, and currency as structured JSON.
  • 👥 Real-time split sessions — Host a split and have friends join live over WebSockets. Item assignments and totals update for everyone in real time.
  • 🧾 Item-level splitting — Assign individual dishes (and their add-ons) to specific people instead of just dividing the bill evenly.
  • 🔐 Phone + biometric onboarding — Sign up with phone-number OTP (Firebase Auth) and protect the app with Face ID / Touch ID.
  • 💳 Real payments & virtual cards — Stripe for payment methods and a Lithic-issued virtual card, with Apple Wallet provisioning so the card can be tapped to pay.
  • 🤝 Social layer — Friend requests, user search, groups, and invites.
  • 🔔 Notifications — Push notifications plus in-app notification banners.
  • 📜 History — Browse past transactions and re-open scanned receipts.
  • 📱 QR codes — Share or join a split quickly by scanning a QR code.

How it works

 ┌─────────────┐   photo    ┌──────────────┐   items+prices   ┌──────────────┐
 │  Camera /   │ ─────────▶ │  OpenAI      │ ───────────────▶ │  Split UI    │
 │  Receipt    │            │  vision OCR  │                  │  (assign to  │
 └─────────────┘            └──────────────┘                  │   friends)   │
                                                              └──────┬───────┘
                                                                     │ live sync
                                                              ┌──────▼───────┐
                                              Socket.IO  ◀───▶│  Express API │
                                                              │  on Cloud Run│
                                                              └──────┬───────┘
                                              Stripe / Lithic ◀──────┤
                                              MySQL (Cloud SQL) ◀────┤
                                              Firebase (Auth/DB/Storage)

Tech stack

Mobile app

Services & APIs

  • Firebase — phone-number Auth, Firestore, and Storage
  • OpenAI — vision model for receipt parsing
  • Stripe — payment methods & intents
  • Lithic — virtual card issuing + Apple Wallet provisioning
  • Socket.IO — real-time split sessions

Backend

Architecture

SplitIt is split into a client app and a stateless API server:

  • app/ — the Expo Router app. Screens are grouped into route segments ((onboarding), (tabs)) plus standalone flows (scan, checkout, wallet, etc.). React Context providers handle auth (AuthContext), notifications, and image preloading.
  • backend/ — Firebase client config and the receipt-analysis module shared by the app, plus backend/server/, the Express API that talks to MySQL, Stripe, and Lithic, and runs the Socket.IO server for live sessions.
  • components/ — reusable UI (gradient buttons, animated buttons, payment-method selector, virtual card, dynamic alerts, themed primitives).

Project structure

SplitIt/
├─ app/                       # Expo Router screens & navigation
│  ├─ (onboarding)/           # sign-up, OTP, password, address, Face ID
│  ├─ (tabs)/                 # home, friends, history
│  ├─ Authentication/         # AuthContext, secure payment hook, API config
│  ├─ Notifications/          # push + in-app notification providers
│  ├─ scan.tsx / selectitems.tsx / summary.tsx   # the splitting flow
│  ├─ walletmanager.tsx / addtowallet.tsx / checkout.tsx
│  └─ _layout.tsx             # root layout / providers
├─ backend/
│  ├─ FirebaseConfig.js       # Firebase web SDK init (config via env)
│  ├─ image.ts                # OpenAI receipt OCR + parsing
│  ├─ RealTimeSession.ts      # client-side socket session helpers
│  └─ server/                 # Express API (index.js), Stripe & Lithic services
├─ components/                # reusable UI components
├─ constants/ • hooks/ • types/
├─ assets/                    # icons & images
├─ .env.example               # frontend env template
└─ app.json                   # Expo app config

Getting started

Prerequisites

  • Node.js 18+ and npm
  • Expo CLI (npx expo)
  • iOS Simulator (Xcode) and/or Android Emulator, or the Expo Go / dev client on a device
  • Accounts/keys for Firebase, OpenAI, Stripe, and Lithic (for full functionality)

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env
# then fill in your own keys (see "Environment variables" below)

3. Run the app

npx expo start          # then press i (iOS) or a (Android)
# or
npm run ios
npm run android

This project uses native modules (camera, biometrics, Stripe), so a development build is recommended over Expo Go. See Expo dev clients.

Environment variables

Two .env files are used and both are git-ignored. Copy the matching .env.example and fill in your own values.

Frontend — .env (project root)

EXPO_PUBLIC_* variables are inlined into the client bundle, so they are not secret. Restrict the Google Maps key by app/bundle ID in the Google Cloud console.

Variable Purpose
EXPO_PUBLIC_GOOGLE_MAPS_API_KEY Google Places address autocomplete
EXPO_PUBLIC_OPENAI_API_KEY OpenAI receipt parsing (see limitations)
EXPO_PUBLIC_FIREBASE_* Firebase web config (API key, project, app id, …)

Backend — backend/server/.env

Variable Purpose
LITHIC_API_KEY, LITHIC_WEBHOOK_SECRET, LITHIC_APPLE_PARTNER_ID Card issuing & Apple Wallet
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET Stripe payments & webhooks
DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_SOCKET_PATH Cloud SQL (MySQL)
PORT API port

Backend

cd backend/server
cp .env.example .env     # fill in real values
npm install
npm start                # node index.js

The server exposes the REST API consumed by the app, runs the Socket.IO server for live splitting sessions, and handles Stripe and Lithic webhooks. It is deployed to Google Cloud Run; the app points at the deployed URL via app/Authentication/authIp.tsx.

Security notes

This repository is intentionally free of secrets:

  • All API keys and credentials are loaded from git-ignored .env files; only .env.example templates with placeholders are committed.
  • Firebase web config is included via env for cleanliness, though those values are designed to be public and are secured by Firebase Security Rules — not by being hidden.
  • Git history was reset to a clean baseline so no previously committed secret is recoverable from this repo.

If you fork this project, supply your own keys and never commit a real .env.

Known limitations & roadmap

  • OpenAI calls run client-side today. backend/image.ts executes on the device, which means an OpenAI key would ship in the app bundle. This should be proxied through the Express backend so the key never leaves the server. (Planned.)
  • Automated tests are not yet set up.
  • Receipt parsing accuracy depends on photo quality and receipt formatting.

Built by @Ramzi788. All rights reserved.

Releases

Packages

Contributors

Languages