|
1 |
| -const main = async () => { |
2 |
| - const user = localStorage.getItem("user"); |
3 |
| - const response = await fetch(`/api/id-token?user=${user}`); |
4 |
| - const data = await response.json(); |
5 |
| - const script = document.createElement("script"); |
6 |
| - script.src = "https://www.paypal.com/sdk/js?client-id=test"; |
7 |
| - script.setAttribute("data-user-id-token", data.id_token); |
8 |
| - script.addEventListener("load", () => renderButtons()); |
9 |
| - document.head.appendChild(script); |
10 |
| -}; |
| 1 | +window.paypal |
| 2 | + .Buttons({ |
| 3 | + async createOrder() { |
| 4 | + try { |
| 5 | + const response = await fetch("/api/orders", { |
| 6 | + method: "POST", |
| 7 | + headers: { |
| 8 | + "Content-Type": "application/json", |
| 9 | + }, |
| 10 | + // use the "body" param to optionally pass additional order information |
| 11 | + // like product ids and quantities |
| 12 | + body: JSON.stringify({ |
| 13 | + cart: [ |
| 14 | + { |
| 15 | + id: "YOUR_PRODUCT_ID", |
| 16 | + quantity: "YOUR_PRODUCT_QUANTITY", |
| 17 | + }, |
| 18 | + ], |
| 19 | + }), |
| 20 | + }); |
11 | 21 |
|
12 |
| -main(); |
| 22 | + const orderData = await response.json(); |
13 | 23 |
|
14 |
| -const renderButtons = () => |
15 |
| - window.paypal |
16 |
| - .Buttons({ |
17 |
| - async createOrder() { |
18 |
| - try { |
19 |
| - const response = await fetch("/api/orders", { |
20 |
| - method: "POST", |
21 |
| - headers: { |
22 |
| - "Content-Type": "application/json", |
23 |
| - }, |
24 |
| - // use the "body" param to optionally pass additional order information |
25 |
| - // like product ids and quantities |
26 |
| - body: JSON.stringify({ |
27 |
| - cart: [ |
28 |
| - { |
29 |
| - id: "YOUR_PRODUCT_ID", |
30 |
| - quantity: "YOUR_PRODUCT_QUANTITY", |
31 |
| - }, |
32 |
| - ], |
33 |
| - }), |
34 |
| - }); |
35 |
| - |
36 |
| - const orderData = await response.json(); |
37 |
| - |
38 |
| - if (orderData.id) { |
39 |
| - return orderData.id; |
40 |
| - } else { |
41 |
| - const errorDetail = orderData?.details?.[0]; |
42 |
| - const errorMessage = errorDetail |
43 |
| - ? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})` |
44 |
| - : JSON.stringify(orderData); |
| 24 | + if (orderData.id) { |
| 25 | + return orderData.id; |
| 26 | + } else { |
| 27 | + const errorDetail = orderData?.details?.[0]; |
| 28 | + const errorMessage = errorDetail |
| 29 | + ? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})` |
| 30 | + : JSON.stringify(orderData); |
45 | 31 |
|
46 |
| - throw new Error(errorMessage); |
47 |
| - } |
48 |
| - } catch (error) { |
49 |
| - console.error(error); |
50 |
| - resultMessage( |
51 |
| - `Could not initiate PayPal Checkout...<br><br>${error}`, |
52 |
| - ); |
| 32 | + throw new Error(errorMessage); |
53 | 33 | }
|
54 |
| - }, |
55 |
| - async onApprove(data, actions) { |
56 |
| - try { |
57 |
| - const response = await fetch(`/api/orders/${data.orderID}/capture`, { |
58 |
| - method: "POST", |
59 |
| - headers: { |
60 |
| - "Content-Type": "application/json", |
61 |
| - }, |
62 |
| - }); |
| 34 | + } catch (error) { |
| 35 | + console.error(error); |
| 36 | + resultMessage(`Could not initiate PayPal Checkout...<br><br>${error}`); |
| 37 | + } |
| 38 | + }, |
| 39 | + async onApprove(data, actions) { |
| 40 | + try { |
| 41 | + const response = await fetch(`/api/orders/${data.orderID}/capture`, { |
| 42 | + method: "POST", |
| 43 | + headers: { |
| 44 | + "Content-Type": "application/json", |
| 45 | + }, |
| 46 | + }); |
63 | 47 |
|
64 |
| - const orderData = await response.json(); |
65 |
| - // Three cases to handle: |
66 |
| - // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() |
67 |
| - // (2) Other non-recoverable errors -> Show a failure message |
68 |
| - // (3) Successful transaction -> Show confirmation or thank you message |
| 48 | + const orderData = await response.json(); |
| 49 | + // Three cases to handle: |
| 50 | + // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() |
| 51 | + // (2) Other non-recoverable errors -> Show a failure message |
| 52 | + // (3) Successful transaction -> Show confirmation or thank you message |
69 | 53 |
|
70 |
| - const errorDetail = orderData?.details?.[0]; |
71 |
| - |
72 |
| - if (errorDetail?.issue === "INSTRUMENT_DECLINED") { |
73 |
| - // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() |
74 |
| - // recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/ |
75 |
| - return actions.restart(); |
76 |
| - } else if (errorDetail) { |
77 |
| - // (2) Other non-recoverable errors -> Show a failure message |
78 |
| - throw new Error( |
79 |
| - `${errorDetail.description} (${orderData.debug_id})`, |
80 |
| - ); |
81 |
| - } else if (!orderData.purchase_units) { |
82 |
| - throw new Error(JSON.stringify(orderData)); |
83 |
| - } else { |
84 |
| - // (3) Successful transaction -> Show confirmation or thank you message |
85 |
| - // Or go to another URL: actions.redirect('thank_you.html'); |
86 |
| - const transaction = |
87 |
| - orderData?.purchase_units?.[0]?.payments?.captures?.[0] || |
88 |
| - orderData?.purchase_units?.[0]?.payments?.authorizations?.[0]; |
89 |
| - resultMessage( |
90 |
| - `Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`, |
91 |
| - ); |
92 |
| - |
93 |
| - localStorage.setItem( |
94 |
| - "user", |
95 |
| - orderData.payment_source.paypal.attributes.vault.customer.id, |
96 |
| - ); |
| 54 | + const errorDetail = orderData?.details?.[0]; |
97 | 55 |
|
98 |
| - console.log( |
99 |
| - "Capture result", |
100 |
| - orderData, |
101 |
| - JSON.stringify(orderData, null, 2), |
102 |
| - ); |
103 |
| - } |
104 |
| - } catch (error) { |
105 |
| - console.error(error); |
| 56 | + if (errorDetail?.issue === "INSTRUMENT_DECLINED") { |
| 57 | + // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart() |
| 58 | + // recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/ |
| 59 | + return actions.restart(); |
| 60 | + } else if (errorDetail) { |
| 61 | + // (2) Other non-recoverable errors -> Show a failure message |
| 62 | + throw new Error(`${errorDetail.description} (${orderData.debug_id})`); |
| 63 | + } else if (!orderData.purchase_units) { |
| 64 | + throw new Error(JSON.stringify(orderData)); |
| 65 | + } else { |
| 66 | + // (3) Successful transaction -> Show confirmation or thank you message |
| 67 | + // Or go to another URL: actions.redirect('thank_you.html'); |
| 68 | + const transaction = |
| 69 | + orderData?.purchase_units?.[0]?.payments?.captures?.[0] || |
| 70 | + orderData?.purchase_units?.[0]?.payments?.authorizations?.[0]; |
106 | 71 | resultMessage(
|
107 |
| - `Sorry, your transaction could not be processed...<br><br>${error}`, |
| 72 | + `Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details.<br> |
| 73 | + <a href='/?${orderData.payment_source.paypal.attributes.vault.customer.id}'>See the return buyer experience</a> |
| 74 | + `, |
| 75 | + ); |
| 76 | + |
| 77 | + console.log( |
| 78 | + "Capture result", |
| 79 | + orderData, |
| 80 | + JSON.stringify(orderData, null, 2), |
108 | 81 | );
|
109 | 82 | }
|
110 |
| - }, |
111 |
| - }) |
112 |
| - .render("#paypal-button-container"); |
| 83 | + } catch (error) { |
| 84 | + console.error(error); |
| 85 | + resultMessage( |
| 86 | + `Sorry, your transaction could not be processed...<br><br>${error}`, |
| 87 | + ); |
| 88 | + } |
| 89 | + }, |
| 90 | + }) |
| 91 | + .render("#paypal-button-container"); |
113 | 92 |
|
114 | 93 | // Example function to show a result to the user. Your site's UI library can be used instead.
|
115 | 94 | function resultMessage(message) {
|
|
0 commit comments