fix(rcart): infer Transak fiat amount from crypto amount for stablecoins

When fiatAmount wasn't explicitly set on a payment request, Transak
defaulted to 300 USD. Now for USDC/USDT/DAI/cUSDC, the fiat amount
is inferred from the crypto amount (1:1 peg) so the widget opens with
the correct payment amount.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-04-03 14:48:48 -07:00
parent 4d06156e5f
commit 15990cc147
1 changed files with 24 additions and 14 deletions

View File

@ -32,6 +32,9 @@ import {
import { extractProductFromUrl } from './extract'; import { extractProductFromUrl } from './extract';
import { createSecureWidgetUrl, extractRootDomain, getTransakApiKey, getTransakEnv } from '../../shared/transak'; import { createSecureWidgetUrl, extractRootDomain, getTransakApiKey, getTransakEnv } from '../../shared/transak';
import { createMoonPayPaymentUrl, getMoonPayApiKey, getMoonPayEnv } from '../../shared/moonpay'; import { createMoonPayPaymentUrl, getMoonPayApiKey, getMoonPayEnv } from '../../shared/moonpay';
/** Tokens pegged 1:1 to USD — fiat amount can be inferred from crypto amount */
const USD_STABLECOINS = ['USDC', 'USDT', 'DAI', 'cUSDC'];
import QRCode from 'qrcode'; import QRCode from 'qrcode';
import { createTransport, type Transporter } from "nodemailer"; import { createTransport, type Transporter } from "nodemailer";
import { import {
@ -1781,14 +1784,16 @@ routes.post("/api/payments/:id/transak-session", async (c) => {
hideMenu: 'true', hideMenu: 'true',
}; };
// Pre-fill fiat amount/currency so user sees the total immediately // Derive fiat amount: use explicit fiatAmount, or infer from crypto amount for stablecoins
if (p.fiatAmount) { const inferredFiat = p.fiatAmount || (USD_STABLECOINS.includes(p.token) ? effectiveAmount : null);
widgetParams.fiatAmount = p.fiatAmount; if (inferredFiat) {
widgetParams.defaultFiatAmount = p.fiatAmount; widgetParams.fiatAmount = inferredFiat;
widgetParams.defaultFiatAmount = inferredFiat;
} }
if (p.fiatCurrency) { const fiatCcy = p.fiatCurrency || (USD_STABLECOINS.includes(p.token) ? 'USD' : null);
widgetParams.fiatCurrency = p.fiatCurrency; if (fiatCcy) {
widgetParams.defaultFiatCurrency = p.fiatCurrency; widgetParams.fiatCurrency = fiatCcy;
widgetParams.defaultFiatCurrency = fiatCcy;
} }
const widgetUrl = await createSecureWidgetUrl(widgetParams); const widgetUrl = await createSecureWidgetUrl(widgetParams);
@ -1855,13 +1860,18 @@ routes.post("/api/payments/:id/card-session", async (c) => {
themeColor: '6366f1', themeColor: '6366f1',
hideMenu: 'true', hideMenu: 'true',
}; };
if (p.fiatAmount) { // Derive fiat amount: use explicit fiatAmount, or infer from crypto amount for stablecoins
widgetParams.fiatAmount = p.fiatAmount; {
widgetParams.defaultFiatAmount = p.fiatAmount; const inferredFiat = p.fiatAmount || (USD_STABLECOINS.includes(p.token) ? effectiveAmount : null);
} if (inferredFiat) {
if (p.fiatCurrency) { widgetParams.fiatAmount = inferredFiat;
widgetParams.fiatCurrency = p.fiatCurrency; widgetParams.defaultFiatAmount = inferredFiat;
widgetParams.defaultFiatCurrency = p.fiatCurrency; }
const fiatCcy = p.fiatCurrency || (USD_STABLECOINS.includes(p.token) ? 'USD' : null);
if (fiatCcy) {
widgetParams.fiatCurrency = fiatCcy;
widgetParams.defaultFiatCurrency = fiatCcy;
}
} }
const widgetUrl = await createSecureWidgetUrl(widgetParams); const widgetUrl = await createSecureWidgetUrl(widgetParams);