@easypayment/medusa-paypal-ui 1.0.44 โ†’ 1.0.45

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.
Files changed (2) hide show
  1. package/README.md +134 -192
  2. package/package.json +5 -1
package/README.md CHANGED
@@ -1,89 +1,76 @@
1
- <div align="center">
1
+ # PayPal for Medusa Frontend UI
2
2
 
3
- <h1>๐Ÿ…ฟ medusa-paypal-frontend</h1>
3
+ **PayPal checkout UI for Medusa v2 storefronts โ€” Smart Buttons, Advanced Card Fields**
4
4
 
5
- <p><strong>PayPal checkout UI for Medusa v2 storefronts</strong></p>
5
+ [![npm version](https://img.shields.io/npm/v/@easypayment/medusa-paypal-ui?color=blue&label=npm)](https://www.npmjs.com/package/@easypayment/medusa-paypal-ui)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
7
+ [![Medusa v2](https://img.shields.io/badge/Medusa-v2-9b59b6)](https://medusajs.com)
8
+ [![Next.js](https://img.shields.io/badge/Next.js-14%2B-black)](https://nextjs.org)
6
9
 
7
- <p>
8
- <a href="https://www.npmjs.com/package/@easypayment/medusa-paypal-ui"><img src="https://img.shields.io/npm/v/@easypayment/medusa-paypal-ui?color=blue&label=npm" alt="npm version" /></a>
9
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT" /></a>
10
- <a href="https://medusajs.com"><img src="https://img.shields.io/badge/Medusa-v2-9b59b6" alt="Medusa v2" /></a>
11
- <a href="https://nextjs.org"><img src="https://img.shields.io/badge/Next.js-14%2B-black" alt="Next.js" /></a>
12
- </p>
13
-
14
- <p>PayPal Smart Buttons ยท Advanced Card Fields ยท Built-in loading states ยท Admin-controlled settings</p>
10
+ ---
15
11
 
16
- </div>
12
+ ## ๐Ÿ“‹ Table of Contents
13
+
14
+ - [๐Ÿ“ฆ Overview](#-overview)
15
+ - [โœ… Requirements](#-requirements)
16
+ - [๐Ÿš€ Installation](#-installation)
17
+ - [๐Ÿ”‘ Environment Variables](#-environment-variables)
18
+ - [๐Ÿ”— Integration Guide](#-integration-guide)
19
+ - [Step 1 โ€” Add the import](#step-1--add-the-import)
20
+ - [Step 2 โ€” Add PayPal helpers and state](#step-2--add-paypal-helpers-and-state)
21
+ - [Step 3 โ€” Load PayPal config](#step-3--load-paypal-config)
22
+ - [Step 4 โ€” Update setPaymentMethod](#step-4--update-setpaymentmethod)
23
+ - [Step 5 โ€” Filter the payment method list](#step-5--filter-the-payment-method-list)
24
+ - [Step 6 โ€” Inject admin-configured titles](#step-6--inject-admin-configured-titles)
25
+ - [Step 7 โ€” Render the PayPal UI](#step-7--render-the-paypal-ui)
26
+ - [Step 8 โ€” Disable the Continue button](#step-8--disable-the-continue-button)
27
+ - [Step 9 โ€” Fix the summary label](#step-9--fix-the-summary-label)
28
+ - [๐Ÿ“„ Complete File](#-complete-file)
29
+ - [๐Ÿงช Testing](#-testing)
30
+ - [๐Ÿ“„ License](#-license)
17
31
 
18
32
  ---
19
33
 
20
- ## Overview
34
+ ## ๐Ÿ“ฆ Overview
21
35
 
22
- `@easypayment/medusa-paypal-ui` is a React UI package that connects your Next.js (App Router) storefront to the `medusa-paypal-backend` plugin. It ships the PayPal adapter used inside your checkout payment step โ€” your storefront adds the adapter, provider filtering, and backend config handling to the existing Medusa payment UI.
36
+ `@easypayment/medusa-paypal-ui` is the **storefront UI package** that connects your Next.js (App Router) storefront to the `@easypayment/medusa-paypal` backend plugin. It ships the PayPal adapter used inside your checkout payment step โ€” your storefront adds the adapter, provider filtering, and backend config handling to the existing Medusa payment UI.
23
37
 
24
38
  | Feature | Details |
25
39
  |---|---|
26
- | **PayPal Smart Buttons** | Wallet-based checkout via `pp_paypal_paypal` |
27
- | **Advanced Card Fields** | Hosted PCI-compliant card inputs via `pp_paypal_card_paypal_card` |
28
- | **Admin-driven config** | Enable/disable providers and set labels from Medusa Admin |
29
- | **Built-in UX** | Smart Buttons and Advanced Card UI are rendered by `MedusaNextPayPalAdapter` |
30
- | **Storefront-controlled flow** | Your payment step controls session creation, loading states, and `placeOrder` |
31
-
32
- ---
33
-
34
- ## Table of Contents
35
-
36
- - [Requirements](#requirements)
37
- - [Installation](#installation)
38
- - [Environment Variables](#environment-variables)
39
- - [Integration Guide](#integration-guide)
40
- - [Step 1 - Add the import](#step-1---add-the-import)
41
- - [Step 2 - Add PayPal helpers and state](#step-2---add-paypal-helpers-and-state)
42
- - [Step 3 - Load config from /store/paypal/config](#step-3---load-config-from-storepaypalconfig)
43
- - [Step 4 - Update setPaymentMethod](#step-4---update-setpaymentmethod)
44
- - [Step 5 - Filter the payment method list](#step-5---filter-the-payment-method-list)
45
- - [Step 6 - Inject admin-configured titles](#step-6---inject-admin-configured-titles)
46
- - [Step 7 - Render the PayPal UI](#step-7---render-the-paypal-ui)
47
- - [Step 8 - Disable the Continue button](#step-8---disable-the-continue-button)
48
- - [Step 9 - Fix the summary label](#step-9---fix-the-summary-label)
49
- - [Complete File](#complete-file)
50
- - [Testing](#testing)
40
+ | ๐Ÿ”ต **PayPal Smart Buttons** | Wallet-based checkout via `pp_paypal_paypal` |
41
+ | ๐Ÿ’ณ **Advanced Card Fields** | Hosted PCI-compliant advanced credit card inputs via `pp_paypal_card_paypal_card` |
42
+ | ๐Ÿ›  **Admin-driven config** | Enable/disable providers and set labels from Medusa Admin |
43
+ | โšก **Built-in UX** | Smart Buttons and Advanced Card UI rendered by `MedusaNextPayPalAdapter` |
44
+ | ๐Ÿ”„ **Storefront-controlled flow** | Your payment step controls session creation, loading states, and `placeOrder` |
51
45
 
52
46
  ---
53
47
 
54
- ## Requirements
48
+ ## โœ… Requirements
55
49
 
56
50
  - **Node.js** 18+
57
51
  - **Next.js** 14+ with App Router
58
- - **`medusa-paypal-backend`** installed and running on your Medusa server
59
- - A PayPal account connected in Medusa Admin โ†’ Settings โ†’ PayPal โ†’ PayPal Connection
52
+ - **`@easypayment/medusa-paypal`** installed and running on your Medusa server
53
+ - A PayPal account connected in **Medusa Admin โ†’ Settings โ†’ PayPal โ†’ PayPal Connection**
60
54
 
61
55
  ---
62
56
 
63
- ## Installation
57
+ ## ๐Ÿš€ Installation
64
58
 
65
- ```bash
66
- npm install @easypayment/medusa-paypal-ui
67
- ```
59
+ **In your storefront directory**, run:
68
60
 
69
61
  ```bash
70
- yarn add @easypayment/medusa-paypal-ui
62
+ npm install @easypayment/medusa-paypal-ui
71
63
  ```
72
64
 
73
65
  ---
74
66
 
75
- ## Environment Variables
67
+ ## ๐Ÿ”‘ Environment Variables
76
68
 
77
69
  Add the following to your storefront `.env.local`. Use separate values for development and production.
78
70
 
79
71
  ```env
80
- # Development
81
72
  NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://localhost:9000
82
73
  NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...
83
-
84
- # Production
85
- NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://your-medusa-server.com
86
- NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...
87
74
  ```
88
75
 
89
76
  > **Where to get the publishable key:**
@@ -91,21 +78,23 @@ NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_...
91
78
 
92
79
  ---
93
80
 
94
- ## Integration Guide
81
+ ## ๐Ÿ”— Integration Guide
95
82
 
96
- All changes are made to a single file in your storefront:
83
+ All changes in this guide are made to **one single file** in your storefront:
97
84
 
98
85
  ```
99
86
  src/modules/checkout/components/payment/index.tsx
100
87
  ```
101
88
 
102
- > **Prefer copy-paste?** Skip to [Complete File](#complete-file) for a ready-to-use drop-in replacement.
89
+ Open that file and follow each step in order.
90
+
91
+ > **Prefer to copy-paste the whole file?** Skip straight to [Complete File](#-complete-file) and replace the entire contents in one go. The complete file has all 9 steps already applied.
103
92
 
104
93
  ---
105
94
 
106
- ### Step 1 - Add the import
95
+ ### Step 1 โ€” Add the import
107
96
 
108
- Add this import alongside your existing imports at the top of the file:
97
+ **Where:** At the very top of the file, alongside your other imports.
109
98
 
110
99
  ```tsx
111
100
  import { MedusaNextPayPalAdapter } from "@easypayment/medusa-paypal-ui"
@@ -113,17 +102,21 @@ import { MedusaNextPayPalAdapter } from "@easypayment/medusa-paypal-ui"
113
102
 
114
103
  ---
115
104
 
116
- ### Step 2 - Add PayPal helpers and state
105
+ ### Step 2 โ€” Add PayPal helpers and state
117
106
 
118
- Inside the file, add PayPal provider helpers and the local state used by the updated implementation:
107
+ **Where:** At the top of the file, outside the component โ€” add the constants. Inside the `Payment` component, add the `useState` lines alongside your other state declarations.
119
108
 
120
109
  ```tsx
110
+ // Outside the component โ€” add these constants
121
111
  const PAYPAL_PROVIDER_ID = "pp_paypal_paypal"
122
112
  const PAYPAL_CARD_PROVIDER_ID = "pp_paypal_card_paypal_card"
123
113
  const PAYPAL_PROVIDER_IDS = [PAYPAL_PROVIDER_ID, PAYPAL_CARD_PROVIDER_ID]
124
114
 
125
115
  const isPayPal = (id: string) => PAYPAL_PROVIDER_IDS.includes(id)
116
+ ```
126
117
 
118
+ ```tsx
119
+ // Inside the Payment component โ€” add alongside your other useState declarations
127
120
  const [paypalEnabled, setPaypalEnabled] = useState(true)
128
121
  const [paypalTitle, setPaypalTitle] = useState("PayPal")
129
122
  const [cardEnabled, setCardEnabled] = useState(true)
@@ -133,21 +126,18 @@ const [paypalLoading, setPaypalLoading] = useState(false)
133
126
 
134
127
  ---
135
128
 
136
- ### Step 3 - Load config from /store/paypal/config
129
+ ### Step 3 โ€” Load PayPal config
130
+
131
+ **Where:** Inside the `Payment` component, alongside your other `useEffect` hooks.
137
132
 
138
- Instead of using a hook, fetch the PayPal config when the payment step is open:
133
+ This fetches PayPal settings from your backend whenever the payment step is opened, so the UI always reflects the latest admin configuration.
139
134
 
140
135
  ```tsx
141
136
  useEffect(() => {
142
- if (!isOpen) {
143
- return
144
- }
137
+ if (!isOpen) return
145
138
 
146
139
  const backendUrl = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL
147
-
148
- if (!backendUrl) {
149
- return
150
- }
140
+ if (!backendUrl) return
151
141
 
152
142
  const key = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
153
143
  const controller = new AbortController()
@@ -165,74 +155,56 @@ useEffect(() => {
165
155
  return
166
156
  }
167
157
 
168
- if (!response.ok) {
169
- return
170
- }
158
+ if (!response.ok) return
171
159
 
172
160
  const config = await response.json()
173
161
 
174
- if (typeof config?.paypal_enabled === "boolean") {
175
- setPaypalEnabled(config.paypal_enabled)
176
- }
177
-
178
- if (typeof config?.paypal_title === "string" && config.paypal_title) {
179
- setPaypalTitle(config.paypal_title)
180
- }
181
-
182
- if (typeof config?.card_enabled === "boolean") {
183
- setCardEnabled(config.card_enabled)
184
- }
185
-
186
- if (typeof config?.card_title === "string" && config.card_title) {
187
- setCardTitle(config.card_title)
188
- }
162
+ if (typeof config?.paypal_enabled === "boolean") setPaypalEnabled(config.paypal_enabled)
163
+ if (typeof config?.paypal_title === "string" && config.paypal_title) setPaypalTitle(config.paypal_title)
164
+ if (typeof config?.card_enabled === "boolean") setCardEnabled(config.card_enabled)
165
+ if (typeof config?.card_title === "string" && config.card_title) setCardTitle(config.card_title)
189
166
  } catch (err) {
190
- if ((err as Error).name !== "AbortError") {
191
- setPaypalLoading(false)
192
- }
167
+ if ((err as Error).name !== "AbortError") setPaypalLoading(false)
193
168
  }
194
169
  }
195
170
 
196
171
  void loadPayPalConfig()
197
-
198
172
  return () => controller.abort()
199
173
  }, [isOpen])
200
174
  ```
201
175
 
202
176
  ---
203
177
 
204
- ### Step 4 - Update setPaymentMethod
178
+ ### Step 4 โ€” Update setPaymentMethod
179
+
180
+ **Where:** Inside the `Payment` component. Find your existing `setPaymentMethod` function and **replace it entirely** with the version below.
205
181
 
206
- Replace your existing `setPaymentMethod` function with the following. The key addition is setting `paypalLoading` while the PayPal session is being created:
182
+ The key addition is `paypalLoading` โ€” it shows a loading indicator while the PayPal payment session is being created in the background.
207
183
 
208
184
  ```tsx
209
185
  const setPaymentMethod = async (method: string) => {
210
186
  setError(null)
211
187
  setSelectedPaymentMethod(method)
212
188
 
213
- if (!isStripeLike(method) && !isPayPal(method)) {
214
- return
215
- }
189
+ if (!isStripeLike(method) && !isPayPal(method)) return
216
190
 
217
- if (isPayPal(method)) {
218
- setPaypalLoading(true)
219
- }
191
+ if (isPayPal(method)) setPaypalLoading(true)
220
192
 
221
193
  try {
222
194
  await initiatePaymentSession(cart, { provider_id: method })
223
195
  } finally {
224
- if (isPayPal(method)) {
225
- setPaypalLoading(false)
226
- }
196
+ if (isPayPal(method)) setPaypalLoading(false)
227
197
  }
228
198
  }
229
199
  ```
230
200
 
231
201
  ---
232
202
 
233
- ### Step 5 - Filter the payment method list
203
+ ### Step 5 โ€” Filter the payment method list
234
204
 
235
- Add a filtered payment method list before your `RadioGroup` render:
205
+ **Where:** Inside the `Payment` component, alongside your other `useMemo` declarations โ€” add this before the `return` statement.
206
+
207
+ This hides PayPal or Card from the list if they have been disabled in Medusa Admin.
236
208
 
237
209
  ```tsx
238
210
  const filteredPaymentMethods = useMemo(
@@ -246,33 +218,33 @@ const filteredPaymentMethods = useMemo(
246
218
  )
247
219
  ```
248
220
 
249
- Then use `filteredPaymentMethods.map(...)` instead of rendering `availablePaymentMethods` directly.
221
+ Then in your JSX, find where you render `availablePaymentMethods.map(...)` and **replace** `availablePaymentMethods` with `filteredPaymentMethods`:
222
+
223
+ ```tsx
224
+ // Before
225
+ availablePaymentMethods.map((paymentMethod) => ( ... ))
226
+
227
+ // After
228
+ filteredPaymentMethods.map((paymentMethod) => ( ... ))
229
+ ```
250
230
 
251
231
  ---
252
232
 
253
- ### Step 6 - Inject admin-configured titles
233
+ ### Step 6 โ€” Inject admin-configured titles
234
+
235
+ **Where:** Inside the `.map()` loop from Step 5, find your `<PaymentContainer>` component and **replace** its `paymentInfoMap` prop with the version below.
254
236
 
255
- Inside your `.map()`, pass an overridden `paymentInfoMap` to the `PaymentContainer` component so the radio button labels reflect the values set in Medusa Admin:
237
+ This makes the radio button labels show the titles configured in Medusa Admin instead of hardcoded defaults.
256
238
 
257
239
  ```tsx
258
240
  <PaymentContainer
259
241
  paymentInfoMap={{
260
242
  ...paymentInfoMap,
261
243
  ...(paymentMethod.id === PAYPAL_PROVIDER_ID
262
- ? {
263
- [paymentMethod.id]: {
264
- ...(paymentInfoMap[paymentMethod.id] || {}),
265
- title: paypalTitle,
266
- },
267
- }
244
+ ? { [paymentMethod.id]: { ...(paymentInfoMap[paymentMethod.id] || {}), title: paypalTitle } }
268
245
  : {}),
269
246
  ...(paymentMethod.id === PAYPAL_CARD_PROVIDER_ID
270
- ? {
271
- [paymentMethod.id]: {
272
- ...(paymentInfoMap[paymentMethod.id] || {}),
273
- title: cardTitle,
274
- },
275
- }
247
+ ? { [paymentMethod.id]: { ...(paymentInfoMap[paymentMethod.id] || {}), title: cardTitle } }
276
248
  : {}),
277
249
  }}
278
250
  paymentProviderId={paymentMethod.id}
@@ -282,17 +254,19 @@ Inside your `.map()`, pass an overridden `paymentInfoMap` to the `PaymentContain
282
254
 
283
255
  ---
284
256
 
285
- ### Step 7 - Render the PayPal UI
257
+ ### Step 7 โ€” Render the PayPal UI
258
+
259
+ **Where:** In the JSX, immediately after the closing `</RadioGroup>` tag.
286
260
 
287
- After the closing `</RadioGroup>` tag, render a loading state while the PayPal session is being prepared, then mount `MedusaNextPayPalAdapter`:
261
+ The first block shows a loading spinner while the session is being set up. The second block renders the PayPal buttons or card fields once the session is ready.
288
262
 
289
263
  ```tsx
264
+ {/* Loading state while PayPal session is being created */}
290
265
  {isPayPal(selectedPaymentMethod) && paypalLoading && (
291
- <div>
292
- <div>Setting up payment...</div>
293
- </div>
266
+ <div>Setting up payment...</div>
294
267
  )}
295
268
 
269
+ {/* PayPal buttons or card fields */}
296
270
  {isPayPal(selectedPaymentMethod) && !paypalLoading && (
297
271
  <MedusaNextPayPalAdapter
298
272
  cartId={cart.id}
@@ -307,17 +281,13 @@ After the closing `</RadioGroup>` tag, render a loading state while the PayPal s
307
281
  )}
308
282
  ```
309
283
 
310
- > **Critical โ€” `onSuccess` must call `placeOrder`**
311
- >
312
- > `placeOrder` is the Next.js Server Action exported from `@lib/data/cart`. It **must** run server-side โ€” it is the only mechanism that can clear the httpOnly cart cookie set by the server. Replacing it with a client-side `fetch` to `/store/carts/:id/complete` will complete the order in Medusa but leave the cart cookie intact, breaking the storefront session.
313
-
314
284
  ---
315
285
 
316
- ### Step 8 - Disable the Continue button
286
+ ### Step 8 โ€” Disable the Continue button
317
287
 
318
- Because PayPal renders its own checkout action, the storefront's "Continue to review" button must be disabled when PayPal is selected.
288
+ **Where:** In the JSX, find your existing `<Button>` with `data-testid="submit-payment-button"` and **add** `isPayPal(selectedPaymentMethod)` to its `disabled` prop.
319
289
 
320
- Add `isPayPal(selectedPaymentMethod)` to your `Button` component's `disabled` prop:
290
+ PayPal handles its own checkout action, so the "Continue to review" button must be hidden from the flow when PayPal is selected.
321
291
 
322
292
  ```tsx
323
293
  <Button
@@ -328,7 +298,7 @@ Add `isPayPal(selectedPaymentMethod)` to your `Button` component's `disabled` pr
328
298
  disabled={
329
299
  (isStripeLike(selectedPaymentMethod) && !cardComplete) ||
330
300
  (!selectedPaymentMethod && !paidByGiftcard) ||
331
- isPayPal(selectedPaymentMethod)
301
+ isPayPal(selectedPaymentMethod) // ๐Ÿ‘ˆ add this line
332
302
  }
333
303
  data-testid="submit-payment-button"
334
304
  >
@@ -340,9 +310,11 @@ Add `isPayPal(selectedPaymentMethod)` to your `Button` component's `disabled` pr
340
310
 
341
311
  ---
342
312
 
343
- ### Step 9 - Fix the summary label
313
+ ### Step 9 โ€” Fix the summary label
344
314
 
345
- In the collapsed summary view (shown after the customer has selected a payment method), replace any hardcoded PayPal label with the admin-configured title:
315
+ **Where:** In the collapsed summary view (shown after the customer has completed the payment step). Find the `<Text>` with `data-testid="payment-method-summary"` and **replace its content** with the version below.
316
+
317
+ This shows the admin-configured title instead of a hardcoded or missing label.
346
318
 
347
319
  ```tsx
348
320
  <Text
@@ -360,9 +332,9 @@ In the collapsed summary view (shown after the customer has selected a payment m
360
332
 
361
333
  ---
362
334
 
363
- ## Complete File
335
+ ## ๐Ÿ“„ Complete File
364
336
 
365
- The following is a complete, working replacement for your payment step file with all changes from the guide above already applied. Copy and replace the entire contents of `src/modules/checkout/components/payment/index.tsx`.
337
+ If you prefer to copy-paste the entire file at once, replace the full contents of `src/modules/checkout/components/payment/index.tsx` with the following:
366
338
 
367
339
  ```tsx
368
340
  "use client"
@@ -420,14 +392,8 @@ const Payment = ({
420
392
  const filteredPaymentMethods = useMemo(
421
393
  () =>
422
394
  availablePaymentMethods.filter((paymentMethod) => {
423
- if (paymentMethod.id === PAYPAL_PROVIDER_ID) {
424
- return paypalEnabled
425
- }
426
-
427
- if (paymentMethod.id === PAYPAL_CARD_PROVIDER_ID) {
428
- return cardEnabled
429
- }
430
-
395
+ if (paymentMethod.id === PAYPAL_PROVIDER_ID) return paypalEnabled
396
+ if (paymentMethod.id === PAYPAL_CARD_PROVIDER_ID) return cardEnabled
431
397
  return true
432
398
  }),
433
399
  [availablePaymentMethods, cardEnabled, paypalEnabled],
@@ -437,20 +403,14 @@ const Payment = ({
437
403
  setError(null)
438
404
  setSelectedPaymentMethod(method)
439
405
 
440
- if (!isStripeLike(method) && !isPayPal(method)) {
441
- return
442
- }
406
+ if (!isStripeLike(method) && !isPayPal(method)) return
443
407
 
444
- if (isPayPal(method)) {
445
- setPaypalLoading(true)
446
- }
408
+ if (isPayPal(method)) setPaypalLoading(true)
447
409
 
448
410
  try {
449
411
  await initiatePaymentSession(cart, { provider_id: method })
450
412
  } finally {
451
- if (isPayPal(method)) {
452
- setPaypalLoading(false)
453
- }
413
+ if (isPayPal(method)) setPaypalLoading(false)
454
414
  }
455
415
  }
456
416
 
@@ -508,15 +468,10 @@ const Payment = ({
508
468
  }, [isOpen])
509
469
 
510
470
  useEffect(() => {
511
- if (!isOpen) {
512
- return
513
- }
471
+ if (!isOpen) return
514
472
 
515
473
  const backendUrl = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL
516
-
517
- if (!backendUrl) {
518
- return
519
- }
474
+ if (!backendUrl) return
520
475
 
521
476
  const key = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
522
477
  const controller = new AbortController()
@@ -534,36 +489,20 @@ const Payment = ({
534
489
  return
535
490
  }
536
491
 
537
- if (!response.ok) {
538
- return
539
- }
492
+ if (!response.ok) return
540
493
 
541
494
  const config = await response.json()
542
495
 
543
- if (typeof config?.paypal_enabled === "boolean") {
544
- setPaypalEnabled(config.paypal_enabled)
545
- }
546
-
547
- if (typeof config?.paypal_title === "string" && config.paypal_title) {
548
- setPaypalTitle(config.paypal_title)
549
- }
550
-
551
- if (typeof config?.card_enabled === "boolean") {
552
- setCardEnabled(config.card_enabled)
553
- }
554
-
555
- if (typeof config?.card_title === "string" && config.card_title) {
556
- setCardTitle(config.card_title)
557
- }
496
+ if (typeof config?.paypal_enabled === "boolean") setPaypalEnabled(config.paypal_enabled)
497
+ if (typeof config?.paypal_title === "string" && config.paypal_title) setPaypalTitle(config.paypal_title)
498
+ if (typeof config?.card_enabled === "boolean") setCardEnabled(config.card_enabled)
499
+ if (typeof config?.card_title === "string" && config.card_title) setCardTitle(config.card_title)
558
500
  } catch (err) {
559
- if ((err as Error).name !== "AbortError") {
560
- setPaypalLoading(false)
561
- }
501
+ if ((err as Error).name !== "AbortError") setPaypalLoading(false)
562
502
  }
563
503
  }
564
504
 
565
505
  void loadPayPalConfig()
566
-
567
506
  return () => controller.abort()
568
507
  }, [isOpen])
569
508
 
@@ -684,14 +623,13 @@ const Payment = ({
684
623
  </div>
685
624
  </div>
686
625
  )}
626
+
687
627
  {isPayPal(selectedPaymentMethod) && !paypalLoading && (
688
628
  <MedusaNextPayPalAdapter
689
629
  cartId={cart.id}
690
630
  selectedProviderId={selectedPaymentMethod}
691
631
  baseUrl={process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL!}
692
- publishableApiKey={
693
- process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY
694
- }
632
+ publishableApiKey={process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY}
695
633
  onSuccess={async () => {
696
634
  await placeOrder(cart.id)
697
635
  }}
@@ -801,18 +739,22 @@ export default Payment
801
739
 
802
740
  ---
803
741
 
804
- ## Testing
742
+ ## ๐Ÿงช Testing
805
743
 
806
- Toggle between sandbox and live in Medusa Admin โ†’ **Settings โ†’ PayPal โ†’ PayPal Connection โ†’ Environment**.
744
+ Toggle between sandbox and live in **Medusa Admin โ†’ Settings โ†’ PayPal โ†’ PayPal Connection โ†’ Environment**.
807
745
 
808
- **Sandbox buyer account**
746
+ **Sandbox buyer account** โ€” log in at [developer.paypal.com](https://developer.paypal.com) โ†’ **Testing โ†’ Sandbox Accounts** to find your auto-generated buyer credentials. Sandbox payments do not charge real money.
809
747
 
810
- Log in at [developer.paypal.com](https://developer.paypal.com) โ†’ **Testing โ†’ Sandbox Accounts** to find your auto-generated buyer credentials. Sandbox payments do not charge real money.
811
-
812
- **Test card number for Advanced Card fields**
748
+ **Test card for Advanced Card Fields:**
813
749
 
814
750
  ```
815
751
  Card number 4111 1111 1111 1111
816
752
  Expiry Any future date
817
753
  CVV Any 3 digits
818
- ```
754
+ ```
755
+
756
+ ---
757
+
758
+ ## ๐Ÿ“„ License
759
+
760
+ MIT ยฉ [Easy Payment](https://www.npmjs.com/package/@easypayment/medusa-paypal-ui)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easypayment/medusa-paypal-ui",
3
- "version": "1.0.44",
3
+ "version": "1.0.45",
4
4
  "description": "Enterprise Gold PayPal UI module for Medusa v2 storefront (Next.js)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,5 +46,9 @@
46
46
  "test": "vitest run",
47
47
  "test:watch": "vitest",
48
48
  "prepublishOnly": "npm run build"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/easypaymentplugins/medusa-paypal-ui"
49
53
  }
50
54
  }