You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 4中PayPal onAuthorize内调用外部函数报错解决咨询

解决PayPal onAuthorize中Cannot read property 'http' of undefined错误及调用外部函数的方法

这个错误的核心原因是**this的上下文指向问题**:你在onAuthorize里用了普通的function()声明,这里面的this指向的是PayPal按钮的上下文,而不是你的Angular组件实例,所以自然找不到组件里的http服务。

下面是两种可行的解决办法,同时也能帮你顺利调用自定义外部函数:

方法1:使用箭头函数(推荐)

箭头函数不会绑定自己的this,它会继承外层上下文的this(也就是你的组件实例),这样就能直接访问this.http和组件里的其他方法了。

修改后的onAuthorize部分代码如下:

onAuthorize: (data, actions) => {
  return actions.payment.execute().then((payment) => {
    const formdata: FormData = new FormData;
    formdata.append('Payment[trns_id]', payment.id);
    formdata.append('Payment[paypal]', JSON.stringify(payment)); // 注意:对象转JSON字符串才能被FormData正确传递
    formdata.append('Payment[amount]', payment.transactions[0].amount.total);
    formdata.append('Payment[order_id]', this.order_id); // 直接访问组件属性
    formdata.append('Payment[state]', payment.state);
    formdata.append('Payment[auth_token]', this.auth_token);

    // 正常调用http服务,也能直接调用组件内的自定义函数
    this.http.post(environment.apiUrl + 'orders/paypal-checkout', formdata).subscribe(
      (result) => {
        this.responceData = result.json();
        if (this.responceData.data.status === true && this.responceData.data.status_message === 'success') {
          this.router.navigateByUrl('/questionnaire/successfully');
        }
        // 比如调用自定义的支付成功处理函数
        this.handlePaymentSuccess(payment);
      },
      (err) => {
        console.log('Error' + err);
        // 调用自定义错误处理函数
        this.handlePaymentError(err);
      }
    )
  })
},

方法2:提前保存组件的this引用

如果更习惯用普通函数写法,可以在PayPal按钮渲染前把组件的this存到一个变量里,比如self,然后在函数内部用self代替this:

ngAfterViewInit(): void { 
  const total = this.total_amount; 
  const selected_package = this.selected_package.name;
  const self = this; // 保存组件的this引用

  this.loadExternalScript('https://www.paypalobjects.com/api/checkout.js').then(() => { 
    paypal.Button.render({ 
      // ...其他配置保持不变
      onAuthorize: function (data, actions) { 
        return actions.payment.execute().then(function (payment) { 
          const formdata: FormData = new FormData;
          // 所有访问组件属性/方法的地方都用self代替this
          formdata.append('Payment[order_id]', self.order_id); 
          formdata.append('Payment[auth_token]', self.auth_token);

          self.http.post(environment.apiUrl + 'orders/paypal-checkout', formdata).subscribe(
            (result) => {
              self.responceData = result.json();
              if (self.responceData.data.status === true && self.responceData.data.status_message === 'success') {
                self.router.navigateByUrl('/questionnaire/successfully');
              }
              // 调用自定义外部函数
              self.customPaymentCallback(payment);
            },
            (err) => {
              console.log('Error' + err);
              self.handlePaymentError(err);
            }
          )
        }) 
      },
      // ...其他配置
    }, '#paypal-button'); 
  }); 
}

另外补充一个小细节:你之前直接把payment对象append到FormData里,后端大概率无法正确解析这个对象,建议用JSON.stringify(payment)转成字符串后再传递。

内容的提问来源于stack exchange,提问作者khurshed alam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:27:28