IAP 中的货币本地化问题
IAP 中的货币本地化问题
背景 & 目标
首先需要了解为什么会有这个需求,一般而言,如谷歌和苹果的支付平台,在后台上配置商品价格时,只能选择有限的价格选项,而不是自由指定价格。因此,在面对诸如折扣礼包的需求时,就需要考虑货币本地化的问题了
如:商品原价 100美元,现价 9.9 美元
要注意,这个商品的实际 product id 对应的价格依然是 9.9 美元,而这个 100 美元具体要如何显示,就是本篇文章要介绍的核心问题了
如:在美国会显示为
100$
*美元汇率(此处为 1)
,在香港会显示为HK$100
*港币汇率
等等
IAP 平台返回的内容
在接入谷歌和苹果的原生 SDK 时,都会提供如下基本信息
- ISO 4217 货币标准
- 商品汇率换算后的价格
- 实际的美元价格
需要注意的是,在 Android 返回中,提供了一个
1,000,000
精度的getPriceAmountMicros
方法
通过这三个变量信息,我们就获取到了所有关键内容,通过 美元价格
/ 汇率换算价格
就可以得到当前货币的实际汇率,而通过 ISO 4217 货币代码,就可以完成货币的本地化显示
CultureInfo
在我们调用 ToString()
方法时,你可能会注意到有如下重载,此处的 IFormatProvider
正是我们接下来需要填入的 CultureInfo
public string ToString(string format, System.IFormatProvider provider);
而微软的 CultureInfo
并不是基于 ISO 4217 标准来建立的,因此我们仍需解决两个标准的映射问题
foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
{
var region = new RegionInfo(culture.LCID);
// ISO 4217
_currency_info.TryAdd(region.ISOCurrencySymbol, new(culture));
}
其他标准
在我们实际使用中,会碰到如下两个标准
- ISO 3166-1 alpha-2
- UnityEngine.SystemLanguage
第一种一般为一些第三方 SDK 返回 国家/地区信息时用到,而第二种是在调用 Application.systemLanguage
时会用到,因此也会有对应的一些转换需求
// ISO 3166-1 alpha-2
foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
{
var region = new RegionInfo(culture.LCID);
Debug.Log(region.TwoLetterISORegionName);
}
但是 SystemLanguage
的转换就比较麻烦了,可以直接拷贝下方代码
private readonly Dictionary<SystemLanguage, CultureInfo> _system_language_info = new()
{
{SystemLanguage.Afrikaans, new("af-ZA")},
{SystemLanguage.Arabic, new("ar-SA")},
{SystemLanguage.Basque, new("eu-ES")},
{SystemLanguage.Belarusian, new("be-BY")},
{SystemLanguage.Bulgarian, new("bg-BG")},
{SystemLanguage.Catalan, new("ca-ES")},
{SystemLanguage.Chinese, new("zh-CN")},
{SystemLanguage.ChineseSimplified, new("zh-CN")},
{SystemLanguage.ChineseTraditional, new("zh-TW")},
{SystemLanguage.Czech, new("cs-CZ")},
{SystemLanguage.Danish, new("da-DK")},
{SystemLanguage.Dutch, new("nl-NL")},
{SystemLanguage.English, new("en-US")},
{SystemLanguage.Estonian, new("et-EE")},
{SystemLanguage.Faroese, new("fo-FO")},
{SystemLanguage.Finnish, new("fi-FI")},
{SystemLanguage.French, new("fr-FR")},
{SystemLanguage.German, new("de-DE")},
{SystemLanguage.Greek, new("el-GR")},
{SystemLanguage.Hebrew, new("he-IL")},
{SystemLanguage.Hungarian, new("hu-HU")},
{SystemLanguage.Icelandic, new("is-IS")},
{SystemLanguage.Indonesian, new("id-ID")},
{SystemLanguage.Italian, new("it-IT")},
{SystemLanguage.Japanese, new("ja-JP")},
{SystemLanguage.Korean, new("ko-KR")},
{SystemLanguage.Latvian, new("lv-LV")},
{SystemLanguage.Lithuanian, new("lt-LT")},
{SystemLanguage.Polish, new("pl-PL")},
{SystemLanguage.Portuguese, new("pt-PT")},
{SystemLanguage.Romanian, new("ro-RO")},
{SystemLanguage.Russian, new("ru-RU")},
{SystemLanguage.Slovak, new("sk-SK")},
{SystemLanguage.Slovenian, new("sl-SI")},
{SystemLanguage.Spanish, new("es-ES")},
{SystemLanguage.Swedish, new("sv-SE")},
{SystemLanguage.Thai, new("th-TH")},
{SystemLanguage.Turkish, new("tr-TR")},
{SystemLanguage.Ukrainian, new("uk-UA")},
{SystemLanguage.Vietnamese, new("vi-VN")},
{SystemLanguage.Unknown, new("en-US")}
};
实际使用
public string Localize(double value, int keep_decimal = 2)
{
// 换算汇率
value *= _PRICE_RATIO;
// 最后进行本地化, 此处的 culture_info,需要根据项目实际情况获取
return value.ToString("C{keep_decimal}", culture_info);
}
参考链接
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果