@storecraft/payments-paypal 1.0.17 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,13 +46,9 @@ const app = new App(config)
46
46
  .withPlatform(new NodePlatform())
47
47
  .withDatabase(new MongoDB())
48
48
  .withStorage(new GoogleStorage())
49
- .withPaymentGateways(
50
- {
51
- 'paypal_standard_prod': new Paypal() // config can be inferred from env variables
52
- }
53
- );
54
-
55
- await app.init();
49
+ .withPaymentGateways({
50
+ paypal_standard_prod: new Paypal() // config can be inferred from env variables
51
+ }).init();
56
52
 
57
53
  ```
58
54
 
package/adapter.html.js CHANGED
@@ -25,112 +25,179 @@ export default function html_buy_ui(config, order_data) {
25
25
  <html style="height: 100%; width: 100%">
26
26
  <head>
27
27
  <meta charset="UTF-8" />
28
+ <meta name="color-scheme" content="light">
28
29
  <meta name="viewport" content="width=device-width; height=device-height, initial-scale=1.0" />
29
30
  <title>PayPal JS SDK Standard Integration</title>
31
+ <style>
32
+ /* Variables */
33
+ * {
34
+ box-sizing: border-box;
35
+ }
36
+
37
+ body {
38
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
39
+ font-size: 10px;
40
+ width: 100vw;
41
+ max-width: 500px;
42
+ margin: auto;
43
+ padding: 10px;
44
+ -webkit-font-smoothing: antialiased;
45
+ background-color: white;
46
+ }
47
+ </style>
30
48
  </head>
31
- <body style='display: flex; flex-direction: column; justify-content: start; height: 100%; align-items: center;'>
32
- <div id="paypal-button-container" style='width: 100%' ></div>
33
- <p id="result-message"></p>
49
+ <body>
50
+ <div id="paypal-button-container" style='width: 100%' ></div>
51
+ <p id="result-message"></p>
52
+
34
53
  <!-- Initialize the JS-SDK -->
35
54
  <script src="https://www.paypal.com/sdk/js?currency=${config.default_currency_code}&client-id=${config.client_id}&intent=${config.intent_on_checkout.toLowerCase()}"></script>
36
55
 
37
56
  <!-- code -->
38
57
  <script>
39
- const resultMessage = (msg) => {
40
- document.getElementById('result-message').innerHTML = msg
41
- console.log(msg);
42
-
43
- }
44
-
45
- window.paypal
46
- .Buttons(
47
- {
48
- style: {
49
- shape: "rect",
50
- layout: "vertical",
51
- color: "gold",
52
- label: "paypal",
53
- disableMaxWidth: true
54
- },
58
+ const resultMessage = (msg) => {
59
+ document.getElementById('result-message').innerHTML = msg
60
+ console.log(msg);
61
+ }
55
62
 
56
- message: {
57
- amount: ${order_data.pricing.total},
63
+ const dispatchEvent = (event, data) => {
64
+ window?.parent?.postMessage(
65
+ {
66
+ who: "storecraft",
67
+ event,
68
+ data
58
69
  },
70
+ "*"
71
+ );
72
+ }
73
+ // Override console.log to send messages to the parent window
74
+ console.log = function(...args) {
75
+ // Log to console
76
+ dispatchEvent(
77
+ "storecraft/checkout-log",
78
+ args
79
+ );
80
+ };
81
+
82
+ console.error = function(...args) {
83
+ // Log to console
84
+ dispatchEvent(
85
+ "storecraft/checkout-error",
86
+ args
87
+ );
88
+ };
89
+
90
+ console.log(
91
+ window.location.href,
92
+ );
93
+
94
+ window.paypal
95
+ .Buttons(
96
+ {
97
+ style: {
98
+ shape: "rect",
99
+ layout: "vertical",
100
+ color: "gold",
101
+ label: "paypal",
102
+ disableMaxWidth: true
103
+ },
104
+
105
+ message: {
106
+ amount: ${order_data.pricing.total},
107
+ },
108
+
109
+ async createOrder() {
110
+ try {
111
+
112
+ if ('${orderData.id}') {
113
+ return '${orderData.id}';
114
+ }
115
+ const errorDetail = ${orderData?.details?.[0]};
116
+ const errorMessage = errorDetail
117
+ ? (errorDetail.issue + errorDetail.description + "(" + '${orderData.debug_id}' + ")")
118
+ : JSON.stringify(orderData);
59
119
 
60
- async createOrder() {
61
- try {
62
- if ('${orderData.id}') {
63
- return '${orderData.id}';
120
+ throw new Error(errorMessage);
121
+ } catch (error) {
122
+ console.error(error);
123
+ resultMessage("Could not initiate PayPal Checkout...<br><br> " + error);
64
124
  }
65
- const errorDetail = ${orderData?.details?.[0]};
66
- const errorMessage = errorDetail
67
- ? (errorDetail.issue + errorDetail.description + "(" + '${orderData.debug_id}' + ")")
68
- : JSON.stringify(orderData);
69
-
70
- throw new Error(errorMessage);
71
- } catch (error) {
72
- console.error(error);
73
- resultMessage("Could not initiate PayPal Checkout...<br><br> " + error);
74
- }
75
- },
125
+ },
76
126
 
77
- async onApprove(data, actions) {
78
- try {
79
- const response = await fetch("/api/checkout/${order_data.id}/complete", {
80
- method: "POST",
81
- headers: {
82
- "Content-Type": "application/json",
83
- },
84
- });
85
-
86
- const orderData_main = await response.json();
87
- const orderData = orderData_main.payment_gateway.on_checkout_complete;
88
-
89
- // Three cases to handle:
90
- // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
91
- // (2) Other non-recoverable errors -> Show a failure message
92
- // (3) Successful transaction -> Show confirmation or thank you message
93
-
94
- const errorDetail = orderData?.details?.[0];
95
-
96
- if (errorDetail?.issue === "INSTRUMENT_DECLINED") {
97
- // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
98
- // recoverable state, per
99
- // https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
100
- return actions.restart();
101
- } else if (errorDetail) {
102
- // (2) Other non-recoverable errors -> Show a failure message
103
- throw new Error(errorDetail.description + "(" + orderData.debug_id + ")");
104
- }
105
- // else if (!orderData.purchase_units) {
106
- // throw new Error(JSON.stringify(orderData));
107
- // }
108
- else {
109
- // (3) Successful transaction -> Show confirmation or thank you message
110
- // Or go to another URL: actions.redirect('thank_you.html');
111
- const transaction =
112
- orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
113
- orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
114
- resultMessage(
115
- "Transaction " + transaction?.status + ":" + transaction?.id +
116
- " See console for all available details"
127
+ async onApprove(data, actions) {
128
+ try {
129
+ const response = await fetch(window.location.origin + "/api/checkout/${order_data.id}/complete", {
130
+ method: "POST",
131
+ headers: {
132
+ "Content-Type": "application/json",
133
+ },
134
+ });
135
+
136
+ const orderData_main = await response.json();
137
+ const orderData = orderData_main.payment_gateway.on_checkout_complete;
138
+
139
+ // Three cases to handle:
140
+ // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
141
+ // (2) Other non-recoverable errors -> Show a failure message
142
+ // (3) Successful transaction -> Show confirmation or thank you message
143
+
144
+ const errorDetail = orderData?.details?.[0];
145
+
146
+ if (errorDetail?.issue === "INSTRUMENT_DECLINED") {
147
+ // (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
148
+ // recoverable state, per
149
+ // https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
150
+ return actions.restart();
151
+ } else if (errorDetail) {
152
+ // (2) Other non-recoverable errors -> Show a failure message
153
+ throw new Error(errorDetail.description + "(" + orderData.debug_id + ")");
154
+ }
155
+ // else if (!orderData.purchase_units) {
156
+ // throw new Error(JSON.stringify(orderData));
157
+ // }
158
+ else {
159
+ // (3) Successful transaction -> Show confirmation or thank you message
160
+ // Or go to another URL: actions.redirect('thank_you.html');
161
+ const transaction =
162
+ orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
163
+ orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
164
+ resultMessage(
165
+ "Transaction " + transaction?.status + ":" + transaction?.id +
166
+ " See console for all available details"
167
+ );
168
+ console.log(
169
+ "Capture result",
170
+ orderData,
171
+ JSON.stringify(orderData, null, 2)
172
+ );
173
+ dispatchEvent(
174
+ "storecraft/checkout-complete",
175
+ {
176
+ orderData,
177
+ order_id: '${orderData.id}',
178
+ payment_gateway: 'paypal'
179
+ }
180
+ );
181
+
182
+ }
183
+ } catch (error) {
184
+ console.error(error);
185
+ dispatchEvent(
186
+ "storecraft/checkout-error",
187
+ {
188
+ error: error.message,
189
+ order_id: '${orderData.id}',
190
+ payment_gateway: 'paypal'
191
+ }
117
192
  );
118
- console.log(
119
- "Capture result",
120
- orderData,
121
- JSON.stringify(orderData, null, 2)
193
+ resultMessage(
194
+ "Sorry, your transaction could not be processed... " + error
122
195
  );
123
196
  }
124
- } catch (error) {
125
- console.error(error);
126
- resultMessage(
127
- "Sorry, your transaction could not be processed... " + error
128
- );
129
197
  }
198
+
130
199
  }
131
-
132
- }
133
- ).render("#paypal-button-container");
200
+ ).render("#paypal-button-container");
134
201
 
135
202
  </script>
136
203
 
package/adapter.js CHANGED
@@ -26,13 +26,13 @@ import html_buy_ui from './adapter.html.js';
26
26
  export class Paypal {
27
27
 
28
28
  /** @satisfies {ENV<Config>} */
29
- static EnvConfigProd = /** @type{const} */ ({
29
+ static EnvConfigProd = /** @type {const} */ ({
30
30
  client_id: `PAYPAL_CLIENT_ID_PROD`,
31
31
  secret: 'PAYPAL_SECRET_PROD',
32
32
  });
33
33
 
34
34
  /** @satisfies {ENV<Config>} */
35
- static EnvConfigTest = /** @type{const} */ ({
35
+ static EnvConfigTest = /** @type {const} */ ({
36
36
  client_id: `PAYPAL_CLIENT_ID_TEST`,
37
37
  secret: 'PAYPAL_SECRET_TEST',
38
38
  });
@@ -56,19 +56,19 @@ export class Paypal {
56
56
  /** @type {Impl["onInit"]} */
57
57
  onInit = (app) => {
58
58
  const is_prod = Boolean(this.config.env==='prod');
59
- this.config.client_id ??= app.platform.env[
59
+ this.config.client_id ??= app.env[
60
60
  is_prod ? Paypal.EnvConfigProd.client_id : Paypal.EnvConfigTest.client_id
61
- ] ?? app.platform.env['PAYPAL_CLIENT_ID'];
61
+ ] ?? app.env['PAYPAL_CLIENT_ID'];
62
62
 
63
- this.config.secret ??= app.platform.env[
63
+ this.config.secret ??= app.env[
64
64
  is_prod ? Paypal.EnvConfigProd.secret : Paypal.EnvConfigTest.secret
65
- ] ?? app.platform.env['PAYPAL_SECRET'];
65
+ ] ?? app.env['PAYPAL_SECRET'];
66
66
 
67
67
  const is_valid = this.config.client_id && this.config.secret;
68
68
 
69
69
  if(!is_valid) {
70
70
  throw new StorecraftError(
71
- `Payment gateway ${this.info.name ?? 'unknown'} has invalid config !!!
71
+ `Payment gateway ${this.info?.name ?? 'unknown'} has invalid config !!!
72
72
  Missing client_id or secret`
73
73
  )
74
74
  }
@@ -77,8 +77,7 @@ export class Paypal {
77
77
  get info() {
78
78
  return {
79
79
  name: 'Paypal payments',
80
- description: `Set up standard and advanced payments to present payment buttons to your payers so they can pay with PayPal, debit and credit cards, Pay Later options, Venmo, and alternative payment methods.
81
- You can get started quickly with this 15-minute copy-and-paste integration. If you have an older Checkout integration, you can upgrade your Checkout integration.`,
80
+ description: `Pay with Paypal Wallet or Credit Card`,
82
81
  url: 'https://developer.paypal.com/docs/checkout/',
83
82
  logo_url: 'https://www.paypalobjects.com/webstatic/mktg/logo/pp_cc_mark_37x23.jpg'
84
83
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/payments-paypal",
3
- "version": "1.0.17",
3
+ "version": "1.3.0",
4
4
  "description": "Official Paypal integration with Storecraft",
5
5
  "license": "MIT",
6
6
  "author": "Tomer Shalev (https://github.com/store-craft)",
@@ -21,8 +21,7 @@
21
21
  "types": "types.public.d.ts",
22
22
  "scripts": {
23
23
  "payments-paypal:test": "uvu -c",
24
- "test": "npm run payments-paypal:test",
25
- "prepublishOnly": "npm version patch --force"
24
+ "test": "npm run payments-paypal:test"
26
25
  },
27
26
  "dependencies": {},
28
27
  "devDependencies": {