Angular集成PayPal沙箱捕获订单报错:付款人未批准订单
解决PayPal沙箱中“Payer has not yet approved the Order for payment”错误
问题根源
你的代码存在两个关键问题,直接导致了授权错误:
createOrder参数传值错误
你直接执行了this.createOrderPaypal(),把函数返回的订单ID传给了createOrder,但PayPal JS SDK要求createOrder必须是一个异步函数引用(而非执行结果),SDK会在用户点击按钮时自动调用这个函数来创建订单。onApprove流程未遵循PayPal规范
跳过了PayPal官方的授权确认步骤,直接调用后端捕获接口,此时用户的授权操作可能还未同步到PayPal服务器,导致订单状态仍为CREATED而非APPROVED。
修复步骤
1. 修正前端createOrder配置
将直接执行函数改为传递函数引用,同时用箭头函数绑定Angular组件的this上下文:
try { this.paypal = await loadScript({ clientId: clientId }); } catch (error) { console.error("failed to load the PayPal JS SDK script", error, HttpStatusCode); } if (this.paypal) { try { await this.paypal.Buttons({ style: { layout: 'vertical', color: 'gold', }, // 改为箭头函数,确保this指向组件,且传递函数引用而非执行结果 createOrder: async () => { const orderData = await this.createOrderPaypal(); return orderData.id; }, onApprove: async (data: any, actions: any) => { // 优先使用PayPal官方的capture方法,确保授权完成后再触发后端逻辑 const captureResult = await actions.order.capture(); // 再调用你的后端接口完成后续业务处理 await this.approveOrderPaypal(data.orderID, captureResult); } }).render("#buttonPaypal"); } catch (error) { console.error("failed to render the PayPal Buttons", error); } }
2. 后端捕获订单的校验补充
在_CaptureOrder方法中,先添加订单状态校验,确保订单处于APPROVED状态再执行捕获:
private async Task<dynamic> _CaptureOrder(string orderID, string _paypalClientId, string _paypalClientSecret, string _base) { var accessToken = await GenerateAccessToken(_paypalClientId, _paypalClientSecret, _base); // 先查询订单状态 var orderUrl = $"{_base}/v2/checkout/orders/{orderID}"; var orderRequest = new HttpRequestMessage(HttpMethod.Get, orderUrl); orderRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var orderResponse = await client.SendAsync(orderRequest); var orderData = await HandleResponse(orderResponse); if (orderData.status != "APPROVED") { throw new Exception("订单未完成授权"); } // 执行捕获操作 var captureUrl = $"{_base}/v2/checkout/orders/{orderID}/capture"; var captureRequest = new HttpRequestMessage(HttpMethod.Post, captureUrl); captureRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); // 补充请求体(如果需要) captureRequest.Content = new StringContent("{}", Encoding.UTF8, "application/json"); var captureResponse = await client.SendAsync(captureRequest); return await HandleResponse(captureResponse); }
额外注意事项
- 确保
createOrderPaypal方法返回的是Promise,且正确获取后端返回的订单ID - 沙箱测试时使用PayPal提供的测试账号,避免使用真实账号
- 检查PayPal应用的沙箱权限是否开启了订单捕获功能
内容的提问来源于stack exchange,提问作者porsha_app
相关产品推荐
相关产品推荐

