Skip to content

Commit 36f4b84

Browse files
ArxMint Workerclaude
andcommitted
feat: show USD equivalent on checkout (amount entry, invoice, paid)
Fetch BTC price from mempool.space. Show ≈ $X.XX USD next to sats amount on the amount input, quick buttons, invoice QR screen, and payment confirmation. Helps merchants and customers understand value. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4d6bab5 commit 36f4b84

1 file changed

Lines changed: 27 additions & 2 deletions

File tree

components/checkout-flow.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export function CheckoutFlow({
8686
const [paidAt, setPaidAt] = useState<string | null>(null);
8787
const [loading, setLoading] = useState(false);
8888
const [error, setError] = useState<string | null>(null);
89+
const [btcPrice, setBtcPrice] = useState<number | null>(null);
8990
const [shipping, setShipping] = useState<ShippingAddress>({
9091
email: "", fullName: "", street: "", city: "", state: "", zip: "",
9192
});
@@ -132,6 +133,19 @@ export function CheckoutFlow({
132133
}
133134
}, [merchantId, presetMemo]);
134135

136+
// Fetch BTC price for USD conversion
137+
useEffect(() => {
138+
fetch("https://mempool.space/api/v1/prices")
139+
.then((r) => r.json())
140+
.then((d) => setBtcPrice(d.USD))
141+
.catch(() => {});
142+
}, []);
143+
144+
const satsToUsd = (sats: number) => {
145+
if (!btcPrice) return null;
146+
return (sats / 100_000_000 * btcPrice).toFixed(2);
147+
};
148+
135149
// Apply merchant light theme to nav + body so the entire page feels light
136150
useEffect(() => {
137151
document.documentElement.setAttribute("data-theme", "merchant");
@@ -324,7 +338,9 @@ export function CheckoutFlow({
324338
autoFocus
325339
/>
326340
<p className="text-xs text-text-muted text-center mt-2">
327-
1 – 1,000,000 sats
341+
{amount && btcPrice
342+
? `≈ $${satsToUsd(Number(amount))} USD`
343+
: "1 – 1,000,000 sats"}
328344
</p>
329345
</div>
330346

@@ -338,6 +354,7 @@ export function CheckoutFlow({
338354
className="px-3 py-1.5 rounded-lg text-sm font-mono border border-border-default hover:border-accent/50 hover:bg-accent/5 transition-colors text-text-secondary"
339355
>
340356
{q.toLocaleString()}
357+
{btcPrice && <span className="text-[10px] text-text-muted block">${satsToUsd(q)}</span>}
341358
</button>
342359
))}
343360
</div>
@@ -488,6 +505,11 @@ export function CheckoutFlow({
488505
<p className="text-3xl font-mono font-semibold text-text-primary">
489506
{displayAmount.toLocaleString()} <span className="text-base text-text-muted">sats</span>
490507
</p>
508+
{btcPrice && (
509+
<p className="text-sm text-text-muted mt-1">
510+
≈ ${satsToUsd(displayAmount)} USD
511+
</p>
512+
)}
491513
</div>
492514

493515
<PaymentRailSelector
@@ -531,9 +553,12 @@ export function CheckoutFlow({
531553
<h2 className="text-2xl font-semibold text-text-primary mb-2">
532554
Payment Received
533555
</h2>
534-
<p className="text-3xl font-mono font-semibold text-green-600 mb-2">
556+
<p className="text-3xl font-mono font-semibold text-green-600 mb-1">
535557
{displayAmount.toLocaleString()} <span className="text-base">sats</span>
536558
</p>
559+
{btcPrice && (
560+
<p className="text-sm text-text-muted mb-2">≈ ${satsToUsd(displayAmount)} USD</p>
561+
)}
537562
<p className="text-sm text-text-muted">
538563
Paid to {merchantName}
539564
</p>

0 commit comments

Comments
 (0)