Inspiration

changaSmart was inspired by a problem we’ve experienced firsthand: managing a fundraiser means digging through countless M-PESA messages, figuring out who actually contributed, and manually updating contribution lists. We wanted to turn that tedious, error-prone work into a simple AI-assisted process that lets organizers focus on the people they are helping—not the paperwork.

What it does

changaSmart takes the manual work out of running a harambee, chama, or any group fundraiser. An organizer creates a project, adds the people expected to contribute, and from there the app does the cross-checking:

  • On-device M-PESA parsing. The app reads M-PESA confirmation SMS directly on the phone — no raw SMS content ever leaves the device, only the structured fields (amount, sender, code) that actually need reconciling.
  • Deterministic-first matching. A near-exact name match (even with formatting differences like "JANE M WANJIKU" vs "Jane Wanjiku") is confirmed instantly in plain code — no AI involved, no ambiguity.
  • AI only for genuinely hard cases. When someone pays on behalf of someone else, or the sender is unrecognized, an AI agent (backed by Amazon Bedrock) reasons about identity, never money — it can suggest who a payment should be credited to, but the actual arithmetic and the final call always stay with deterministic code and a human.
  • Real-time alerts. Instead of manually opening the app to check for new payments, changaSmart watches for a matching M-PESA SMS as it arrives — even while the app is closed — and notifies the organizer. If the evidence is strong enough (the name, the amount, and a mentioned group name all line up), it imports and reconciles the payment completely unattended, with a one-tap Undo if it ever gets it wrong.
  • Instant reports and WhatsApp updates. No more manually retyping "who's paid" into the group chat — one tap generates a clean, copy-paste-ready summary.

It's a live, working MVP today: the Android app is downloadable from GitHub, backed by a real, publicly deployed AWS backend — not a local demo.

How we built it

  • Backend: Python + FastAPI, deployed serverless on AWS (API Gateway → Lambda) via AWS SAM, with DynamoDB for persistence in the cloud and SQLite for local development.
  • Deterministic reconciliation core: name-similarity scoring, duplicate M-PESA code detection, and alias learning, all in plain, testable Python — this layer gets first refusal on every transaction, and the AI is only ever invoked for what it can't resolve.
  • AI layer: the Strands Agents SDK wired to Amazon Bedrock (Nova Micro), governed by an explicit system prompt with hard rules — never invent data, never touch amounts, never silently rename the sender, flag ambiguity instead of guessing — and forced into a validated, structured output schema instead of free text.
  • Mobile app: Flutter/Dart, with a from-scratch on-device M-PESA SMS parser, a background SMS listener with local notifications for real-time alerts, and a thin typed HTTP client talking to the backend.
  • Infrastructure as code: the entire AWS stack (Lambda, API Gateway, IAM policy scoped tightly to Bedrock's InvokeModel, DynamoDB tables) is defined in AWS SAM, so it's reproducible from a clean account.
  • Landing page: React, TypeScript, and Tailwind, fetching live data straight from the public backend (CORS enabled read-only) to show an actual real-time leaderboard of top-performing projects — not mocked screenshots.
  • Testing: 130+ automated backend tests that run fully offline and cost nothing, including a deterministic stand-in for the one function that would otherwise call Bedrock, so the AI-routing logic is still exercised on every run without needing live model access.

Challenges we ran into

  • Real SMS is messier than any spec. Lowercase sender names, partially masked phone numbers, inconsistent amount formatting — several parser bugs only ever surfaced through testing against real phone SMS inboxes, not synthetic examples.
  • Never let identity confusion touch the money. The hardest invariant to get right (and keep right) was making sure the actual M-PESA sender and the contributor a payment gets credited to never collapse into one field, all the way through AI reasoning, human review, and reversal.
  • Local vs. Lambda Python version mismatch broke sam build outright until we switched to a containerized build matching the Lambda runtime exactly.
  • Shipping a build that quietly pointed nowhere. An early test APK defaulted to an emulator-only loopback address instead of the real deployed backend — the first real-device test looked like a dead backend when it was actually just a misconfigured build.
  • Opening the backend up safely. The public landing page needed browser-side access to live data, which meant introducing CORS for the first time — deliberately scoped to read-only endpoints so it couldn't become a way to trigger writes from an arbitrary site.
  • Deciding how much autonomy to trust the app with. We explicitly rejected "alert on every SMS" as no smarter than the phone's own notifications, and only let the app act completely unattended when three independent signals agree — with a real Undo, since earning that trust incrementally mattered more than looking impressively automatic. ## Accomplishments that we're proud of

What we learned

Deploying early surfaces the boring-but-critical problems (runtime version mismatches, CORS, a misconfigured API URL) far sooner than polishing features locally ever would.

What's next for changaSmart

  • Authentication and per-project access control — today it's intentionally single-tenant with no login, fine for a hackathon MVP, not for real groups' money.
  • WhatsApp Business API integration, so contribution updates post automatically instead of being copy-pasted.
  • Per-group tuning of the real-time alert's confidence bar, so an organizer can decide how aggressive unattended auto-import should be for their own contributors.
  • Broader message-format coverage beyond M-PESA, if there's demand from other mobile money platforms.
  • iOS support — currently Android-only, since the real-time alert depends on Android's SMS permissions model.

Built With

Share this project:

Updates

Submission history