【问题标题】:How to approve order from response links of create order api using paypal's javascript sdk?如何使用paypal的javascript sdk从create order api的响应链接中批准订单?
【发布时间】:2021-10-03 00:00:34
【问题描述】:

我正在尝试在客户端使用 javascript sdk 实施 paypal 高级信用卡和借记卡付款。我使用以下示例作为参考https://developer.paypal.com/docs/business/checkout/advanced-card-payments/

我已经创建了订单,获得了响应链接,如何使用批准 url 链接批准订单,因为用户在执行订单捕获之前使用信用卡详细信息进行付款而无需登录贝宝。

我知道这不是此实现的最佳方法。首先我想尝试一下paypal docs中给出的这个例子。我稍后会在服务器端实现它以避免安全漏洞。

<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>

执行上面的 sn-p 后,得到这个作为响应

{名称:“UNPROCESSABLE_ENTITY”,详细信息:[{问题:“ORDER_NOT_APPROVED”,…}],…} debug_id:“a63fbc3806995” 详细信息:[{问题:“ORDER_NOT_APPROVED”,...}] 0:{问题:“ORDER_NOT_APPROVED”,…} 链接:[{href:“https://developer.paypal.com/docs/api/orders/v2/#error-ORDER_NOT_APPROVED”,...}] 0:{href:“https://developer.paypal.com/docs/api/orders/v2/#error-ORDER_NOT_APPROVED”,...} 消息:“请求的操作无法执行、语义不正确或业务验证失败。” 名称:“UNPROCESSABLE_ENTITY

【问题讨论】:

    标签: javascript paypal paypal-sandbox paypal-rest-sdk


    【解决方案1】:

    当用户在执行订单捕获之前使用信用卡详细信息进行支付而无需登录贝宝时,如何使用批准 url 链接批准订单。

    审批 URL 链接不与 JavaScript SDK 一起使用。

    使用托管字段时,审批步骤为卡片字段提交,触发cardFields.submit({

    使用托管字段需要服务器端集成以捕获已批准(提交)的付款。

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 1970-01-01
      • 2021-02-20
      • 2022-01-15
      • 2021-01-15
      • 2021-02-24
      • 2020-11-11
      • 2017-04-09
      • 1970-01-01
      相关资源
      最近更新 更多