Skip to content

fix: show dollar amounts instead of misleading percentages in cashback banners#1742

Open
Hugo0 wants to merge 3 commits intomainfrom
fix/cashback-dollar-amounts
Open

fix: show dollar amounts instead of misleading percentages in cashback banners#1742
Hugo0 wants to merge 3 commits intomainfrom
fix/cashback-dollar-amounts

Conversation

@Hugo0
Copy link
Contributor

@Hugo0 Hugo0 commented Mar 12, 2026

Summary

  • Show actual dollar amounts instead of misleading percentages in cashback banners
  • Users were seeing "10% cashback" but getting far less due to dynamic point-based caps, causing confusion and support tickets (~10% of Crisp tickets last week)
  • Updated both qr-pay/page.tsx (pre-claim and post-claim banners) and TransactionDetailsReceipt.tsx for consistency
  • Removed unused percentage variable and aligned full-coverage detection logic between banners

Test plan

  • Make a QR payment with an eligible perk — pre-claim banner should show "$X.XX back" not "10% cashback"
  • Claim the perk — post-claim banner should show "$X.XX back" not "10% cashback"
  • Check transaction details for a claimed perk — should show "$X.XX cashback" not percentage
  • Test with 100%+ coverage perk — should show "This bill can be covered by Peanut!"
  • Test with campaign-capped perk — should show "campaign limit reached"

chip-peanut-bot bot and others added 2 commits March 12, 2026 11:26
…k banners

Previously the QR payment flow showed "You're getting 10% cashback!" based on
the perk campaign's discountPercentage. But the actual amount is capped by the
user's points balance (dynamicCapFormula), so users often received far less than
10% — creating confusion and support tickets.

Now we show the actual dollar amount (amountSponsored) which already accounts
for all caps. Users see "Peanut's got you! $0.50 back" instead of a misleading
percentage.

Changes:
- Pre-claim banner: shows "$X.XX back" instead of "X% cashback"
- Post-claim banner: shows "$X.XX back" with invite CTA
- 100%+ perks still get special messaging ("We paid for this bill!")
- Fallback copy when amount isn't available yet
…ounts consistently

Remove unused percentage variable from pre-claim banner and align full-coverage
detection logic between pre-claim and post-claim banners. Also update
TransactionDetailsReceipt to use dollar-amount messaging instead of percentage-based,
keeping perk messaging consistent across the app.
@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Mar 12, 2026 0:19am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2cee4b4d-6bfc-4cd3-ab1d-f95ebc099950

📥 Commits

Reviewing files that changed from the base of the PR and between 73e61f5 and a0dfbc5.

📒 Files selected for processing (1)
  • src/app/(mobile-ui)/qr-pay/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/(mobile-ui)/qr-pay/page.tsx

Walkthrough

Perk messaging in two UI components was converted from percentage-based wording and calculations to dollar-amount-based wording. Code now shows amountSponsored (dollar) when available, with campaign-cap and generic fallback messages when amount is absent; percentage calculations and tolerance logic were removed.

Changes

Cohort / File(s) Summary
QR Pay Perk UI
src/app/(mobile-ui)/qr-pay/page.tsx
Replaced percentage-based messaging with dollar-amount messages using amountSponsored. Removed percentage derivation/tolerance logic; added fallbacks when no amount is present; adjusted eligible, success, and cashback banner texts.
Transaction Details / Receipt
src/components/TransactionDetails/TransactionDetailsReceipt.tsx
Removed discountPercentage logic and percent-based branches. Always display $<amount> when amountSponsored exists; handle perk.isCapped && perk.campaignCapUsd with a campaign-cap message; otherwise show generic perk fallback text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: replacing misleading percentage-based cashback messaging with actual dollar amounts in banners.
Description check ✅ Passed The description clearly explains the problem, solution, affected files, and includes a comprehensive test plan directly related to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/cashback-dollar-amounts

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`(mobile-ui)/qr-pay/page.tsx:
- Around line 1241-1250: The condition `if (amountSponsored && typeof
amountSponsored === 'number')` incorrectly treats 0 as missing; change the guard
to accept zero by checking only for a numeric value (e.g., `if (typeof
amountSponsored === 'number')` or `if (amountSponsored != null && typeof
amountSponsored === 'number')`) so zero-valued perks render the dollar copy;
update both occurrences that reference amountSponsored and transactionUsd in the
QR pay page rendering code (the blocks that build the
"$${amountSponsored.toFixed(2)}" messages) to use the new guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6cf75092-c60e-4f93-bb68-d9c34bca5f08

📥 Commits

Reviewing files that changed from the base of the PR and between 514b9d9 and 73e61f5.

📒 Files selected for processing (2)
  • src/app/(mobile-ui)/qr-pay/page.tsx
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx

Comment on lines +1241 to +1250
// Always show actual dollar amount — never percentage (misleading due to dynamic caps)
if (amountSponsored && typeof amountSponsored === 'number') {
if (transactionUsd > 0 && amountSponsored >= transactionUsd) {
return `This bill can be covered by Peanut! $${amountSponsored.toFixed(2)} back. Claim it now.`
}
return `Peanut's got you! $${amountSponsored.toFixed(2)} back on this payment. Claim it now.`
}

return amountSponsored && typeof amountSponsored === 'number'
? `Get $${amountSponsored.toFixed(2)} back!`
: 'Claim it now to unlock your reward.'
// Fallback: no amount available yet
return 'You earned a Peanut Perk! Claim it now to unlock your reward.'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Treat $0.00 perks as real values, not “missing”.

if (amountSponsored && typeof amountSponsored === 'number') drops zero-valued sponsored amounts into the fallback copy. That makes capped/no-reward cases read like “unlock your reward” / generic cashback instead of reflecting the actual computed amount. This is a user-facing regression for the same capped-formula cases this PR is addressing.

🐛 Proposed fix
- if (amountSponsored && typeof amountSponsored === 'number') {
+ if (typeof amountSponsored === 'number' && Number.isFinite(amountSponsored)) {
    if (transactionUsd > 0 && amountSponsored >= transactionUsd) {
        return `This bill can be covered by Peanut! $${amountSponsored.toFixed(2)} back. Claim it now.`
    }
    return `Peanut's got you! $${amountSponsored.toFixed(2)} back on this payment. Claim it now.`
}
- if (amountSponsored && typeof amountSponsored === 'number') {
+ if (typeof amountSponsored === 'number' && Number.isFinite(amountSponsored)) {
    if (transactionUsd > 0 && amountSponsored >= transactionUsd) {
        return 'We paid for this bill! Earn points, climb tiers and unlock even better perks.'
    }
    return `We gave you $${amountSponsored.toFixed(2)} back! Invite friends to unlock bigger rewards.`
}

Also applies to: 1271-1279

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`(mobile-ui)/qr-pay/page.tsx around lines 1241 - 1250, The condition
`if (amountSponsored && typeof amountSponsored === 'number')` incorrectly treats
0 as missing; change the guard to accept zero by checking only for a numeric
value (e.g., `if (typeof amountSponsored === 'number')` or `if (amountSponsored
!= null && typeof amountSponsored === 'number')`) so zero-valued perks render
the dollar copy; update both occurrences that reference amountSponsored and
transactionUsd in the QR pay page rendering code (the blocks that build the
"$${amountSponsored.toFixed(2)}" messages) to use the new guard.

@Hugo0
Copy link
Contributor Author

Hugo0 commented Mar 12, 2026

Reopened from #1741 (which had unrelated Crisp commits mixed in).

Context: ~10% of Crisp tickets last week were cashback-related. Users see "10% cashback" but get far less due to dynamic point-based caps (dynamicCapFormula with TOTAL_POINTS_MULTIPLIER). A user with 100 points paying $50 expects $5 back but gets $0.05.

Fix: Always show the actual dollar amount (amountSponsored) instead of the misleading discountPercentage. Updated both qr-pay/page.tsx and TransactionDetailsReceipt.tsx for consistency.

Separate note: the legacy "10% cashback" perk (2a9e42f4, probability: 0.5, no end date) should probably be paused — it competes with the new LATAM system and causes inconsistent cashback amounts.

@Hugo0
Copy link
Contributor Author

Hugo0 commented Mar 12, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 12, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Small amounts (<$0.50) get factual tone + invite nudge instead of
celebratory "Peanut's got you!" framing that feels patronizing for
pocket change. Large amounts ($5+) get "your points are paying off"
to reinforce the gamification loop.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant