PayPal Express Checkout.js - Checkout.js 中未定义的 indexOf

Posted

技术标签:

【中文标题】PayPal Express Checkout.js - Checkout.js 中未定义的 indexOf【英文标题】:PayPal Express Checkout.js - indexOf on undefined within Checkout.js 【发布时间】:2017-05-12 07:58:17 【问题描述】:

我正在尝试使用他们的 checkout.js 和此处提供的说明集成 PayPal Express Checkout:https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/advanced-integration/

每当我单击“PayPal”按钮时,我都会收到来自 checkout.js 脚本的未定义的 indexOf 错误。我确实很快得到了模态弹出窗口,然后消失了。

TypeError: Cannot read property 'indexOf' of undefined
    at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js:11449:30)
    at _loop2 (https://www.paypalobjects.com/api/checkout.js:1670:62)
    at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js:1700:29)
    at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js:1718:18)
    at Component.buildUrl (https://www.paypalobjects.com/api/checkout.js:11448:40)
    at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js:8770:57)
    at _loop2 (https://www.paypalobjects.com/api/checkout.js:1670:62)
    at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js:1700:29)
    at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js:1718:18)
    at Function.syncPromiseTry [as try] (https://www.paypalobjects.com/api/checkout.js:1763:42)"

它引用的行在 checkout.js 中:

return props.payment().then(function(token) 
    if (token.indexOf("BA-") === 0) 

我使用的代码直接来自 PayPal 的文档:

        paypal.Button.render(
            env: 'sandbox', // Specify 'sandbox' for the test environment
            payment: function() 
                var CREATE_PAYMENT_URL = '/api/checkout/create-express-payment';
                paypal.request.post(CREATE_PAYMENT_URL)
                    .then(function(data) 
                        console.log('Payment ID: ', data.paymentId);
                        resolve(data.paymentId);
                    )
                    .catch(function(err) 
                        reject(err);
                    );
            ,

            onAuthorize: function(data, actions) 
                // Execute the payment here, when the buyer approves the transaction
            

        , '#paypal-button');

我可以确认 data.paymentId 实际上返回了正确的付款 ID,我什至尝试将其硬编码到 resolve 调用中。这个错误似乎发生在我的内部 API 甚至被调用以获取付款 ID 之前(然后在它被调用之后再次发生)。

一周以来,我一直在尝试联系 PayPal 技术支持,但在多次请求后,我什至没有收到确认。此外,我无法在 Heroku 上测试 REST API,因为它们的沙箱需要 30 多秒才能响应并且 Heroku 会超时。这将是我最后一次在项目中使用 PayPal……按照这个速度,我似乎需要尽快改变这个项目。

【问题讨论】:

【参考方案1】:

我遇到了这个问题。我的用例是 Express Checkout(客户端)和 Paypal SDK(服务器)。 Paypal 将此称为高级集成。

我解决了这个问题如下:

我让我的服务器返回一个 JSON 对象作为具有单个属性“paymentID”的响应。这在Paypal documentation 的高级集成页面中进行了解释,但是它的重要性并没有足够清楚地说明。

查看该文档的第 4 步,它清楚地说明了您需要返回什么:

    您的服务器向您的客户端发送响应以传回付款 ID:

    
        "paymentID": "PAY-0J356327TH335450NK56Y2PQ"
    
    

checkout.js 将此返回值作为“token”参数处理。

下面是适合我的代码:

 paypal.Button.render(
   env: 'sandbox',
   payment: function(resolve, reject) 
     var CREATE_PAYMENT_URL = 'http://localhost/api/payment/create';
     paypal.request.post(CREATE_PAYMENT_URL, 
     // js object used to create payment
     ).then(function(data) 
         resolve(data.paymentID);
     ).catch(function(err) 
         reject(err);
     );
   ,
   onAuthorize: function(data) 
     var EXECUTE_PAYMENT_URL = 'http://localhost/api/payment/execute';
     paypal.request.post(EXECUTE_PAYMENT_URL, 
     // js object used to complete payment
     // needs to include properties for paymentID and payerID
     ).then(function(data) 
     // process results after transaction is completed
     ).catch(function(err) );
   ,
   onCancel: function(data) 
 , '#paypal-button');

【讨论】:

不幸的是,实际上我已经设置好了。我看到的唯一区别是我返回paymentId 而不是paymentID。但是,resolve() 调用实际上不是将 paymentId 返还给它吗?你是在本地开发的吗?试图弄清楚这是否可能是一个问题,或者可能是一个没有 SSL 的问题。我最近在使用所有 PayPal API 时都遇到了问题。 我的代码使用localhost(无 ssl)在本地运行并调用 Paypal 沙箱环境。是的,传递给 resolve 方法的属性应该与服务器端返回的匹配。 这实际上是 我的问题。你已经解决了,谢谢。但我不得不嘲笑这个文档写得多么糟糕,真的。我从来没有像现在这样经常被误导或挠头。【参考方案2】:

现在你有:

payment: function() 

这需要:

payment: function(resolve, reject) 

否则resolvereject 函数将无法将paymentID 传递回checkout.js。

【讨论】:

【参考方案3】:

这个解决方案真的很有帮助,但是我们可以通过从 paypal 收到的令牌 id 来代替 payid 到 resolve 方法,resolve(data.tokenid);而不是 paypal.request.post 方法,我们可以进行 ajax 调用,代码如下,

<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div id="paypal-buttoncheckout"></div>
    paypal.Button.render(
        env: "sandbox", // Optional: specify 'sandbox' environment
        locale: //your respective locale,
        payment: function(resolve, reject)  
            var CREATE_PAYMENT_URL = //URL for creating payment
            $.ajax(
               type:'POST',
               dataType : 'html',
               contentType: 'application/html',
               url : CREATE_PAYMENT_URL,
               success : function(data)    
                   resolve(data.tokenid);
               ,
               error : function(response)

               
           );

      ,

            onAuthorize: function(data) 
                // Note: you can display a confirmation page before executing
                var EXECUTE_PAYMENT_URL = //reauthorize URL;
                paypal.request.post(EXECUTE_PAYMENT_URL,
                         paymentID: data.paymentID, payerID: data.payerID,token: data.paymentToken )
                        .then(function(data)  window.location = //SUCCESS PAGE )
                        .catch(function(err)  window.location = //ERROR PAGE);
            ,

            onCancel: function(data, actions) 
                window.location = //ON CANCEL URL
            



        , '#paypal-buttoncheckout');

谢谢, 马诺吉

【讨论】:

paypal.request.post 只是一种进行ajax调用的便捷方法

以上是关于PayPal Express Checkout.js - Checkout.js 中未定义的 indexOf的主要内容,如果未能解决你的问题,请参考以下文章

Paypal:通过 Express Checkout 定期付款,无需用户拥有 paypal 帐户

具有 Paypal 权限和 Paypal Express Checkout 的 Rails

更改 PayPal Express Checkout 插件中的 paypal 项目名称

支付完成后注销Paypal Express账户

Paypal Sandbox (express-checkout) 返回内部错误

PayPal按钮和PayPal Express Checkout之间有什么区别?