@easypayment/medusa-paypal-ui 1.2.8 → 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/CHANGELOG.md +82 -0
- package/LICENSE +21 -1
- package/README.md +8 -2
- package/dist/index.cjs +605 -676
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -28
- package/dist/index.d.ts +101 -28
- package/dist/index.mjs +601 -676
- package/dist/index.mjs.map +1 -1
- package/dist/order.cjs +11 -8
- package/dist/order.cjs.map +1 -1
- package/dist/order.d.cts +1 -1
- package/dist/order.d.ts +1 -1
- package/dist/order.mjs +10 -8
- package/dist/order.mjs.map +1 -1
- package/package.json +43 -4
- package/src/adapters/MedusaNextPayPalAdapter.tsx +48 -10
- package/src/client/config-cache.ts +96 -0
- package/src/client/http.ts +24 -5
- package/src/client/paypal.ts +28 -6
- package/src/components/PayPalAdvancedCard.tsx +88 -214
- package/src/components/PayPalPaymentSection.tsx +17 -6
- package/src/components/PayPalProvider.tsx +4 -1
- package/src/components/PayPalSmartButtons.tsx +92 -224
- package/src/components/internal/ui.tsx +221 -0
- package/src/hooks/usePayPalConfig.ts +43 -32
- package/src/hooks/usePayPalPaymentMethods.ts +59 -54
- package/src/index.ts +4 -0
- package/src/order.ts +16 -8
- package/src/utils/processing-overlay.ts +25 -21
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client/http.ts","../src/client/paypal.ts","../src/hooks/usePayPalConfig.ts","../src/components/PayPalProvider.tsx","../src/components/PayPalCurrencyNotice.tsx","../src/components/PayPalSmartButtons.tsx","../src/utils/captured-state.ts","../src/utils/next-errors.ts","../src/utils/processing-overlay.ts","../src/components/PayPalAdvancedCard.tsx","../src/adapters/MedusaNextPayPalAdapter.tsx","../src/constants.ts","../src/components/PayPalPaymentSection.tsx","../src/hooks/usePayPalPaymentMethods.ts"],"sourcesContent":["export * from \"./client/types\"\nexport * from \"./client/paypal\"\nexport * from \"./hooks/usePayPalConfig\"\nexport * from \"./components/PayPalProvider\"\nexport * from \"./components/PayPalCurrencyNotice\"\nexport * from \"./components/PayPalSmartButtons\"\nexport * from \"./components/PayPalAdvancedCard\"\nexport * from \"./adapters/MedusaNextPayPalAdapter\"\nexport * from \"./components/PayPalPaymentSection\"\nexport * from \"./hooks/usePayPalPaymentMethods\"\nexport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"./utils/processing-overlay\"\nexport {\n markCartCaptured,\n wasCartCaptured,\n clearCartCaptured,\n} from \"./utils/captured-state\"\n","export type HttpOptions = {\n baseUrl: string\n publishableApiKey?: string\n /**\n * `credentials` mode for every request. Defaults to \"include\" (the\n * historical behavior, required when the backend sits behind cookie-based\n * gateways like Cloudflare Access). Set to \"omit\" or \"same-origin\" when the\n * backend answers with `Access-Control-Allow-Origin: *` — browsers reject\n * credentialed requests against a wildcard CORS origin outright.\n */\n credentials?: RequestCredentials\n}\n\nexport type RequestOptions = {\n /**\n * Number of extra attempts on transient failures (network error, timeout,\n * HTTP 429/5xx). Only use for idempotent calls — the PayPal capture/complete\n * endpoints are idempotent server-side, so a retried request after a network\n * blip re-uses the existing result instead of duplicating work. Default 0.\n */\n retries?: number\n}\n\nclass HttpError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = \"HttpError\"\n this.status = status\n }\n}\n\nconst RETRY_BASE_DELAY_MS = 400\n\nfunction isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500\n}\n\nfunction isRetryableError(err: unknown): boolean {\n // Network failures and our own timeout error are safe to retry.\n return err instanceof Error && !(err instanceof HttpError)\n}\n\nconst wait = (ms: number) => new Promise((r) => setTimeout(r, ms))\n\n/** Best-effort extraction of a `{ message: string }` payload from a response body. */\nfunction extractJsonMessage(text: string): string | null {\n if (!text) return null\n try {\n const parsed = JSON.parse(text)\n const message = parsed?.message\n if (typeof message === \"string\" && message.trim()) {\n return message.trim().slice(0, 500)\n }\n } catch {\n // not JSON — caller falls back to the raw text\n }\n return null\n}\n\nfunction toHeaderRecord(\n headers?: RequestInit[\"headers\"]\n): Record<string, string> {\n if (!headers) {\n return {}\n }\n\n if (headers instanceof Headers) {\n return Object.fromEntries(headers.entries())\n }\n\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers)\n }\n\n return { ...headers }\n}\n\nexport function createHttpClient(opts: HttpOptions) {\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\n\n async function attempt<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...toHeaderRecord(init?.headers),\n }\n\n if (opts.publishableApiKey) {\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\n }\n\n // Always arm the timeout — a caller-supplied signal composes with it\n // rather than replacing it. Without this, hook-issued requests (which\n // always pass an abort signal) could hang forever on a stalled\n // connection. The timer also covers reading the body: a server that sends\n // headers then stalls the response stream would otherwise hang the\n // request indefinitely with the old header-only timeout.\n const timeoutMs = 30_000\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\n const callerSignal = init?.signal ?? null\n const onCallerAbort = () => controller.abort()\n if (callerSignal) {\n if (callerSignal.aborted) controller.abort()\n else callerSignal.addEventListener(\"abort\", onCallerAbort)\n }\n let res: Response\n let text: string\n try {\n res = await fetch(url, {\n ...init,\n headers,\n credentials: opts.credentials ?? \"include\",\n signal: controller.signal,\n })\n text = await res.text().catch(() => \"\")\n } catch (err) {\n if (\n err instanceof Error &&\n err.name === \"AbortError\" &&\n !(callerSignal && callerSignal.aborted)\n ) {\n throw new Error(\n `[PayPal] Request to ${path} timed out after ${timeoutMs / 1000}s`\n )\n }\n throw err\n } finally {\n clearTimeout(timeoutId)\n if (callerSignal) callerSignal.removeEventListener(\"abort\", onCallerAbort)\n }\n\n if (!res.ok) {\n // Backend routes return structured JSON errors ({ message }) written for\n // the buyer (e.g. unsupported currency, rate-limit, \"payment processed\n // but order not finalized\"). Prefer that message over raw response text\n // or a generic hint so the user sees something actionable instead of a\n // JSON blob.\n const parsedMessage = extractJsonMessage(text)\n if (res.status === 401) {\n throw new HttpError(\n parsedMessage ||\n \"[PayPal] Unauthorized (401) — check that your publishable API key is correct and set in NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY\",\n 401\n )\n }\n if (res.status === 403) {\n throw new HttpError(\n parsedMessage ||\n \"[PayPal] Forbidden (403) — this request is not allowed. Check your CORS and API key settings.\",\n 403\n )\n }\n throw new HttpError(\n parsedMessage ||\n text.slice(0, 500).replace(/<[^>]*>/g, \"\") ||\n `Request failed (${res.status})`,\n res.status\n )\n }\n if (!text) {\n throw new HttpError(\n `[PayPal] Empty response body from ${path} (${res.status})`,\n res.status\n )\n }\n\n const contentType = res.headers.get(\"content-type\") || \"\"\n if (!contentType.includes(\"application/json\")) {\n throw new Error(\n `[PayPal] Unexpected non-JSON response (${contentType}) from ${path}`\n )\n }\n\n try {\n return JSON.parse(text) as T\n } catch {\n throw new Error(`[PayPal] Failed to parse JSON response from ${path}`)\n }\n }\n\n async function request<T>(\n path: string,\n init?: RequestInit,\n reqOpts?: RequestOptions\n ): Promise<T> {\n const retries = Math.max(0, reqOpts?.retries ?? 0)\n let lastError: unknown\n for (let i = 0; i <= retries; i++) {\n try {\n return await attempt<T>(path, init)\n } catch (err) {\n lastError = err\n const transient =\n (err instanceof HttpError && isRetryableStatus(err.status)) ||\n isRetryableError(err)\n // Don't retry a caller-supplied AbortSignal cancellation.\n const aborted =\n err instanceof Error && err.name === \"AbortError\" && !!init?.signal\n if (i >= retries || !transient || aborted) {\n throw err\n }\n await wait(\n RETRY_BASE_DELAY_MS * Math.pow(2, i) +\n Math.random() * RETRY_BASE_DELAY_MS\n )\n }\n }\n throw lastError\n }\n\n return { request }\n}\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\nimport { createHttpClient, type HttpOptions } from \"./http\"\n\n/**\n * Fresh idempotency key per create-order ATTEMPT (i.e. per buyer click).\n *\n * The backend derives the PayPal-Request-Id from this header. It must be\n * unique per attempt: PayPal replays the cached response for a reused request\n * id, so a key stable across cart changes would hand back the ORIGINAL order —\n * at the original total — after the buyer edits the cart, charging a stale\n * amount. Reuse/dedup of an unchanged order is handled server-side by the\n * stored-order staleness check, not by this key.\n */\nexport function generateIdempotencyKey(): string {\n try {\n const c = (globalThis as { crypto?: Crypto }).crypto\n if (c?.randomUUID) return c.randomUUID()\n } catch {\n // fall through\n }\n return `pp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`\n}\n\nexport async function markPaymentComplete(\n baseUrl: string,\n cartId: string,\n publishableApiKey?: string\n): Promise<Record<string, unknown>> {\n const http = createHttpClient({ baseUrl, publishableApiKey })\n // Retry transient failures: /store/paypal-complete is idempotent (it returns\n // already_completed for a finished cart), so a network blip right after\n // capture — the classic \"captured but cart not completed\" gap — is retried\n // instead of stranding a paid-but-unfinalized order.\n return http.request<Record<string, unknown>>(\n `/store/paypal-complete`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId }),\n },\n { retries: 3 }\n )\n}\n\nexport function createPayPalStoreApi(opts: HttpOptions) {\n const http = createHttpClient(opts)\n\n return {\n getConfig(cartId?: string, signal?: AbortSignal) {\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\n return http.request<PayPalConfig>(`/store/paypal/config${q}`, { signal })\n },\n\n getSettings() {\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`)\n },\n\n createOrder(cartId: string, isCardPayment = false) {\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n // One key per attempt — see generateIdempotencyKey. Deliberately NOT\n // sent for capture-order: there the server's deterministic\n // per-order-id fallback is the correct idempotency scope.\n \"Idempotency-Key\": generateIdempotencyKey(),\n },\n body: JSON.stringify({\n cart_id: cartId,\n is_card_payment: isCardPayment,\n }),\n })\n },\n\n captureOrder(cartId: string, orderId: string) {\n // Retry transient failures: capture-order is idempotent server-side (it\n // short-circuits on an existing capture and PayPal dedupes by request id),\n // so a network blip during capture doesn't leave the buyer's funds\n // authorized-but-not-captured with no recovery.\n return http.request<Record<string, unknown>>(\n `/store/paypal/capture-order`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\n },\n { retries: 2 }\n )\n },\n }\n}\n","\"use client\"\n\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n enabled?: boolean\n}\n\nconst MAX_CACHE_ENTRIES = 50\nconst _cache = new Map<string, { config: PayPalConfig; at: number }>()\nconst CACHE_TTL = 5 * 60 * 1000\n\nfunction cacheSet(key: string, value: { config: PayPalConfig; at: number }) {\n if (_cache.size >= MAX_CACHE_ENTRIES) {\n const oldest = _cache.keys().next().value\n if (oldest !== undefined) _cache.delete(oldest)\n }\n _cache.set(key, value)\n}\n\nfunction cacheKey(baseUrl: string, cartId?: string) {\n return `${baseUrl}::${cartId ?? \"\"}`\n}\n\nexport function usePayPalConfig({\n baseUrl,\n publishableApiKey,\n cartId,\n enabled = true,\n}: Args) {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const key = cacheKey(baseUrl, cartId)\n const hit = _cache.get(key)\n const seedConfig = hit && Date.now() - hit.at < CACHE_TTL ? hit.config : null\n\n const [config, setConfig] = useState<PayPalConfig | null>(seedConfig)\n const [loading, setLoading] = useState<boolean>(\n seedConfig === null && enabled\n )\n const [error, setError] = useState<string | null>(null)\n\n const fetchIdRef = useRef(0)\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false)\n setError(null)\n return\n }\n\n const k = cacheKey(baseUrl, cartId)\n const cached = _cache.get(k)\n if (cached && Date.now() - cached.at < CACHE_TTL) {\n setConfig(cached.config)\n setLoading(false)\n setError(null)\n return\n }\n\n const id = ++fetchIdRef.current\n let mounted = true\n const controller = new AbortController()\n\n setLoading(true)\n setError(null)\n ;(async () => {\n try {\n const cfg = await api.getConfig(cartId, controller.signal)\n if (!mounted || id !== fetchIdRef.current) return\n cacheSet(k, { config: cfg, at: Date.now() })\n setConfig(cfg)\n } catch (e: unknown) {\n if (e instanceof Error && e.name === \"AbortError\") return\n if (!mounted || id !== fetchIdRef.current) return\n setError(\n e instanceof Error ? e.message : \"Failed to load PayPal config\"\n )\n } finally {\n if (mounted && id === fetchIdRef.current) setLoading(false)\n }\n })()\n\n return () => {\n mounted = false\n controller.abort()\n }\n }, [api, baseUrl, cartId, enabled])\n\n return { config, loading, error }\n}\n","\"use client\"\n\nimport React, { useMemo } from \"react\"\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\nimport type { ReactPayPalScriptOptions } from \"@paypal/react-paypal-js\"\nimport type { PayPalConfig } from \"../client/types\"\n\nconst BN_CODE = \"MBJTechnolabs_SI_SPB\"\n\nexport function PayPalProvider(props: {\n config: PayPalConfig\n intent?: \"capture\" | \"authorize\"\n disableFunding?: string\n children: React.ReactNode\n}) {\n const { config, intent = \"capture\", disableFunding, children } = props\n\n const options = useMemo((): ReactPayPalScriptOptions => {\n return {\n clientId: config.client_id,\n currency: config.currency,\n intent,\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\n \"data-client-token\": config.client_token || undefined,\n \"disable-funding\": disableFunding,\n \"data-partner-attribution-id\": BN_CODE,\n }\n }, [\n config.client_id,\n config.currency,\n config.client_token,\n intent,\n disableFunding,\n ])\n\n return (\n <PayPalScriptProvider\n key={`${options.clientId}-${options[\"data-client-token\"] ?? \"no-token\"}`}\n options={options}\n >\n {children}\n </PayPalScriptProvider>\n )\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\n if (config.currency_supported) return null\n\n return (\n <div\n role=\"alert\"\n style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}\n >\n <div style={{ fontWeight: 600, marginBottom: 6 }}>\n PayPal currency issue\n </div>\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {(config.currency_errors || []).map((e) => (\n <li key={e}>{e}</li>\n ))}\n </ul>\n </div>\n )\n}\n","\"use client\"\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { PayPalButtons, usePayPalScriptReducer } from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\nimport {\n clearCartCaptured,\n markCartCaptured,\n wasCartCaptured,\n} from \"../utils/captured-state\"\nimport { isNextRouterError } from \"../utils/next-errors\"\nimport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"../utils/processing-overlay\"\n\nconst SPIN_STYLE = `\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\n`\n\nconst BUTTON_WIDTH_MAP: Record<string, string> = {\n small: \"300px\",\n medium: \"400px\",\n large: \"500px\",\n responsive: \"100%\",\n}\n\nexport function PayPalSmartButtons(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: Record<string, unknown>) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [processing, setProcessing] = useState(false)\n const [buttonsReady, setButtonsReady] = useState(false)\n const [loadTimedOut, setLoadTimedOut] = useState(false)\n // Once a capture succeeded, the buyer's money is taken — any later failure\n // (order finalization, consumer callback) must retry ONLY the finalization,\n // never a fresh createOrder/capture, or a retry click would charge again.\n const capturedRef = useRef<Record<string, unknown> | null>(null)\n const [completionPending, setCompletionPending] = useState(false)\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\n\n const handleInit = useCallback(() => {\n setButtonsReady(true)\n }, [])\n\n // bfcache restore (Back button after a redirect) revives this page with the\n // old React state — clear the processing flag so the buyer isn't stuck\n // behind the in-component overlay.\n useEffect(() => {\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) setProcessing(false)\n }\n window.addEventListener(\"pageshow\", onPageShow)\n return () => window.removeEventListener(\"pageshow\", onPageShow)\n }, [])\n\n // A reload/crash between capture and finalization loses the in-memory\n // capturedRef — restore it from the persisted per-cart flag so the buyer\n // gets the finalize-only Retry button instead of payment buttons that would\n // fail confusingly against an already-captured PayPal order.\n useEffect(() => {\n if (capturedRef.current || !wasCartCaptured(cartId)) return\n capturedRef.current = {}\n setCompletionPending(true)\n const msg =\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\n setError(msg)\n }, [cartId])\n\n // The PayPal SDK never calls onInit when the buttons are ineligible (wrong\n // country/currency/funding) — it silently renders nothing. Without a\n // fallback the buyer stares at \"Loading PayPal…\" forever.\n useEffect(() => {\n if (!isResolved || buttonsReady) {\n return\n }\n const t = setTimeout(() => setLoadTimedOut(true), 10_000)\n return () => clearTimeout(t)\n }, [isResolved, buttonsReady])\n\n const finalizeCapturedPayment = useCallback(async () => {\n const captured = capturedRef.current\n if (!captured) return\n setProcessing(true)\n showProcessingOverlay()\n setError(null)\n try {\n const completeResult = await markPaymentComplete(\n baseUrl,\n cartId,\n publishableApiKey\n )\n // The order is finalized — the persisted \"captured\" flag has served its\n // purpose. Clear it before the consumer callback (which may redirect).\n clearCartCaptured(cartId)\n await onPaid?.({ ...captured, ...completeResult })\n setCompletionPending(false)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n hideProcessingOverlay()\n setProcessing(false)\n setCompletionPending(true)\n const msg =\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\n setError(msg)\n onError?.(msg)\n }\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError])\n\n const showSpinner =\n (isPending || (isResolved && !buttonsReady)) && !loadTimedOut\n\n if (!config.currency_supported) return null\n\n const containerWidth =\n BUTTON_WIDTH_MAP[config.button_width ?? \"responsive\"] ?? \"100%\"\n\n return (\n <div style={{ width: containerWidth, position: \"relative\" }}>\n <style>{SPIN_STYLE}</style>\n\n {processing && (\n <div\n role=\"status\"\n aria-label=\"Processing payment\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 9999,\n background: \"rgba(255,255,255,0.96)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 20,\n }}\n >\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid #e5e7eb\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid transparent\",\n borderTopColor: \"#0070ba\",\n animation: \"_pp_spin .8s linear infinite\",\n }}\n />\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#0070ba\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: 24,\n height: 24,\n }}\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n fontSize: 18,\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n }}\n >\n Processing your payment\n </div>\n <div\n style={{\n fontSize: 14,\n color: \"#6b7280\",\n marginTop: 6,\n lineHeight: 1.5,\n }}\n >\n This may take a few moments. Please do not close\n <br />\n or refresh this page.\n </div>\n </div>\n <div\n style={{\n width: 200,\n height: 3,\n background: \"#e5e7eb\",\n borderRadius: 3,\n overflow: \"hidden\",\n marginTop: 4,\n }}\n >\n <div\n style={{\n width: \"40%\",\n height: \"100%\",\n background: \"linear-gradient(90deg, #0070ba, #003087)\",\n borderRadius: 3,\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n )}\n\n {showSpinner && (\n <div\n role=\"status\"\n aria-label=\"Loading PayPal\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 10,\n padding: \"18px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 8,\n minHeight: 55,\n }}\n >\n <div\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n animation: \"_pp_spin .7s linear infinite\",\n flexShrink: 0,\n }}\n />\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\n Loading PayPal…\n </div>\n </div>\n )}\n\n {loadTimedOut && !buttonsReady && !isRejected && (\n <div\n role=\"alert\"\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n }}\n >\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\n <span>\n PayPal is not available for this purchase. Please try a different\n payment method.\n </span>\n </div>\n )}\n\n {isRejected && (\n <div\n role=\"alert\"\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n }}\n >\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\n <span>\n PayPal failed to load. Please refresh the page or try a different\n payment method.\n </span>\n </div>\n )}\n\n {config.environment === \"sandbox\" && buttonsReady && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#eff6ff\",\n border: \"1px solid #bfdbfe\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#1e40af\",\n lineHeight: 1.5,\n marginBottom: 10,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#1e40af\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n style={{ flexShrink: 0, marginTop: 1 }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4M12 16h.01\" />\n </svg>\n <span>\n Sandbox mode — you will not be charged. Use your PayPal sandbox\n account to complete the payment.\n </span>\n </div>\n )}\n\n {isResolved && !completionPending && (\n <div\n style={\n buttonsReady\n ? undefined\n : {\n position: \"absolute\",\n left: -9999,\n opacity: 0,\n pointerEvents: \"none\",\n }\n }\n >\n <PayPalButtons\n forceReRender={[config.currency, config.intent, cartId]}\n onInit={handleInit}\n style={{\n layout: \"vertical\",\n color: config.button_color,\n shape: config.button_shape,\n label: config.button_label,\n height: config.button_height,\n }}\n createOrder={async () => {\n if (processing) throw new Error(\"Payment already processing\")\n if (capturedRef.current) {\n // Money was already captured for this cart — retry the order\n // finalization instead of creating (and charging) a new order.\n void finalizeCapturedPayment()\n throw new Error(\n \"Your payment was already received — finalizing your order.\"\n )\n }\n setError(null)\n setProcessing(true)\n try {\n const r = await api.createOrder(cartId)\n return r.id\n } catch (e: unknown) {\n setProcessing(false)\n throw e\n }\n }}\n onApprove={async (data: { orderID?: string }) => {\n try {\n setProcessing(true)\n showProcessingOverlay()\n setError(null)\n const orderId = String(data?.orderID || \"\")\n if (!orderId)\n throw new Error(\n \"PayPal order ID is missing from approval response\"\n )\n const result = await api.captureOrder(cartId, orderId)\n capturedRef.current = (result || {}) as Record<string, unknown>\n // Persist across reloads: from here on, only finalization may\n // ever be retried for this cart — never a fresh payment.\n markCartCaptured(cartId)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n hideProcessingOverlay()\n setProcessing(false)\n const msg =\n e instanceof Error ? e.message : \"Payment capture failed\"\n setError(msg)\n onError?.(msg)\n return\n }\n // Past this point the buyer has been charged: completion failures\n // surface a finalize-only Retry, never a fresh payment.\n await finalizeCapturedPayment()\n }}\n onCancel={() => {\n hideProcessingOverlay()\n setProcessing(false)\n }}\n onError={(err: Error | { message?: string }) => {\n hideProcessingOverlay()\n setProcessing(false)\n const msg =\n err instanceof Error\n ? err.message\n : err?.message || \"PayPal error\"\n setError(msg)\n onError?.(msg)\n }}\n />\n </div>\n )}\n\n {completionPending && (\n <button\n type=\"button\"\n onClick={() => void finalizeCapturedPayment()}\n disabled={processing}\n aria-busy={processing}\n style={{\n width: \"100%\",\n padding: \"12px 16px\",\n marginTop: 4,\n background: \"#0070ba\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: 8,\n fontSize: 14,\n fontWeight: 600,\n cursor: processing ? \"not-allowed\" : \"pointer\",\n opacity: processing ? 0.7 : 1,\n }}\n >\n Retry — finish placing my order\n </button>\n )}\n\n {error ? (\n <div\n role=\"alert\"\n style={{\n marginTop: 10,\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n }}\n >\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\n <span>{error}</span>\n </div>\n ) : null}\n </div>\n )\n}\n","/**\n * Per-cart \"money was captured\" flag, persisted in sessionStorage.\n *\n * The in-memory `capturedRef` protects a buyer within one page lifetime, but a\n * reload/crash between the capture and the order finalization loses it — the\n * buyer would then see fresh payment buttons for a cart whose money is already\n * taken. Persisting the flag lets the components restore the finalize-only\n * Retry path after a reload instead of offering a second payment.\n *\n * sessionStorage is deliberately chosen over localStorage: it is scoped to the\n * tab/session, so an abandoned flag can't leak into a future visit after the\n * cart id is reused, and it needs no expiry logic. Every access is guarded —\n * private browsing modes and storage-blocking settings throw on access, and a\n * storage failure must never break the payment flow.\n */\n\nconst KEY_PREFIX = \"__pp_captured::\"\n\nexport function markCartCaptured(cartId: string): void {\n if (!cartId) return\n try {\n window.sessionStorage.setItem(`${KEY_PREFIX}${cartId}`, String(Date.now()))\n } catch {\n // storage unavailable — in-memory state still covers the common path\n }\n}\n\nexport function wasCartCaptured(cartId: string): boolean {\n if (!cartId) return false\n try {\n return window.sessionStorage.getItem(`${KEY_PREFIX}${cartId}`) !== null\n } catch {\n return false\n }\n}\n\nexport function clearCartCaptured(cartId: string): void {\n if (!cartId) return\n try {\n window.sessionStorage.removeItem(`${KEY_PREFIX}${cartId}`)\n } catch {\n // ignore\n }\n}\n","/**\n * Detect Next.js router errors (redirect / notFound) that must be re-thrown.\n *\n * Next.js implements redirect() and notFound() by throwing special errors with\n * a `digest` property starting with \"NEXT_REDIRECT\" or \"NEXT_NOT_FOUND\".\n * Catching these in user-land try/catch blocks prevents the navigation from\n * happening. Because this package can't import from `next` (it's a peer dep),\n * we detect them by duck-typing the digest.\n */\nexport function isNextRouterError(e: unknown): boolean {\n if (typeof e !== \"object\" || e === null || !(\"digest\" in e)) return false\n const digest = (e as { digest: unknown }).digest\n return (\n typeof digest === \"string\" &&\n (digest.startsWith(\"NEXT_REDIRECT\") ||\n digest.startsWith(\"NEXT_NOT_FOUND\") ||\n // Next.js 15: notFound()/forbidden()/unauthorized() throw\n // HTTPAccessFallbackError with digest \"NEXT_HTTP_ERROR_FALLBACK;<status>\".\n digest.startsWith(\"NEXT_HTTP_ERROR_FALLBACK\"))\n )\n}\n","const OVERLAY_ID = \"__pp_processing_overlay\"\n\nlet cleanupNavListener: (() => void) | null = null\n\nexport function showProcessingOverlay() {\n if (typeof document === \"undefined\") return\n if (document.getElementById(OVERLAY_ID)) return\n\n const overlay = document.createElement(\"div\")\n overlay.id = OVERLAY_ID\n overlay.setAttribute(\"role\", \"status\")\n overlay.setAttribute(\"aria-label\", \"Processing payment\")\n\n overlay.innerHTML = `\n <style>\n @keyframes _pp_spin { to { transform: rotate(360deg) } }\n @keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\n </style>\n <div style=\"position:relative;width:56px;height:56px\">\n <div style=\"position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb\"></div>\n <div style=\"position:absolute;inset:0;border-radius:50%;border:3px solid transparent;border-top-color:#0070ba;animation:_pp_spin .8s linear infinite\"></div>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0070ba\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n style=\"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px\">\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\n </svg>\n </div>\n <div style=\"text-align:center\">\n <div style=\"font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em\">Processing your payment</div>\n <div style=\"font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5\">\n This may take a few moments. Please do not close<br>or refresh this page.\n </div>\n </div>\n <div style=\"width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px\">\n <div style=\"width:40%;height:100%;background:linear-gradient(90deg,#0070ba,#003087);border-radius:3px;animation:_pp_progress 1.5s ease-in-out infinite\"></div>\n </div>\n `\n\n Object.assign(overlay.style, {\n position: \"fixed\",\n inset: \"0\",\n zIndex: \"99999\",\n background: \"rgba(255,255,255,0.96)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"20px\",\n fontFamily: \"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif\",\n })\n\n document.body.appendChild(overlay)\n\n // Auto-remove on client-side navigation (Next.js App Router uses\n // pushState/replaceState for soft navigations, not full reloads).\n const startUrl = location.href\n const onNav = () => {\n if (location.href !== startUrl) hideProcessingOverlay()\n }\n window.addEventListener(\"popstate\", onNav)\n\n const origPush = history.pushState.bind(history)\n const origReplace = history.replaceState.bind(history)\n history.pushState = function (...args) {\n origPush(...args)\n onNav()\n }\n history.replaceState = function (...args) {\n origReplace(...args)\n onNav()\n }\n\n // bfcache restore: the overlay intentionally survives the unload of a\n // full-page navigation (that's its purpose), but when the buyer presses\n // Back the browser restores this page from the back/forward cache with the\n // overlay element still in the DOM and the URL equal to startUrl — no nav\n // listener ever fires, leaving checkout permanently covered. `pageshow`\n // with `persisted: true` is exactly that restore.\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) hideProcessingOverlay()\n }\n window.addEventListener(\"pageshow\", onPageShow)\n\n cleanupNavListener = () => {\n window.removeEventListener(\"popstate\", onNav)\n window.removeEventListener(\"pageshow\", onPageShow)\n history.pushState = origPush\n history.replaceState = origReplace\n }\n}\n\nexport function hideProcessingOverlay() {\n if (typeof document === \"undefined\") return\n cleanupNavListener?.()\n cleanupNavListener = null\n document.getElementById(OVERLAY_ID)?.remove()\n}\n","\"use client\"\n\nimport React, { useMemo, useRef, useState } from \"react\"\nimport {\n PayPalCardFieldsProvider,\n PayPalNumberField,\n PayPalExpiryField,\n PayPalCVVField,\n usePayPalCardFields,\n usePayPalScriptReducer,\n} from \"@paypal/react-paypal-js\"\n\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\nimport {\n clearCartCaptured,\n markCartCaptured,\n wasCartCaptured,\n} from \"../utils/captured-state\"\nimport { isNextRouterError } from \"../utils/next-errors\"\nimport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"../utils/processing-overlay\"\n\nconst SPIN_STYLE = `\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\n`\n\nconst cardStyle = {\n input: {\n \"font-size\": \"15px\",\n \"font-family\":\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n \"font-weight\": \"400\",\n color: \"#111827\",\n padding: \"0 14px\",\n height: \"42px\",\n \"border-radius\": \"8px\",\n border: \"1px solid #d1d5db\",\n background: \"#ffffff\",\n \"box-shadow\": \"none\",\n transition: \"border-color 0.15s ease\",\n },\n \"::placeholder\": {\n color: \"#9ca3af\",\n },\n \".invalid\": {\n color: \"#dc2626\",\n border: \"1px solid #fca5a5\",\n background: \"#fff7f7\",\n \"box-shadow\": \"none\",\n },\n \".valid\": {\n color: \"#111827\",\n border: \"1px solid #d1d5db\",\n \"box-shadow\": \"none\",\n },\n \"input:focus\": {\n outline: \"none\",\n border: \"1px solid #2563eb\",\n \"box-shadow\": \"0 0 0 3px rgba(37,99,235,0.12)\",\n },\n}\n\nconst labelStyle: React.CSSProperties = {\n display: \"block\",\n fontSize: 13,\n fontWeight: 500,\n color: \"#374151\",\n marginBottom: 6,\n letterSpacing: \"0.01em\",\n}\n\nfunction SubmitButton({\n disabled,\n label,\n onSubmit,\n onSubmitError,\n}: {\n disabled: boolean\n label: string\n onSubmit: () => void\n onSubmitError: (message: string) => void\n}) {\n const { cardFieldsForm } = usePayPalCardFields()\n const isDisabled = disabled || !cardFieldsForm\n\n return (\n <button\n type=\"button\"\n disabled={isDisabled}\n aria-busy={disabled}\n onClick={() => {\n onSubmit()\n // submit() returns a promise and its rejection is NOT routed to the\n // provider's onError — PayPal's contract is that the caller catches\n // it. A sync try/catch here would miss it entirely, leaving the buyer\n // stuck under the full-screen processing overlay forever (e.g. on a\n // card-field validation error).\n Promise.resolve(cardFieldsForm?.submit()).catch((e: unknown) => {\n const msg =\n e instanceof Error && e.message\n ? e.message\n : \"Card payment could not be submitted. Please check your card details.\"\n onSubmitError(msg)\n })\n }}\n style={{\n width: \"100%\",\n height: 48,\n padding: \"0 20px\",\n borderRadius: 8,\n border: \"none\",\n background: isDisabled\n ? \"#e5e7eb\"\n : \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\",\n color: isDisabled ? \"#9ca3af\" : \"#ffffff\",\n fontSize: 15,\n fontWeight: 600,\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\n letterSpacing: \"0.01em\",\n boxShadow: isDisabled\n ? \"none\"\n : \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n if (!isDisabled) {\n ;(e.target as HTMLButtonElement).style.background =\n \"linear-gradient(180deg, #1d4ed8 0%, #1e40af 100%)\"\n ;(e.target as HTMLButtonElement).style.boxShadow =\n \"0 4px 6px rgba(37,99,235,0.35), 0 2px 4px rgba(0,0,0,0.06)\"\n }\n }}\n onMouseLeave={(e) => {\n if (!isDisabled) {\n ;(e.target as HTMLButtonElement).style.background =\n \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\"\n ;(e.target as HTMLButtonElement).style.boxShadow =\n \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\"\n }\n }}\n >\n {label}\n </button>\n )\n}\n\nexport function PayPalAdvancedCard(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: Record<string, unknown>) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n const submittingRef = useRef(false)\n const creatingOrderRef = useRef(false)\n // Once a capture succeeded the buyer's money is taken: any later failure\n // must retry ONLY the order finalization, never a fresh order/capture.\n const capturedRef = useRef<Record<string, unknown> | null>(null)\n const [completionPending, setCompletionPending] = useState(false)\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\n\n const resetSubmitState = React.useCallback(() => {\n hideProcessingOverlay()\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n }, [])\n\n // bfcache restore (Back button after a redirect) revives this page with the\n // old React state — clear the submitting flag so the buyer isn't stuck\n // behind the in-component overlay.\n React.useEffect(() => {\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) {\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n }\n }\n window.addEventListener(\"pageshow\", onPageShow)\n return () => window.removeEventListener(\"pageshow\", onPageShow)\n }, [])\n\n // A reload/crash between capture and finalization loses the in-memory\n // capturedRef — restore it from the persisted per-cart flag so the buyer\n // gets the finalize-only Retry button instead of card fields that would\n // charge (or confusingly fail) again.\n React.useEffect(() => {\n if (capturedRef.current || !wasCartCaptured(cartId)) return\n capturedRef.current = {}\n setCompletionPending(true)\n setError(\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\n )\n }, [cartId])\n\n const finalizeCapturedPayment = React.useCallback(async () => {\n const captured = capturedRef.current\n if (!captured) return\n setSubmitting(true)\n showProcessingOverlay()\n setError(null)\n try {\n const completeResult = await markPaymentComplete(\n baseUrl,\n cartId,\n publishableApiKey\n )\n // The order is finalized — the persisted \"captured\" flag has served its\n // purpose. Clear it before the consumer callback (which may redirect).\n clearCartCaptured(cartId)\n await onPaid?.({ ...captured, ...completeResult })\n setCompletionPending(false)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n resetSubmitState()\n setCompletionPending(true)\n const msg =\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\n setError(msg)\n onError?.(msg)\n }\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError, resetSubmitState])\n\n if (!config.currency_supported) return null\n\n if (isRejected) {\n return (\n <div\n role=\"alert\"\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n }}\n >\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\n <span>\n PayPal failed to load. Please refresh the page or try a different\n payment method.\n </span>\n </div>\n )\n }\n\n if (!config.client_token) {\n return (\n <div\n style={{\n padding: \"12px 16px\",\n background: \"#fefce8\",\n border: \"1px solid #fde68a\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#92400e\",\n }}\n >\n Card fields unavailable — missing client token from backend.\n </div>\n )\n }\n\n const isSandbox = config.environment === \"sandbox\"\n\n if (isPending) {\n return (\n <div\n role=\"status\"\n aria-label=\"Loading PayPal\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 10,\n padding: \"18px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 8,\n minHeight: 55,\n }}\n >\n <style>{SPIN_STYLE}</style>\n <div\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n animation: \"_pp_spin .7s linear infinite\",\n flexShrink: 0,\n }}\n />\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\n Loading card fields…\n </div>\n </div>\n )\n }\n\n if (!isResolved) return null\n\n return (\n <div style={{ position: \"relative\" }}>\n <style>{SPIN_STYLE}</style>\n\n {submitting && (\n <div\n role=\"status\"\n aria-label=\"Processing payment\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 9999,\n background: \"rgba(255,255,255,0.96)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 20,\n }}\n >\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid #e5e7eb\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid transparent\",\n borderTopColor: \"#2563eb\",\n animation: \"_pp_spin .8s linear infinite\",\n }}\n />\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#2563eb\"\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: 24,\n height: 24,\n }}\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n fontSize: 18,\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n }}\n >\n Processing your payment\n </div>\n <div\n style={{\n fontSize: 14,\n color: \"#6b7280\",\n marginTop: 6,\n lineHeight: 1.5,\n }}\n >\n This may take a few moments. Please do not close\n <br />\n or refresh this page.\n </div>\n </div>\n <div\n style={{\n width: 200,\n height: 3,\n background: \"#e5e7eb\",\n borderRadius: 3,\n overflow: \"hidden\",\n marginTop: 4,\n }}\n >\n <div\n style={{\n width: \"40%\",\n height: \"100%\",\n background: \"linear-gradient(90deg, #2563eb, #1d4ed8)\",\n borderRadius: 3,\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n )}\n\n <PayPalCardFieldsProvider\n style={cardStyle}\n createOrder={async () => {\n if (creatingOrderRef.current)\n throw new Error(\"Payment already processing\")\n if (capturedRef.current) {\n // Money was already captured for this cart — retry the order\n // finalization instead of creating (and charging) a new order.\n void finalizeCapturedPayment()\n throw new Error(\n \"Your payment was already received — finalizing your order.\"\n )\n }\n creatingOrderRef.current = true\n try {\n setError(null)\n const r = await api.createOrder(cartId, true)\n return r.id\n } catch (e) {\n creatingOrderRef.current = false\n throw e\n }\n }}\n onApprove={async (data: { orderID?: string }) => {\n try {\n setError(null)\n showProcessingOverlay()\n const orderId = String(data?.orderID || \"\")\n if (!orderId)\n throw new Error(\n \"PayPal order ID is missing from approval response\"\n )\n const result = await api.captureOrder(cartId, orderId)\n capturedRef.current = (result || {}) as Record<string, unknown>\n // Persist across reloads: from here on, only finalization may\n // ever be retried for this cart — never a fresh payment.\n markCartCaptured(cartId)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n resetSubmitState()\n const msg = e instanceof Error ? e.message : \"Card payment failed\"\n setError(msg)\n onError?.(msg)\n return\n }\n // Past this point the buyer has been charged: completion failures\n // surface a finalize-only Retry, never a fresh payment.\n await finalizeCapturedPayment()\n }}\n onCancel={() => {\n hideProcessingOverlay()\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n }}\n onError={(e: Error | { message?: string }) => {\n const msg =\n e instanceof Error ? e.message : e?.message || \"CardFields error\"\n setError(msg)\n onError?.(msg)\n hideProcessingOverlay()\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n width: \"100%\",\n }}\n >\n {isSandbox && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 10,\n padding: \"10px 14px\",\n background: \"#eff6ff\",\n border: \"1px solid #bfdbfe\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#1e40af\",\n lineHeight: 1.55,\n }}\n >\n <span style={{ fontSize: 15, flexShrink: 0, marginTop: 1 }}>\n 🧪\n </span>\n <span>\n Sandbox mode — use test card{\" \"}\n <strong\n style={{ fontFamily: \"monospace\", letterSpacing: \"0.05em\" }}\n >\n 4111 1111 1111 1111\n </strong>{\" \"}\n with any future date and any CVV.\n </span>\n </div>\n )}\n\n <div>\n <label style={labelStyle}>Card number</label>\n <PayPalNumberField />\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: 16,\n }}\n >\n <div>\n <label style={labelStyle}>Expiration date</label>\n <PayPalExpiryField />\n </div>\n <div>\n <label style={labelStyle}>Security code</label>\n <PayPalCVVField />\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n fontSize: 12,\n color: \"#6b7280\",\n }}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#10b981\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n <span>Your payment is secured with 256-bit SSL encryption</span>\n </div>\n\n {completionPending ? (\n <button\n type=\"button\"\n onClick={() => void finalizeCapturedPayment()}\n disabled={submitting}\n aria-busy={submitting}\n style={{\n width: \"100%\",\n height: 48,\n padding: \"0 20px\",\n borderRadius: 8,\n border: \"none\",\n background: \"#0070ba\",\n color: \"#ffffff\",\n fontSize: 15,\n fontWeight: 600,\n cursor: submitting ? \"not-allowed\" : \"pointer\",\n opacity: submitting ? 0.7 : 1,\n }}\n >\n Retry — finish placing my order\n </button>\n ) : (\n <SubmitButton\n disabled={submitting}\n label={submitting ? \"Processing…\" : \"Pay by Card\"}\n onSubmit={() => {\n if (submittingRef.current) return\n submittingRef.current = true\n setError(null)\n setSubmitting(true)\n showProcessingOverlay()\n }}\n onSubmitError={(msg) => {\n resetSubmitState()\n setError(msg)\n onError?.(msg)\n }}\n />\n )}\n\n {error && (\n <div\n role=\"alert\"\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 10,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n }}\n >\n <span style={{ flexShrink: 0, marginTop: 1 }}>⚠️</span>\n <span>{error}</span>\n </div>\n )}\n </div>\n </PayPalCardFieldsProvider>\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useCallback } from \"react\"\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\nimport { PayPalProvider } from \"../components/PayPalProvider\"\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\nimport {\n PAYPAL_WALLET_PROVIDER_ID as DEFAULT_PAYPAL_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID as DEFAULT_PAYPAL_CARD_PROVIDER_ID,\n} from \"../constants\"\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\n\nconst SPIN_STYLE = `@keyframes _pp_spin { to { transform: rotate(360deg) } }`\n\nfunction PayPalLoadingCard() {\n return (\n <div\n role=\"status\"\n aria-label=\"Connecting to PayPal\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"14px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n }}\n >\n <style>{SPIN_STYLE}</style>\n <div\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n animation: \"_pp_spin .7s linear infinite\",\n flexShrink: 0,\n }}\n />\n <div>\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\n Connecting to PayPal…\n </div>\n <div style={{ fontSize: 12, color: \"#6b7280\", marginTop: 2 }}>\n Setting up secure payment\n </div>\n </div>\n </div>\n )\n}\n\nfunction PayPalErrorCard({ message }: { message: string }) {\n return (\n <div\n role=\"alert\"\n style={{\n padding: \"12px 16px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 10,\n fontSize: 13,\n color: \"#b91c1c\",\n }}\n >\n {message}\n </div>\n )\n}\n\n/**\n * Shown when the merchant has disabled the selected PayPal method in admin\n * settings. Rendering nothing here (the old behavior) left the buyer staring\n * at blank space under a selected payment option.\n */\nfunction PayPalUnavailableCard({ label }: { label: string }) {\n return (\n <div\n role=\"status\"\n style={{\n padding: \"12px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 13,\n color: \"#6b7280\",\n }}\n >\n {label} is currently unavailable. Please choose a different payment\n method.\n </div>\n )\n}\n\nexport type MedusaNextPayPalAdapterProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n providerIds?: {\n paypal?: string\n paypalCard?: string\n }\n onSuccess?: (cartId: string) => void\n onError?: (message: string) => void\n onPaid?: (result: unknown) => void\n}\n\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\n const {\n cartId,\n selectedProviderId,\n baseUrl,\n publishableApiKey,\n providerIds,\n onSuccess,\n onError,\n onPaid,\n } = props\n\n const paypalProviderId = providerIds?.paypal || DEFAULT_PAYPAL_PROVIDER_ID\n const paypalCardProviderId =\n providerIds?.paypalCard || DEFAULT_PAYPAL_CARD_PROVIDER_ID\n\n const shouldRender =\n selectedProviderId === paypalProviderId ||\n selectedProviderId === paypalCardProviderId\n\n const { config, loading, error } = usePayPalConfig({\n baseUrl,\n publishableApiKey,\n cartId,\n enabled: shouldRender,\n })\n\n const handlePaid = useCallback(\n async (captureResult: unknown) => {\n onPaid?.(captureResult)\n await onSuccess?.(cartId)\n },\n [cartId, onPaid, onSuccess]\n )\n\n if (!shouldRender) return null\n\n if (loading) return <PayPalLoadingCard />\n\n if (error) return <PayPalErrorCard message={error} />\n\n if (!config) return null\n\n const isCardProvider = selectedProviderId === paypalCardProviderId\n if (config.paypal_enabled === false && !isCardProvider) {\n return <PayPalUnavailableCard label={config.paypal_title || \"PayPal\"} />\n }\n if (isCardProvider && config.card_enabled === false) {\n return <PayPalUnavailableCard label={config.card_title || \"Card payment\"} />\n }\n\n const disableFunding = Array.isArray(config.disable_buttons)\n ? config.disable_buttons.join(\",\")\n : undefined\n\n return (\n <div key={selectedProviderId} style={{ display: \"grid\", gap: 12 }}>\n <PayPalCurrencyNotice config={config} />\n <PayPalProvider\n config={config}\n intent={config.intent === \"authorize\" ? \"authorize\" : \"capture\"}\n disableFunding={disableFunding}\n >\n {isCardProvider ? (\n <PayPalAdvancedCard\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config}\n onPaid={handlePaid}\n onError={onError}\n />\n ) : (\n <PayPalSmartButtons\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config}\n onPaid={handlePaid}\n onError={onError}\n />\n )}\n </PayPalProvider>\n </div>\n )\n}\n","/**\n * Provider ids registered by `@easypayment/medusa-payment-paypal`.\n *\n * Single source of truth — `PayPalPaymentSection`, `MedusaNextPayPalAdapter`,\n * and the server-safe `order` entrypoint all re-export from here so the ids\n * can never drift between entrypoints.\n */\nexport const PAYPAL_WALLET_PROVIDER_ID = \"pp_paypal_paypal\" as const\nexport const PAYPAL_CARD_PROVIDER_ID = \"pp_paypal_card_paypal_card\" as const\n\nexport const PAYPAL_PROVIDER_IDS = [\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n] as const\n\nexport type PayPalProviderId = (typeof PAYPAL_PROVIDER_IDS)[number]\n\n/** True when the provider id belongs to this PayPal plugin. */\nexport function isPayPalProviderId(\n providerId?: string | null\n): providerId is PayPalProviderId {\n if (!providerId) return false\n return PAYPAL_PROVIDER_IDS.includes(providerId as PayPalProviderId)\n}\n","\"use client\"\n\nimport React from \"react\"\nimport { MedusaNextPayPalAdapter } from \"../adapters/MedusaNextPayPalAdapter\"\nimport {\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n isPayPalProviderId,\n} from \"../constants\"\n\n// Re-exported for backward compatibility — these have always been part of this\n// module's public API. The canonical definitions live in ../constants.\nexport {\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n isPayPalProviderId,\n}\n\nconst SPIN_STYLE = `@keyframes _pp_section_spin { to { transform: rotate(360deg) } }`\n\nfunction SessionInitCard() {\n return (\n <div\n role=\"status\"\n aria-label=\"Setting up payment\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"14px 16px\",\n marginTop: 8,\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n }}\n >\n <style>{SPIN_STYLE}</style>\n <div\n style={{\n width: 20,\n height: 20,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n animation: \"_pp_section_spin .7s linear infinite\",\n flexShrink: 0,\n }}\n />\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\n Setting up payment…\n </div>\n </div>\n )\n}\n\nexport type PayPalPaymentSectionProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n sessionLoading?: boolean\n onSuccess?: (cartId: string) => void\n onError?: (message: string) => void\n onPaid?: (result: unknown) => void\n}\n\n/**\n * Drop-in PayPal payment section for a Medusa checkout.\n *\n * A thin wrapper over {@link MedusaNextPayPalAdapter} (they previously carried\n * two ~90%-identical render paths that had to be edited in lockstep): this\n * component pins the default provider ids and adds the `sessionLoading` gate\n * shown while the storefront is still creating the payment session.\n */\nexport function PayPalPaymentSection({\n cartId,\n selectedProviderId,\n baseUrl,\n publishableApiKey,\n sessionLoading = false,\n onSuccess,\n onError,\n onPaid,\n}: PayPalPaymentSectionProps) {\n if (!isPayPalProviderId(selectedProviderId)) return null\n if (sessionLoading) return <SessionInitCard />\n\n return (\n <MedusaNextPayPalAdapter\n cartId={cartId}\n selectedProviderId={selectedProviderId}\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n onSuccess={onSuccess}\n onError={onError}\n onPaid={onPaid}\n />\n )\n}\n","\"use client\"\n\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n enabled?: boolean\n}\n\ntype Result = {\n paypalEnabled: boolean\n paypalTitle: string\n cardEnabled: boolean\n cardTitle: string\n loading: boolean\n /**\n * Non-null when the config fetch failed and the returned flags are the\n * optimistic defaults rather than the merchant's real settings. Storefronts\n * can use this to hide or annotate the PayPal options instead of advertising\n * methods that will fail once selected.\n */\n error: string | null\n}\n\nconst MAX_CACHE_ENTRIES = 50\nconst _cache = new Map<string, { result: Result; at: number }>()\nconst CACHE_TTL = 5 * 60 * 1000\n\nfunction cacheSet(key: string, value: { result: Result; at: number }) {\n if (_cache.size >= MAX_CACHE_ENTRIES) {\n const oldest = _cache.keys().next().value\n if (oldest !== undefined) _cache.delete(oldest)\n }\n _cache.set(key, value)\n}\n\nfunction cacheKey(baseUrl: string, cartId?: string) {\n return `ppm::${baseUrl}::${cartId ?? \"\"}`\n}\n\nconst DEFAULT_RESULT: Result = {\n paypalEnabled: true,\n paypalTitle: \"PayPal\",\n cardEnabled: true,\n cardTitle: \"Credit or Debit Card\",\n loading: false,\n error: null,\n}\n\nexport function usePayPalPaymentMethods({\n baseUrl,\n publishableApiKey,\n cartId,\n enabled = true,\n}: Args): Result {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const key = cacheKey(baseUrl, cartId)\n const hit = _cache.get(key)\n const seed = hit && Date.now() - hit.at < CACHE_TTL ? hit.result : null\n\n const [result, setResult] = useState<Result>(\n seed ?? { ...DEFAULT_RESULT, loading: enabled }\n )\n const fetchIdRef = useRef(0)\n\n useEffect(() => {\n if (!enabled) {\n setResult((prev) => ({ ...prev, loading: false }))\n return\n }\n\n const k = cacheKey(baseUrl, cartId)\n const cached = _cache.get(k)\n if (cached && Date.now() - cached.at < CACHE_TTL) {\n setResult(cached.result)\n return\n }\n\n const id = ++fetchIdRef.current\n let mounted = true\n const controller = new AbortController()\n\n setResult((prev) => ({ ...prev, loading: true }))\n ;(async () => {\n try {\n const cfg = await api.getConfig(cartId, controller.signal)\n if (!mounted || id !== fetchIdRef.current) return\n\n const next: Result = {\n paypalEnabled: cfg.paypal_enabled !== false,\n paypalTitle:\n typeof cfg.paypal_title === \"string\" && cfg.paypal_title\n ? cfg.paypal_title\n : \"PayPal\",\n cardEnabled: cfg.card_enabled !== false,\n cardTitle:\n typeof cfg.card_title === \"string\" && cfg.card_title\n ? cfg.card_title\n : \"Credit or Debit Card\",\n loading: false,\n error: null,\n }\n\n cacheSet(k, { result: next, at: Date.now() })\n setResult(next)\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : \"\"\n if (e instanceof Error && e.name === \"AbortError\") return\n if (!mounted || id !== fetchIdRef.current) return\n\n if (msg.includes(\"403\") || msg.includes(\"Forbidden\")) {\n const disabled: Result = {\n ...DEFAULT_RESULT,\n paypalEnabled: false,\n cardEnabled: false,\n loading: false,\n error: msg || \"PayPal is disabled\",\n }\n setResult(disabled)\n return\n }\n\n setResult({\n ...DEFAULT_RESULT,\n loading: false,\n error: msg || \"Failed to load PayPal payment methods\",\n })\n }\n })()\n\n return () => {\n mounted = false\n controller.abort()\n }\n }, [api, baseUrl, cartId, enabled])\n\n return result\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_react_paypal_js","import_jsx_runtime","import_react","import_react_paypal_js","import_jsx_runtime","SPIN_STYLE","React","import_react","import_jsx_runtime","SPIN_STYLE","import_jsx_runtime","SPIN_STYLE","import_react","MAX_CACHE_ENTRIES","_cache","CACHE_TTL","cacheSet","cacheKey"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client/http.ts","../src/client/paypal.ts","../src/client/config-cache.ts","../src/constants.ts","../src/hooks/usePayPalConfig.ts","../src/components/PayPalProvider.tsx","../src/components/PayPalCurrencyNotice.tsx","../src/components/PayPalSmartButtons.tsx","../src/utils/captured-state.ts","../src/utils/next-errors.ts","../src/utils/processing-overlay.ts","../src/components/internal/ui.tsx","../src/components/PayPalAdvancedCard.tsx","../src/adapters/MedusaNextPayPalAdapter.tsx","../src/components/PayPalPaymentSection.tsx","../src/hooks/usePayPalPaymentMethods.ts"],"sourcesContent":["export * from \"./client/types\"\nexport * from \"./client/paypal\"\nexport { createHttpClient, HttpError } from \"./client/http\"\nexport type { HttpOptions, RequestOptions } from \"./client/http\"\nexport { invalidatePayPalConfigCache } from \"./client/config-cache\"\nexport * from \"./constants\"\nexport * from \"./hooks/usePayPalConfig\"\nexport * from \"./components/PayPalProvider\"\nexport * from \"./components/PayPalCurrencyNotice\"\nexport * from \"./components/PayPalSmartButtons\"\nexport * from \"./components/PayPalAdvancedCard\"\nexport * from \"./adapters/MedusaNextPayPalAdapter\"\nexport * from \"./components/PayPalPaymentSection\"\nexport * from \"./hooks/usePayPalPaymentMethods\"\nexport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"./utils/processing-overlay\"\nexport {\n markCartCaptured,\n wasCartCaptured,\n clearCartCaptured,\n} from \"./utils/captured-state\"\n","export type HttpOptions = {\n baseUrl: string\n publishableApiKey?: string\n /**\n * `credentials` mode for every request. Defaults to \"include\" (the\n * historical behavior, required when the backend sits behind cookie-based\n * gateways like Cloudflare Access). Set to \"omit\" or \"same-origin\" when the\n * backend answers with `Access-Control-Allow-Origin: *` — browsers reject\n * credentialed requests against a wildcard CORS origin outright.\n */\n credentials?: RequestCredentials\n /**\n * Per-request timeout in milliseconds. Covers the full request including\n * reading the body. Defaults to 30 000. A caller-supplied AbortSignal\n * composes with (never replaces) this timeout.\n */\n timeoutMs?: number\n}\n\nexport type RequestOptions = {\n /**\n * Number of extra attempts on transient failures (network error, timeout,\n * HTTP 429/5xx). Only use for idempotent calls — the PayPal capture/complete\n * endpoints are idempotent server-side, so a retried request after a network\n * blip re-uses the existing result instead of duplicating work. Default 0.\n */\n retries?: number\n}\n\n/**\n * Error thrown for HTTP-level failures (non-2xx responses and malformed\n * response bodies). `status` carries the HTTP status code so callers can\n * branch on it (e.g. 403 → \"PayPal is disabled\") instead of matching\n * localized/backend-authored message text.\n */\nexport class HttpError extends Error {\n status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = \"HttpError\"\n this.status = status\n }\n}\n\nconst RETRY_BASE_DELAY_MS = 400\n\nfunction isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500\n}\n\nfunction isRetryableError(err: unknown): boolean {\n // Network failures and our own timeout error are safe to retry.\n return err instanceof Error && !(err instanceof HttpError)\n}\n\nconst wait = (ms: number) => new Promise((r) => setTimeout(r, ms))\n\n/** Best-effort extraction of a `{ message: string }` payload from a response body. */\nfunction extractJsonMessage(text: string): string | null {\n if (!text) return null\n try {\n const parsed = JSON.parse(text)\n const message = parsed?.message\n if (typeof message === \"string\" && message.trim()) {\n return message.trim().slice(0, 500)\n }\n } catch {\n // not JSON — caller falls back to the raw text\n }\n return null\n}\n\nfunction toHeaderRecord(\n headers?: RequestInit[\"headers\"]\n): Record<string, string> {\n if (!headers) {\n return {}\n }\n\n if (headers instanceof Headers) {\n return Object.fromEntries(headers.entries())\n }\n\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers)\n }\n\n return { ...headers }\n}\n\nexport function createHttpClient(opts: HttpOptions) {\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\n\n async function attempt<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...toHeaderRecord(init?.headers),\n }\n\n if (opts.publishableApiKey) {\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\n }\n\n // Always arm the timeout — a caller-supplied signal composes with it\n // rather than replacing it. Without this, hook-issued requests (which\n // always pass an abort signal) could hang forever on a stalled\n // connection. The timer also covers reading the body: a server that sends\n // headers then stalls the response stream would otherwise hang the\n // request indefinitely with the old header-only timeout.\n const timeoutMs = opts.timeoutMs ?? 30_000\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\n const callerSignal = init?.signal ?? null\n const onCallerAbort = () => controller.abort()\n if (callerSignal) {\n if (callerSignal.aborted) controller.abort()\n else callerSignal.addEventListener(\"abort\", onCallerAbort)\n }\n let res: Response\n let text: string\n try {\n res = await fetch(url, {\n ...init,\n headers,\n credentials: opts.credentials ?? \"include\",\n signal: controller.signal,\n })\n text = await res.text().catch(() => \"\")\n } catch (err) {\n if (\n err instanceof Error &&\n err.name === \"AbortError\" &&\n !(callerSignal && callerSignal.aborted)\n ) {\n throw new Error(\n `[PayPal] Request to ${path} timed out after ${timeoutMs / 1000}s`\n )\n }\n throw err\n } finally {\n clearTimeout(timeoutId)\n if (callerSignal) callerSignal.removeEventListener(\"abort\", onCallerAbort)\n }\n\n if (!res.ok) {\n // Backend routes return structured JSON errors ({ message }) written for\n // the buyer (e.g. unsupported currency, rate-limit, \"payment processed\n // but order not finalized\"). Prefer that message over raw response text\n // or a generic hint so the user sees something actionable instead of a\n // JSON blob.\n const parsedMessage = extractJsonMessage(text)\n if (res.status === 401) {\n throw new HttpError(\n parsedMessage ||\n \"[PayPal] Unauthorized (401) — check that your publishable API key is correct and set in NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY\",\n 401\n )\n }\n if (res.status === 403) {\n throw new HttpError(\n parsedMessage ||\n \"[PayPal] Forbidden (403) — this request is not allowed. Check your CORS and API key settings.\",\n 403\n )\n }\n throw new HttpError(\n parsedMessage ||\n text.slice(0, 500).replace(/<[^>]*>/g, \"\") ||\n `Request failed (${res.status})`,\n res.status\n )\n }\n if (!text) {\n throw new HttpError(\n `[PayPal] Empty response body from ${path} (${res.status})`,\n res.status\n )\n }\n\n // Malformed success responses are HttpError (carrying the 2xx status) so\n // the retry logic treats them as non-transient — a server answering 200\n // with HTML will answer the same way on a retry.\n const contentType = res.headers.get(\"content-type\") || \"\"\n if (!contentType.includes(\"application/json\")) {\n throw new HttpError(\n `[PayPal] Unexpected non-JSON response (${contentType}) from ${path}`,\n res.status\n )\n }\n\n try {\n return JSON.parse(text) as T\n } catch {\n throw new HttpError(\n `[PayPal] Failed to parse JSON response from ${path}`,\n res.status\n )\n }\n }\n\n async function request<T>(\n path: string,\n init?: RequestInit,\n reqOpts?: RequestOptions\n ): Promise<T> {\n const retries = Math.max(0, reqOpts?.retries ?? 0)\n let lastError: unknown\n for (let i = 0; i <= retries; i++) {\n try {\n return await attempt<T>(path, init)\n } catch (err) {\n lastError = err\n const transient =\n (err instanceof HttpError && isRetryableStatus(err.status)) ||\n isRetryableError(err)\n // Don't retry a caller-supplied AbortSignal cancellation.\n const aborted =\n err instanceof Error && err.name === \"AbortError\" && !!init?.signal\n if (i >= retries || !transient || aborted) {\n throw err\n }\n await wait(\n RETRY_BASE_DELAY_MS * Math.pow(2, i) +\n Math.random() * RETRY_BASE_DELAY_MS\n )\n }\n }\n throw lastError\n }\n\n return { request }\n}\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\nimport { createHttpClient, type HttpOptions } from \"./http\"\n\n/**\n * Fresh idempotency key per create-order ATTEMPT (i.e. per buyer click).\n *\n * The backend derives the PayPal-Request-Id from this header. It must be\n * unique per attempt: PayPal replays the cached response for a reused request\n * id, so a key stable across cart changes would hand back the ORIGINAL order —\n * at the original total — after the buyer edits the cart, charging a stale\n * amount. Reuse/dedup of an unchanged order is handled server-side by the\n * stored-order staleness check, not by this key.\n */\nexport function generateIdempotencyKey(): string {\n try {\n const c = (globalThis as { crypto?: Crypto }).crypto\n if (c?.randomUUID) return c.randomUUID()\n } catch {\n // fall through\n }\n return `pp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`\n}\n\nexport type MarkPaymentCompleteOptions = {\n publishableApiKey?: string\n credentials?: RequestCredentials\n timeoutMs?: number\n signal?: AbortSignal\n}\n\nexport async function markPaymentComplete(\n baseUrl: string,\n cartId: string,\n /** Publishable API key string (legacy signature) or an options object. */\n options?: string | MarkPaymentCompleteOptions\n): Promise<Record<string, unknown>> {\n const opts: MarkPaymentCompleteOptions =\n typeof options === \"string\"\n ? { publishableApiKey: options }\n : (options ?? {})\n const http = createHttpClient({\n baseUrl,\n publishableApiKey: opts.publishableApiKey,\n credentials: opts.credentials,\n timeoutMs: opts.timeoutMs,\n })\n // Retry transient failures: /store/paypal-complete is idempotent (it returns\n // already_completed for a finished cart), so a network blip right after\n // capture — the classic \"captured but cart not completed\" gap — is retried\n // instead of stranding a paid-but-unfinalized order.\n return http.request<Record<string, unknown>>(\n `/store/paypal-complete`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId }),\n signal: opts.signal,\n },\n { retries: 3 }\n )\n}\n\nexport function createPayPalStoreApi(opts: HttpOptions) {\n const http = createHttpClient(opts)\n\n return {\n getConfig(cartId?: string, signal?: AbortSignal) {\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\n return http.request<PayPalConfig>(`/store/paypal/config${q}`, { signal })\n },\n\n getSettings(signal?: AbortSignal) {\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`, {\n signal,\n })\n },\n\n createOrder(cartId: string, isCardPayment = false, signal?: AbortSignal) {\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n // One key per attempt — see generateIdempotencyKey. Deliberately NOT\n // sent for capture-order: there the server's deterministic\n // per-order-id fallback is the correct idempotency scope.\n \"Idempotency-Key\": generateIdempotencyKey(),\n },\n body: JSON.stringify({\n cart_id: cartId,\n is_card_payment: isCardPayment,\n }),\n signal,\n })\n },\n\n captureOrder(cartId: string, orderId: string, signal?: AbortSignal) {\n // Retry transient failures: capture-order is idempotent server-side (it\n // short-circuits on an existing capture and PayPal dedupes by request id),\n // so a network blip during capture doesn't leave the buyer's funds\n // authorized-but-not-captured with no recovery.\n return http.request<Record<string, unknown>>(\n `/store/paypal/capture-order`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\n signal,\n },\n { retries: 2 }\n )\n },\n }\n}\n","import type { PayPalConfig } from \"./types\"\n\n/**\n * Shared module-level cache for `/store/paypal/config` responses.\n *\n * Both `usePayPalConfig` and `usePayPalPaymentMethods` read the same endpoint;\n * sharing one cache (and one in-flight promise per key) means a checkout page\n * that mounts both hooks issues a single network request instead of two.\n *\n * The key includes the publishable API key and an optional currency code so a\n * region/currency switch on the same cart busts the cache instead of serving\n * a stale config for up to the TTL.\n */\n\ntype Entry = { config: PayPalConfig; at: number }\n\nconst MAX_CACHE_ENTRIES = 50\nconst CACHE_TTL_MS = 5 * 60 * 1000\n\n/** Separator that cannot appear in URLs, API keys, cart ids, or currencies. */\nconst SEP = \"\\u0001\"\n\nconst cache = new Map<string, Entry>()\nconst inflight = new Map<string, Promise<PayPalConfig>>()\n\nexport function configCacheKey(args: {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n currencyCode?: string\n}): string {\n return [\n args.baseUrl,\n args.publishableApiKey ?? \"\",\n args.cartId ?? \"\",\n (args.currencyCode ?? \"\").toLowerCase(),\n ].join(SEP)\n}\n\nexport function getCachedPayPalConfig(key: string): PayPalConfig | null {\n const hit = cache.get(key)\n if (!hit) return null\n if (Date.now() - hit.at >= CACHE_TTL_MS) {\n cache.delete(key)\n return null\n }\n return hit.config\n}\n\n/**\n * Drop cached configs — all of them, or only the entries for one cart.\n * Call after anything that changes what the config endpoint would return\n * (region/currency switch, plugin settings change).\n */\nexport function invalidatePayPalConfigCache(cartId?: string): void {\n if (cartId === undefined) {\n cache.clear()\n return\n }\n for (const key of [...cache.keys()]) {\n if (key.split(SEP)[2] === cartId) cache.delete(key)\n }\n}\n\n/**\n * Fetch a config, deduplicating concurrent requests for the same key.\n *\n * The fetcher deliberately receives no caller AbortSignal: the resulting\n * promise may be shared by several mounted hooks, so one unmounting must not\n * cancel the others. Callers discard the result after unmount instead; the\n * HTTP client's own timeout bounds the request.\n */\nexport function fetchPayPalConfigShared(\n key: string,\n fetcher: () => Promise<PayPalConfig>\n): Promise<PayPalConfig> {\n const existing = inflight.get(key)\n if (existing) return existing\n\n const p = (async () => {\n try {\n const config = await fetcher()\n if (cache.size >= MAX_CACHE_ENTRIES && !cache.has(key)) {\n const oldest = cache.keys().next().value\n if (oldest !== undefined) cache.delete(oldest)\n }\n cache.set(key, { config, at: Date.now() })\n return config\n } finally {\n inflight.delete(key)\n }\n })()\n\n inflight.set(key, p)\n return p\n}\n","/**\n * Provider ids registered by `@easypayment/medusa-payment-paypal`.\n *\n * Single source of truth — `PayPalPaymentSection`, `MedusaNextPayPalAdapter`,\n * and the server-safe `order` entrypoint all re-export from here so the ids\n * can never drift between entrypoints.\n */\nexport const PAYPAL_WALLET_PROVIDER_ID = \"pp_paypal_paypal\" as const\nexport const PAYPAL_CARD_PROVIDER_ID = \"pp_paypal_card_paypal_card\" as const\n\nexport const PAYPAL_PROVIDER_IDS = [\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n] as const\n\nexport type PayPalProviderId = (typeof PAYPAL_PROVIDER_IDS)[number]\n\n/** True when the provider id belongs to this PayPal plugin. */\nexport function isPayPalProviderId(\n providerId?: string | null\n): providerId is PayPalProviderId {\n if (!providerId) return false\n return PAYPAL_PROVIDER_IDS.includes(providerId as PayPalProviderId)\n}\n","\"use client\"\n\n/* eslint-disable react-hooks/set-state-in-effect --\n This hook mirrors an external module-level cache into React state inside\n its fetch effect (cache seed, enabled gate, fetch results). Each sync set\n runs at most once per key change, not per render, so no render cascade. */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport {\n configCacheKey,\n fetchPayPalConfigShared,\n getCachedPayPalConfig,\n} from \"../client/config-cache\"\nimport type { PayPalConfig } from \"../client/types\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n /**\n * The cart's current currency code (e.g. \"usd\"). Optional, but recommended:\n * when provided it becomes part of the cache key, so a region/currency\n * switch on the same cart refetches the config instead of serving a stale\n * one for up to 5 minutes.\n */\n currencyCode?: string\n credentials?: RequestCredentials\n enabled?: boolean\n}\n\nexport function usePayPalConfig({\n baseUrl,\n publishableApiKey,\n cartId,\n currencyCode,\n credentials,\n enabled = true,\n}: Args) {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey, credentials }),\n [baseUrl, publishableApiKey, credentials]\n )\n\n const key = configCacheKey({\n baseUrl,\n publishableApiKey,\n cartId,\n currencyCode,\n })\n const seedConfig = getCachedPayPalConfig(key)\n\n const [config, setConfig] = useState<PayPalConfig | null>(seedConfig)\n const [loading, setLoading] = useState<boolean>(\n seedConfig === null && enabled\n )\n const [error, setError] = useState<string | null>(null)\n // Bumping this re-runs the effect after an error, bypassing nothing (the\n // failed fetch was never cached) — gives consumers a retry() without\n // tearing down the hook.\n const [retryToken, setRetryToken] = useState(0)\n\n const fetchIdRef = useRef(0)\n\n useEffect(() => {\n if (!enabled) {\n setLoading(false)\n setError(null)\n return\n }\n\n const cached = getCachedPayPalConfig(key)\n if (cached) {\n setConfig(cached)\n setLoading(false)\n setError(null)\n return\n }\n\n const id = ++fetchIdRef.current\n let mounted = true\n\n setLoading(true)\n setError(null)\n ;(async () => {\n try {\n const cfg = await fetchPayPalConfigShared(key, () =>\n api.getConfig(cartId)\n )\n if (!mounted || id !== fetchIdRef.current) return\n setConfig(cfg)\n } catch (e: unknown) {\n if (!mounted || id !== fetchIdRef.current) return\n setError(\n e instanceof Error ? e.message : \"Failed to load PayPal config\"\n )\n } finally {\n if (mounted && id === fetchIdRef.current) setLoading(false)\n }\n })()\n\n return () => {\n mounted = false\n }\n }, [api, key, cartId, enabled, retryToken])\n\n const retry = useMemo(() => () => setRetryToken((t) => t + 1), [])\n\n return { config, loading, error, retry }\n}\n","\"use client\"\n\nimport React, { useMemo } from \"react\"\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\nimport type { ReactPayPalScriptOptions } from \"@paypal/react-paypal-js\"\nimport type { PayPalConfig } from \"../client/types\"\n\n// \"MBJ_Medusa_SI\" is the Medusa-platform BN code PayPal assigned on 2026-10-06\n// (replacing \"MBJTechnolabs_SI_SPB\"). Must stay in sync with the backend's\n// PAYPAL_PARTNER_ATTRIBUTION_ID so SDK and REST attribution match.\nconst BN_CODE = \"MBJ_Medusa_SI\"\n\nexport function PayPalProvider(props: {\n config: PayPalConfig\n intent?: \"capture\" | \"authorize\"\n disableFunding?: string\n children: React.ReactNode\n}) {\n const { config, intent = \"capture\", disableFunding, children } = props\n\n const options = useMemo((): ReactPayPalScriptOptions => {\n return {\n clientId: config.client_id,\n currency: config.currency,\n intent,\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\n \"data-client-token\": config.client_token || undefined,\n \"disable-funding\": disableFunding,\n \"data-partner-attribution-id\": BN_CODE,\n }\n }, [\n config.client_id,\n config.currency,\n config.client_token,\n intent,\n disableFunding,\n ])\n\n return (\n <PayPalScriptProvider\n key={`${options.clientId}-${options[\"data-client-token\"] ?? \"no-token\"}`}\n options={options}\n >\n {children}\n </PayPalScriptProvider>\n )\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\n if (config.currency_supported) return null\n\n return (\n <div\n role=\"alert\"\n style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}\n >\n <div style={{ fontWeight: 600, marginBottom: 6 }}>\n PayPal currency issue\n </div>\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {(config.currency_errors || []).map((e) => (\n <li key={e}>{e}</li>\n ))}\n </ul>\n </div>\n )\n}\n","\"use client\"\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { PayPalButtons, usePayPalScriptReducer } from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\nimport {\n clearCartCaptured,\n markCartCaptured,\n wasCartCaptured,\n} from \"../utils/captured-state\"\nimport { isNextRouterError } from \"../utils/next-errors\"\nimport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"../utils/processing-overlay\"\nimport {\n AnimationStyles,\n ErrorBanner,\n LoadingCard,\n ProcessingOverlayView,\n} from \"./internal/ui\"\n\nconst BUTTON_WIDTH_MAP: Record<string, string> = {\n small: \"300px\",\n medium: \"400px\",\n large: \"500px\",\n responsive: \"100%\",\n}\n\nexport function PayPalSmartButtons(props: {\n baseUrl: string\n publishableApiKey?: string\n /** Forwarded to every API call — see `HttpOptions.credentials`. */\n credentials?: RequestCredentials\n cartId: string\n config: PayPalConfig\n onPaid?: (result: Record<string, unknown>) => void | Promise<void>\n onError?: (message: string) => void\n}) {\n const {\n baseUrl,\n publishableApiKey,\n credentials,\n cartId,\n config,\n onPaid,\n onError,\n } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey, credentials }),\n [baseUrl, publishableApiKey, credentials]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [processing, setProcessing] = useState(false)\n // Synchronous mirror of `processing` — React state updates are async, so a\n // second click in the same tick would slip past a state-based guard.\n const processingRef = useRef(false)\n // True while the shared full-page DOM overlay is mounted, so the component\n // doesn't also render its own copy on top of it.\n const [domOverlayUp, setDomOverlayUp] = useState(false)\n const [buttonsReady, setButtonsReady] = useState(false)\n const [loadTimedOut, setLoadTimedOut] = useState(false)\n // Once a capture succeeded, the buyer's money is taken — any later failure\n // (order finalization, consumer callback) must retry ONLY the finalization,\n // never a fresh createOrder/capture, or a retry click would charge again.\n const capturedRef = useRef<Record<string, unknown> | null>(null)\n const [completionPending, setCompletionPending] = useState(false)\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\n\n const startProcessing = useCallback(() => {\n processingRef.current = true\n setProcessing(true)\n }, [])\n\n const stopProcessing = useCallback(() => {\n hideProcessingOverlay()\n setDomOverlayUp(false)\n processingRef.current = false\n setProcessing(false)\n }, [])\n\n const showOverlay = useCallback(() => {\n showProcessingOverlay()\n setDomOverlayUp(true)\n }, [])\n\n const handleInit = useCallback(() => {\n setButtonsReady(true)\n }, [])\n\n // bfcache restore (Back button after a redirect) revives this page with the\n // old React state — clear the processing flag so the buyer isn't stuck\n // behind the in-component overlay.\n useEffect(() => {\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) {\n processingRef.current = false\n setProcessing(false)\n setDomOverlayUp(false)\n }\n }\n window.addEventListener(\"pageshow\", onPageShow)\n return () => window.removeEventListener(\"pageshow\", onPageShow)\n }, [])\n\n // A reload/crash between capture and finalization loses the in-memory\n // capturedRef — restore it from the persisted per-cart flag so the buyer\n // gets the finalize-only Retry button instead of payment buttons that would\n // fail confusingly against an already-captured PayPal order.\n useEffect(() => {\n if (capturedRef.current || !wasCartCaptured(cartId)) return\n capturedRef.current = {}\n setCompletionPending(true)\n const msg =\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\n setError(msg)\n }, [cartId])\n\n // The PayPal SDK never calls onInit when the buttons are ineligible (wrong\n // country/currency/funding) — it silently renders nothing. Without a\n // fallback the buyer stares at \"Loading PayPal…\" forever.\n useEffect(() => {\n if (!isResolved || buttonsReady) {\n return\n }\n const t = setTimeout(() => setLoadTimedOut(true), 10_000)\n return () => clearTimeout(t)\n }, [isResolved, buttonsReady])\n\n const finalizeCapturedPayment = useCallback(async () => {\n const captured = capturedRef.current\n if (!captured) return\n startProcessing()\n showOverlay()\n setError(null)\n try {\n const completeResult = await markPaymentComplete(baseUrl, cartId, {\n publishableApiKey,\n credentials,\n })\n // The order is finalized — the persisted \"captured\" flag has served its\n // purpose. Clear it before the consumer callback (which may redirect).\n clearCartCaptured(cartId)\n await onPaid?.({ ...captured, ...completeResult })\n setCompletionPending(false)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n stopProcessing()\n setCompletionPending(true)\n const msg =\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\n setError(msg)\n onError?.(msg)\n }\n }, [\n baseUrl,\n cartId,\n publishableApiKey,\n credentials,\n onPaid,\n onError,\n startProcessing,\n showOverlay,\n stopProcessing,\n ])\n\n const showSpinner =\n (isPending || (isResolved && !buttonsReady)) && !loadTimedOut\n\n if (!config.currency_supported) return null\n\n const containerWidth =\n BUTTON_WIDTH_MAP[config.button_width ?? \"responsive\"] ?? \"100%\"\n\n return (\n <div style={{ width: containerWidth, position: \"relative\" }}>\n <AnimationStyles />\n\n {processing && !domOverlayUp && (\n <ProcessingOverlayView accent=\"#0070ba\" />\n )}\n\n {showSpinner && <LoadingCard label=\"Loading PayPal…\" />}\n\n {loadTimedOut && !buttonsReady && !isRejected && (\n <ErrorBanner>\n PayPal is not available for this purchase. Please try a different\n payment method.\n </ErrorBanner>\n )}\n\n {isRejected && (\n <ErrorBanner>\n PayPal failed to load. Please refresh the page or try a different\n payment method.\n </ErrorBanner>\n )}\n\n {config.environment === \"sandbox\" && buttonsReady && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#eff6ff\",\n border: \"1px solid #bfdbfe\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#1e40af\",\n lineHeight: 1.5,\n marginBottom: 10,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#1e40af\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0, marginTop: 1 }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 8v4M12 16h.01\" />\n </svg>\n <span>\n Sandbox mode — you will not be charged. Use your PayPal sandbox\n account to complete the payment.\n </span>\n </div>\n )}\n\n {isResolved && !completionPending && (\n <div\n style={\n buttonsReady\n ? undefined\n : {\n position: \"absolute\",\n left: -9999,\n opacity: 0,\n pointerEvents: \"none\",\n }\n }\n >\n <PayPalButtons\n forceReRender={[config.currency, config.intent, cartId]}\n onInit={handleInit}\n style={{\n layout: \"vertical\",\n color: config.button_color,\n shape: config.button_shape,\n label: config.button_label,\n height: config.button_height,\n }}\n createOrder={async () => {\n // Ref, not state: a double click lands before React applies the\n // state update, so only the synchronous ref reliably blocks the\n // second createOrder (and its duplicate PayPal order).\n if (processingRef.current)\n throw new Error(\"Payment already processing\")\n if (capturedRef.current) {\n // Money was already captured for this cart — retry the order\n // finalization instead of creating (and charging) a new order.\n void finalizeCapturedPayment()\n throw new Error(\n \"Your payment was already received — finalizing your order.\"\n )\n }\n setError(null)\n startProcessing()\n try {\n const r = await api.createOrder(cartId)\n return r.id\n } catch (e: unknown) {\n stopProcessing()\n throw e\n }\n }}\n onApprove={async (data: { orderID?: string }) => {\n try {\n startProcessing()\n showOverlay()\n setError(null)\n const orderId = String(data?.orderID || \"\")\n if (!orderId)\n throw new Error(\n \"PayPal order ID is missing from approval response\"\n )\n const result = await api.captureOrder(cartId, orderId)\n capturedRef.current = (result || {}) as Record<string, unknown>\n // Persist across reloads: from here on, only finalization may\n // ever be retried for this cart — never a fresh payment.\n markCartCaptured(cartId)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n stopProcessing()\n const msg =\n e instanceof Error ? e.message : \"Payment capture failed\"\n setError(msg)\n onError?.(msg)\n return\n }\n // Past this point the buyer has been charged: completion failures\n // surface a finalize-only Retry, never a fresh payment.\n await finalizeCapturedPayment()\n }}\n onCancel={() => {\n stopProcessing()\n }}\n onError={(err: Error | { message?: string }) => {\n stopProcessing()\n const msg =\n err instanceof Error\n ? err.message\n : err?.message || \"PayPal error\"\n setError(msg)\n onError?.(msg)\n }}\n />\n </div>\n )}\n\n {completionPending && (\n <button\n type=\"button\"\n onClick={() => void finalizeCapturedPayment()}\n disabled={processing}\n aria-busy={processing}\n style={{\n width: \"100%\",\n padding: \"12px 16px\",\n marginTop: 4,\n background: \"#0070ba\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: 8,\n fontSize: 14,\n fontWeight: 600,\n cursor: processing ? \"not-allowed\" : \"pointer\",\n opacity: processing ? 0.7 : 1,\n }}\n >\n Retry — finish placing my order\n </button>\n )}\n\n {error ? (\n <ErrorBanner style={{ marginTop: 10 }}>{error}</ErrorBanner>\n ) : null}\n </div>\n )\n}\n","/**\n * Per-cart \"money was captured\" flag, persisted in sessionStorage.\n *\n * The in-memory `capturedRef` protects a buyer within one page lifetime, but a\n * reload/crash between the capture and the order finalization loses it — the\n * buyer would then see fresh payment buttons for a cart whose money is already\n * taken. Persisting the flag lets the components restore the finalize-only\n * Retry path after a reload instead of offering a second payment.\n *\n * sessionStorage is deliberately chosen over localStorage: it is scoped to the\n * tab/session, so an abandoned flag can't leak into a future visit after the\n * cart id is reused, and it needs no expiry logic. Every access is guarded —\n * private browsing modes and storage-blocking settings throw on access, and a\n * storage failure must never break the payment flow.\n */\n\nconst KEY_PREFIX = \"__pp_captured::\"\n\nexport function markCartCaptured(cartId: string): void {\n if (!cartId) return\n try {\n window.sessionStorage.setItem(`${KEY_PREFIX}${cartId}`, String(Date.now()))\n } catch {\n // storage unavailable — in-memory state still covers the common path\n }\n}\n\nexport function wasCartCaptured(cartId: string): boolean {\n if (!cartId) return false\n try {\n return window.sessionStorage.getItem(`${KEY_PREFIX}${cartId}`) !== null\n } catch {\n return false\n }\n}\n\nexport function clearCartCaptured(cartId: string): void {\n if (!cartId) return\n try {\n window.sessionStorage.removeItem(`${KEY_PREFIX}${cartId}`)\n } catch {\n // ignore\n }\n}\n","/**\n * Detect Next.js router errors (redirect / notFound) that must be re-thrown.\n *\n * Next.js implements redirect() and notFound() by throwing special errors with\n * a `digest` property starting with \"NEXT_REDIRECT\" or \"NEXT_NOT_FOUND\".\n * Catching these in user-land try/catch blocks prevents the navigation from\n * happening. Because this package can't import from `next` (it's a peer dep),\n * we detect them by duck-typing the digest.\n */\nexport function isNextRouterError(e: unknown): boolean {\n if (typeof e !== \"object\" || e === null || !(\"digest\" in e)) return false\n const digest = (e as { digest: unknown }).digest\n return (\n typeof digest === \"string\" &&\n (digest.startsWith(\"NEXT_REDIRECT\") ||\n digest.startsWith(\"NEXT_NOT_FOUND\") ||\n // Next.js 15: notFound()/forbidden()/unauthorized() throw\n // HTTPAccessFallbackError with digest \"NEXT_HTTP_ERROR_FALLBACK;<status>\".\n digest.startsWith(\"NEXT_HTTP_ERROR_FALLBACK\"))\n )\n}\n","const OVERLAY_ID = \"__pp_processing_overlay\"\n\nlet cleanupNavListener: (() => void) | null = null\n\n/** True while the shared DOM overlay is mounted. */\nexport function isProcessingOverlayVisible(): boolean {\n if (typeof document === \"undefined\") return false\n return !!document.getElementById(OVERLAY_ID)\n}\n\nexport function showProcessingOverlay() {\n if (typeof document === \"undefined\") return\n if (document.getElementById(OVERLAY_ID)) return\n\n const overlay = document.createElement(\"div\")\n overlay.id = OVERLAY_ID\n // role=\"status\" announces the visible text politely; no aria-label so the\n // text itself (which explains what's happening) is what gets read.\n overlay.setAttribute(\"role\", \"status\")\n\n overlay.innerHTML = `\n <style>\n @keyframes _pp_ov_spin { to { transform: rotate(360deg) } }\n @keyframes _pp_ov_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\n ._pp-ov-spin { animation: _pp_ov_spin .8s linear infinite }\n ._pp-ov-progress { animation: _pp_ov_progress 1.5s ease-in-out infinite }\n @media (prefers-reduced-motion: reduce) {\n ._pp-ov-spin, ._pp-ov-progress { animation: none }\n }\n </style>\n <div style=\"position:relative;width:56px;height:56px\" aria-hidden=\"true\">\n <div style=\"position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb\"></div>\n <div class=\"_pp-ov-spin\" style=\"position:absolute;inset:0;border-radius:50%;border:3px solid transparent;border-top-color:#0070ba\"></div>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0070ba\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n style=\"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px\">\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\n </svg>\n </div>\n <div style=\"text-align:center\">\n <div style=\"font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em\">Processing your payment</div>\n <div style=\"font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5\">\n This may take a few moments. Please do not close<br>or refresh this page.\n </div>\n </div>\n <div style=\"width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px\" aria-hidden=\"true\">\n <div class=\"_pp-ov-progress\" style=\"width:40%;height:100%;background:linear-gradient(90deg,#0070ba,#003087);border-radius:3px\"></div>\n </div>\n `\n\n Object.assign(overlay.style, {\n position: \"fixed\",\n inset: \"0\",\n zIndex: \"99999\",\n background: \"rgba(255,255,255,0.96)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"20px\",\n fontFamily: \"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif\",\n })\n\n document.body.appendChild(overlay)\n\n // Auto-remove on client-side navigation (Next.js App Router uses\n // pushState/replaceState for soft navigations, not full reloads). The URL is\n // polled instead of monkeypatching history.pushState — patching fights with\n // the Next router and any other library that wraps history, and a stale\n // restore on cleanup could undo THEIR patch.\n const startUrl = location.href\n const onNav = () => {\n if (location.href !== startUrl) hideProcessingOverlay()\n }\n window.addEventListener(\"popstate\", onNav)\n const urlWatcher = window.setInterval(onNav, 250)\n\n // bfcache restore: the overlay intentionally survives the unload of a\n // full-page navigation (that's its purpose), but when the buyer presses\n // Back the browser restores this page from the back/forward cache with the\n // overlay element still in the DOM and the URL equal to startUrl — no nav\n // listener ever fires, leaving checkout permanently covered. `pageshow`\n // with `persisted: true` is exactly that restore.\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) hideProcessingOverlay()\n }\n window.addEventListener(\"pageshow\", onPageShow)\n\n cleanupNavListener = () => {\n window.removeEventListener(\"popstate\", onNav)\n window.removeEventListener(\"pageshow\", onPageShow)\n window.clearInterval(urlWatcher)\n }\n}\n\nexport function hideProcessingOverlay() {\n if (typeof document === \"undefined\") return\n cleanupNavListener?.()\n cleanupNavListener = null\n document.getElementById(OVERLAY_ID)?.remove()\n}\n","\"use client\"\n\nimport React from \"react\"\n\n/**\n * Shared presentational pieces for the payment components. One definition of\n * the keyframes/animation CSS (previously copied into four files) and the\n * overlay/spinner/error markup used by both PayPalSmartButtons and\n * PayPalAdvancedCard.\n *\n * Animations are applied through class names so a single\n * `prefers-reduced-motion` rule can disable them for buyers who ask for less\n * motion, without a global selector leaking into the host page.\n */\nexport const ANIMATION_CSS = `\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\n._pp-spin { animation: _pp_spin .8s linear infinite }\n._pp-spin-sm { animation: _pp_spin .7s linear infinite }\n._pp-progress { animation: _pp_progress 1.5s ease-in-out infinite }\n@media (prefers-reduced-motion: reduce) {\n ._pp-spin, ._pp-spin-sm, ._pp-progress { animation: none }\n}\n`\n\nexport function AnimationStyles() {\n return <style>{ANIMATION_CSS}</style>\n}\n\nexport function ShieldIcon({\n color,\n size = 24,\n style,\n}: {\n color: string\n size?: number\n style?: React.CSSProperties\n}) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"1.8\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ width: size, height: size, ...style }}\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n )\n}\n\n/**\n * Full-screen \"Processing your payment\" overlay. role=\"status\" makes screen\n * readers announce the visible text — deliberately no aria-label, which would\n * override that text.\n */\nexport function ProcessingOverlayView({ accent }: { accent: string }) {\n return (\n <div\n role=\"status\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 9999,\n background: \"rgba(255,255,255,0.96)\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 20,\n }}\n >\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid #e5e7eb\",\n }}\n />\n <div\n className=\"_pp-spin\"\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n border: \"3px solid transparent\",\n borderTopColor: accent,\n }}\n />\n <ShieldIcon\n color={accent}\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n }}\n />\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n fontSize: 18,\n fontWeight: 600,\n color: \"#111827\",\n letterSpacing: \"-0.01em\",\n }}\n >\n Processing your payment\n </div>\n <div\n style={{\n fontSize: 14,\n color: \"#6b7280\",\n marginTop: 6,\n lineHeight: 1.5,\n }}\n >\n This may take a few moments. Please do not close\n <br />\n or refresh this page.\n </div>\n </div>\n <div\n style={{\n width: 200,\n height: 3,\n background: \"#e5e7eb\",\n borderRadius: 3,\n overflow: \"hidden\",\n marginTop: 4,\n }}\n aria-hidden=\"true\"\n >\n <div\n className=\"_pp-progress\"\n style={{\n width: \"40%\",\n height: \"100%\",\n background: `linear-gradient(90deg, ${accent}, #003087)`,\n borderRadius: 3,\n }}\n />\n </div>\n </div>\n )\n}\n\n/** Small inline loading card (\"Loading PayPal…\", \"Loading card fields…\"). */\nexport function LoadingCard({ label }: { label: string }) {\n return (\n <div\n role=\"status\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 10,\n padding: \"18px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 8,\n minHeight: 55,\n }}\n >\n <div\n className=\"_pp-spin-sm\"\n aria-hidden=\"true\"\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n flexShrink: 0,\n }}\n />\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\n {label}\n </div>\n </div>\n )\n}\n\n/** Red role=\"alert\" banner with a decorative warning icon. */\nexport function ErrorBanner({\n children,\n style,\n}: {\n children: React.ReactNode\n style?: React.CSSProperties\n}) {\n return (\n <div\n role=\"alert\"\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 8,\n padding: \"10px 14px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#b91c1c\",\n lineHeight: 1.5,\n ...style,\n }}\n >\n <span aria-hidden=\"true\" style={{ flexShrink: 0, fontSize: 15 }}>\n ⚠️\n </span>\n <span>{children}</span>\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useMemo, useRef, useState } from \"react\"\nimport {\n PayPalCardFieldsProvider,\n PayPalNumberField,\n PayPalExpiryField,\n PayPalCVVField,\n usePayPalCardFields,\n usePayPalScriptReducer,\n} from \"@paypal/react-paypal-js\"\n\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\nimport {\n clearCartCaptured,\n markCartCaptured,\n wasCartCaptured,\n} from \"../utils/captured-state\"\nimport { isNextRouterError } from \"../utils/next-errors\"\nimport {\n showProcessingOverlay,\n hideProcessingOverlay,\n} from \"../utils/processing-overlay\"\nimport {\n AnimationStyles,\n ErrorBanner,\n LoadingCard,\n ProcessingOverlayView,\n ShieldIcon,\n} from \"./internal/ui\"\n\nconst cardStyle = {\n input: {\n \"font-size\": \"15px\",\n \"font-family\":\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n \"font-weight\": \"400\",\n color: \"#111827\",\n padding: \"0 14px\",\n height: \"42px\",\n \"border-radius\": \"8px\",\n border: \"1px solid #d1d5db\",\n background: \"#ffffff\",\n \"box-shadow\": \"none\",\n transition: \"border-color 0.15s ease\",\n },\n \"::placeholder\": {\n color: \"#9ca3af\",\n },\n \".invalid\": {\n color: \"#dc2626\",\n border: \"1px solid #fca5a5\",\n background: \"#fff7f7\",\n \"box-shadow\": \"none\",\n },\n \".valid\": {\n color: \"#111827\",\n border: \"1px solid #d1d5db\",\n \"box-shadow\": \"none\",\n },\n \"input:focus\": {\n outline: \"none\",\n border: \"1px solid #2563eb\",\n \"box-shadow\": \"0 0 0 3px rgba(37,99,235,0.12)\",\n },\n}\n\nconst labelStyle: React.CSSProperties = {\n display: \"block\",\n fontSize: 13,\n fontWeight: 500,\n color: \"#374151\",\n marginBottom: 6,\n letterSpacing: \"0.01em\",\n}\n\nfunction SubmitButton({\n disabled,\n busy,\n label,\n onSubmit,\n onSubmitError,\n}: {\n disabled: boolean\n busy: boolean\n label: string\n onSubmit: () => void\n onSubmitError: (message: string) => void\n}) {\n const { cardFieldsForm } = usePayPalCardFields()\n const isDisabled = disabled || !cardFieldsForm\n\n return (\n <button\n type=\"button\"\n disabled={isDisabled}\n aria-busy={busy}\n onClick={() => {\n onSubmit()\n // submit() returns a promise and its rejection is NOT routed to the\n // provider's onError — PayPal's contract is that the caller catches\n // it. A sync try/catch here would miss it entirely, leaving the buyer\n // stuck under the full-screen processing overlay forever (e.g. on a\n // card-field validation error).\n Promise.resolve(cardFieldsForm?.submit()).catch((e: unknown) => {\n const msg =\n e instanceof Error && e.message\n ? e.message\n : \"Card payment could not be submitted. Please check your card details.\"\n onSubmitError(msg)\n })\n }}\n style={{\n width: \"100%\",\n height: 48,\n padding: \"0 20px\",\n borderRadius: 8,\n border: \"none\",\n background: isDisabled\n ? \"#e5e7eb\"\n : \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\",\n color: isDisabled ? \"#9ca3af\" : \"#ffffff\",\n fontSize: 15,\n fontWeight: 600,\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\n letterSpacing: \"0.01em\",\n boxShadow: isDisabled\n ? \"none\"\n : \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\",\n transition: \"all 0.15s ease\",\n }}\n onMouseEnter={(e) => {\n if (!isDisabled) {\n ;(e.target as HTMLButtonElement).style.background =\n \"linear-gradient(180deg, #1d4ed8 0%, #1e40af 100%)\"\n ;(e.target as HTMLButtonElement).style.boxShadow =\n \"0 4px 6px rgba(37,99,235,0.35), 0 2px 4px rgba(0,0,0,0.06)\"\n }\n }}\n onMouseLeave={(e) => {\n if (!isDisabled) {\n ;(e.target as HTMLButtonElement).style.background =\n \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\"\n ;(e.target as HTMLButtonElement).style.boxShadow =\n \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\"\n }\n }}\n >\n {label}\n </button>\n )\n}\n\nexport function PayPalAdvancedCard(props: {\n baseUrl: string\n publishableApiKey?: string\n /** Forwarded to every API call — see `HttpOptions.credentials`. */\n credentials?: RequestCredentials\n cartId: string\n config: PayPalConfig\n onPaid?: (result: Record<string, unknown>) => void | Promise<void>\n onError?: (message: string) => void\n}) {\n const {\n baseUrl,\n publishableApiKey,\n credentials,\n cartId,\n config,\n onPaid,\n onError,\n } = props\n\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey, credentials }),\n [baseUrl, publishableApiKey, credentials]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n const submittingRef = useRef(false)\n const creatingOrderRef = useRef(false)\n // True while the shared full-page DOM overlay is mounted, so the component\n // doesn't also render its own copy on top of it.\n const [domOverlayUp, setDomOverlayUp] = useState(false)\n // Once a capture succeeded the buyer's money is taken: any later failure\n // must retry ONLY the order finalization, never a fresh order/capture.\n const capturedRef = useRef<Record<string, unknown> | null>(null)\n const [completionPending, setCompletionPending] = useState(false)\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\n\n const showOverlay = React.useCallback(() => {\n showProcessingOverlay()\n setDomOverlayUp(true)\n }, [])\n\n const resetSubmitState = React.useCallback(() => {\n hideProcessingOverlay()\n setDomOverlayUp(false)\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n }, [])\n\n // bfcache restore (Back button after a redirect) revives this page with the\n // old React state — clear the submitting flag so the buyer isn't stuck\n // behind the in-component overlay.\n React.useEffect(() => {\n const onPageShow = (e: PageTransitionEvent) => {\n if (e.persisted) {\n creatingOrderRef.current = false\n submittingRef.current = false\n setSubmitting(false)\n setDomOverlayUp(false)\n }\n }\n window.addEventListener(\"pageshow\", onPageShow)\n return () => window.removeEventListener(\"pageshow\", onPageShow)\n }, [])\n\n // A reload/crash between capture and finalization loses the in-memory\n // capturedRef — restore it from the persisted per-cart flag so the buyer\n // gets the finalize-only Retry button instead of card fields that would\n // charge (or confusingly fail) again.\n React.useEffect(() => {\n if (capturedRef.current || !wasCartCaptured(cartId)) return\n capturedRef.current = {}\n setCompletionPending(true)\n setError(\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\n )\n }, [cartId])\n\n const finalizeCapturedPayment = React.useCallback(async () => {\n const captured = capturedRef.current\n if (!captured) return\n setSubmitting(true)\n showOverlay()\n setError(null)\n try {\n const completeResult = await markPaymentComplete(baseUrl, cartId, {\n publishableApiKey,\n credentials,\n })\n // The order is finalized — the persisted \"captured\" flag has served its\n // purpose. Clear it before the consumer callback (which may redirect).\n clearCartCaptured(cartId)\n await onPaid?.({ ...captured, ...completeResult })\n setCompletionPending(false)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n resetSubmitState()\n setCompletionPending(true)\n const msg =\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\n setError(msg)\n onError?.(msg)\n }\n }, [\n baseUrl,\n cartId,\n publishableApiKey,\n credentials,\n onPaid,\n onError,\n showOverlay,\n resetSubmitState,\n ])\n\n if (!config.currency_supported) return null\n\n if (isRejected) {\n return (\n <ErrorBanner>\n PayPal failed to load. Please refresh the page or try a different\n payment method.\n </ErrorBanner>\n )\n }\n\n if (!config.client_token) {\n return (\n <div\n style={{\n padding: \"12px 16px\",\n background: \"#fefce8\",\n border: \"1px solid #fde68a\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#92400e\",\n }}\n >\n Card fields unavailable — missing client token from backend.\n </div>\n )\n }\n\n const isSandbox = config.environment === \"sandbox\"\n\n if (isPending) {\n return (\n <div>\n <AnimationStyles />\n <LoadingCard label=\"Loading card fields…\" />\n </div>\n )\n }\n\n if (!isResolved) return null\n\n return (\n <div style={{ position: \"relative\" }}>\n <AnimationStyles />\n\n {submitting && !domOverlayUp && (\n <ProcessingOverlayView accent=\"#2563eb\" />\n )}\n\n <PayPalCardFieldsProvider\n style={cardStyle}\n createOrder={async () => {\n if (creatingOrderRef.current)\n throw new Error(\"Payment already processing\")\n if (capturedRef.current) {\n // Money was already captured for this cart — retry the order\n // finalization instead of creating (and charging) a new order.\n void finalizeCapturedPayment()\n throw new Error(\n \"Your payment was already received — finalizing your order.\"\n )\n }\n creatingOrderRef.current = true\n try {\n setError(null)\n const r = await api.createOrder(cartId, true)\n return r.id\n } catch (e) {\n creatingOrderRef.current = false\n throw e\n }\n }}\n onApprove={async (data: { orderID?: string }) => {\n try {\n setError(null)\n showOverlay()\n const orderId = String(data?.orderID || \"\")\n if (!orderId)\n throw new Error(\n \"PayPal order ID is missing from approval response\"\n )\n const result = await api.captureOrder(cartId, orderId)\n capturedRef.current = (result || {}) as Record<string, unknown>\n // Persist across reloads: from here on, only finalization may\n // ever be retried for this cart — never a fresh payment.\n markCartCaptured(cartId)\n } catch (e: unknown) {\n if (isNextRouterError(e)) return\n resetSubmitState()\n const msg = e instanceof Error ? e.message : \"Card payment failed\"\n setError(msg)\n onError?.(msg)\n return\n }\n // Past this point the buyer has been charged: completion failures\n // surface a finalize-only Retry, never a fresh payment.\n await finalizeCapturedPayment()\n }}\n onCancel={() => {\n resetSubmitState()\n }}\n onError={(e: Error | { message?: string }) => {\n const msg =\n e instanceof Error ? e.message : e?.message || \"CardFields error\"\n setError(msg)\n onError?.(msg)\n resetSubmitState()\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n width: \"100%\",\n }}\n >\n {isSandbox && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: 10,\n padding: \"10px 14px\",\n background: \"#eff6ff\",\n border: \"1px solid #bfdbfe\",\n borderRadius: 8,\n fontSize: 13,\n color: \"#1e40af\",\n lineHeight: 1.55,\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{ fontSize: 15, flexShrink: 0, marginTop: 1 }}\n >\n 🧪\n </span>\n <span>\n Sandbox mode — use test card{\" \"}\n <strong\n style={{ fontFamily: \"monospace\", letterSpacing: \"0.05em\" }}\n >\n 4111 1111 1111 1111\n </strong>{\" \"}\n with any future date and any CVV.\n </span>\n </div>\n )}\n\n <div>\n {/* eslint-disable-next-line jsx-a11y/label-has-associated-control --\n the PayPal hosted field below is a cross-origin iframe; it cannot be\n associated via htmlFor, and PayPal provides the accessible name inside */}\n <label style={labelStyle} id=\"_pp-label-card-number\">\n Card number\n </label>\n <PayPalNumberField />\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: 16,\n }}\n >\n <div>\n {/* eslint-disable-next-line jsx-a11y/label-has-associated-control --\n the PayPal hosted field below is a cross-origin iframe; it cannot be\n associated via htmlFor, and PayPal provides the accessible name inside */}\n <label style={labelStyle} id=\"_pp-label-expiry\">\n Expiration date\n </label>\n <PayPalExpiryField />\n </div>\n <div>\n {/* eslint-disable-next-line jsx-a11y/label-has-associated-control --\n the PayPal hosted field below is a cross-origin iframe; it cannot be\n associated via htmlFor, and PayPal provides the accessible name inside */}\n <label style={labelStyle} id=\"_pp-label-cvv\">\n Security code\n </label>\n <PayPalCVVField />\n </div>\n </div>\n\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n fontSize: 12,\n color: \"#6b7280\",\n }}\n >\n <ShieldIcon color=\"#10b981\" size={14} />\n <span>Your payment is secured with 256-bit SSL encryption</span>\n </div>\n\n {completionPending ? (\n <button\n type=\"button\"\n onClick={() => void finalizeCapturedPayment()}\n disabled={submitting}\n aria-busy={submitting}\n style={{\n width: \"100%\",\n height: 48,\n padding: \"0 20px\",\n borderRadius: 8,\n border: \"none\",\n background: \"#0070ba\",\n color: \"#ffffff\",\n fontSize: 15,\n fontWeight: 600,\n cursor: submitting ? \"not-allowed\" : \"pointer\",\n opacity: submitting ? 0.7 : 1,\n }}\n >\n Retry — finish placing my order\n </button>\n ) : (\n <SubmitButton\n disabled={submitting}\n busy={submitting}\n label={submitting ? \"Processing…\" : \"Pay by Card\"}\n onSubmit={() => {\n if (submittingRef.current) return\n submittingRef.current = true\n setError(null)\n setSubmitting(true)\n showOverlay()\n }}\n onSubmitError={(msg) => {\n resetSubmitState()\n setError(msg)\n onError?.(msg)\n }}\n />\n )}\n\n {error && <ErrorBanner>{error}</ErrorBanner>}\n </div>\n </PayPalCardFieldsProvider>\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useCallback } from \"react\"\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\nimport { PayPalProvider } from \"../components/PayPalProvider\"\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\nimport {\n PAYPAL_WALLET_PROVIDER_ID as DEFAULT_PAYPAL_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID as DEFAULT_PAYPAL_CARD_PROVIDER_ID,\n} from \"../constants\"\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\nimport { AnimationStyles } from \"../components/internal/ui\"\n\nfunction PayPalLoadingCard() {\n return (\n <div\n role=\"status\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"14px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n }}\n >\n <AnimationStyles />\n <div\n className=\"_pp-spin-sm\"\n aria-hidden=\"true\"\n style={{\n width: 22,\n height: 22,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n flexShrink: 0,\n }}\n />\n <div>\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\n Connecting to PayPal…\n </div>\n <div style={{ fontSize: 12, color: \"#6b7280\", marginTop: 2 }}>\n Setting up secure payment\n </div>\n </div>\n </div>\n )\n}\n\nfunction PayPalErrorCard({\n message,\n onRetry,\n}: {\n message: string\n onRetry?: () => void\n}) {\n return (\n <div\n role=\"alert\"\n style={{\n padding: \"12px 16px\",\n background: \"#fef2f2\",\n border: \"1px solid #fecaca\",\n borderRadius: 10,\n fontSize: 13,\n color: \"#b91c1c\",\n }}\n >\n {message}\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n style={{\n display: \"block\",\n marginTop: 8,\n padding: \"6px 14px\",\n background: \"#ffffff\",\n color: \"#b91c1c\",\n border: \"1px solid #fecaca\",\n borderRadius: 6,\n fontSize: 13,\n fontWeight: 500,\n cursor: \"pointer\",\n }}\n >\n Try again\n </button>\n )}\n </div>\n )\n}\n\n/**\n * Shown when the merchant has disabled the selected PayPal method in admin\n * settings. Rendering nothing here (the old behavior) left the buyer staring\n * at blank space under a selected payment option.\n */\nfunction PayPalUnavailableCard({ label }: { label: string }) {\n return (\n <div\n role=\"status\"\n style={{\n padding: \"12px 16px\",\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n fontSize: 13,\n color: \"#6b7280\",\n }}\n >\n {label} is currently unavailable. Please choose a different payment\n method.\n </div>\n )\n}\n\nexport type MedusaNextPayPalAdapterProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n /** Forwarded to every API call — see `HttpOptions.credentials`. */\n credentials?: RequestCredentials\n /**\n * The cart's currency code (e.g. \"usd\"). Recommended: busts the config\n * cache when the buyer switches region/currency on the same cart.\n */\n currencyCode?: string\n providerIds?: {\n paypal?: string\n paypalCard?: string\n }\n onSuccess?: (cartId: string) => void | Promise<void>\n onError?: (message: string) => void\n onPaid?: (result: unknown) => void | Promise<void>\n}\n\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\n const {\n cartId,\n selectedProviderId,\n baseUrl,\n publishableApiKey,\n credentials,\n currencyCode,\n providerIds,\n onSuccess,\n onError,\n onPaid,\n } = props\n\n const paypalProviderId = providerIds?.paypal || DEFAULT_PAYPAL_PROVIDER_ID\n const paypalCardProviderId =\n providerIds?.paypalCard || DEFAULT_PAYPAL_CARD_PROVIDER_ID\n\n const shouldRender =\n selectedProviderId === paypalProviderId ||\n selectedProviderId === paypalCardProviderId\n\n const { config, loading, error, retry } = usePayPalConfig({\n baseUrl,\n publishableApiKey,\n credentials,\n cartId,\n currencyCode,\n enabled: shouldRender,\n })\n\n const handlePaid = useCallback(\n async (captureResult: unknown) => {\n onPaid?.(captureResult)\n await onSuccess?.(cartId)\n },\n [cartId, onPaid, onSuccess]\n )\n\n if (!shouldRender) return null\n\n if (loading) return <PayPalLoadingCard />\n\n if (error) return <PayPalErrorCard message={error} onRetry={retry} />\n\n if (!config) return null\n\n const isCardProvider = selectedProviderId === paypalCardProviderId\n if (config.paypal_enabled === false && !isCardProvider) {\n return <PayPalUnavailableCard label={config.paypal_title || \"PayPal\"} />\n }\n if (isCardProvider && config.card_enabled === false) {\n return <PayPalUnavailableCard label={config.card_title || \"Card payment\"} />\n }\n\n const disableFunding = Array.isArray(config.disable_buttons)\n ? config.disable_buttons.join(\",\")\n : undefined\n\n return (\n <div key={selectedProviderId} style={{ display: \"grid\", gap: 12 }}>\n <PayPalCurrencyNotice config={config} />\n <PayPalProvider\n config={config}\n intent={config.intent === \"authorize\" ? \"authorize\" : \"capture\"}\n disableFunding={disableFunding}\n >\n {isCardProvider ? (\n <PayPalAdvancedCard\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n credentials={credentials}\n cartId={cartId}\n config={config}\n onPaid={handlePaid}\n onError={onError}\n />\n ) : (\n <PayPalSmartButtons\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n credentials={credentials}\n cartId={cartId}\n config={config}\n onPaid={handlePaid}\n onError={onError}\n />\n )}\n </PayPalProvider>\n </div>\n )\n}\n","\"use client\"\n\nimport React from \"react\"\nimport { MedusaNextPayPalAdapter } from \"../adapters/MedusaNextPayPalAdapter\"\nimport {\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n isPayPalProviderId,\n} from \"../constants\"\n\n// Re-exported for backward compatibility — these have always been part of this\n// module's public API. The canonical definitions live in ../constants.\nexport {\n PAYPAL_WALLET_PROVIDER_ID,\n PAYPAL_CARD_PROVIDER_ID,\n isPayPalProviderId,\n}\n\nimport { AnimationStyles } from \"./internal/ui\"\n\nfunction SessionInitCard() {\n return (\n <div\n role=\"status\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"14px 16px\",\n marginTop: 8,\n background: \"#f9fafb\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 10,\n }}\n >\n <AnimationStyles />\n <div\n className=\"_pp-spin-sm\"\n aria-hidden=\"true\"\n style={{\n width: 20,\n height: 20,\n borderRadius: \"50%\",\n border: \"2.5px solid #e5e7eb\",\n borderTopColor: \"#0070ba\",\n flexShrink: 0,\n }}\n />\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\n Setting up payment…\n </div>\n </div>\n )\n}\n\nexport type PayPalPaymentSectionProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n /** Forwarded to every API call — see `HttpOptions.credentials`. */\n credentials?: RequestCredentials\n /**\n * The cart's currency code (e.g. \"usd\"). Recommended: busts the config\n * cache when the buyer switches region/currency on the same cart.\n */\n currencyCode?: string\n sessionLoading?: boolean\n onSuccess?: (cartId: string) => void | Promise<void>\n onError?: (message: string) => void\n onPaid?: (result: unknown) => void | Promise<void>\n}\n\n/**\n * Drop-in PayPal payment section for a Medusa checkout.\n *\n * A thin wrapper over {@link MedusaNextPayPalAdapter} (they previously carried\n * two ~90%-identical render paths that had to be edited in lockstep): this\n * component pins the default provider ids and adds the `sessionLoading` gate\n * shown while the storefront is still creating the payment session.\n */\nexport function PayPalPaymentSection({\n cartId,\n selectedProviderId,\n baseUrl,\n publishableApiKey,\n credentials,\n currencyCode,\n sessionLoading = false,\n onSuccess,\n onError,\n onPaid,\n}: PayPalPaymentSectionProps) {\n if (!isPayPalProviderId(selectedProviderId)) return null\n if (sessionLoading) return <SessionInitCard />\n\n return (\n <MedusaNextPayPalAdapter\n cartId={cartId}\n selectedProviderId={selectedProviderId}\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n credentials={credentials}\n currencyCode={currencyCode}\n onSuccess={onSuccess}\n onError={onError}\n onPaid={onPaid}\n />\n )\n}\n","\"use client\"\n\n/* eslint-disable react-hooks/set-state-in-effect --\n This hook mirrors an external module-level cache into React state inside\n its fetch effect (cache seed, enabled gate, fetch results). Each sync set\n runs at most once per key change, not per render, so no render cascade. */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport { HttpError } from \"../client/http\"\nimport {\n configCacheKey,\n fetchPayPalConfigShared,\n getCachedPayPalConfig,\n} from \"../client/config-cache\"\nimport type { PayPalConfig } from \"../client/types\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n /** See `usePayPalConfig` — include to bust the cache on currency switches. */\n currencyCode?: string\n credentials?: RequestCredentials\n enabled?: boolean\n}\n\ntype Result = {\n paypalEnabled: boolean\n paypalTitle: string\n cardEnabled: boolean\n cardTitle: string\n loading: boolean\n /**\n * Non-null when the config fetch failed and the returned flags are the\n * optimistic defaults rather than the merchant's real settings. Storefronts\n * can use this to hide or annotate the PayPal options instead of advertising\n * methods that will fail once selected.\n */\n error: string | null\n}\n\nconst DEFAULT_RESULT: Result = {\n paypalEnabled: true,\n paypalTitle: \"PayPal\",\n cardEnabled: true,\n cardTitle: \"Credit or Debit Card\",\n loading: false,\n error: null,\n}\n\nfunction toResult(cfg: PayPalConfig): Result {\n return {\n paypalEnabled: cfg.paypal_enabled !== false,\n paypalTitle:\n typeof cfg.paypal_title === \"string\" && cfg.paypal_title\n ? cfg.paypal_title\n : \"PayPal\",\n cardEnabled: cfg.card_enabled !== false,\n cardTitle:\n typeof cfg.card_title === \"string\" && cfg.card_title\n ? cfg.card_title\n : \"Credit or Debit Card\",\n loading: false,\n error: null,\n }\n}\n\nexport function usePayPalPaymentMethods({\n baseUrl,\n publishableApiKey,\n cartId,\n currencyCode,\n credentials,\n enabled = true,\n}: Args): Result {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey, credentials }),\n [baseUrl, publishableApiKey, credentials]\n )\n\n const key = configCacheKey({\n baseUrl,\n publishableApiKey,\n cartId,\n currencyCode,\n })\n const seed = getCachedPayPalConfig(key)\n\n const [result, setResult] = useState<Result>(\n seed ? toResult(seed) : { ...DEFAULT_RESULT, loading: enabled }\n )\n const fetchIdRef = useRef(0)\n\n useEffect(() => {\n if (!enabled) {\n setResult((prev) => ({ ...prev, loading: false }))\n return\n }\n\n const cached = getCachedPayPalConfig(key)\n if (cached) {\n setResult(toResult(cached))\n return\n }\n\n const id = ++fetchIdRef.current\n let mounted = true\n\n setResult((prev) => ({ ...prev, loading: true }))\n ;(async () => {\n try {\n const cfg = await fetchPayPalConfigShared(key, () =>\n api.getConfig(cartId)\n )\n if (!mounted || id !== fetchIdRef.current) return\n setResult(toResult(cfg))\n } catch (e: unknown) {\n if (!mounted || id !== fetchIdRef.current) return\n const msg = e instanceof Error ? e.message : \"\"\n\n // 403 means the backend explicitly refused (plugin disabled for this\n // sales channel / key). Branch on the status code, not message text —\n // the backend's JSON message rarely contains the literal \"403\".\n if (e instanceof HttpError && e.status === 403) {\n setResult({\n ...DEFAULT_RESULT,\n paypalEnabled: false,\n cardEnabled: false,\n loading: false,\n error: msg || \"PayPal is disabled\",\n })\n return\n }\n\n setResult({\n ...DEFAULT_RESULT,\n loading: false,\n error: msg || \"Failed to load PayPal payment methods\",\n })\n }\n })()\n\n return () => {\n mounted = false\n }\n }, [api, key, cartId, enabled])\n\n return result\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_react_paypal_js","import_jsx_runtime","import_jsx_runtime","import_react","import_react_paypal_js","import_jsx_runtime","React","import_react","import_jsx_runtime","import_jsx_runtime","import_react"]}
|