The Credit Card Optimization Problem
I've always been fascinated by how much money people leave on the table with credit card rewards. The average person has 3-4 credit cards, each with different bonus categories, annual credits, and spending requirements. Yet most users just swipe whatever card is on top of their wallet.
The math is brutal. Someone with a Chase Sapphire Preferred (3x on dining) using their basic 1% cashback card at restaurants is literally throwing away 2% on every meal. Scale that across thousands of dollars annually, and you're looking at hundreds in missed rewards.
When I built Atlas Finance's credit card rewards system, I wanted to solve this optimization problem without making users think about it. The goal: make smart spending decisions feel automatic.
Auto-Detection: Reading Cards from Plaid Data
The first challenge was identifying which cards users actually have. Plaid gives us account data, but it's messy. A Chase Sapphire Preferred might show up as "CHASE SAPPHIRE" or "SAPPHIRE PREFERRED" or even just "CHASE *1234".
I built a matching engine that works in layers:
const detectCardType = (account: PlaidAccount) => {
const name = account.name.toLowerCase();
const subtype = account.subtype; // credit_card, etc.
// Exact matches first
if (name.includes('sapphire preferred')) {
return CardTypes.CHASE_SAPPHIRE_PREFERRED;
}
// Fuzzy matching with confidence scoring
const matches = CARD_DATABASE.map(card => ({
card,
score: calculateSimilarity(name, card.identifiers)
})).sort((a, b) => b.score - a.score);
return matches[0].score > 0.8 ? matches[0].card : null;
};
The card database contains over 100 popular cards with their known name variations, bonus categories, and annual benefits. When a user connects a new bank account, we run detection automatically and surface the results in their dashboard.
The tricky part was handling edge cases. Some users have business versions of personal cards, or older discontinued products. I added a fallback system that lets users manually confirm or correct detected cards, which also feeds back into improving the detection algorithm.
The Benefit Suggestion Modal
Here's where it gets interesting. Most credit cards come with annual credits that users completely forget about. Amex Gold gives you $120 in Uber credits. Chase Sapphire has $300 in travel credits. Capital One Venture gives you $100 for Global Entry.
I built the BenefitSuggestionModal to proactively surface these opportunities:
const BenefitSuggestionModal = ({ userCards }: Props) => {
const unusedBenefits = userCards.flatMap(card =>
card.annualBenefits.filter(benefit =>
!benefit.claimed && benefit.expiresAt > new Date()
)
);
return (
<Modal>
<h2>You're Missing Out on ${totalValue} in Benefits</h2>
{unusedBenefits.map(benefit => (
<BenefitCard
key={benefit.id}
title={benefit.name}
value={benefit.value}
instructions={benefit.howToRedeem}
deadline={benefit.expiresAt}
/>
))}
</Modal>
);
};
The modal triggers based on user behavior patterns. If someone has an Amex Gold but hasn't used Uber in 6 months, we'll remind them about that $10 monthly credit. If it's November and they haven't used their airline incidental credit, we'll surface that too.
The key was making these suggestions feel helpful, not nagging. I added smart timing โ no benefit reminders during the first week after signup (users are still learning the app), and we space them out so users don't get overwhelmed.
Reward Transaction Tracking
The real magic happens at the transaction level. Every time a transaction comes through Plaid, we calculate potential earnings across all of the user's cards:
const calculateOptimalCard = (transaction: Transaction, userCards: CreditCard[]) => {
const category = categorizeTransaction(transaction);
const cardRewards = userCards.map(card => {
const multiplier = card.bonusCategories[category] || card.baseRate;
const earnings = transaction.amount * (multiplier / 100);
return {
card,
earnings,
multiplier,
isOptimal: false
};
}).sort((a, b) => b.earnings - a.earnings);
cardRewards[0].isOptimal = true;
return cardRewards;
};
This creates a "rewards report" for every transaction. Users can see exactly how much they earned versus how much they could have earned. The psychological impact is powerful โ seeing "You could have earned $3.50 more" makes the next decision obvious.
I also built category-level summaries. Users can see they've earned $45 on dining this month, but left $23 on the table by using suboptimal cards. These insights drive behavior change better than abstract optimization advice.
Making Complexity Feel Simple
The biggest design challenge was presenting this information without overwhelming users. Credit card rewards are inherently complex โ quarterly categories, spending caps, anniversary years, temporary bonuses. I needed to distill this into actionable guidance.
My approach was progressive disclosure. The main dashboard shows simple recommendations: "Use Chase Freedom for groceries this quarter" or "Switch to Amex Gold for your next restaurant meal." Users who want deeper analysis can drill into detailed breakdowns.
I also added contextual timing. Instead of showing all possible optimizations, we focus on the user's upcoming spending patterns. If someone has a recurring Spotify charge, we'll specifically mention that their Amex Gold gets 4x on music streaming.
The notification system was crucial too. I built smart alerts that trigger when users are about to miss significant rewards:
- "You're $200 away from your Chase Sapphire bonus threshold"
- "Your Discover quarterly bonus expires in 2 weeks"
- "You haven't used your Amex airline credit yet this year"
Real-World Impact
The system has been live for several months now, and the results are encouraging. Users who actively follow the card suggestions are earning 40-60% more in rewards compared to their historical patterns. More importantly, they're not thinking about it โ the optimization happens naturally as part of their spending routine.
One user told me they finally used their $300 Chase travel credit after having the card for two years. Another discovered they had been using their 1% card at gas stations when their Costco Visa gives 4% on gas. These aren't earth-shattering discoveries, but they add up to real money.
What's Next
I'm working on expanding the card database and adding more sophisticated spend forecasting. The goal is to not just react to transactions, but proactively help users plan their spending to maximize rewards. Imagine knowing exactly how to spend your next $500 to hit multiple bonus thresholds simultaneously.
The credit card optimization space is ripe for innovation, and I'm excited to keep pushing the boundaries of what's possible when you combine transaction data with intelligent recommendations.