簡體   English   中英

如何使用 paypal 的 javascript sdk 從創建訂單 api 的響應鏈接批准訂單?

[英]How to approve order from response links of create order api using paypal's javascript sdk?

我正在嘗試在客戶端使用 javascript sdk 實現貝寶高級信用卡和借記卡付款。 我使用以下示例作為參考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>

執行上述代碼段后,將其作為響應

{name: "UNPROCESSABLE_ENTITY", details: [{issue: "ORDER_NOT_APPROVED",…}],…} debug_id: "a63fbc3806995" details: [{issue: "ORDER_NOT_APPROVED",…}] 0: {issue: "ORDER_NOT_APPROVED",_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",...} 消息:“無法執行請求的操作、語義不正確或業務驗證失敗。” name: "UNPROCESSABLE_ENTITY

如何使用批准 url 鏈接批准訂單,因為用戶在執行訂單捕獲之前使用信用卡詳細信息進行付款而無需登錄貝寶。

批准 URL 鏈接不與 JavaScript SDK 結合使用。

使用托管字段時,審批步驟是卡片字段提交,這會觸發cardFields.submit({ .

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM