如何使用paypal的javascript sdk从创建订单api的响应链接批准订单?

jc3wubiy  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(591)

我正在尝试在客户端使用javascript sdk实现paypal高级信用卡和借记卡支付。我使用下面的例子作为参考https://developer.paypal.com/docs/business/checkout/advanced-card-payments/.
我已经创建了订单,获得了作为响应的链接,如何使用approve url链接批准订单,因为用户在执行订单捕获之前使用信用卡详细信息进行支付,而不使用paypal登录。
我知道这并不是实现这一目标的最佳方法。首先,我想尝试一下paypal文档中给出的这个示例。稍后我将在服务器端实现它,以避免安全漏洞。

<html>
<head>

  <meta charset="utf-8"/>

  <!-- Optimal rendering on mobile devices. -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- Optimal Internet Explorer compatibility -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />

  <!-- Sample CSS styles for demo purposes. You can override these styles to match your web page's branding. -->
  <link rel="stylesheet" type="text/css" href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"/>

</head>
<body>

<!-- JavaScript SDK -->
 <script src="https://www.paypal.com/sdk/js?components=buttons,hosted-fields&client-id=abc" 
 data-client-token="xyz">

   <div align="center"> or </div>

   <!-- Advanced credit and debit card payments form -->
   <div class="card_container">
     <form id="card-form">

       <label for="card-number">Card Number</label><div id="card-number" class="card_field"></div>
       <div>
         <label for="expiration-date">Expiration Date</label>
         <div id="expiration-date" class="card_field"></div>
       </div>
       <div>
         <label for="cvv">CVV</label><div id="cvv" class="card_field"></div>
       </div>
       <label for="card-holder-name">Name on Card</label>
       <input type="text" id="card-holder-name" name="card-holder-name" autocomplete="off" placeholder="card holder name"/>
       <button value="submit" id="submit" class="btn">Pay</button>
     </form>
   </div>

   <!-- Implementation -->
   <script>
     let orderId;

     // Displays PayPal buttons
     paypal.Buttons({
       style: {
         layout: 'horizontal'
       },
        createOrder: function(data, actions) {
           return actions.order.create({
             purchase_units: [{
               amount: {
                 value: "1.00"
               }
             }]
           });
         },
         onApprove: function(data, actions) {
           return actions.order.capture().then(function(details) {
               console.log(details)
             window.location.href = '/success.html';
           });
         }
     }).render("#paypal-button-container");

     // If this returns false or the card fields aren't visible, see Step #1.
     if (paypal.HostedFields.isEligible()) {

       // Renders card fields
       paypal.HostedFields.render({
         // Call your server to set up the transaction
         createOrder: function () {
           return fetch('https://api-m.sandbox.paypal.com/v2/checkout/orders', {
            method: 'post',
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json',
              'Authorization': 'Bearer wert'
            }

          }).then(function(res) {
              return res.json();
          }).then(function(orderData) {
              console.log(orderData)
            orderId = orderData.id;

             fetch('https://api-m.sandbox.paypal.com/v2/checkout/orders/' + orderId + '/capture/', {
               method: 'post',
               headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer AGeU7jOKBXFPa0Fe_e9Xv3g',
                    'PayPal-Request-Id': '7b92603e-77ed-4896-8e78-5dea2050476a'
                    },
                    "application_context": {
                    "return_url": "https://google.com"
                }
             }).then(function(res) {
               console.log(res)
                return res.json();
             })

           // return orderId;
          });
         },
         onApprove: function(data) {
          console.log(data) 
          return fetch('/my-server/capture-paypal-transaction', {
            headers: {
              'content-type': 'application/json'
            },
            body: JSON.stringify({
              orderID: data.orderID
            })
          }).then(function(res) {
            return res.json();
          }).then(function(details) {
            alert('Transaction funds captured from ' + details.payer_given_name);
          })

         },

         styles: {
           '.valid': {
            'color': 'green'
           },
           '.invalid': {
            'color': 'red'
           }
         },

         fields: {
           number: {
             selector: "#card-number",
             placeholder: "4111 1111 1111 1111"
           },
           cvv: {
             selector: "#cvv",
             placeholder: "123"
           },
           expirationDate: {
             selector: "#expiration-date",
             placeholder: "MM/YY"
           }
         }
       }).then(function (cardFields) {
         document.querySelector("#card-form").addEventListener('submit', (event) => {
           event.preventDefault();

           cardFields.submit({
             // Cardholder's first and last name
             cardholderName: document.getElementById('card-holder-name').value,
             // Billing Address
            //  billingAddress: {
            //    // Street address, line 1
            //    streetAddress: document.getElementById('card-billing-address-street').value,
            //    // Street address, line 2 (Ex: Unit, Apartment, etc.)
            //    extendedAddress: document.getElementById('card-billing-address-unit').value,
            //    // State
            //    region: document.getElementById('card-billing-address-state').value,
            //    // City
            //    locality: document.getElementById('card-billing-address-city').value,
            //    // Postal Code
            //    postalCode: document.getElementById('card-billing-address-zip').value,
            //    // Country Code
            //    countryCodeAlpha2: document.getElementById('card-billing-address-country').value
            //  }
           }).then(function (data) {
               console.log(orderId)
               console.log(data);
            fetch('https://api-m.sandbox.paypal.com/v2/checkout/orders/' + orderId + '/capture/', {
               method: 'post',
               headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer AjOKBXFPa0Fe_e9Xv3g'

                    },
                    "application_context": {
                    "return_url": "https://google.com"
                }
             }).then(function(res) {
               console.log(res)
                return res.json();
             }).then(function (orderData) {
               console.log(orderData)
                // Three cases to handle:
                //   (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
                //   (2) Other non-recoverable errors -> Show a failure message
                //   (3) Successful transaction -> Show confirmation or thank you

                // This example reads a v2/checkout/orders capture response, propagated from the server
                // You could use a different API or structure for your 'orderData'
                var errorDetail = Array.isArray(orderData.details) && orderData.details[0];

                if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
                  return actions.restart(); // Recoverable state, per:
                  // https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
                }

                if (errorDetail) {
                    var msg = 'Sorry, your transaction could not be processed.';
                    if (errorDetail.description) msg += '\n\n' + errorDetail.description;
                    if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
                    return alert(msg); // Show a failure message
                }

                // Show a success message or redirect
                alert('Transaction completed!');
             })
          }).catch(function (err) {
            alert('Payment could not be captured! ' + JSON.stringify(err))
          });
         });
       });
     } else {
       // Hides card fields if the merchant isn't eligible
       document.querySelector("#card-form").style = 'display: none';
     }
   </script>

   </body>
   </html>

执行上述代码段后,将其作为响应获取
{name:“无法处理的实体”,详细信息:[{issue:“订单未批准”,…},…}调试id:“a63fbc3806995”详细信息:[{issue:“订单未批准”,…}]0:{issue:“订单未批准”,…}链接:[{href:https://developer.paypal.com/docs/api/orders/v2/#error-订单未批准“,…}]0:{href:https://developer.paypal.com/docs/api/orders/v2/#error-订单未批准“,…}消息:“请求的操作无法执行、语义不正确或业务验证失败。”名称:“无法处理的实体”

agyaoht7

agyaoht71#

如何使用approve url链接批准订单,因为用户在执行订单捕获之前使用信用卡详细信息进行支付,而无需登录paypal。
approval url链接未与javascript sdk一起使用。
使用托管字段时,审批步骤是提交卡片字段,这会触发 cardFields.submit({ .
使用托管字段需要服务器端集成来捕获已批准(提交)的付款。

相关问题