电子商务网站的货币换算 - 防止因四舍五入而出现错误的总购物车
我正在向电子商务应用程序添加多货币支持。 我解决这个问题的方法是让应用程序保持其基础货币,并让模板在显示价格时调用 PriceDisplay() 函数/插件。 因此,模板继续接收以美元金额表示的价格。 如果需要,priceDisplay 函数会正确转换价格,并根据存储在会话中的查看者设置添加正确的 $ 或欧元符号。 提交订单后,应用程序将以美元金额以及货币代码和货币汇率存储订单。 此外,我们将以客户的货币从其信用卡中扣款,以确保他们收到的账单与订单屏幕上显示的完全一致。
现在我遇到的问题是在购物车中以及结帐期间显示购物车总计时。 例如,应用程序向模板发送要在购物车中显示的价格:
小计:9.75
船:5.95
总计:15.70
模板获取这些金额并调用每个项目的priceDisplay 函数。 如果货币汇率是 1.1,那么我们会向用户显示:
小计:10.725 -> 10.73
船舶: 6.545 -> 6.55
总计:17.27
可以看到小计+船舶=17.28,但是转换后的总计是17.27。
因此,我认为有几个选项可以工作,尽管没有完全考虑到:
- 在应用程序端处理所有转换 在对
- 项目进行总计的情况下,模板应将所有单独的加数和总计以基础货币一起发送到 PriceDisplay 函数,这将转换它们并确保转换后的总数与加数之和匹配。 在这种情况下,我如何向应用程序传达总金额不是 15.70,而是 15.71 或 15.69(因为我们将以基础货币存储订单,并在处理付款时乘以汇率。)
- 跟踪已删除/添加小数点作为转换的一部分,并用它做一些“聪明”的事情。 因此,在本例中,10.725,我们添加了千分之五。 所以当我们转换6.545时,我们应该先去掉0.005,然后再转换。 也许这就是上面选项2所做的过程?
- 你的建议在这里。
如果有什么区别的话,应用程序是 PHP 的,模板是 Smarty 的。
您还可以在添加购物车商品的行总计时看到相同的问题:
3 件物品 x 每件 9.75 = 29.25
转换:
3 项 x 10.73 (10.725) = 32.18 (32.175)
但 3 x 10.73 = 32.19 != 32.18
I'm adding multi-currency support to an e-commerce application. The way I approached the problem was to keep the application in it's base currency and have the template call a priceDisplay() function/plugin anytime it displays a price. So the template continues to receive prices in dollar amounts. The priceDisplay function correctly converts the price if needed and adds the correct $ or Euro sign depending on the viewers settings, stored in the session. On order submit, the application will store the order in dollar amount as well as the currencyCode and currencyRate. Additionally we will charge the customer's credit card in their currency to ensure they get billed exactly what was shown on the order screen.
Now the issue I am having is when displaying the cart totals in the cart as well as during checkout. As an example, the application sends the template the prices to display in the shopping cart:
subtotal: 9.75
ship: 5.95
total: 15.70
The template takes these amounts and calls the priceDisplay function on each item. If the currency rate is 1.1, then we get displayed to the user:
subtotal: 10.725 -> 10.73
ship: 6.545 -> 6.55
total: 17.27
You can see that the subtotal + ship = 17.28, but the total converted is 17.27.
So couple of options I think could work, though not thought all the way through:
- Handle all conversion on the application side
- Where items will be totaled, the template should send all the individual addends and total together in the base currency to the priceDisplay function, which will convert them and ensure that the converted total and sum of addends match up. In this case, then how do I communicate to the application that the total is not 15.70 but perhaps 15.71 or 15.69 (since we will be storing the order in base currency and multiply by the exchangeRate when processing the payment.)
- Keep track of dropped/added decimal points as part of the conversions and do something 'smart' with that. So in this example, 10.725, we added 5 thousandths. So when we convert 6.545, we should first drop .005 then convert. Perhaps this is the process that option 2 above does?
- Your suggestion here.
If it makes any difference, application is in PHP and template is Smarty.
You can also see the same issue in adding the line totals of the cart items:
3 items x 9.75 each = 29.25
converted:
3 items x 10.73 (10.725) = 32.18 (32.175)
but 3 x 10.73 = 32.19 != 32.18
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我坚定地站在1阵营。 货币换算是核心业务逻辑,属于您的模型,而不是您的视图。
此外,虽然货币看起来像浮点数,但事实并非如此。 货币以整数数量易手,无论你的基本单位是什么。 例如,在美国,如果口香糖每个 10 美分,我买 10 个,那么我就用 100 便士换 10 个口香糖。 即使我给出一张钞票,从软件角度来看,最好将其算作 100 便士。
有关这方面的更多信息,请参阅 Martin Fowler 的 “企业应用程序架构模式” 和 “分析模式”。 他详细讨论了所有问题并提供了很好的示例代码。 您还可以在网上找到一些信息:
如果您需要会计工作,我会也和会计师谈谈。 货币兑换通常会因汇率变化、奇怪的费用和其他无意义的事情而变得复杂,如果你没有从一开始就做好准备,你可能会花很长时间去追逐便士以保持账面平衡。
I'm firmly in the 1 camp. Currency conversion is core business logic, and belongs in your models, not your views.
Further, although money looks like floating-point numbers, it isn't. Money changes hands in integer quantities of whatever your base unit is. In the US, for example, If gumballs are 10 cents each and I buy ten, then I'm trading 100 pennies for 10 gumballs. Even if I give a dollar bill, from a software perspective, it's best to count that as 100 pennies.
For more on this, see Martin Fowler's "Patterns of Enterprise Application Architecture" and "Analysis Patterns". He talks through all the issues in detail and gives good sample code. You can also find some of that info on the web:
If you need the accounting to work, I'd also talk to the accountant. Currency conversion is often complicated by changing rates, weird fees, and other nonsense, and you can spend a long time chasing pennies to make the books balance if you don't get it right from the get-go.
如果您根据转换后的货币进行计费,那么您确实不应该在视图逻辑中进行该计算。
If you are billing based on the converted currency, you really shouldn't be doing that calculation in your view logic.
就我个人而言,我只会计算总金额,将小计添加到船舶金额中。 这显然是最简单的使用方法,没有人会错过多余的一分钱。
Well personally, I would just make the total amount, the subtotal added to the ship amount. This is obviously the simplest method to use, and no-one will miss the extra penny.
永远不要使用浮点数来赚钱! 你正在让自己进入一个无缘由的四舍五入受伤的世界。 由于 PHP 没有十进制定点类型,因此所有货币计算都使用整数。 请参阅威廉的链接。
Don't use floating point numbers for money, ever! You are letting yourself into a world of hurt with rounding for no good reason. Since PHP doesn't have a decimal fixed point type, do all money calculations with integers. See William's links.