Skip to main content

splitkaro: split expenses & settle up with UPI

A bill splitter for friends, flatmates and trips: track shared expenses, see who owes whom, and settle up with the fewest payments and one-tap UPI links.

CI Python Dependencies License: MIT

Split karo is Hinglish for "split it". It is the phrase every group says at the end of a trip, right before the hisaab (the accounts) gets complicated.

Every trip, every shared flat and every office lunch ends with the same questions:

  • Who paid for what, and who still owes whom?
  • The hotel was ₹9,000, but a couple shared one room. How do we split that fairly?
  • Five people owe each other money. Do we really need ten transfers?
  • Somebody paid in dollars. What is that in rupees?

splitkaro answers all of them from your terminal. It keeps the group's records in one readable JSON file, does every calculation with exact decimal arithmetic so the totals always add up to the paisa, and works out the smallest set of payments that settles everyone, with UPI links you can open in GPay, PhonePe, Paytm or BHIM.

$ splitkaro balances
Asha             gets back ₹2,618.00
Ravi             owes ₹682.00
Meera            owes ₹1,936.00

$ splitkaro settle --upi
2 payment(s) settle everything:
  Meera pays Asha ₹1,936.00
    upi://pay?pa=asha%40okbank&pn=Asha&am=1936.00&cu=INR&tn=splitkaro%3A+Goa+trip
  Ravi pays Asha ₹682.00
    upi://pay?pa=asha%40okbank&pn=Asha&am=682.00&cu=INR&tn=splitkaro%3A+Goa+trip

Contents

Features

Four ways to split Equally, by exact amounts, by percentage, or by shares (a couple counts as 2).
Several payers "I paid ₹1,000 and you paid ₹500" for the same bill works naturally.
Fewest payments Suggests at most n − 1 transfers for n people, and pairs up exact matches first.
UPI links One upi://pay link per payment; the payer just confirms it in their app.
Exact to the paisa Decimal arithmetic and fair rounding: ₹100 split three ways is 33.34 + 33.33 + 33.33.
Foreign currency Record an expense in USD or EUR; it is converted with the rate you set.
Reports Spending by category and month, and who paid vs. who consumed.
Statements A running, line-by-line history of one person's balance.
CSV import/export Move data to and from spreadsheets. Imports are all-or-nothing.
Your data, your file Plain JSON you can read, back up, sync or put under git. No account, no server, no ads.
Zero dependencies Pure Python standard library, Python 3.9+.

Install

pip install splitkaro

Or straight from GitHub:

pip install git+https://github.com/K70281095/splitkaro.git

Check it works:

splitkaro --version

A full example: a Goa trip

Asha, Ravi and Meera go to Goa. Asha travels with her partner, so on the hotel she counts as two.

splitkaro init "Goa trip"
splitkaro member add Asha Ravi Meera
splitkaro member upi Asha asha@okbank          # so others can pay her with one tap

# Hotel: Asha paid, split by shares (Asha 2, Ravi 1, Meera 1)
splitkaro add "Hotel (2 nights)" 9000 --paid-by Asha --shares Asha=2,Ravi=1,Meera=1 --category stay

# Dinner: Ravi paid, split equally among everyone (the default)
splitkaro add "Dinner at the shack" 2400 --paid-by Ravi --category food

# Scooters: two people paid, and only they used them
splitkaro add "Scooter rental" 1500 --paid-by Asha=1000 --paid-by Meera=500 --among Asha,Meera --category travel

# Parasailing was paid in dollars
splitkaro rate USD 83.20
splitkaro add "Parasailing" 30 --currency USD --paid-by Meera --category fun

# Groceries: everyone took different things
splitkaro add "Groceries" 1260 --paid-by Ravi --exact Asha=500,Ravi=460,Meera=300 --category food

Where does everyone stand, and how do they square up?

$ splitkaro settle
2 payment(s) settle everything:
  Meera pays Asha ₹1,936.00
  Ravi pays Asha ₹682.00

Where did the money go?

$ splitkaro report
Goa trip: 5 expense(s), ₹16,656.00 in total

By category
  stay                  ₹9,000.00  54%
  food                  ₹3,660.00  22%
  fun                   ₹2,496.00  15%
  travel                ₹1,500.00  9%

By month
  2026-11              ₹16,656.00

  member                     paid          share
  Asha                 ₹10,000.00      ₹7,382.00
  Ravi                  ₹3,660.00      ₹4,342.00
  Meera                 ₹2,996.00      ₹4,932.00

Meera wants to see exactly how she ended up owing ₹1,936:

$ splitkaro statement meera
2026-11-01      -₹2,250.00      -₹2,250.00  #1 Hotel (2 nights)
2026-11-01        -₹800.00      -₹3,050.00  #2 Dinner at the shack
2026-11-02        -₹250.00      -₹3,300.00  #3 Scooter rental
2026-11-02       ₹1,664.00      -₹1,636.00  #4 Parasailing
2026-11-03        -₹300.00      -₹1,936.00  #5 Groceries

Meera owes ₹1,936.00

Once the money has moved, record it, and everyone is back to zero:

splitkaro pay Meera Asha 1936
splitkaro pay Ravi Asha 682
splitkaro settle      # Everyone is settled up. 🎉

The same trip is available as examples/goa-trip.csv, which you can load with splitkaro import examples/goa-trip.csv.

Ways to split

Option Example Meaning
(none) --paid-by Ravi Equally among all members.
--among --among Asha,Meera Equally among the listed members.
--exact --exact Asha=500,Ravi=460,Meera=300 Fixed amounts; must add up to the total.
--percent --percent Asha=50,Ravi=25,Meera=25 Percentages; must add up to 100.
--shares --shares Asha=2,Ravi=1,Meera=1 Proportional weights, e.g. couples, or nights stayed.

Whoever paid is given with --paid-by NAME, or --paid-by NAME=AMOUNT repeated when several people paid the same bill. Names are case-insensitive.

Command reference

Command What it does
splitkaro init NAME [--currency INR] Start a group (creates splitkaro.json).
splitkaro member add NAME... [--upi ID] Add members.
splitkaro member upi NAME ID Set a member's UPI ID.
splitkaro member list / remove NAME List members, or remove one who has no history.
splitkaro add DESC AMOUNT --paid-by ... Record an expense (--category, --date, --currency, --note).
splitkaro list [--month YYYY-MM] [--category C] [--member M] List expenses.
splitkaro delete ID Delete an expense.
splitkaro balances [--json] Who gets money back, who owes.
splitkaro settle [--upi] [--json] Fewest payments to settle everything.
splitkaro pay FROM TO AMOUNT Record a payment between members.
splitkaro statement NAME Running history of one member's balance.
splitkaro report [filters] [--json] Totals by category, month and member.
splitkaro rate CUR VALUE Exchange rate: 1 CUR = VALUE in the group currency.
splitkaro export FILE / import FILE CSV out and in (- for stdout/stdin).

Every command accepts --file PATH (or the SPLITKARO_FILE environment variable) to work with more than one group, for example splitkaro -f flat.json balances.

Errors are printed as splitkaro: <message> with exit code 1, and nothing is saved when a command fails.

Your data

A group lives in a single JSON file, splitkaro.json by default (shortened here):

{
  "version": 1,
  "name": "Goa trip",
  "currency": "INR",
  "members": [{ "name": "Asha", "upi": "asha@okbank" }, { "name": "Ravi", "upi": null }],
  "expenses": [
    {
      "id": 2,
      "date": "2026-11-01",
      "description": "Dinner at the shack",
      "amount": "2400.00",
      "paid_by": { "Ravi": "2400.00" },
      "split": { "kind": "equal", "among": ["Asha", "Ravi", "Meera"], "values": {} }
    }
  ]
}
  • Amounts are stored as strings, never floats, so nothing is ever rounded away.
  • Files are written atomically: a crash or a full disk cannot leave a half-written file.
  • There is no account, server or tracking. Share the file however your group likes.

The CSV format is documented in docs/csv-format.md.

Using splitkaro from Python

import datetime as dt
from decimal import Decimal

from splitkaro import Expense, Group, Split, balances, settle

group = Group("Flat 302")
for name in ("Asha", "Ravi", "Meera"):
    group.add_member(name)

group.add_expense(Expense(
    id=0, description="Electricity", amount=Decimal("3120"),
    paid_by={"Ravi": Decimal("3120")}, split=Split.equal(["Asha", "Ravi", "Meera"]),
    date=dt.date(2026, 11, 5), currency="INR", category="bills",
))

for t in settle(balances(group)):
    print(f"{t.sender} pays {t.receiver} {t.amount}")

How it works

  • Rounding: amounts are split with the largest-remainder method on whole paise, so the parts always add up to the exact total and nobody is ever short-changed by more than one paisa.
  • Balances: each member's balance is what they paid minus their share, plus payments made minus payments received. Balances always add up to exactly zero.
  • Settling: exact matches (someone owes exactly what someone else is owed) are paired first; the rest is settled greedily between the largest debtor and the largest creditor. This never needs more than n − 1 payments.

The details, with worked examples, are in docs/how-it-works.md.

Roadmap

  • Recurring expenses (rent, Wi-Fi, maid) added automatically each month
  • UPI QR codes in the terminal
  • Simplify across groups (one payment per pair of people for several trips)
  • Budgets per category with warnings
  • Hindi and other Indian language output
  • A small web or mobile front end on top of the same file format

Ideas and pull requests are welcome, see the issues.

Contributing

Bug reports, ideas, translations and code are all welcome. Please read CONTRIBUTING.md and the Code of Conduct. To report a security problem, see SECURITY.md.

License

MIT © 2026 Kanhaiya Kumar

UPI is a system of the National Payments Corporation of India. splitkaro only creates standard upi://pay links and never handles money, bank details or PINs.

Metadata

Release files for splitkaro 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for splitkaro 0.1.0
File Size Uploaded Provenance Actions
splitkaro-0.1.0.tar.gz 30.1 kB With provenance Details for splitkaro-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for splitkaro 0.1.0
File Interpreter ABI Platform Actions
splitkaro-0.1.0-py3-none-any.whl Python 3 none any Details for splitkaro-0.1.0-py3-none-any.whl

Total release size: 54.2 kB

Release files / splitkaro-0.1.0.tar.gz

Download URL splitkaro-0.1.0.tar.gz
Size 30.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e09806b3c1f78736c68d1b518adedf11c6baf2d58fea22134199dbff96e7beb6
BLAKE2b-256 checksum
How to use checksums
48224389efc34aa5f0f6911dd9c9606589209a832efd938ff2ff061d19f71b9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Release files / splitkaro-0.1.0-py3-none-any.whl

Download URL splitkaro-0.1.0-py3-none-any.whl
Size 24.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9e82d40a4beaec29039d75508c1d94a81e9d72f27311017bd9b8a8e4fcc7304c
BLAKE2b-256 checksum
How to use checksums
c4bff4132841e545c7c54157c02c8c6523de7df51ab84acdff47dec5c5c6b44d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Security for splitkaro 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for splitkaro-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page