@easypayment/medusa-paypal-ui 1.2.8 → 1.3.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,90 @@
2
2
 
3
3
  All notable changes to `@easypayment/medusa-paypal-ui` are documented here.
4
4
 
5
+ ## 1.3.1 — 2026-10-06
6
+
7
+ _(Published as 1.3.1: the 1.3.0 version number was burned by an interrupted npm publish and can't be reused.)_
8
+
9
+ ### Fixed
10
+
11
+ - **"PayPal is disabled" (403) detection works again.** It matched the text
12
+ "403"/"Forbidden" in error messages, but the HTTP client prefers the
13
+ backend's JSON message, which rarely contains either — so a disabled plugin
14
+ fell back to showing both payment methods as enabled. Detection is now by
15
+ status code (`HttpError.status === 403`), and `HttpError` is exported so
16
+ storefronts can branch on statuses too.
17
+ - **A currency/region switch no longer serves a stale config for up to 5
18
+ minutes.** The config cache key now includes the publishable API key and an
19
+ optional `currencyCode` (new prop on `PayPalPaymentSection`,
20
+ `MedusaNextPayPalAdapter`, and both hooks — pass the cart's currency);
21
+ `invalidatePayPalConfigCache(cartId?)` is exported for manual invalidation.
22
+ - **Double-click on the PayPal button can no longer create two orders.** The
23
+ guard read async React state, so two clicks in the same tick both passed;
24
+ it now uses a synchronous ref (as the card form already did).
25
+ - Malformed 2xx responses (non-JSON content type, JSON parse failure) are no
26
+ longer treated as transient and retried — a server answering 200 with HTML
27
+ answers the same on a retry.
28
+ - The full-screen processing overlay no longer monkeypatches
29
+ `history.pushState`/`replaceState` to detect soft navigations (fragile next
30
+ to the Next.js router); it watches the URL instead. The in-component and
31
+ shared DOM overlays also no longer stack on top of each other.
32
+ - The server-safe `fetchPayPalConfig` (order entrypoint) now composes a
33
+ caller-supplied `AbortSignal` with its 30s timeout instead of letting the
34
+ signal replace the timeout entirely.
35
+
36
+ ### Added
37
+
38
+ - `credentials` prop on `PayPalPaymentSection`, `MedusaNextPayPalAdapter`,
39
+ `PayPalSmartButtons`, and `PayPalAdvancedCard`, forwarded to every API call
40
+ (previously only `createPayPalStoreApi` accepted it, so the README's
41
+ wildcard-CORS advice didn't reach the components).
42
+ - `usePayPalConfig` returns a `retry()` function, and the adapter's
43
+ config-error card shows a "Try again" button instead of requiring a reload.
44
+ - Both hooks share one config cache and deduplicate in-flight requests — a
45
+ checkout page that mounts both issues a single `/store/paypal/config` call.
46
+ - `createOrder` / `captureOrder` / `getSettings` accept an `AbortSignal`;
47
+ `markPaymentComplete` accepts an options object (`{ publishableApiKey,
48
+ credentials, timeoutMs, signal }` — the legacy string argument still works);
49
+ `createHttpClient` accepts `timeoutMs`.
50
+ - Accessibility: decorative icons are `aria-hidden`, overlays/spinners
51
+ announce their visible text (no overriding `aria-label`), `aria-busy`
52
+ reflects busy (not disabled) state, and animations respect
53
+ `prefers-reduced-motion`.
54
+
55
+ ### Changed
56
+
57
+ - **PayPal partner attribution (BN) code changed to `MBJ_Medusa_SI`** — the
58
+ Medusa-platform code PayPal assigned (2026-10-06), passed to the PayPal JS
59
+ SDK as `data-partner-attribution-id` (previously `MBJTechnolabs_SI_SPB`),
60
+ matching the backend's REST attribution.
61
+ - `onPaid` / `onSuccess` callback types are now `void | Promise<void>` (they
62
+ were always awaited).
63
+ - `PAYPAL_PROVIDER_IDS` and the `PayPalProviderId` type are actually exported
64
+ from both entrypoints now (1.2.8 exported them from an internal module that
65
+ consumers couldn't reach).
66
+ - The spinner/overlay/error markup that was copied across four components
67
+ lives in one shared internal module.
68
+
69
+ ### Dev
70
+
71
+ - ESLint (typescript-eslint + react-hooks + jsx-a11y) added and clean; lint,
72
+ format, and a React 18 test job run in CI; `tsc` now typechecks the tests.
73
+ - 40 new tests (73 total): shared config cache (TTL, dedupe, invalidation,
74
+ eviction), hooks under React Testing Library (403 handling, retry, shared
75
+ in-flight fetch, currency-change refetch), client timeout/abort/credentials
76
+ behavior, and the server-safe order helpers.
77
+ - `react`/`react-dom` are proper devDependencies; full MIT license text;
78
+ npm keywords, `engines`, `homepage`/`bugs` metadata added.
79
+
80
+ ## 1.2.8 — 2026-09-28
81
+
82
+ ### Changed
83
+
84
+ - `isPayPalProviderId` is now a type guard and the `PayPalProviderId` type is
85
+ exported from an internal constants module (aligned with
86
+ `@easypayment/medusa-payment-paypal` 1.2.8). Superseded by 1.3.0, which
87
+ exports them from the public entrypoints.
88
+
5
89
  ## 1.2.7 — 2026-09-23
6
90
 
7
91
  ### Changed
package/LICENSE CHANGED
@@ -1 +1,21 @@
1
- MIT License
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -786,9 +786,15 @@ You don't need to do anything for these — they're automatic:
786
786
 
787
787
  <br>
788
788
 
789
- - `usePayPalPaymentMethods` returns an `error` field (non-null when the config fetch failed and the enabled flags are optimistic defaults).
789
+ - `usePayPalPaymentMethods` returns an `error` field (non-null when the config fetch failed and the enabled flags are optimistic defaults). A `403` from the backend (plugin disabled) is detected by status code and flips both methods off.
790
+ - `usePayPalConfig` returns `{ config, loading, error, retry }` — call `retry()` to refetch after a failure (the adapter's error card has a built-in "Try again" button).
791
+ - Pass `currencyCode` (the cart's currency) to the components/hooks: it's part of the config cache key, so a region/currency switch refetches instead of serving a stale config. `invalidatePayPalConfigCache(cartId?)` is exported for manual invalidation.
792
+ - Both hooks share one config cache **and one in-flight request** — a page that mounts both issues a single `/store/paypal/config` call.
793
+ - `HttpError` is exported: every non-2xx API failure carries a `status` you can branch on.
794
+ - All API calls time out after 30s by default (`timeoutMs` option on `createHttpClient` / `markPaymentComplete`), retry transient failures on idempotent endpoints, and accept an `AbortSignal`.
790
795
  - Captured-state helpers are exported for custom flows: `markCartCaptured` / `wasCartCaptured` / `clearCartCaptured` (per-cart `sessionStorage` flag behind the reload-safe retry).
791
- - If your backend responds with `Access-Control-Allow-Origin: *`, pass `credentials: "omit"` to `createPayPalStoreApi({ ... })` — browsers block credentialed requests against a wildcard origin. Default stays `"include"`.
796
+ - If your backend responds with `Access-Control-Allow-Origin: *`, pass `credentials: "omit"` — either to `createPayPalStoreApi({ ... })` or directly as a `credentials` prop on `PayPalPaymentSection` / `MedusaNextPayPalAdapter` / the components. Default stays `"include"`.
797
+ - Accessibility: spinners and overlays are `role="status"`, errors are `role="alert"`, decorative icons are `aria-hidden`, and animations respect `prefers-reduced-motion`.
792
798
 
793
799
  </details>
794
800