Skip to content

feat(card): inform users card runs on credit + flag USD FX abroad#2318

Open
kushagrasarathe wants to merge 5 commits into
devfrom
feat/card-fx-and-credit-notices
Open

feat(card): inform users card runs on credit + flag USD FX abroad#2318
kushagrasarathe wants to merge 5 commits into
devfrom
feat/card-fx-and-credit-notices

Conversation

@kushagrasarathe

@kushagrasarathe kushagrasarathe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Screenshots: the "Your card" (credit note) and AR/BR shots below are current. The old "Charged in EUR" shot is obsolete after the DCC rework — replace it with the USD-abroad (Selfridges / UK) drawer.

AR/BR — Pay like a local Your card — Pay as credit

TASK-19799 — card runs as credit

The Peanut card authorizes on the credit network. At a terminal that asks "debit or credit?", picking debit fails. Adds a persistent InfoCard on the Your Card screen telling users to choose credit.

  • src/components/Card/YourCardScreen.tsx — one InfoCard (variant info) below the auto-renew banner.

TASK-19800 — pick local currency abroad (DCC)

A card spend abroad can be billed in USD when the terminal offers "pay in dollars" (dynamic currency conversion). The terminal's markup is worse than Peanut's rate, so we nudge the user to choose the local currency next time. A spend already billed in the local currency is the good outcome — no notice.

  • New CardUsdAbroadNotice.tsx — fires for a card_pay billed in USD (cardPayment.localCurrency === 'USD') whose merchant sits in a non-USD country (small USD_COUNTRIES set: US + territories + sovereign USD users like PA/EC/SV).
  • Suppressed in AR/BR where LocalRailNudge already carries the stronger "pay with the local rail" message — one nudge per receipt. Reuses LOCAL_RAIL_BY_COUNTRY, now extracted to local-rail-countries.ts (per CodeRabbit).
  • Rendered next to LocalRailNudge in TransactionDetailsReceipt.tsx, same !isPublic gate.
  • No backend/transformer change — localCurrency (the merchant's billing currency) already flows through transactionTransformer.

Note: an earlier revision surfaced the opposite case (spend billed in a non-USD currency → "Charged in EUR"). Reworked per @jota's review — that's the good outcome and needs no notice; the DCC/USD-abroad case is the one to flag.

Component consistency (drawer nudges)

Both drawer nudges render via the shared InfoCard (variant info), matching the credit note:

  • CardUsdAbroadNotice uses InfoCard.
  • LocalRailNudge migrated from its hand-rolled Card+Icon to InfoCard — copy, gating, and markup-rate logic unchanged; visual parity only.

Tests

  • CardUsdAbroadNotice.test.tsx (7 cases: USD-abroad fires; local-currency / domestic-USD / other-USD-country / unknown-country / AR-BR / non-card-spend all suppressed). LocalRailNudge suite still green.
  • npm run typecheck clean, prettier clean.

QA (verified locally in the real UI with seeded card spends)

  • Your Card screen → "Pay as credit" note.
  • USD billed abroad (UK) → "Pay in local currency next time" notice. ← the DCC case
  • Local currency billed abroad (EUR / France) → no notice (good outcome).
  • Domestic USD (US) and other USD-currency countries → no notice.
  • AR/BR → only "Pay like a local" (LocalRailNudge).

Two card-transparency asks from Jota:

- TASK-19799: the Peanut card authorizes on the credit network, so a
  terminal that asks debit/credit needs 'credit' or the payment fails.
  Add a persistent InfoCard on the Your Card screen saying so.

- TASK-19800: the card settles in USD, so a spend charged in another
  currency silently goes through an FX conversion. Add a drawer notice
  (CardForeignCurrencyNotice) mirroring LocalRailNudge, gated on a non-USD
  charge currency and suppressed in AR/BR where LocalRailNudge already
  carries the stronger 'pay a cheaper way' message.
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Jul 2, 2026 2:48pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds a foreign-currency notice for card spend receipts, wires it into transaction details with local-rail suppression, updates the local-rail nudge to use a shared country map and InfoCard, and adds a credit guidance card to the card screen.

Changes

Foreign currency receipt notice and local rail reuse

Layer / File(s) Summary
Local rail export and card layout
src/components/TransactionDetails/provider-rows/local-rail-countries.ts, src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx
LOCAL_RAIL_BY_COUNTRY is exported, and the local-rail nudge now renders through InfoCard with the same displayed values.
CardForeignCurrencyNotice component
src/components/TransactionDetails/provider-rows/CardForeignCurrencyNotice.tsx
Adds a client component that shows an informational card for card spend with a non-USD local currency, while suppressing cases already covered by local-rail countries.
Receipt wiring and tests
src/components/TransactionDetails/TransactionDetailsReceipt.tsx, src/components/TransactionDetails/__tests__/CardForeignCurrencyNotice.test.tsx
CardForeignCurrencyNotice is imported and rendered after LocalRailNudge on non-public receipts, and tests cover the visible and suppressed states.
Pay-as-credit InfoCard
src/components/Card/YourCardScreen.tsx
Adds an info card below the auto-renew banner that instructs users to choose credit at terminals.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs

  • peanutprotocol/peanut-ui#2010: Both PRs change conditional rendering in src/components/TransactionDetails/TransactionDetailsReceipt.tsx around receipt display.
  • peanutprotocol/peanut-ui#2078: This PR uses the same local-rail mapping and receipt-side suppression path for transaction notices.

Suggested labels: enhancement

Suggested reviewers: jjramirezn

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly captures the main change: credit-network guidance and foreign-currency receipt notice.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description clearly matches the UI and receipt notice changes, including the credit note and foreign-currency/AR-BR behavior.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5858.65 → 5869.39 (+10.74)
Findings: +3 net (+16 new, -13 resolved)

🆕 New findings (16)

  • critical complexity — src/components/TransactionDetails/TransactionDetailsReceipt.tsx — CC 166, MI 52.79, SLOC 352
  • critical method-complexity — src/components/TransactionDetails/TransactionDetailsReceipt.tsx:73 — CC 114 SLOC 170
  • high hotspot — src/components/TransactionDetails/TransactionDetailsReceipt.tsx — 37 commits, +454/-1057 lines since 6 months ago
  • medium high-mdd — src/components/TransactionDetails/TransactionDetailsReceipt.tsx:73 — TransactionDetailsReceipt: MDD 178.3 (uses across many lines from declarations)
  • medium high-dlt — src/components/TransactionDetails/TransactionDetailsReceipt.tsx:73 — TransactionDetailsReceipt: DLT 80 (calls 80 distinct functions — high context load)
  • medium high-mdd — src/components/Card/YourCardScreen.tsx:29 — YourCardScreen: MDD 47.6 (uses across many lines from declarations)
  • medium complexity — src/components/Card/YourCardScreen.tsx — CC 22, MI 63.55, SLOC 52
  • medium complexity — src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx — CC 9, MI 64.65, SLOC 21
  • medium complexity — src/components/TransactionDetails/provider-rows/CardUsdAbroadNotice.tsx — CC 7, MI 63.98, SLOC 16
  • low high-dlt — src/components/Card/YourCardScreen.tsx:29 — YourCardScreen: DLT 16 (calls 16 distinct functions — high context load)
  • low structural-dup — components/Send/link/views/Success.link.send.view.tsx:102 — 14 duplicate lines / 73 tokens with components/TransactionDetails/TransactionDetailsReceipt.tsx:834
  • low missing-return-type — src/components/TransactionDetails/provider-rows/CardUsdAbroadNotice.tsx:28 — CardUsdAbroadNotice: exported fn missing return type annotation
  • low nextjs-use-client-overuse — src/components/TransactionDetails/provider-rows/CardUsdAbroadNotice.tsx:1 — 'use client' but no hooks/handlers/browser API
  • low missing-return-type — src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx:21 — LocalRailNudge: exported fn missing return type annotation
  • low missing-return-type — src/components/TransactionDetails/TransactionDetailsReceipt.tsx:73 — TransactionDetailsReceipt: exported fn missing return type annotation
  • low non-null-asserts — src/components/TransactionDetails/TransactionDetailsReceipt.tsx:73 — TransactionDetailsReceipt: 9 non-null assertions inside body

✅ Resolved (13)

  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx — CC 165, MI 52.8, SLOC 352
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx:72 — CC 113 SLOC 170
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx — 35 commits, +442/-1052 lines since 6 months ago
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx:72 — TransactionDetailsReceipt: MDD 177.0 (uses across many lines from declarations)
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx:72 — TransactionDetailsReceipt: DLT 80 (calls 80 distinct functions — high context load)
  • src/components/Card/YourCardScreen.tsx:28 — YourCardScreen: MDD 44.6 (uses across many lines from declarations)
  • src/components/Card/YourCardScreen.tsx — CC 22, MI 63.58, SLOC 52
  • src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx — CC 9, MI 60.92, SLOC 30
  • src/components/Card/YourCardScreen.tsx:28 — YourCardScreen: DLT 16 (calls 16 distinct functions — high context load)
  • components/Send/link/views/Success.link.send.view.tsx:102 — 14 duplicate lines / 73 tokens with components/TransactionDetails/TransactionDetailsReceipt.tsx:827
  • src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx:36 — LocalRailNudge: exported fn missing return type annotation
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx:72 — TransactionDetailsReceipt: exported fn missing return type annotation
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx:72 — TransactionDetailsReceipt: 9 non-null assertions inside body

📈 Painscore deltas (top movers)

File Before After Δ
src/components/TransactionDetails/provider-rows/CardUsdAbroadNotice.tsx 0.0 6.4 +6.4
src/components/TransactionDetails/provider-rows/local-rail-countries.ts 0.0 3.8 +3.8

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 1650 ran, 0 failed, 0 skipped, 24.7s

📊 Coverage (unit)

metric %
statements 54.7%
branches 37.7%
functions 42.5%
lines 54.6%
⏱ 10 slowest test cases
time test
3.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
0.4s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in updateUserById body
0.4s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.3s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in updateUserById
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid 9-digit US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle maximum length (17 digits) US account
0.1s src/app/(mobile-ui)/qr-pay/__tests__/qr-pay-states.test.tsx › Perk claimed shows shake class + go home button
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle too long for US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle minimum length (6 digits) US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle invalid ETH address (too short)
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx (1)

20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider moving the shared country map to a dedicated module.

Exporting LOCAL_RAIL_BY_COUNTRY so CardForeignCurrencyNotice can reach into it couples two independently-gated sibling components to one component's internal constant. LocalRailNudge also gates on useCardMarkupRate/percent, so CardForeignCurrencyNotice's reuse of this map (via LOCAL_RAIL_BY_COUNTRY[iso2.toUpperCase()], see src/components/TransactionDetails/provider-rows/CardForeignCurrencyNotice.tsx:32) only checks country membership, not whether LocalRailNudge actually renders — a future third consumer of this map would compound the coupling. Extracting the map into a small shared constants file (e.g. local-rail-countries.ts) would make ownership explicit and avoid reaching into a sibling component's file for shared data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx` at line
20, The shared country lookup is currently owned by LocalRailNudge but reused by
CardForeignCurrencyNotice, which tightly couples sibling components through an
exported constant. Move LOCAL_RAIL_BY_COUNTRY out of LocalRailNudge into a
dedicated shared module and update both LocalRailNudge and
CardForeignCurrencyNotice to import it from there, keeping the gating logic in
each component separate from the shared data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx`:
- Line 20: The shared country lookup is currently owned by LocalRailNudge but
reused by CardForeignCurrencyNotice, which tightly couples sibling components
through an exported constant. Move LOCAL_RAIL_BY_COUNTRY out of LocalRailNudge
into a dedicated shared module and update both LocalRailNudge and
CardForeignCurrencyNotice to import it from there, keeping the gating logic in
each component separate from the shared data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4213b658-bb83-4a94-a7c1-1d5c096bfb12

📥 Commits

Reviewing files that changed from the base of the PR and between efbb2bd and 498ee92.

📒 Files selected for processing (5)
  • src/components/Card/YourCardScreen.tsx
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx
  • src/components/TransactionDetails/__tests__/CardForeignCurrencyNotice.test.tsx
  • src/components/TransactionDetails/provider-rows/CardForeignCurrencyNotice.tsx
  • src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx

Swap the hand-rolled Card+Icon in CardForeignCurrencyNotice for the
standard InfoCard (variant=info), matching the credit note on the Your
Card screen and every other info surface (KYC, Withdraw). Less code,
consistent styling. Copy and gating unchanged.
Swap the hand-rolled Card+Icon in LocalRailNudge for the same InfoCard
(variant=info) the FX notice and credit note use, so both drawer nudges
render identically. Copy, gating, and the markup-rate logic unchanged.
@notion-workspace

Copy link
Copy Markdown

@notion-workspace

Copy link
Copy Markdown

@kushagrasarathe

Copy link
Copy Markdown
Contributor Author

@coderabbitai review in depth.

Evaluate:

  • risk of introducing new bugs and breaking existing functionality
  • performance impact and latency
  • code quality and DRY

Also, write a very concise testing guide for QA

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
fd . -e tsx -e ts | grep -E "CardForeignCurrencyNotice|LocalRailNudge|YourCardScreen|TransactionDetailsReceipt|InfoCard" 

echo "---- CardForeignCurrencyNotice.tsx ----"
cat -n src/components/TransactionDetails/provider-rows/CardForeignCurrencyNotice.tsx

echo "---- LocalRailNudge.tsx ----"
cat -n src/components/TransactionDetails/provider-rows/LocalRailNudge.tsx

echo "---- InfoCard ----"
fd -i infocard
</bash>

Length of output: 7028


🏁 Script executed:

#!/bin/bash
set -e
echo "---- InfoCard/index.tsx ----"
cat -n src/components/Global/InfoCard/index.tsx

echo "---- TransactionDetailsReceipt.tsx (relevant section) ----"
grep -n "LocalRailNudge\|CardForeignCurrencyNotice\|isPublic" src/components/TransactionDetails/TransactionDetailsReceipt.tsx

echo "---- full receipt context ----"
sed -n '1,200p' src/components/TransactionDetails/TransactionDetailsReceipt.tsx

echo "---- YourCardScreen.tsx context ----"
grep -n "InfoCard\|auto.renew\|credit" -i src/components/Card/YourCardScreen.tsx

echo "---- extractMerchantIso2 ----"
rg -n "extractMerchantIso2" -A 15 src/components/TransactionDetails/transaction-details.utils.ts

echo "---- test file ----"
cat -n src/components/TransactionDetails/__tests__/CardForeignCurrencyNotice.test.tsx

Length of output: 20152


🏁 Script executed:

#!/bin/bash
set -e
echo "---- CARD_FX_MARKUP_BY_CURRENCY ----"
rg -n "CARD_FX_MARKUP_BY_CURRENCY" -A 10 src/constants/payment.consts.ts

echo "---- useCardMarkupRate ----"
cat -n src/hooks/useCardMarkupRate.ts 2>/dev/null || fd useCardMarkupRate

echo "---- YourCardScreen.tsx full relevant block ----"
sed -n '1,120p' src/components/Card/YourCardScreen.tsx

echo "---- Icon list check for credit-card / info ----"
rg -n "'credit-card'|\"credit-card\"|'info'|\"info\"" src/components/Global/Icons/Icon.tsx | head -30

echo "---- check card.merchantCountry type / cardPayment type ----"
rg -n "merchantCountry|localCurrency" -B2 -A2 src/components/TransactionDetails/transactionTransformer.ts | head -80

Length of output: 10204


@kushagrasarathe Reviewed the diff in depth across CardForeignCurrencyNotice.tsx, LocalRailNudge.tsx, TransactionDetailsReceipt.tsx, YourCardScreen.tsx, InfoCard, and the new test suite. Summary below.

Risk of new bugs / breaking existing functionality — Low

  • Gating logic is solid: card_pay-only, localCurrency present & non-USD, ISO2 country not in LOCAL_RAIL_BY_COUNTRY. Test suite (Line 30-60 of CardForeignCurrencyNotice.test.tsx) covers the full matrix (fires, unknown country, USD suppressed, missing currency, AR/BR suppressed, non-card-spend suppressed).
  • Exporting LOCAL_RAIL_BY_COUNTRY (Line 19 of LocalRailNudge.tsx) is a pure visibility change — no behavior risk.
  • One latent coupling worth flagging (not a bug today, but a future footgun): CardForeignCurrencyNotice suppresses based purely on whether the merchant's ISO2 is a key in LOCAL_RAIL_BY_COUNTRY, while LocalRailNudge only actually renders if useCardMarkupRate/CARD_FX_MARKUP_BY_CURRENCY resolves a truthy percent for that currency. Today CARD_FX_MARKUP_BY_CURRENCY (Line 48-51 of src/constants/payment.consts.ts) has entries for both ARS and BRL, so the two components stay perfectly in sync. But if a new country is ever added to LOCAL_RAIL_BY_COUNTRY without a matching markup entry, LocalRailNudge would silently render nothing while CardForeignCurrencyNotice is still suppressed for it — leaving the receipt with no notice at all for that country. Consider a comment pointing at this invariant, or deriving suppression from "would LocalRailNudge render" rather than raw country-key presence.
  • Rendering order in TransactionDetailsReceipt.tsx (Line 649, 654) is correct: LocalRailNudge then CardForeignCurrencyNotice, both behind !isPublic, matching the screenshots (AR → local-rail nudge only, FR/EUR → FX notice only, USD/US → neither).

Performance impact / latency — Negligible

  • CardForeignCurrencyNotice is pure derived-state, no network calls.
  • LocalRailNudge's useCardMarkupRate query is only triggered for AR/BR merchants, has a 5-min client staleTime and 5-min server cache, and a static fallback avoids an extra loading flash.
  • YourCardScreen's new InfoCard is fully static — no re-render or fetch cost.

Code quality / DRY

  • Good move reusing the shared InfoCard component (per commit history) instead of a bespoke Card+Icon layout — consistent styling/variants with the rest of the app.
  • Minor duplication: both LocalRailNudge and CardForeignCurrencyNotice independently re-implement the transactionCardType !== 'card_pay' gate and extractMerchantIso2(card?.merchantCountry) call. Not urgent, but a shared helper (e.g., getCardSpendMerchantIso2(transaction)) would remove the drift risk described above and keep both components' gating logic single-sourced.
  • No transformer changes needed, as noted in the PR description — confirmed localCurrency/merchantCountry are already piped through transactionTransformer.ts (Lines 368-379, 603-611).

Concise QA testing guide

  1. Credit-network banner (Your Card screen)

    • Open Card tab → Your Card. Confirm the blue "Pay as credit" InfoCard appears below the card face (and below the auto-renew banner if visible), reading: "When a terminal asks debit or credit, choose credit — your Peanut card runs on the credit network."
    • Dismiss the auto-renew banner (if shown) and confirm the credit InfoCard persists (it's not dismissible).
  2. FX notice on card-spend receipts

    • Open a completed card-spend receipt where the merchant charged in a non-USD, non-AR/BR currency (e.g., EUR in France). Confirm the blue "Charged in EUR" notice appears with the FX-conversion copy.
    • Open a card-spend receipt charged in USD (e.g., US merchant). Confirm no FX notice and no local-rail nudge appear.
    • Open a card-spend receipt in Argentina or Brazil (ARS/BRL). Confirm only the "Pay like a local next time" nudge appears — not the FX notice (no double-nudging).
    • Open a non-card transaction (send/receive/link, etc.). Confirm neither notice appears.
    • Open a card-spend receipt via a public/shared receipt link. Confirm neither notice appears (both are gated on !isPublic).
  3. Regression check

    • Confirm existing "Pay like a local next time" nudge for AR/BR still renders with the correct percentage, unaffected by the LOCAL_RAIL_BY_COUNTRY export change.
✅ Action performed

Review finished.

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.

Addresses CodeRabbit: the map lived in LocalRailNudge and was reached into
by CardForeignCurrencyNotice, coupling two sibling components through one
component's exported internal. Move it to local-rail-countries.ts so the
shared data has explicit ownership; both components import from there and
keep their own gating.
Per Jota: the notice we want is NOT the local-currency spend (that's the
good outcome) but the dynamic-currency-conversion trap — a spend abroad
billed in USD because the terminal offered 'pay in dollars', which gives a
worse rate than paying local. Fire only when the merchant billed USD
(localCurrency === 'USD') AND the country is non-USD (small USD_COUNTRIES
set), advising the user to pick local currency next time. Renamed
CardForeignCurrencyNotice -> CardUsdAbroadNotice to match. AR/BR suppression
unchanged (LocalRailNudge owns those).
@kushagrasarathe

Copy link
Copy Markdown
Contributor Author

Good catch — reworked to the DCC case. The notice now fires only when a spend abroad was billed in USD (the terminal's "pay in dollars?" trap) and the merchant is in a non-USD country, advising the user to pick the local currency next time. A spend billed in the local currency is the good outcome and shows nothing. Renamed CardForeignCurrencyNoticeCardUsdAbroadNotice. Verified live: USD-in-UK shows the notice, EUR-in-France shows nothing. (04f686a61)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant