Inspiration

Most of us carry three or four credit cards, and each has its own rules: 5% back on dining this quarter, 3x points on groceries, 0% APR until March. Nobody remembers all of that at the register, so we tap whatever card is on top and leave rewards on the table every week. Apple Wallet stores your cards, but it doesn't help you choose. We wanted a wallet that makes the choice for you before you tap.

What it does

Juno is one physical or virtual card that stands in for all of your real ones. When you make a purchase, Juno looks at the merchant and category, checks every linked card's reward rates, rotating categories, spending caps, and promo APR windows, then sends the charge to the card that earns you the most, in real time.

  • Smart routing: buy coffee, and Juno picks your 5% dining card over your 1% flat card automatically
  • APR-aware: big purchases can go to the card still inside a 0% intro window
  • Cap tracking: once you hit a quarterly category cap, Juno switches to the next best card
  • Transparent receipts: every transaction shows which card was used, why, and how much more you earned than you would have with your default card

How we built it

  • Frontend: a Next.js + Tailwind wallet app with a tap-to-pay demo flow, a linked-cards view, and a live transaction feed
  • Backend: a Python FastAPI service that runs the routing engine and stores users, cards, and transactions in PostgreSQL
  • Card data: a structured JSON library of reward rules for popular cards (category rates, rotating quarterly categories, caps, point values, and intro APR windows), mapped to merchant category codes (MCCs)
  • Payments layer: a Stripe Issuing virtual card in test mode. When a test purchase is made, Stripe's real-time authorization webhook hits our backend, Juno picks the best card, and then approves the authorization. For the live demo, we also built a simulator that fires authorization events for sample merchants like coffee shops, grocery stores, and gas stations.

The routing engine

For a transaction of amount $a$ in merchant category $c$, Juno scores each linked card $i$ by the dollar value it would return:

$$ V_i = p_i \Big[ \min(a, k_i)\, r_i(c) + \max(0,\, a - k_i)\, b_i \Big] - C_i(a) $$

where:

  • $r_i(c)$ is card $i$'s reward rate for category $c$ (including rotating categories)
  • $k_i$ is how much is left under that category's spending cap
  • $b_i$ is the base rate once the cap is used up
  • $p_i$ is the value of one point in dollars (e.g. $1.0$ for cashback, about $1.5$ for some travel points)
  • $C_i(a)$ is the expected interest cost, which is $0$ inside a 0% APR window

The charge goes to

$$ i^* = \arg\max_i \; V_i $$

and Juno shows the user the extra value $V_{i^*} - V_{\text{default}}$ they earned on that purchase.

Challenges we ran into

  • Reward rules are messy. Rotating quarterly categories, spending caps, and merchants coded under unexpected MCCs (a coffee shop inside a grocery store, for example) made it hard to turn card terms into clean rules.
  • Speed. Stripe's authorization webhook only gives you a couple of seconds to respond, so the routing engine had to be fast, with all card rules loaded in memory instead of fetched per request.
  • Valuing points fairly. Comparing 5% cashback with 3x travel points means picking a point value, and different users value points differently.
  • Testing payments without real money. Getting Stripe Issuing test mode, webhooks, and our local backend to talk to each other took a lot of debugging, which is why we built our own transaction simulator for the demo.

What we learned

  • How card authorization works behind the scenes, and where software can step in before a charge is approved
  • How merchant category codes (MCCs) determine which rewards you actually get
  • How to handle webhooks reliably under tight time limits
  • How to split work across frontend, backend, and data within a hackathon deadline

What's next for Juno

  • Learn each user's spending patterns to project yearly rewards and recommend the next card to get
  • Track signup bonus progress ("route here until you hit \$4,000")
  • Use Plaid to link real accounts and pull live balances and promo APR end dates automatically
  • Explore issuer or card-network partnerships so Juno works at every merchant, not just in the demo

Built With

Share this project:

Updates

Submission history