Inspiration
Between credit cards, memberships, and loyalty programs, we all collect benefits faster than we use them.
Every store wants you to join its rewards program. Download the app. Make an account. Remember the password. Congratulations: you now have another coupon to forget about. VISA found that consumers hold an average of 17.4 loyalty memberships but actively use only 8.8. In fact, Americans miss out on up to $10 billion in loyalty savings every year!
People are signing up for rewards, earning benefits, and then forgetting they ever existed!
So we built Lapse: a browser extension that remembers your rewards and does the checkout math for you, because we're obsessed with our customers.
Innovation
It finds coupons, checks your coupons, memberships, and credit card benefits to find the best combination that gives our customers the best deal. We call this "stacking".
Lapse also keeps track of what’s about to expire, so a reward you meant to “save for later” will be pushed to the front of the stack so you'll actually get a chance to use it before it's gone. Expiration-aware search brings those offers forward, while checkout recommendations prioritize savings.
Lapse does the math for you. Minimum spends, exclusions, and cashback rates all affect the answer, so we built a constraint model using Google’s OR-Tools solver to handle the math.
User Experience
Lapse finds your rewards while you shop. Your dashboard keeps the coupons, expiration dates, and savings in one place.
We chose an extension because people already have somewhere to shop, and our extension is a friendly aid to save people time, money, and maximize the benefits they already have.
Our LapseSense notice brings relevant benefits into that shopping experience. Live updates arrive through server-sent events, so a newly received reward can appear without a manual refresh.
A reward alert needs a recognizable identity across very different shopping pages, which is why we went with a brutalist style UI. Bold colors, thick outlines, and our brutalist visual direction make Lapse feel distinct and unique. On the dashboard, individual rewards look like real little coupons to add a fun touch.
How We Stand Out
Lapse connects your personal offers to the cart in front of you.
That means checking eligibility, comparing combinations, selecting a payment card, and recording the resulting savings.
Our custom merchant tags and term-to-category map also help connect everyday shopping language to rewards. So, searching for “shoes” should not need to remember the exact wording of a footwear email.
The distinction is the decision process. A large discount can block another benefit. A smaller compatible offer can produce a better result. An impressive cashback rate can be irrelevant at the wrong merchant. Lapse puts those conditions into the calculation.
Commerce Impact
Picture a $500 cart, a fully eligible 10% voucher, and a card that earns 5% cashback on the remaining purchase.
Here is the math with that example:
Voucher: $500 × 10% = $50 Checkout price: $500 − $50 = $450 Cashback: $450 × 5% = $22.50 Total benefit: $50 + $22.50 = $72.50 You pay $450 at checkout. The $22.50 cashback is a separate benefit. We keep that distinction explicit.
For shoppers, easier access to existing benefits could mean fewer forgotten offers and less comparison work. For merchants, easier redemption could support return visits and stronger loyalty engagement. These are potential outcomes, not measured conversion results.
85% of surveyed consumers say loyalty programs make them more likely to continue doing business with brands, according to the 2025 Bond Loyalty Report, produced in partnership with VISA. Lapse helps turn that loyalty into action by bringing forgotten rewards back into the shopping experience. Shoppers get more value from their purchases, while merchants get another reason for customers to come back.
Lapse helps people access the value they have earned, while helping businesses deliver on their loyalty promises.
Technical Execution
Our backend uses Python, FastAPI, and Pydantic, with PostgreSQL for persistent storage, pgvector for vector search, and pgcrypto for encrypted reward codes.
The intake pipeline gives users dedicated reward inboxes and deduplicates messages using both Message-ID and content hashes. Our merchant console sends real emails through that pipeline. We fine-tuned SetFit on labeled emails using our training script, running training locally on a MacBook. It classifies whether an email contains a reward.
Our custom extraction cascade then tries JSON-LD → regex rules → GLiNER, merging results with confidence scores for individual fields. GLiNER, Presidio, and the optional MiniLM search fallback use pretrained models.
Checkout is a constraint problem We express our stacking rules in Google OR-Tools CP-SAT. Each reward gets a binary variable: xᵢ ∈ {0, 1} Selecting a reward sets its variable to 1. Constraints enforce minimum spends, exclusions, membership requirements, and compatibility.
Two incompatible rewards satisfy: xᵢ + xⱼ ≤ 1 Code-bearing rewards satisfy: Σ xᵢ ≤ 1
The objective combines immediate discounts and eligible cashback: maximize cart total − checkout price + reward cashback + card cashback Percentages apply to the appropriate remaining balance. Two compatible, sequential 10% discounts produce:
1 − (0.9 × 0.9) = 19%
The engine handles rounding and caps, then constructs an explanation from the selected benefits and calculated amounts. A 200-millisecond solver budget keeps the interaction responsive; a greedy fallback provides a feasible recommendation when that budget is exceeded, without promising global optimality.
Search has its own math
Our custom ranking combines: score = match × value × urgency Merchant tags and category mappings determine relevance. The urgency component raises the priority of approaching expirations: use it before you lose it. Redemptions feed an itemized ledger and cumulative savings: S(t) = Σ savedᵢ for redemptions recorded through day t. The chart has receipts behind it.
Security, Trust, & Responsibility
Trust and security are built into Lapse from day one, because making commerce easier means earning people’s confidence.
Our dedicated rewards inbox keeps personal inboxes private, while lightweight ML extracts reward details without relying on an LLM to follow instructions in an email. Confidence scores flag uncertainty, and explainable recommendations show where the savings come from.
Everything is run locally your device; Lapse doesn’t use any outside services or make any outside calls.
Our goal is to connect people and businesses through innovative, reliable, and secure payments. We’re bringing that principle to everyday rewards: helping shoppers use their benefits with less friction and helping businesses deliver on their loyalty promises.
Convenience should never come at the cost of consumer trust.
Challenges we ran into
The hardest part of stacking was defining what counts as a valid combination. With Google’s OR-Tools CP-SAT solver, we had to translate reward terms into explicit constraints: one promo code per order, minimum spends, exclusions, and restrictions on combining offers. When stacking permission was unclear, we took the conservative approach and treated the rewards as incompatible.
The arithmetic was another part that we had to spend time thinking about. Two compatible 10% discounts applied sequentially save 19%, not 20%: 1 − (0.9 × 0.9) = 0.19
Cashback also needs the correct base. A $500 cart with 10% off becomes $450, so 5% cashback earns $22.50, not $25. Discount caps, eligible items, and cent-level rounding added further complexity. We also had to separate expiration urgency from maximum savings. Search can prioritize rewards approaching expiration, while checkout optimization prioritizes the best eligible financial result. To keep recommendations grounded, we built explanations from the engine’s actual selections and calculated amounts. The challenge was making every promised dollar traceable to a reward, an eligibility rule, and the arithmetic.
Future of Lapse
Here are some future features that we'll implement as we continue working on Lapse:
Location-based SMS alerts: With user permission, notify shoppers of relevant rewards when they enter a store. This would extend Lapse beyond online shopping and require location capabilities outside the browser extension.
Receipt and confirmation processing: Extract merchant, purchase date, items, and amounts from receipts and order confirmations to populate purchase records automatically. Link purchases to rewards where supported, flag uncertain matches for review, and record confirmed savings without duplicate entries.
Built With
- chromeextension
- docker
- fastapi
- gliner2
- googleortools
- minilm
- pgvector
- postgresql
- postmark
- presidio
- python
- pytorch
- react
- sentencetransformers
- setfit
- spacy
- typescript
- wxt


Log in or sign up for Devpost to join the conversation.