Javascript 在Vue.js组件中放置PayPal按钮

Javascript 在Vue.js组件中放置PayPal按钮,javascript,vue.js,paypal,vue-component,Javascript,Vue.js,Paypal,Vue Component,我正在尝试将PayPal订单按钮放在我的Vue.js组件中 我遵循的原则基本上是做3件事: 导入PayPal SDK脚本 定义将在其中呈现按钮的元素 添加一些javascript tode来配置回调,并使用变量paypal 这是我在普通HTML文件中执行此操作时的外观: <!-- 1 --> <script src="https://www.paypal.com/sdk/js?&client-id=xxx"></script>

我正在尝试将PayPal订单按钮放在我的Vue.js组件中

我遵循的原则基本上是做3件事:

  • 导入PayPal SDK脚本
  • 定义将在其中呈现按钮的
    元素
  • 添加一些javascript tode来配置回调,并使用变量
    paypal
  • 这是我在普通HTML文件中执行此操作时的外观:

    <!-- 1 -->
    
    <script src="https://www.paypal.com/sdk/js?&client-id=xxx"></script>
    
    <!-- 2 -->
    
    <div id="paypal-button-container"></div>
    
    <!-- 3 -->
    
    <script>
      paypal.Buttons({
        createOrder: function (data, actions) {
          return fetch('http://localhost:8081/api/v1/pay-pal/create-order', {
            method: 'POST'
          }).then(function(res) {
            return res.json();
          }).then(function(data) {
            return data.id;
          });
        },
        onApprove: function (data, actions) {
          return fetch('http://localhost:8081/api/v1/pay-pal/capture-order/' + data.orderID, {
            method: 'POST'
          }).then(function(res) {
            if (!res.ok) {
              alert('Something went wrong');
            }
          });
        }
      }).render('#paypal-button-container');
    </script>
    
    步骤2很简单,我只是在模板中添加了
    div
    元素

    但是我应该把javascript代码放在哪里执行步骤3呢

    我尝试将其放置在外部js文件中,并将其加载到
    mounted()
    方法中,如下所示:

    mounted() {
        let payPalSdk = document.createElement('script')
        payPalSdk.setAttribute('src', 'https://www.paypal.com/sdk/js?&client-id=xxx')
        document.head.appendChild(payPalSdk)
    }
    
    mounted() {
        let payPalSdk = document.createElement('script')
        payPalSdk.setAttribute('src', 'https://www.paypal.com/sdk/js?&client-id=xxx')
        document.head.appendChild(payPalSdk)
    
        let payPalScript = document.createElement('script')
        payPalScript.setAttribute('src', '/js/paypal.js')
        document.head.appendChild(payPalScript)
    }
    
    paypal.js:

      paypal.Buttons({
        createOrder: function (data, actions) {
          return fetch('http://localhost:8081/api/v1/pay-pal/create-order', {
            method: 'POST'
          }).then(function(res) {
            return res.json();
          }).then(function(data) {
            return data.id;
          });
        },
        onApprove: function (data, actions) {
          return fetch('http://localhost:8081/api/v1/pay-pal/capture-order/' + data.orderID, {
            method: 'POST'
          }).then(function(res) {
            if (!res.ok) {
              alert('Something went wrong');
            }
          });
        }
      }).render('#paypal-button-container');
    
    按钮确实会被渲染,但控制台显示以下错误:

    buttons?style.layout…re&commit=true:1182 unhandled_error 
    {err: "Error: Invalid json: .↵    at XMLHttpRequest.<anon…rrency=USD&intent=capture&commit=true:1182:22901)", timestamp: "1605367583366", referer: "www.sandbox.paypal.com", sdkCorrelationID: "7d650f42fd450", sessionID: "09b33213cd_mtu6mjy6mja", …}
    buttonCorrelationID: "72135879fd67d"
    buttonSessionID: "473d7ab57f_mtu6mjy6mja"
    env: "sandbox"
    err: "Error: Invalid json: .↵    at XMLHttpRequest.<anonymous> (https://www.sandbox.paypal.com/smart/buttons?style.layout=vertical&style.color=gold&style.shape=rect&style.tagline=false&components.0=buttons&locale.country=US&locale.lang=en&sdkMeta=eyJ1cmwiOiJodHRwczovL3d3dy5wYXlwYWwuY29tL3Nkay9qcz8mY2xpZW50LWlkPUFUX1hyMUl3ekZpM2ItRmhFd0RMQ0VndEM2Y2F4MHgwaWR1VF9yeEprQUhycFRlUXpkbHZRRDhKWFUxZmlNQ01vclN3T1hSWWU1eVVPaENBIiwiYXR0cnMiOnsiZGF0YS11aWQiOiJlOGQyMGY4MzBlX210dTZtank2bWphIn19&clientID=xxx&sessionID=09b33213cd_mtu6mjy6mja&buttonSessionID=473d7ab57f_mtu6mjy6mja&enableBNPL=true&env=sandbox&fundingEligibility=eyJwYXlwYWwiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sInBheWxhdGVyIjp7ImVsaWdpYmxlIjpmYWxzZSwicHJvZHVjdHMiOnsiZmxleCI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJwYXlJbjQiOnsiZWxpZ2libGUiOmZhbHNlfX19LCJjYXJkIjp7ImVsaWdpYmxlIjp0cnVlLCJicmFuZGVkIjp0cnVlLCJpbnN0YWxsbWVudHMiOmZhbHNlLCJ2ZW5kb3JzIjp7InZpc2EiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sIm1hc3RlcmNhcmQiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImFtZXgiOnsiZWxpZ2libGUiOnRydWUsInZhdWx0YWJsZSI6dHJ1ZX0sImRpc2NvdmVyIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiaGlwZXIiOnsiZWxpZ2libGUiOmZhbHNlLCJ2YXVsdGFibGUiOmZhbHNlfSwiZWxvIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfSwiamNiIjp7ImVsaWdpYmxlIjpmYWxzZSwidmF1bHRhYmxlIjp0cnVlfX19LCJ2ZW5tbyI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJpdGF1Ijp7ImVsaWdpYmxlIjpmYWxzZX0sImNyZWRpdCI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJzZXBhIjp7ImVsaWdpYmxlIjpmYWxzZX0sImlkZWFsIjp7ImVsaWdpYmxlIjpmYWxzZX0sImJhbmNvbnRhY3QiOnsiZWxpZ2libGUiOmZhbHNlfSwiZ2lyb3BheSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJlcHMiOnsiZWxpZ2libGUiOmZhbHNlfSwic29mb3J0Ijp7ImVsaWdpYmxlIjpmYWxzZX0sIm15YmFuayI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJwMjQiOnsiZWxpZ2libGUiOmZhbHNlfSwiemltcGxlciI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJ3ZWNoYXRwYXkiOnsiZWxpZ2libGUiOmZhbHNlfSwicGF5dSI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJibGlrIjp7ImVsaWdpYmxlIjpmYWxzZX0sInRydXN0bHkiOnsiZWxpZ2libGUiOmZhbHNlfSwib3h4byI6eyJlbGlnaWJsZSI6ZmFsc2V9LCJtYXhpbWEiOnsiZWxpZ2libGUiOmZhbHNlfSwiYm9sZXRvIjp7ImVsaWdpYmxlIjpmYWxzZX0sIm1lcmNhZG9wYWdvIjp7ImVsaWdpYmxlIjpmYWxzZX19&platform=desktop&flow=purchase&currency=USD&intent=capture&commit=true:1182:22901)"
    referer: "www.sandbox.paypal.com"
    sdkCorrelationID: "7d650f42fd450"
    sessionID: "09b33213cd_mtu6mjy6mja"
    timestamp: "1605367583366"
    __proto__: Object
    y   @   buttons?style.layout…re&commit=true:1182
    S   @   buttons?style.layout…re&commit=true:1182
    error   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    setTimeout (async)      
    n.reject    @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.reject    @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.reject    @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.reject    @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    load (async)        
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    e   @   buttons?style.layout…re&commit=true:1182
    ke  @   buttons?style.layout…re&commit=true:1182
    Oe  @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    e.try   @   buttons?style.layout…re&commit=true:1182
    w   @   buttons?style.layout…re&commit=true:1182
    e.try   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    setTimeout (async)      
    w::promiseDebounced @   buttons?style.layout…re&commit=true:1182
    G.then.intent   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    n.dispatch  @   buttons?style.layout…re&commit=true:1182
    n.resolve   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    setInterval (async)     
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    e   @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1182
    anonymous::memoized @   buttons?style.layout…re&commit=true:1182
    G.style @   buttons?style.layout…re&commit=true:1182
    ht  @   buttons?style.layout…re&commit=true:1182
    (anonymous) @   buttons?style.layout…re&commit=true:1183
    
    buttons?style.layout…re&commit=true:1182未处理的\u错误
    {err:“错误:无效的json:”。↵    在XMLHttpRequest.尝试从mounted()执行此操作,查看加载PayPal JS后使用回调或客户端createOrder/onApprove是否会有所不同

    function loadAsync(url, callback) {
      var s = document.createElement('script');
      s.setAttribute('src', url); s.onload = callback;
      document.head.insertBefore(s, document.head.firstElementChild);
    }
    
    loadAsync('https://www.paypal.com/sdk/js?client-id=sb&currency=USD', function() {
      paypal.Buttons({
    
        // Set up the transaction
        createOrder: function(data, actions) {
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: '0.01'
                    }
                }]
            });
        },
    
        // Finalize the transaction
        onApprove: function(data, actions) {
            return actions.order.capture().then(function(details) {
                // Show a success message to the buyer
                alert('Transaction completed by ' + details.payer.name.given_name);
            });
        }
    
      }).render('#paypal-button-container');
    });
    


    至于实际的客户端批准代码,并与您的服务器后端配对,我建议使用

    的错误处理。谢谢,我用这种方法尝试过,但得到了完全相同的错误。有关您的vue环境的某些信息正在干扰或阻止XHR请求。请检查网络选项卡和跨站点标题。所有致电paypal.com的电话在“网络”选项卡中,返回200。您所说的“检查跨站点标题”是什么意思“?如果它们是200,那么响应体不是JSON呢?我没有看到任何返回JSON的请求。即使在工作示例中也没有。@tao该URL实际上返回HTML,而不是JSON。这不是问题所在,因为当我在工作示例中尝试它时,它返回相同的HTML。”。