我正在尝试使用react-paypal-express-checkout实施安全的付款方式... 但是我看到用户可以使用chrome开发工具轻松更改金额...我不应该向我的服务器发出API请求支付宝并用我的数据库验证金额吗?我没有看到使用Paypal进行此操作的任何选择...
这是我的代码:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import 'react-credit-cards/es/styles-compiled.css'
import './checkout.css';
import PaypalExpressBtn from 'react-paypal-express-checkout';
class CheckOut extends Component {
constructor(props) {
super(props);
this.state = {
amount: 40
}
}
render() {
const client = {
sandbox: 'XXXX',
production: 'Your-Production-Client-ID',
}
return (
<PaypalExpressBtn client={client} currency={'USD'} total={this.state.amount} />
);
}
}
export default connect(CheckOut);
答案 0 :(得分:8)
Paypal允许从客户端和服务器两种使用类型。我想客户有可能在其端修改请求以减少费用。但是,最后,无论您从事什么业务,都将获得订单和付款。只需检查付款是否与应有的金额有所不同,并且不履行订单,即可退款。
如果您想节省麻烦,请使用server option来通过您的服务器付款。
无论如何,与任何其他付款方式一样,我建议您花些时间按照Paypal提供的功能齐全且记录明确的API自行实施。他们有很多示例和用例,以及用于浏览器和服务器的代码。
答案 1 :(得分:2)
从不来自客户端的信任值。您应该绝对在服务器端验证金额。
正如@jorbuedo所说,您可以创建一个server integration,这样就不会在客户端暴露这些值。将会话ID或订单号或其他内容发送到您的服务器,从数据库中检索订单,然后重定向到PayPal以处理服务器端的交易。
或者,您可以保留自己的客户端内容,但是在交易完成后对其进行验证。您可以使用Instant Payment Notifications或更新的Webhooks来做到这一点。
您可以将custom
变量传递到paymentOptions
的{{1}}属性中,然后使用该值来验证是否已在IPN中支付了正确的金额。
例如:
<PaypalExpressButton ...>
然后,作为IPN的一部分,您可以将会话ID从数据库中拉出,检查预期付款金额(您需要存储该金额,或者根据保存的商品/价格进行计算会话ID)与Paypal提供的付款金额相同(例如<PaypalExpressButton
client={client}
currency="USD"
total={this.state.amount}
paymentOptions={{
custom: this.props.sessionId
}}
/>
)。您可以在here中获得作为IPN一部分获得的变量的完整列表。
使用IPN不收取任何费用。如果您不想建立此流程,则必须手动验证所下的每个订单,以确保金额正确。如果您运行的是小型产品,这可能是一个可以接受的折衷方案。
编辑:不要只是将期望的金额作为“自定义”变量发送,并且将其与mc_gross
值进行比较,因为也可以使用F12或browser extension来进行更改。该值必须是不透明的,您可以将服务器端转换为有意义的值。
答案 2 :(得分:2)
@jorbuedo和@Dave Salomon对安全性给出了很好的答案,您应该考虑它们。
但是,如果您确实不想用户更改组件状态和道具,则可以使用此技巧禁用React Devtools。
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.emit = function() {};
}
基本上,它模拟了react-devtools
的某些方法,Devtool仍然无法找到您的组件树。
此答案仅用于禁止用户编辑您的组件。这不是最佳的安全解决方案)