CASE STUDY · PRODUCT · 2026
CardWise — swipe the right card.
A personalized credit-card recommendation surface that ranks your wallet by estimated dollars back for a purchase — category, fees, caps, and valuation stance. Built as a free demo wallet on Next.js. Educational estimates, not financial advice.
Overview
People leave money on the table when the “right card” depends on issuer rules, rotating categories, portal-only rates, foreign-transaction fees, and how you value points. CardWise turns that into one screen: pick a category and amount, see a ranked wallet with explainable dollars-back estimates.
- Problem. Rewards math is messy across issuers and valuation assumptions.
- Approach. Deterministic ranking over a maintained card catalog + user inputs — not ML, not “guaranteed savings.”
- Constraint. Demo wallet first so value is obvious before account friction.
Guided journey
Four steps from intent to an explainable pick.
Choose a spend category (dining, groceries, travel, …). Matching uses each card’s reward rules, with catch-all / 1× fallbacks.
Enter the purchase amount. Caps split elevated-rate spend onto the base rate — the same way issuers actually pay out.
Pick a valuation stance (cashback / balanced / aspirational) or override cents-per-point. Points become comparable dollars.
Every card in the wallet is scored and sorted by estimated dollars back, with a plain-language reason string on each row.
Explainable sample recommendation
Labeled demo inputs — not live bank data.
Top pick estimated
Chase Freedom Unlimited (illustrative)
3× dining = about $3.00 back · valuation stance applied
Figures are educational estimates from catalog rules and assumed cents-per-point. Not financial advice. Actual issuer terms and redemptions vary.
Methodology
Core logic lives in recommend.ts: for each card, resolve the best rule for the
category (respecting portal-only / direct travel mode), compute points with remaining
elevated-rate caps, convert via cents-per-point, then subtract foreign-transaction fees
when applicable. Results sort by estimated dollar value, then lower annual fee as a tie-break.
- Apply rotating categories for the current period.
bestRuleForCategory— elevated rule, else catch-all, else 1×.pointsEarned— split spend above remaining cap onto base multiplier.- Value = (points × cpp) / 100; optional FX fee deduction (~3%).
- Surface portal direct-alternative and cap / FX warnings for explainability.
Architecture
Real ship path — Next.js App Router on Vercel; Supabase optional.
- UI + API routes in one Next.js app; TypeScript end-to-end.
- Catalog and programs as maintained data modules — not scraped bank APIs.
- Optional Supabase for persistence when signed in; demo works without auth.
- Vitest covers ranking edge cases (caps, FX, portal-only).
Decisions
- Deterministic over ML. Recruiters and users can audit the reason string; no black-box “savings score.”
- Demo wallet first. Prove ranking in one screen before signup.
- Valuation stance as a first-class input. Points are not dollars until you say how you redeem.
- Private source. Product iteration stays private; public proof is the live demo + this case study.
Limitations
- No bank linking or issuer APIs — catalog is maintained manually.
- Estimates depend on assumed cents-per-point and published category rules.
- Not financial advice; issuer terms and redemptions change.
- Does not model signup bonuses, credit score, or approval odds.
Future
- Richer wallet sync and spend logging against caps.
- Merchant-level category hints where unambiguous.
- Broader catalog coverage and clearer “rule freshness” labeling.