Braintree PHP 设置金额并避免舍入错误
Braintree PHP setting amount and avoiding rounding errors
我正在使用 PHP/Laravel 和 Braintree 创建一个用于支付的网络应用程序。我正在使用 Braintree dropin.
Web 应用程序的简化流程:
- 用户上传文件并从下拉列表中选择服务,提交表单
- 显示用户 quote/price 这是通过上传文件的字数 * 所选服务计算得出的
- 用户通过 Braintree 插件选择付款,提交付款表格
- Web 应用程序触发
Braintree_Transaction::sale()
- 用户显示成功页面
向客户收费
关于上述内容,我想获得一些关于在步骤 4 的 Braintree_Transaction::sale()
方法调用中设置金额的最佳实践的建议。
在 Braintree PHP example on github 中,Braintree_Transaction::sale()
方法调用中使用的数量取自表单中的文本输入,这可以由用户编辑,我假设出于示例目的。
在我上面描述的网络应用程序流程中,在第 1 步之后,我是否正确地在会话中设置所选服务的 quote/price,然后在第 2 步中从会话向用户显示此值,以及最终将会话中的值作为 amount
传递给 Braintree_Transaction::sale()
?或者是否有不同的推荐方法?我主要关心的是向客户收取正确的金额。
避免舍入错误
由于 quote/price 是在 PHP 中通过计算上传文件的字数并将其乘以客户选择的服务来计算的,因此有时会涉及浮点数。例如。字数为 1000,所选服务为 x1.5 校对,因此报价为 1500 => £15.00。
如果我没记错的话,Stripe 表示例如一磅 (£) 便士 100
。这很好,因为它有助于避免舍入错误。另一方面,我相信 Braintree 期望用小数点 1.00
.
表示一磅 (£)
在这种情况下避免任何舍入错误的最佳方法是什么?
感谢您的任何建议,如有需要,请询问更多详细信息,我已尽量做到简明扼要。
would I be correct to set the quote/price of the selected service in the session then show this value from the session to the user in step 2 and finally pass the value from the session as the amount to Braintree_Transaction::sale()?
是的,这是一种有效的方法。会话值存储在服务器端,因此用户不能直接操作它们,用于跨页面请求携带信息。
另一个解决方案是在数据库中存储购物车之类的东西。这具有长期存储的优势,因此用户可能会在以后回来完成该过程,您可以轻松地 运行 对其进行报告,并且您可以跟踪诸如辍学率之类的事情。
除了显示值外,不要相信浏览器。意思是不要将报价存储在浏览器中或在那里执行任何计算,因为它们可以被用户更改。
What would be my best approach to avoid any rounding errors in such a scenario?
没有足够多的开发人员在开始项目之前考虑这一点。如果您不使用整数,则需要使用定点数学。
如果您使用的是关系数据库,请将货币值存储为 DECIMAL。
在 PHP 中使用正确处理固定位置小数的 bcmath 库计算所有内容。它非常简单,并将数字保存在字符串中。按照你的例子:
$quote = bcmul('1000', '1.5', 2);
// '1500.0'
// Get 2 decimal places for Braintree
$sale = number_format((float)$quote, 2, '.', '');
我正在使用 PHP/Laravel 和 Braintree 创建一个用于支付的网络应用程序。我正在使用 Braintree dropin.
Web 应用程序的简化流程:
- 用户上传文件并从下拉列表中选择服务,提交表单
- 显示用户 quote/price 这是通过上传文件的字数 * 所选服务计算得出的
- 用户通过 Braintree 插件选择付款,提交付款表格
- Web 应用程序触发
Braintree_Transaction::sale()
- 用户显示成功页面
向客户收费
关于上述内容,我想获得一些关于在步骤 4 的 Braintree_Transaction::sale()
方法调用中设置金额的最佳实践的建议。
在 Braintree PHP example on github 中,Braintree_Transaction::sale()
方法调用中使用的数量取自表单中的文本输入,这可以由用户编辑,我假设出于示例目的。
在我上面描述的网络应用程序流程中,在第 1 步之后,我是否正确地在会话中设置所选服务的 quote/price,然后在第 2 步中从会话向用户显示此值,以及最终将会话中的值作为 amount
传递给 Braintree_Transaction::sale()
?或者是否有不同的推荐方法?我主要关心的是向客户收取正确的金额。
避免舍入错误
由于 quote/price 是在 PHP 中通过计算上传文件的字数并将其乘以客户选择的服务来计算的,因此有时会涉及浮点数。例如。字数为 1000,所选服务为 x1.5 校对,因此报价为 1500 => £15.00。
如果我没记错的话,Stripe 表示例如一磅 (£) 便士 100
。这很好,因为它有助于避免舍入错误。另一方面,我相信 Braintree 期望用小数点 1.00
.
在这种情况下避免任何舍入错误的最佳方法是什么?
感谢您的任何建议,如有需要,请询问更多详细信息,我已尽量做到简明扼要。
would I be correct to set the quote/price of the selected service in the session then show this value from the session to the user in step 2 and finally pass the value from the session as the amount to Braintree_Transaction::sale()?
是的,这是一种有效的方法。会话值存储在服务器端,因此用户不能直接操作它们,用于跨页面请求携带信息。
另一个解决方案是在数据库中存储购物车之类的东西。这具有长期存储的优势,因此用户可能会在以后回来完成该过程,您可以轻松地 运行 对其进行报告,并且您可以跟踪诸如辍学率之类的事情。
除了显示值外,不要相信浏览器。意思是不要将报价存储在浏览器中或在那里执行任何计算,因为它们可以被用户更改。
What would be my best approach to avoid any rounding errors in such a scenario?
没有足够多的开发人员在开始项目之前考虑这一点。如果您不使用整数,则需要使用定点数学。
如果您使用的是关系数据库,请将货币值存储为 DECIMAL。
在 PHP 中使用正确处理固定位置小数的 bcmath 库计算所有内容。它非常简单,并将数字保存在字符串中。按照你的例子:
$quote = bcmul('1000', '1.5', 2);
// '1500.0'
// Get 2 decimal places for Braintree
$sale = number_format((float)$quote, 2, '.', '');