如何在 payment callback 中执行函数
支付老李
结论
不要在 Vue 的 methods 中用箭头函数定义 processPayment。箭头函数不会把 this 绑定到组件实例,因此 this.postPayment 很可能是 undefined。
把它改成普通方法,再将方法传给支付组件:
methods: {
processPayment(res) {
return this.postPayment(res);
},
async postPayment(res) {
// 将支付结果提交给后端
}
}
原因
问题出在下面这种写法:
processPayment: res => {
this.postPayment(res);
}
箭头函数没有自己的 this,而是从定义它的位置继承 this。放在 Vue 组件的 methods 中时,这里的 this 通常不是当前组件实例,也就无法访问 postPayment、组件数据和其他实例方法。
普通方法会由 Vue 绑定到组件实例,可以通过 this 调用组件中的其他方法。
Vue 组件中的正确写法
如果支付组件接收 callback 属性,可以直接传入方法引用:
<PaymentComponent :callback="processPayment">
Proceed to payment
</PaymentComponent>
export default {
methods: {
async processPayment(res) {
try {
await this.postPayment(res);
console.log("Payment status submitted");
} catch (error) {
console.error("Failed to submit payment status", error);
}
},
async postPayment(res) {
return this.$http.post("/api/payments/complete", {
transactionId: res.transactionId,
status: res.status
});
}
}
};
使用 Axios 时可以这样写:
import axios from "axios";
export default {
methods: {
async processPayment(res) {
await this.postPayment(res);
},
async postPayment(res) {
const response = await axios.post("/api/payments/complete", {
transactionId: res.transactionId,
status: res.status
});
return response.data;
}
}
};
如果支付组件通过事件返回结果,就监听对应事件:
<PaymentComponent @payment-success="processPayment">
Proceed to payment
</PaymentComponent>
该用 :callback 还是 @payment-success,要看这个 payment component 提供了哪种 API。
如果必须使用箭头函数
可以在已经正确绑定 this 的普通方法中创建箭头函数:
methods: {
processPayment(res) {
const submit = () => this.postPayment(res);
return submit();
},
postPayment(res) {
// 提交数据
}
}
不过这种写法多了一层,没有必要。直接调用更清楚:
processPayment(res) {
return this.postPayment(res);
}
如果使用的是 React 类组件
如果实际环境不是 Vue,而是 React class component,需要绑定回调,或者将回调定义为类字段箭头函数:
class PaymentPage extends React.Component {
processPayment = async res => {
await this.postPayment(res);
};
postPayment = async res => {
// 将支付结果提交给后端
};
render() {
return (
<PaymentComponent callback={this.processPayment}>
Proceed to payment
</PaymentComponent>
);
}
}
也可以在构造函数中完成绑定:
constructor(props) {
super(props);
this.processPayment = this.processPayment.bind(this);
}
注意事项
前端 callback 只能说明浏览器收到了支付结果,不能作为后端确认付款成功的唯一依据。用户可能关闭页面或重复触发请求,客户端数据也可能遭到篡改。
更稳妥的处理流程是:
- callback 将支付平台返回的交易编号提交给后端;
- 后端向支付平台查询交易状态或进行验签;
- 将交易编号作为幂等键,防止重复入账;
- 最终付款状态以支付平台的服务端通知或后端查询结果为准;
- 在 callback 中处理网络失败,并允许安全重试。
要解决 this.postPayment(res) 无法执行的问题,只需把 processPayment 改为普通组件方法。支付状态是否有效,则应由后端最终确认。
备注:内容仅供参考。
