用 25 行代码将 Stripe 价格本地化为访客的货币
发布: (2026年5月5日 GMT+8 03:20)
4 分钟阅读
原文: Dev.to
Source: Dev.to
请提供您希望翻译的完整文本(文章正文、代码示例等),我将按照要求保留源链接、Markdown 格式和技术术语,仅翻译正文内容。谢谢!
概览
Stripe 的 Price 对象绑定到单一货币(例如 $79 USD)。
为了解决转化率优化,您可以 显示 访客本地货币的价格(ARS、BRL、EUR,……),同时在后端仍以标准的 USD 金额计费。
工作原理
- 将标准价格存储为 USD – 切勿修改 Stripe Price。
- 在服务器上检测访客的国家(基于 IP)。
- 将国家映射到其本地货币。
- 从外汇 API 获取实时 USD → 本地货币 汇率。
- 渲染本地化金额(例如 “≈ AR$ 7 900”)并显示在 USD 价格旁边。
- 当用户点击 Buy 时,Stripe 以 USD 处理付款;汇率转换仅用于显示。
这种做法让访客看到熟悉的数字,同时保持 Stripe 的会计简洁且防止退款争议。
Source: …
实现
辅助函数:localizedPrice
// lib/localized-price.ts
import { headers } from 'next/headers';
interface LocalizedPrice {
usd: number;
display: string;
currency: string;
rate: number;
}
const APOGEO = 'https://api.apogeoapi.com/v1';
export async function localizedPrice(usdAmount: number): Promise {
const ip =
headers().get('x-forwarded-for')?.split(',')[0] ??
headers().get('x-real-ip') ??
'';
if (!ip) return fallback(usdAmount, 'USD', 1);
// 1️⃣ Detect visitor country
const ipRes = await fetch(`${APOGEO}/ip/${ip}`, {
headers: { 'X-API-Key': process.env.APOGEOAPI_KEY! },
next: { revalidate: 3600 }, // 1 h
});
if (!ipRes.ok) return fallback(usdAmount, 'USD', 1);
const { country } = await ipRes.json();
const currency: string = country.currency;
if (currency === 'USD') return fallback(usdAmount, 'USD', 1);
// 2️⃣ Fetch live FX rate
const fxRes = await fetch(`${APOGEO}/exchange-rates/${currency}`, {
headers: { 'X-API-Key': process.env.APOGEOAPI_KEY! },
next: { revalidate: 14400 }, // 4 h
});
if (!fxRes.ok) return fallback(usdAmount, 'USD', 1);
const { usdRate }: { usdRate: number } = await fxRes.json();
const localAmount = Math.round(usdAmount * usdRate);
const display = new Intl.NumberFormat(undefined, {
style: 'currency',
currency,
maximumFractionDigits: 0,
}).format(localAmount);
return { usd: usdAmount, display, currency, rate: usdRate };
}
function fallback(usdAmount: number, currency: string, rate: number): LocalizedPrice {
return {
usd: usdAmount,
display: `$${usdAmount} ${currency}`,
currency,
rate,
};
}
在组件中使用该辅助函数
// components/PricingCard.tsx
import { localizedPrice } from '@/lib/localized-price';
export default async function PricingCard() {
const price = await localizedPrice(79); // Stripe price in USD
return (
<>
<h2>Professional Plan</h2>
<p>$79 USD</p>
{price.currency !== 'USD' && (
<p>≈ {price.display} at today's rate</p>
)}
<button>Buy now</button>
</>
);
}
Practical Tips
- 永不更改 Stripe Price 对象(按货币),保持单一的美元价格并使用仅显示本地化。
- 适当四舍五入 —— 例如,ARS(阿根廷比索)没有实用的分位,因此
maximumFractionDigits: 0可去除小数。 - 优雅的回退 —— 如果外汇 API 不可用,显示美元金额而不是 “$undefined”。
- 缓存汇率 4 小时(与 API 刷新频率相匹配),以避免过多请求。
- 自适应定价(Stripe 提供的按货币 Prices)会产生约 2 % 的外汇差价,由 Stripe 收取并隐藏访客原始的显示价格。仅显示方式免费、透明且更简单。
可选:货币切换器
如果您希望用户覆盖自动检测:
- 将所选货币存储在 cookie 中。
- 将该值传递给
localizedPrice(添加可选的overrideCurrency参数)。 - 同一辅助函数将返回相应的显示金额。
成本与限制
- ApogeoAPI 免费层:每月 1 000 次请求。
- 使用 4 小时缓存,这大约相当于每月 5 000 次页面浏览。
- 在 . 获取密钥。