@easypayment/medusa-paypal-ui 1.1.1 → 1.2.2
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 +97 -61
- package/README.md +781 -759
- package/dist/index.cjs +143 -142
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -2
- package/dist/index.d.ts +64 -2
- package/dist/index.mjs +133 -136
- package/dist/index.mjs.map +1 -1
- package/dist/order.cjs +14 -3
- package/dist/order.cjs.map +1 -1
- package/dist/order.d.cts +13 -4
- package/dist/order.d.ts +13 -4
- package/dist/order.mjs +13 -4
- package/dist/order.mjs.map +1 -1
- package/package.json +76 -75
- package/src/adapters/MedusaNextPayPalAdapter.tsx +34 -5
- package/src/client/http.ts +9 -1
- package/src/client/paypal.ts +27 -1
- package/src/components/PayPalAdvancedCard.tsx +24 -0
- package/src/components/PayPalPaymentSection.tsx +95 -202
- package/src/components/PayPalSmartButtons.tsx +24 -0
- package/src/constants.ts +22 -0
- package/src/hooks/usePayPalPaymentMethods.ts +15 -1
- package/src/index.ts +5 -0
- package/src/order.ts +7 -10
- package/src/utils/captured-state.ts +44 -0
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/next-errors.ts","../src/utils/processing-overlay.ts","../src/components/PayPalAdvancedCard.tsx","../src/adapters/MedusaNextPayPalAdapter.tsx","../src/components/PayPalPaymentSection.tsx","../src/hooks/usePayPalPaymentMethods.ts"],"sourcesContent":["export * from \"./client/types\"\r\nexport * from \"./client/paypal\"\r\nexport * from \"./hooks/usePayPalConfig\"\r\nexport * from \"./components/PayPalProvider\"\r\nexport * from \"./components/PayPalCurrencyNotice\"\r\nexport * from \"./components/PayPalSmartButtons\"\r\nexport * from \"./components/PayPalAdvancedCard\"\r\nexport * from \"./adapters/MedusaNextPayPalAdapter\"\r\nexport * from \"./components/PayPalPaymentSection\"\r\nexport * from \"./hooks/usePayPalPaymentMethods\"\r\nexport { showProcessingOverlay, hideProcessingOverlay } from \"./utils/processing-overlay\"\r\n","export type HttpOptions = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n}\r\n\r\nexport type RequestOptions = {\r\n /**\r\n * Number of extra attempts on transient failures (network error, timeout,\r\n * HTTP 429/5xx). Only use for idempotent calls — the PayPal capture/complete\r\n * endpoints are idempotent server-side, so a retried request after a network\r\n * blip re-uses the existing result instead of duplicating work. Default 0.\r\n */\r\n retries?: number\r\n}\r\n\r\nclass HttpError extends Error {\r\n status: number\r\n constructor(message: string, status: number) {\r\n super(message)\r\n this.name = \"HttpError\"\r\n this.status = status\r\n }\r\n}\r\n\r\nconst RETRY_BASE_DELAY_MS = 400\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return status === 429 || status >= 500\r\n}\r\n\r\nfunction isRetryableError(err: unknown): boolean {\r\n // Network failures and our own timeout error are safe to retry.\r\n return err instanceof Error && !(err instanceof HttpError)\r\n}\r\n\r\nconst wait = (ms: number) => new Promise((r) => setTimeout(r, ms))\r\n\r\n/** Best-effort extraction of a `{ message: string }` payload from a response body. */\r\nfunction extractJsonMessage(text: string): string | null {\r\n if (!text) return null\r\n try {\r\n const parsed = JSON.parse(text)\r\n const message = parsed?.message\r\n if (typeof message === \"string\" && message.trim()) {\r\n return message.trim().slice(0, 500)\r\n }\r\n } catch {\r\n // not JSON — caller falls back to the raw text\r\n }\r\n return null\r\n}\r\n\r\nfunction toHeaderRecord(headers?: RequestInit[\"headers\"]): Record<string, string> {\r\n if (!headers) {\r\n return {}\r\n }\r\n\r\n if (headers instanceof Headers) {\r\n return Object.fromEntries(headers.entries())\r\n }\r\n\r\n if (Array.isArray(headers)) {\r\n return Object.fromEntries(headers)\r\n }\r\n\r\n return { ...headers }\r\n}\r\n\r\nexport function createHttpClient(opts: HttpOptions) {\r\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\r\n\r\n async function attempt<T>(path: string, init?: RequestInit): Promise<T> {\r\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\r\n const headers: Record<string, string> = {\r\n Accept: \"application/json\",\r\n ...toHeaderRecord(init?.headers),\r\n }\r\n\r\n if (opts.publishableApiKey) {\r\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\r\n }\r\n\r\n // Always arm the timeout — a caller-supplied signal composes with it\r\n // rather than replacing it. Without this, hook-issued requests (which\r\n // always pass an abort signal) could hang forever on a stalled\r\n // connection. The timer also covers reading the body: a server that sends\r\n // headers then stalls the response stream would otherwise hang the\r\n // request indefinitely with the old header-only timeout.\r\n const timeoutMs = 30_000\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\r\n const callerSignal = init?.signal ?? null\r\n const onCallerAbort = () => controller.abort()\r\n if (callerSignal) {\r\n if (callerSignal.aborted) controller.abort()\r\n else callerSignal.addEventListener(\"abort\", onCallerAbort)\r\n }\r\n let res: Response\r\n let text: string\r\n try {\r\n res = await fetch(url, {\r\n ...init,\r\n headers,\r\n credentials: \"include\",\r\n signal: controller.signal,\r\n })\r\n text = await res.text().catch(() => \"\")\r\n } catch (err) {\r\n if (\r\n err instanceof Error &&\r\n err.name === \"AbortError\" &&\r\n !(callerSignal && callerSignal.aborted)\r\n ) {\r\n throw new Error(`[PayPal] Request to ${path} timed out after ${timeoutMs / 1000}s`)\r\n }\r\n throw err\r\n } finally {\r\n clearTimeout(timeoutId)\r\n if (callerSignal) callerSignal.removeEventListener(\"abort\", onCallerAbort)\r\n }\r\n\r\n if (!res.ok) {\r\n // Backend routes return structured JSON errors ({ message }) written for\r\n // the buyer (e.g. unsupported currency, rate-limit, \"payment processed\r\n // but order not finalized\"). Prefer that message over raw response text\r\n // or a generic hint so the user sees something actionable instead of a\r\n // JSON blob.\r\n const parsedMessage = extractJsonMessage(text)\r\n if (res.status === 401) {\r\n throw new HttpError(\r\n parsedMessage ||\r\n \"[PayPal] Unauthorized (401) — check that your publishable API key is correct and set in NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY\",\r\n 401\r\n )\r\n }\r\n if (res.status === 403) {\r\n throw new HttpError(\r\n parsedMessage ||\r\n \"[PayPal] Forbidden (403) — this request is not allowed. Check your CORS and API key settings.\",\r\n 403\r\n )\r\n }\r\n throw new HttpError(\r\n parsedMessage ||\r\n text.slice(0, 500).replace(/<[^>]*>/g, \"\") ||\r\n `Request failed (${res.status})`,\r\n res.status\r\n )\r\n }\r\n if (!text) {\r\n throw new HttpError(`[PayPal] Empty response body from ${path} (${res.status})`, res.status)\r\n }\r\n\r\n const contentType = res.headers.get(\"content-type\") || \"\"\r\n if (!contentType.includes(\"application/json\")) {\r\n throw new Error(\r\n `[PayPal] Unexpected non-JSON response (${contentType}) from ${path}`\r\n )\r\n }\r\n\r\n try {\r\n return JSON.parse(text) as T\r\n } catch {\r\n throw new Error(`[PayPal] Failed to parse JSON response from ${path}`)\r\n }\r\n }\r\n\r\n async function request<T>(\r\n path: string,\r\n init?: RequestInit,\r\n reqOpts?: RequestOptions\r\n ): Promise<T> {\r\n const retries = Math.max(0, reqOpts?.retries ?? 0)\r\n let lastError: unknown\r\n for (let i = 0; i <= retries; i++) {\r\n try {\r\n return await attempt<T>(path, init)\r\n } catch (err) {\r\n lastError = err\r\n const transient =\r\n (err instanceof HttpError && isRetryableStatus(err.status)) ||\r\n isRetryableError(err)\r\n // Don't retry a caller-supplied AbortSignal cancellation.\r\n const aborted =\r\n err instanceof Error && err.name === \"AbortError\" && !!init?.signal\r\n if (i >= retries || !transient || aborted) {\r\n throw err\r\n }\r\n await wait(RETRY_BASE_DELAY_MS * Math.pow(2, i) + Math.random() * RETRY_BASE_DELAY_MS)\r\n }\r\n }\r\n throw lastError\r\n }\r\n\r\n return { request }\r\n}\r\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\r\nimport { createHttpClient, type HttpOptions } from \"./http\"\r\n\r\nexport async function markPaymentComplete(\r\n baseUrl: string,\r\n cartId: string,\r\n publishableApiKey?: string\r\n): Promise<Record<string, unknown>> {\r\n const http = createHttpClient({ baseUrl, publishableApiKey })\r\n // Retry transient failures: /store/paypal-complete is idempotent (it returns\r\n // already_completed for a finished cart), so a network blip right after\r\n // capture — the classic \"captured but cart not completed\" gap — is retried\r\n // instead of stranding a paid-but-unfinalized order.\r\n return http.request<Record<string, unknown>>(\r\n `/store/paypal-complete`,\r\n {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ cart_id: cartId }),\r\n },\r\n { retries: 3 }\r\n )\r\n}\r\n\r\nexport function createPayPalStoreApi(opts: HttpOptions) {\r\n const http = createHttpClient(opts)\r\n\r\n return {\r\n getConfig(cartId?: string, signal?: AbortSignal) {\r\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\r\n return http.request<PayPalConfig>(`/store/paypal/config${q}`, { signal })\r\n },\r\n\r\n getSettings() {\r\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`)\r\n },\r\n\r\n createOrder(cartId: string, isCardPayment = false) {\r\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ cart_id: cartId, is_card_payment: isCardPayment }),\r\n })\r\n },\r\n\r\n captureOrder(cartId: string, orderId: string) {\r\n // Retry transient failures: capture-order is idempotent server-side (it\r\n // short-circuits on an existing capture and PayPal dedupes by request id),\r\n // so a network blip during capture doesn't leave the buyer's funds\r\n // authorized-but-not-captured with no recovery.\r\n return http.request<Record<string, unknown>>(\r\n `/store/paypal/capture-order`,\r\n {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\r\n },\r\n { retries: 2 }\r\n )\r\n },\r\n }\r\n}\r\n","\"use client\"\r\n\r\nimport { useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { createPayPalStoreApi } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\ntype Args = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId?: string\r\n enabled?: boolean\r\n}\r\n\r\nconst MAX_CACHE_ENTRIES = 50\r\nconst _cache = new Map<string, { config: PayPalConfig; at: number }>()\r\nconst CACHE_TTL = 5 * 60 * 1000\r\n\r\nfunction cacheSet(key: string, value: { config: PayPalConfig; at: number }) {\r\n if (_cache.size >= MAX_CACHE_ENTRIES) {\r\n const oldest = _cache.keys().next().value\r\n if (oldest !== undefined) _cache.delete(oldest)\r\n }\r\n _cache.set(key, value)\r\n}\r\n\r\nfunction cacheKey(baseUrl: string, cartId?: string) {\r\n return `${baseUrl}::${cartId ?? \"\"}`\r\n}\r\n\r\nexport function usePayPalConfig({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled = true,\r\n}: Args) {\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const key = cacheKey(baseUrl, cartId)\r\n const hit = _cache.get(key)\r\n const seedConfig = hit && Date.now() - hit.at < CACHE_TTL ? hit.config : null\r\n\r\n const [config, setConfig] = useState<PayPalConfig | null>(seedConfig)\r\n const [loading, setLoading] = useState<boolean>(seedConfig === null && enabled)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const fetchIdRef = useRef(0)\r\n\r\n useEffect(() => {\r\n if (!enabled) {\r\n setLoading(false)\r\n setError(null)\r\n return\r\n }\r\n\r\n const k = cacheKey(baseUrl, cartId)\r\n const cached = _cache.get(k)\r\n if (cached && Date.now() - cached.at < CACHE_TTL) {\r\n setConfig(cached.config)\r\n setLoading(false)\r\n setError(null)\r\n return\r\n }\r\n\r\n const id = ++fetchIdRef.current\r\n let mounted = true\r\n const controller = new AbortController()\r\n\r\n setLoading(true)\r\n setError(null)\r\n\r\n ;(async () => {\r\n try {\r\n const cfg = await api.getConfig(cartId, controller.signal)\r\n if (!mounted || id !== fetchIdRef.current) return\r\n cacheSet(k, { config: cfg, at: Date.now() })\r\n setConfig(cfg)\r\n } catch (e: unknown) {\r\n if (e instanceof Error && e.name === \"AbortError\") return\r\n if (!mounted || id !== fetchIdRef.current) return\r\n setError(e instanceof Error ? e.message : \"Failed to load PayPal config\")\r\n } finally {\r\n if (mounted && id === fetchIdRef.current) setLoading(false)\r\n }\r\n })()\r\n\r\n return () => {\r\n mounted = false\r\n controller.abort()\r\n }\r\n }, [api, baseUrl, cartId, enabled])\r\n\r\n return { config, loading, error }\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useMemo } from \"react\"\r\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\r\nimport type { ReactPayPalScriptOptions } from \"@paypal/react-paypal-js\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\nconst BN_CODE = \"MBJTechnolabs_SI_SPB\"\r\n\r\nexport function PayPalProvider(props: {\r\n config: PayPalConfig\r\n intent?: \"capture\" | \"authorize\"\r\n disableFunding?: string\r\n children: React.ReactNode\r\n}) {\r\n const { config, intent = \"capture\", disableFunding, children } = props\r\n\r\n const options = useMemo((): ReactPayPalScriptOptions => {\r\n return {\r\n clientId: config.client_id,\r\n currency: config.currency,\r\n intent,\r\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\r\n \"data-client-token\": config.client_token || undefined,\r\n \"disable-funding\": disableFunding,\r\n \"data-partner-attribution-id\": BN_CODE,\r\n }\r\n }, [config.client_id, config.currency, config.client_token, intent, disableFunding])\r\n\r\n return (\r\n <PayPalScriptProvider\r\n key={`${options.clientId}-${options[\"data-client-token\"] ?? \"no-token\"}`}\r\n options={options}\r\n >\r\n {children}\r\n </PayPalScriptProvider>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport React from \"react\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\r\n if (config.currency_supported) return null\r\n\r\n return (\r\n <div role=\"alert\" style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\r\n <div style={{ fontWeight: 600, marginBottom: 6 }}>PayPal currency issue</div>\r\n <ul style={{ margin: 0, paddingLeft: 18 }}>\r\n {(config.currency_errors || []).map((e) => (\r\n <li key={e}>{e}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { PayPalButtons, usePayPalScriptReducer } from \"@paypal/react-paypal-js\"\r\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\nimport { isNextRouterError } from \"../utils/next-errors\"\r\nimport { showProcessingOverlay, hideProcessingOverlay } from \"../utils/processing-overlay\"\r\n\r\nconst SPIN_STYLE = `\r\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n`\r\n\r\nconst BUTTON_WIDTH_MAP: Record<string, string> = {\r\n small: \"300px\",\r\n medium: \"400px\",\r\n large: \"500px\",\r\n responsive: \"100%\",\r\n}\r\n\r\nexport function PayPalSmartButtons(props: {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId: string\r\n config: PayPalConfig\r\n onPaid?: (result: Record<string, unknown>) => void\r\n onError?: (message: string) => void\r\n}) {\r\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const [error, setError] = useState<string | null>(null)\r\n const [processing, setProcessing] = useState(false)\r\n const [buttonsReady, setButtonsReady] = useState(false)\r\n const [loadTimedOut, setLoadTimedOut] = useState(false)\r\n // Once a capture succeeded, the buyer's money is taken — any later failure\r\n // (order finalization, consumer callback) must retry ONLY the finalization,\r\n // never a fresh createOrder/capture, or a retry click would charge again.\r\n const capturedRef = useRef<Record<string, unknown> | null>(null)\r\n const [completionPending, setCompletionPending] = useState(false)\r\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\r\n\r\n const handleInit = useCallback(() => {\r\n setButtonsReady(true)\r\n }, [])\r\n\r\n // bfcache restore (Back button after a redirect) revives this page with the\r\n // old React state — clear the processing flag so the buyer isn't stuck\r\n // behind the in-component overlay.\r\n useEffect(() => {\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) setProcessing(false)\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n return () => window.removeEventListener(\"pageshow\", onPageShow)\r\n }, [])\r\n\r\n // The PayPal SDK never calls onInit when the buttons are ineligible (wrong\r\n // country/currency/funding) — it silently renders nothing. Without a\r\n // fallback the buyer stares at \"Loading PayPal…\" forever.\r\n useEffect(() => {\r\n if (!isResolved || buttonsReady) {\r\n return\r\n }\r\n const t = setTimeout(() => setLoadTimedOut(true), 10_000)\r\n return () => clearTimeout(t)\r\n }, [isResolved, buttonsReady])\r\n\r\n const finalizeCapturedPayment = useCallback(async () => {\r\n const captured = capturedRef.current\r\n if (!captured) return\r\n setProcessing(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n try {\r\n const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey)\r\n await onPaid?.({ ...captured, ...completeResult })\r\n setCompletionPending(false)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n setCompletionPending(true)\r\n const msg =\r\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\r\n setError(msg)\r\n onError?.(msg)\r\n }\r\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError])\r\n\r\n const showSpinner = (isPending || (isResolved && !buttonsReady)) && !loadTimedOut\r\n\r\n if (!config.currency_supported) return null\r\n\r\n const containerWidth = BUTTON_WIDTH_MAP[config.button_width ?? \"responsive\"] ?? \"100%\"\r\n\r\n return (\r\n <div style={{ width: containerWidth, position: \"relative\" }}>\r\n <style>{SPIN_STYLE}</style>\r\n\r\n {processing && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Processing payment\"\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n zIndex: 9999,\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 20,\r\n }}\r\n >\r\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid #e5e7eb\",\r\n }}\r\n />\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid transparent\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .8s linear infinite\",\r\n }}\r\n />\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#0070ba\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{\r\n position: \"absolute\",\r\n top: \"50%\",\r\n left: \"50%\",\r\n transform: \"translate(-50%, -50%)\",\r\n width: 24,\r\n height: 24,\r\n }}\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n </div>\r\n <div style={{ textAlign: \"center\" }}>\r\n <div style={{ fontSize: 18, fontWeight: 600, color: \"#111827\", letterSpacing: \"-0.01em\" }}>\r\n Processing your payment\r\n </div>\r\n <div style={{ fontSize: 14, color: \"#6b7280\", marginTop: 6, lineHeight: 1.5 }}>\r\n This may take a few moments. Please do not close<br />\r\n or refresh this page.\r\n </div>\r\n </div>\r\n <div\r\n style={{\r\n width: 200,\r\n height: 3,\r\n background: \"#e5e7eb\",\r\n borderRadius: 3,\r\n overflow: \"hidden\",\r\n marginTop: 4,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: \"40%\",\r\n height: \"100%\",\r\n background: \"linear-gradient(90deg, #0070ba, #003087)\",\r\n borderRadius: 3,\r\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\r\n }}\r\n />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {showSpinner && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Loading PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 10,\r\n padding: \"18px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 8,\r\n minHeight: 55,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\r\n Loading PayPal…\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loadTimedOut && !buttonsReady && !isRejected && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal is not available for this purchase. Please try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {isRejected && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal failed to load. Please refresh the page or try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {config.environment === \"sandbox\" && buttonsReady && (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#eff6ff\",\r\n border: \"1px solid #bfdbfe\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#1e40af\",\r\n lineHeight: 1.5,\r\n marginBottom: 10,\r\n }}\r\n >\r\n <svg\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#1e40af\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n style={{ flexShrink: 0, marginTop: 1 }}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path d=\"M12 8v4M12 16h.01\" />\r\n </svg>\r\n <span>\r\n Sandbox mode — you will not be charged. Use your PayPal sandbox\r\n account to complete the payment.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {isResolved && !completionPending && (\r\n <div style={buttonsReady ? undefined : { position: \"absolute\", left: -9999, opacity: 0, pointerEvents: \"none\" }}>\r\n <PayPalButtons\r\n forceReRender={[config.currency, config.intent, cartId]}\r\n onInit={handleInit}\r\n style={{\r\n layout: \"vertical\",\r\n color: config.button_color,\r\n shape: config.button_shape,\r\n label: config.button_label,\r\n height: config.button_height,\r\n }}\r\n createOrder={async () => {\r\n if (processing) throw new Error(\"Payment already processing\")\r\n if (capturedRef.current) {\r\n // Money was already captured for this cart — retry the order\r\n // finalization instead of creating (and charging) a new order.\r\n void finalizeCapturedPayment()\r\n throw new Error(\"Your payment was already received — finalizing your order.\")\r\n }\r\n setError(null)\r\n setProcessing(true)\r\n try {\r\n const r = await api.createOrder(cartId)\r\n return r.id\r\n } catch (e: unknown) {\r\n setProcessing(false)\r\n throw e\r\n }\r\n }}\r\n onApprove={async (data: { orderID?: string }) => {\r\n try {\r\n setProcessing(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n const orderId = String(data?.orderID || \"\")\r\n if (!orderId) throw new Error(\"PayPal order ID is missing from approval response\")\r\n const result = await api.captureOrder(cartId, orderId)\r\n capturedRef.current = (result || {}) as Record<string, unknown>\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n const msg = e instanceof Error ? e.message : \"Payment capture failed\"\r\n setError(msg)\r\n onError?.(msg)\r\n return\r\n }\r\n // Past this point the buyer has been charged: completion failures\r\n // surface a finalize-only Retry, never a fresh payment.\r\n await finalizeCapturedPayment()\r\n }}\r\n onCancel={() => {\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n }}\r\n onError={(err: Error | { message?: string }) => {\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n const msg = err instanceof Error ? err.message : err?.message || \"PayPal error\"\r\n setError(msg)\r\n onError?.(msg)\r\n }}\r\n />\r\n </div>\r\n )}\r\n\r\n {completionPending && (\r\n <button\r\n type=\"button\"\r\n onClick={() => void finalizeCapturedPayment()}\r\n disabled={processing}\r\n aria-busy={processing}\r\n style={{\r\n width: \"100%\",\r\n padding: \"12px 16px\",\r\n marginTop: 4,\r\n background: \"#0070ba\",\r\n color: \"#ffffff\",\r\n border: \"none\",\r\n borderRadius: 8,\r\n fontSize: 14,\r\n fontWeight: 600,\r\n cursor: processing ? \"not-allowed\" : \"pointer\",\r\n opacity: processing ? 0.7 : 1,\r\n }}\r\n >\r\n Retry — finish placing my order\r\n </button>\r\n )}\r\n\r\n {error ? (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n marginTop: 10,\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>{error}</span>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n}\r\n","/**\r\n * Detect Next.js router errors (redirect / notFound) that must be re-thrown.\r\n *\r\n * Next.js implements redirect() and notFound() by throwing special errors with\r\n * a `digest` property starting with \"NEXT_REDIRECT\" or \"NEXT_NOT_FOUND\".\r\n * Catching these in user-land try/catch blocks prevents the navigation from\r\n * happening. Because this package can't import from `next` (it's a peer dep),\r\n * we detect them by duck-typing the digest.\r\n */\r\nexport function isNextRouterError(e: unknown): boolean {\r\n if (typeof e !== \"object\" || e === null || !(\"digest\" in e)) return false\r\n const digest = (e as { digest: unknown }).digest\r\n return (\r\n typeof digest === \"string\" &&\r\n (digest.startsWith(\"NEXT_REDIRECT\") ||\r\n digest.startsWith(\"NEXT_NOT_FOUND\") ||\r\n // Next.js 15: notFound()/forbidden()/unauthorized() throw\r\n // HTTPAccessFallbackError with digest \"NEXT_HTTP_ERROR_FALLBACK;<status>\".\r\n digest.startsWith(\"NEXT_HTTP_ERROR_FALLBACK\"))\r\n )\r\n}\r\n","const OVERLAY_ID = \"__pp_processing_overlay\"\r\n\r\nlet cleanupNavListener: (() => void) | null = null\r\n\r\nexport function showProcessingOverlay() {\r\n if (typeof document === \"undefined\") return\r\n if (document.getElementById(OVERLAY_ID)) return\r\n\r\n const overlay = document.createElement(\"div\")\r\n overlay.id = OVERLAY_ID\r\n overlay.setAttribute(\"role\", \"status\")\r\n overlay.setAttribute(\"aria-label\", \"Processing payment\")\r\n\r\n overlay.innerHTML = `\r\n <style>\r\n @keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n @keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n </style>\r\n <div style=\"position:relative;width:56px;height:56px\">\r\n <div style=\"position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb\"></div>\r\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>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0070ba\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n style=\"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div style=\"text-align:center\">\r\n <div style=\"font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em\">Processing your payment</div>\r\n <div style=\"font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5\">\r\n This may take a few moments. Please do not close<br>or refresh this page.\r\n </div>\r\n </div>\r\n <div style=\"width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px\">\r\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>\r\n </div>\r\n `\r\n\r\n Object.assign(overlay.style, {\r\n position: \"fixed\",\r\n inset: \"0\",\r\n zIndex: \"99999\",\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: \"20px\",\r\n fontFamily: \"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif\",\r\n })\r\n\r\n document.body.appendChild(overlay)\r\n\r\n // Auto-remove on client-side navigation (Next.js App Router uses\r\n // pushState/replaceState for soft navigations, not full reloads).\r\n const startUrl = location.href\r\n const onNav = () => {\r\n if (location.href !== startUrl) hideProcessingOverlay()\r\n }\r\n window.addEventListener(\"popstate\", onNav)\r\n\r\n const origPush = history.pushState.bind(history)\r\n const origReplace = history.replaceState.bind(history)\r\n history.pushState = function (...args) {\r\n origPush(...args)\r\n onNav()\r\n }\r\n history.replaceState = function (...args) {\r\n origReplace(...args)\r\n onNav()\r\n }\r\n\r\n // bfcache restore: the overlay intentionally survives the unload of a\r\n // full-page navigation (that's its purpose), but when the buyer presses\r\n // Back the browser restores this page from the back/forward cache with the\r\n // overlay element still in the DOM and the URL equal to startUrl — no nav\r\n // listener ever fires, leaving checkout permanently covered. `pageshow`\r\n // with `persisted: true` is exactly that restore.\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) hideProcessingOverlay()\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n\r\n cleanupNavListener = () => {\r\n window.removeEventListener(\"popstate\", onNav)\r\n window.removeEventListener(\"pageshow\", onPageShow)\r\n history.pushState = origPush\r\n history.replaceState = origReplace\r\n }\r\n}\r\n\r\nexport function hideProcessingOverlay() {\r\n if (typeof document === \"undefined\") return\r\n cleanupNavListener?.()\r\n cleanupNavListener = null\r\n document.getElementById(OVERLAY_ID)?.remove()\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useMemo, useRef, useState } from \"react\"\r\nimport {\r\n PayPalCardFieldsProvider,\r\n PayPalNumberField,\r\n PayPalExpiryField,\r\n PayPalCVVField,\r\n usePayPalCardFields,\r\n usePayPalScriptReducer,\r\n} from \"@paypal/react-paypal-js\"\r\n\r\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\nimport { isNextRouterError } from \"../utils/next-errors\"\r\nimport { showProcessingOverlay, hideProcessingOverlay } from \"../utils/processing-overlay\"\r\n\r\nconst SPIN_STYLE = `\r\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n`\r\n\r\nconst cardStyle = {\r\n input: {\r\n \"font-size\": \"15px\",\r\n \"font-family\": \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n \"font-weight\": \"400\",\r\n color: \"#111827\",\r\n padding: \"0 14px\",\r\n height: \"42px\",\r\n \"border-radius\": \"8px\",\r\n border: \"1px solid #d1d5db\",\r\n background: \"#ffffff\",\r\n \"box-shadow\": \"none\",\r\n transition: \"border-color 0.15s ease\",\r\n },\r\n \"::placeholder\": {\r\n color: \"#9ca3af\",\r\n },\r\n \".invalid\": {\r\n color: \"#dc2626\",\r\n border: \"1px solid #fca5a5\",\r\n background: \"#fff7f7\",\r\n \"box-shadow\": \"none\",\r\n },\r\n \".valid\": {\r\n color: \"#111827\",\r\n border: \"1px solid #d1d5db\",\r\n \"box-shadow\": \"none\",\r\n },\r\n \"input:focus\": {\r\n outline: \"none\",\r\n border: \"1px solid #2563eb\",\r\n \"box-shadow\": \"0 0 0 3px rgba(37,99,235,0.12)\",\r\n },\r\n}\r\n\r\nconst labelStyle: React.CSSProperties = {\r\n display: \"block\",\r\n fontSize: 13,\r\n fontWeight: 500,\r\n color: \"#374151\",\r\n marginBottom: 6,\r\n letterSpacing: \"0.01em\",\r\n}\r\n\r\nfunction SubmitButton({\r\n disabled,\r\n label,\r\n onSubmit,\r\n onSubmitError,\r\n}: {\r\n disabled: boolean\r\n label: string\r\n onSubmit: () => void\r\n onSubmitError: (message: string) => void\r\n}) {\r\n const { cardFieldsForm } = usePayPalCardFields()\r\n const isDisabled = disabled || !cardFieldsForm\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n disabled={isDisabled}\r\n aria-busy={disabled}\r\n onClick={() => {\r\n onSubmit()\r\n // submit() returns a promise and its rejection is NOT routed to the\r\n // provider's onError — PayPal's contract is that the caller catches\r\n // it. A sync try/catch here would miss it entirely, leaving the buyer\r\n // stuck under the full-screen processing overlay forever (e.g. on a\r\n // card-field validation error).\r\n Promise.resolve(cardFieldsForm?.submit()).catch((e: unknown) => {\r\n const msg =\r\n e instanceof Error && e.message\r\n ? e.message\r\n : \"Card payment could not be submitted. Please check your card details.\"\r\n onSubmitError(msg)\r\n })\r\n }}\r\n style={{\r\n width: \"100%\",\r\n height: 48,\r\n padding: \"0 20px\",\r\n borderRadius: 8,\r\n border: \"none\",\r\n background: isDisabled\r\n ? \"#e5e7eb\"\r\n : \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\",\r\n color: isDisabled ? \"#9ca3af\" : \"#ffffff\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\r\n letterSpacing: \"0.01em\",\r\n boxShadow: isDisabled\r\n ? \"none\"\r\n : \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\",\r\n transition: \"all 0.15s ease\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!isDisabled) {\r\n ;(e.target as HTMLButtonElement).style.background =\r\n \"linear-gradient(180deg, #1d4ed8 0%, #1e40af 100%)\"\r\n ;(e.target as HTMLButtonElement).style.boxShadow =\r\n \"0 4px 6px rgba(37,99,235,0.35), 0 2px 4px rgba(0,0,0,0.06)\"\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isDisabled) {\r\n ;(e.target as HTMLButtonElement).style.background =\r\n \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\"\r\n ;(e.target as HTMLButtonElement).style.boxShadow =\r\n \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\"\r\n }\r\n }}\r\n >\r\n {label}\r\n </button>\r\n )\r\n}\r\n\r\nexport function PayPalAdvancedCard(props: {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId: string\r\n config: PayPalConfig\r\n onPaid?: (result: Record<string, unknown>) => void\r\n onError?: (message: string) => void\r\n}) {\r\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\r\n\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const [error, setError] = useState<string | null>(null)\r\n const [submitting, setSubmitting] = useState(false)\r\n const submittingRef = useRef(false)\r\n const creatingOrderRef = useRef(false)\r\n // Once a capture succeeded the buyer's money is taken: any later failure\r\n // must retry ONLY the order finalization, never a fresh order/capture.\r\n const capturedRef = useRef<Record<string, unknown> | null>(null)\r\n const [completionPending, setCompletionPending] = useState(false)\r\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\r\n\r\n const resetSubmitState = React.useCallback(() => {\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }, [])\r\n\r\n // bfcache restore (Back button after a redirect) revives this page with the\r\n // old React state — clear the submitting flag so the buyer isn't stuck\r\n // behind the in-component overlay.\r\n React.useEffect(() => {\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) {\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n return () => window.removeEventListener(\"pageshow\", onPageShow)\r\n }, [])\r\n\r\n const finalizeCapturedPayment = React.useCallback(async () => {\r\n const captured = capturedRef.current\r\n if (!captured) return\r\n setSubmitting(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n try {\r\n const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey)\r\n await onPaid?.({ ...captured, ...completeResult })\r\n setCompletionPending(false)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n resetSubmitState()\r\n setCompletionPending(true)\r\n const msg =\r\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\r\n setError(msg)\r\n onError?.(msg)\r\n }\r\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError, resetSubmitState])\r\n\r\n if (!config.currency_supported) return null\r\n\r\n if (isRejected) {\r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal failed to load. Please refresh the page or try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )\r\n }\r\n\r\n if (!config.client_token) {\r\n return (\r\n <div\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#fefce8\",\r\n border: \"1px solid #fde68a\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#92400e\",\r\n }}\r\n >\r\n Card fields unavailable — missing client token from backend.\r\n </div>\r\n )\r\n }\r\n\r\n const isSandbox = config.environment === \"sandbox\"\r\n\r\n if (isPending) {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Loading PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 10,\r\n padding: \"18px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 8,\r\n minHeight: 55,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\r\n Loading card fields…\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n if (!isResolved) return null\r\n\r\n return (\r\n <div style={{ position: \"relative\" }}>\r\n <style>{SPIN_STYLE}</style>\r\n\r\n {submitting && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Processing payment\"\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n zIndex: 9999,\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 20,\r\n }}\r\n >\r\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid #e5e7eb\",\r\n }}\r\n />\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid transparent\",\r\n borderTopColor: \"#2563eb\",\r\n animation: \"_pp_spin .8s linear infinite\",\r\n }}\r\n />\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#2563eb\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{\r\n position: \"absolute\",\r\n top: \"50%\",\r\n left: \"50%\",\r\n transform: \"translate(-50%, -50%)\",\r\n width: 24,\r\n height: 24,\r\n }}\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n </div>\r\n <div style={{ textAlign: \"center\" }}>\r\n <div style={{ fontSize: 18, fontWeight: 600, color: \"#111827\", letterSpacing: \"-0.01em\" }}>\r\n Processing your payment\r\n </div>\r\n <div style={{ fontSize: 14, color: \"#6b7280\", marginTop: 6, lineHeight: 1.5 }}>\r\n This may take a few moments. Please do not close<br />\r\n or refresh this page.\r\n </div>\r\n </div>\r\n <div\r\n style={{\r\n width: 200,\r\n height: 3,\r\n background: \"#e5e7eb\",\r\n borderRadius: 3,\r\n overflow: \"hidden\",\r\n marginTop: 4,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: \"40%\",\r\n height: \"100%\",\r\n background: \"linear-gradient(90deg, #2563eb, #1d4ed8)\",\r\n borderRadius: 3,\r\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\r\n }}\r\n />\r\n </div>\r\n </div>\r\n )}\r\n\r\n <PayPalCardFieldsProvider\r\n style={cardStyle}\r\n createOrder={async () => {\r\n if (creatingOrderRef.current) throw new Error(\"Payment already processing\")\r\n if (capturedRef.current) {\r\n // Money was already captured for this cart — retry the order\r\n // finalization instead of creating (and charging) a new order.\r\n void finalizeCapturedPayment()\r\n throw new Error(\"Your payment was already received — finalizing your order.\")\r\n }\r\n creatingOrderRef.current = true\r\n try {\r\n setError(null)\r\n const r = await api.createOrder(cartId, true)\r\n return r.id\r\n } catch (e) {\r\n creatingOrderRef.current = false\r\n throw e\r\n }\r\n }}\r\n onApprove={async (data: { orderID?: string }) => {\r\n try {\r\n setError(null)\r\n showProcessingOverlay()\r\n const orderId = String(data?.orderID || \"\")\r\n if (!orderId) throw new Error(\"PayPal order ID is missing from approval response\")\r\n const result = await api.captureOrder(cartId, orderId)\r\n capturedRef.current = (result || {}) as Record<string, unknown>\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n resetSubmitState()\r\n const msg = e instanceof Error ? e.message : \"Card payment failed\"\r\n setError(msg)\r\n onError?.(msg)\r\n return\r\n }\r\n // Past this point the buyer has been charged: completion failures\r\n // surface a finalize-only Retry, never a fresh payment.\r\n await finalizeCapturedPayment()\r\n }}\r\n onCancel={() => {\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }}\r\n onError={(e: Error | { message?: string }) => {\r\n const msg = e instanceof Error ? e.message : e?.message || \"CardFields error\"\r\n setError(msg)\r\n onError?.(msg)\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }}\r\n >\r\n <div\r\n style={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: 16,\r\n width: \"100%\",\r\n }}\r\n >\r\n {isSandbox && (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 10,\r\n padding: \"10px 14px\",\r\n background: \"#eff6ff\",\r\n border: \"1px solid #bfdbfe\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#1e40af\",\r\n lineHeight: 1.55,\r\n }}\r\n >\r\n <span style={{ fontSize: 15, flexShrink: 0, marginTop: 1 }}>🧪</span>\r\n <span>\r\n Sandbox mode — use test card{\" \"}\r\n <strong style={{ fontFamily: \"monospace\", letterSpacing: \"0.05em\" }}>\r\n 4111 1111 1111 1111\r\n </strong>{\" \"}\r\n with any future date and any CVV.\r\n </span>\r\n </div>\r\n )}\r\n\r\n <div>\r\n <label style={labelStyle}>Card number</label>\r\n <PayPalNumberField />\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"1fr 1fr\",\r\n gap: 16,\r\n }}\r\n >\r\n <div>\r\n <label style={labelStyle}>Expiration date</label>\r\n <PayPalExpiryField />\r\n </div>\r\n <div>\r\n <label style={labelStyle}>Security code</label>\r\n <PayPalCVVField />\r\n </div>\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 6,\r\n fontSize: 12,\r\n color: \"#6b7280\",\r\n }}\r\n >\r\n <svg\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#10b981\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n <span>Your payment is secured with 256-bit SSL encryption</span>\r\n </div>\r\n\r\n {completionPending ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => void finalizeCapturedPayment()}\r\n disabled={submitting}\r\n aria-busy={submitting}\r\n style={{\r\n width: \"100%\",\r\n height: 48,\r\n padding: \"0 20px\",\r\n borderRadius: 8,\r\n border: \"none\",\r\n background: \"#0070ba\",\r\n color: \"#ffffff\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n cursor: submitting ? \"not-allowed\" : \"pointer\",\r\n opacity: submitting ? 0.7 : 1,\r\n }}\r\n >\r\n Retry — finish placing my order\r\n </button>\r\n ) : (\r\n <SubmitButton\r\n disabled={submitting}\r\n label={submitting ? \"Processing…\" : \"Pay by Card\"}\r\n onSubmit={() => {\r\n if (submittingRef.current) return\r\n submittingRef.current = true\r\n setError(null)\r\n setSubmitting(true)\r\n showProcessingOverlay()\r\n }}\r\n onSubmitError={(msg) => {\r\n resetSubmitState()\r\n setError(msg)\r\n onError?.(msg)\r\n }}\r\n />\r\n )}\r\n\r\n {error && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 10,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, marginTop: 1 }}>⚠️</span>\r\n <span>{error}</span>\r\n </div>\r\n )}\r\n </div>\r\n </PayPalCardFieldsProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useCallback } from \"react\"\r\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\r\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\r\nimport { PayPalProvider } from \"../components/PayPalProvider\"\r\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\r\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\r\n\r\nconst DEFAULT_PAYPAL_PROVIDER_ID = \"pp_paypal_paypal\"\r\nconst DEFAULT_PAYPAL_CARD_PROVIDER_ID = \"pp_paypal_card_paypal_card\"\r\n\r\nconst SPIN_STYLE = `@keyframes _pp_spin { to { transform: rotate(360deg) } }`\r\n\r\nfunction PayPalLoadingCard() {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Connecting to PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n padding: \"14px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 10,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div>\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\r\n Connecting to PayPal…\r\n </div>\r\n <div style={{ fontSize: 12, color: \"#6b7280\", marginTop: 2 }}>\r\n Setting up secure payment\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction PayPalErrorCard({ message }: { message: string }) {\r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 10,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n }}\r\n >\r\n {message}\r\n </div>\r\n )\r\n}\r\n\r\nexport type MedusaNextPayPalAdapterProps = {\r\n cartId: string\r\n selectedProviderId: string | null | undefined\r\n baseUrl: string\r\n publishableApiKey?: string\r\n providerIds?: {\r\n paypal?: string\r\n paypalCard?: string\r\n }\r\n onSuccess?: (cartId: string) => void\r\n onError?: (message: string) => void\r\n onPaid?: (result: unknown) => void\r\n}\r\n\r\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\r\n const {\r\n cartId,\r\n selectedProviderId,\r\n baseUrl,\r\n publishableApiKey,\r\n providerIds,\r\n onSuccess,\r\n onError,\r\n onPaid,\r\n } = props\r\n\r\n const paypalProviderId = providerIds?.paypal || DEFAULT_PAYPAL_PROVIDER_ID\r\n const paypalCardProviderId = providerIds?.paypalCard || DEFAULT_PAYPAL_CARD_PROVIDER_ID\r\n\r\n const shouldRender =\r\n selectedProviderId === paypalProviderId ||\r\n selectedProviderId === paypalCardProviderId\r\n\r\n const { config, loading, error } = usePayPalConfig({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled: shouldRender,\r\n })\r\n\r\n const handlePaid = useCallback(\r\n async (captureResult: unknown) => {\r\n onPaid?.(captureResult)\r\n await onSuccess?.(cartId)\r\n },\r\n [cartId, onPaid, onSuccess]\r\n )\r\n\r\n if (!shouldRender) return null\r\n\r\n if (loading) return <PayPalLoadingCard />\r\n\r\n if (error) return <PayPalErrorCard message={error} />\r\n\r\n if (!config) return null\r\n\r\n const isCardProvider = selectedProviderId === paypalCardProviderId\r\n if (config.paypal_enabled === false && !isCardProvider) return null\r\n if (isCardProvider && config.card_enabled === false) return null\r\n\r\n const disableFunding = Array.isArray(config.disable_buttons)\r\n ? config.disable_buttons.join(\",\")\r\n : undefined\r\n\r\n return (\r\n <div key={selectedProviderId} style={{ display: \"grid\", gap: 12 }}>\r\n <PayPalCurrencyNotice config={config} />\r\n <PayPalProvider\r\n config={config}\r\n intent={config.intent === \"authorize\" ? \"authorize\" : \"capture\"}\r\n disableFunding={disableFunding}\r\n >\r\n {isCardProvider ? (\r\n <PayPalAdvancedCard\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n ) : (\r\n <PayPalSmartButtons\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n )}\r\n </PayPalProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useCallback } from \"react\"\r\nimport { PayPalCurrencyNotice } from \"./PayPalCurrencyNotice\"\r\nimport { PayPalAdvancedCard } from \"./PayPalAdvancedCard\"\r\nimport { PayPalProvider } from \"./PayPalProvider\"\r\nimport { PayPalSmartButtons } from \"./PayPalSmartButtons\"\r\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\r\n\r\nexport const PAYPAL_WALLET_PROVIDER_ID = \"pp_paypal_paypal\" as const\r\nexport const PAYPAL_CARD_PROVIDER_ID = \"pp_paypal_card_paypal_card\" as const\r\n\r\nconst PAYPAL_PROVIDER_IDS = [\r\n PAYPAL_WALLET_PROVIDER_ID,\r\n PAYPAL_CARD_PROVIDER_ID,\r\n] as const\r\n\r\nexport function isPayPalProviderId(id?: string | null): boolean {\r\n if (!id) return false\r\n return PAYPAL_PROVIDER_IDS.includes(id as (typeof PAYPAL_PROVIDER_IDS)[number])\r\n}\r\n\r\nconst SPIN_STYLE = `@keyframes _pp_section_spin { to { transform: rotate(360deg) } }`\r\n\r\nfunction SessionInitCard() {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Setting up payment\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n padding: \"14px 16px\",\r\n marginTop: 8,\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 10,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 20,\r\n height: 20,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_section_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\r\n Setting up payment…\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction ConfigLoadingCard() {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Connecting to PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n padding: \"14px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 10,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_section_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div>\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\r\n Connecting to PayPal…\r\n </div>\r\n <div style={{ fontSize: 12, color: \"#6b7280\", marginTop: 2 }}>\r\n Setting up secure payment\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction ErrorCard({ message }: { message: string }) {\r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 10,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n }}\r\n >\r\n {message}\r\n </div>\r\n )\r\n}\r\n\r\nexport type PayPalPaymentSectionProps = {\r\n cartId: string\r\n selectedProviderId: string | null | undefined\r\n baseUrl: string\r\n publishableApiKey?: string\r\n sessionLoading?: boolean\r\n onSuccess?: (cartId: string) => void\r\n onError?: (message: string) => void\r\n onPaid?: (result: unknown) => void\r\n}\r\n\r\nexport function PayPalPaymentSection({\r\n cartId,\r\n selectedProviderId,\r\n baseUrl,\r\n publishableApiKey,\r\n sessionLoading = false,\r\n onSuccess,\r\n onError,\r\n onPaid,\r\n}: PayPalPaymentSectionProps) {\r\n const shouldRender = isPayPalProviderId(selectedProviderId)\r\n\r\n const { config, loading, error } = usePayPalConfig({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled: shouldRender,\r\n })\r\n\r\n const handlePaid = useCallback(\r\n async (captureResult: unknown) => {\r\n onPaid?.(captureResult)\r\n await onSuccess?.(cartId)\r\n },\r\n [cartId, onPaid, onSuccess]\r\n )\r\n\r\n if (!shouldRender) return null\r\n if (sessionLoading) return <SessionInitCard />\r\n if (loading) return <ConfigLoadingCard />\r\n if (error) return <ErrorCard message={error} />\r\n if (!config) return null\r\n\r\n if (config.paypal_enabled === false && selectedProviderId === PAYPAL_WALLET_PROVIDER_ID) {\r\n return null\r\n }\r\n\r\n const isCardProvider = selectedProviderId === PAYPAL_CARD_PROVIDER_ID\r\n if (isCardProvider && config.card_enabled === false) return null\r\n\r\n const disableFunding = Array.isArray(config.disable_buttons)\r\n ? config.disable_buttons.join(\",\")\r\n : undefined\r\n\r\n return (\r\n <div key={selectedProviderId} style={{ display: \"grid\", gap: 12 }}>\r\n <PayPalCurrencyNotice config={config} />\r\n <PayPalProvider\r\n config={config}\r\n intent={config.intent === \"authorize\" ? \"authorize\" : \"capture\"}\r\n disableFunding={disableFunding}\r\n >\r\n {isCardProvider ? (\r\n <PayPalAdvancedCard\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n ) : (\r\n <PayPalSmartButtons\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n )}\r\n </PayPalProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\n\r\nimport { useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { createPayPalStoreApi } from \"../client/paypal\"\r\n\r\ntype Args = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId?: string\r\n enabled?: boolean\r\n}\r\n\r\ntype Result = {\r\n paypalEnabled: boolean\r\n paypalTitle: string\r\n cardEnabled: boolean\r\n cardTitle: string\r\n loading: boolean\r\n}\r\n\r\nconst MAX_CACHE_ENTRIES = 50\r\nconst _cache = new Map<string, { result: Result; at: number }>()\r\nconst CACHE_TTL = 5 * 60 * 1000\r\n\r\nfunction cacheSet(key: string, value: { result: Result; at: number }) {\r\n if (_cache.size >= MAX_CACHE_ENTRIES) {\r\n const oldest = _cache.keys().next().value\r\n if (oldest !== undefined) _cache.delete(oldest)\r\n }\r\n _cache.set(key, value)\r\n}\r\n\r\nfunction cacheKey(baseUrl: string, cartId?: string) {\r\n return `ppm::${baseUrl}::${cartId ?? \"\"}`\r\n}\r\n\r\nconst DEFAULT_RESULT: Result = {\r\n paypalEnabled: true,\r\n paypalTitle: \"PayPal\",\r\n cardEnabled: true,\r\n cardTitle: \"Credit or Debit Card\",\r\n loading: false,\r\n}\r\n\r\nexport function usePayPalPaymentMethods({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled = true,\r\n}: Args): Result {\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const key = cacheKey(baseUrl, cartId)\r\n const hit = _cache.get(key)\r\n const seed = hit && Date.now() - hit.at < CACHE_TTL ? hit.result : null\r\n\r\n const [result, setResult] = useState<Result>(seed ?? { ...DEFAULT_RESULT, loading: enabled })\r\n const fetchIdRef = useRef(0)\r\n\r\n useEffect(() => {\r\n if (!enabled) {\r\n setResult((prev) => ({ ...prev, loading: false }))\r\n return\r\n }\r\n\r\n const k = cacheKey(baseUrl, cartId)\r\n const cached = _cache.get(k)\r\n if (cached && Date.now() - cached.at < CACHE_TTL) {\r\n setResult(cached.result)\r\n return\r\n }\r\n\r\n const id = ++fetchIdRef.current\r\n let mounted = true\r\n const controller = new AbortController()\r\n\r\n setResult((prev) => ({ ...prev, loading: true }))\r\n\r\n ;(async () => {\r\n try {\r\n const cfg = await api.getConfig(cartId, controller.signal)\r\n if (!mounted || id !== fetchIdRef.current) return\r\n\r\n const next: Result = {\r\n paypalEnabled: cfg.paypal_enabled !== false,\r\n paypalTitle:\r\n typeof cfg.paypal_title === \"string\" && cfg.paypal_title\r\n ? cfg.paypal_title\r\n : \"PayPal\",\r\n cardEnabled: cfg.card_enabled !== false,\r\n cardTitle:\r\n typeof cfg.card_title === \"string\" && cfg.card_title\r\n ? cfg.card_title\r\n : \"Credit or Debit Card\",\r\n loading: false,\r\n }\r\n\r\n cacheSet(k, { result: next, at: Date.now() })\r\n setResult(next)\r\n } catch (e: unknown) {\r\n const msg = e instanceof Error ? e.message : \"\"\r\n if (e instanceof Error && e.name === \"AbortError\") return\r\n if (!mounted || id !== fetchIdRef.current) return\r\n\r\n if (msg.includes(\"403\") || msg.includes(\"Forbidden\")) {\r\n const disabled: Result = {\r\n ...DEFAULT_RESULT,\r\n paypalEnabled: false,\r\n cardEnabled: false,\r\n loading: false,\r\n }\r\n setResult(disabled)\r\n return\r\n }\r\n\r\n setResult({ ...DEFAULT_RESULT, loading: false })\r\n }\r\n })()\r\n\r\n return () => {\r\n mounted = false\r\n controller.abort()\r\n }\r\n }, [api, baseUrl, cartId, enabled])\r\n\r\n return result\r\n}\r\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_react","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/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\"\r\nexport * from \"./client/paypal\"\r\nexport * from \"./hooks/usePayPalConfig\"\r\nexport * from \"./components/PayPalProvider\"\r\nexport * from \"./components/PayPalCurrencyNotice\"\r\nexport * from \"./components/PayPalSmartButtons\"\r\nexport * from \"./components/PayPalAdvancedCard\"\r\nexport * from \"./adapters/MedusaNextPayPalAdapter\"\r\nexport * from \"./components/PayPalPaymentSection\"\r\nexport * from \"./hooks/usePayPalPaymentMethods\"\r\nexport { showProcessingOverlay, hideProcessingOverlay } from \"./utils/processing-overlay\"\r\nexport {\r\n markCartCaptured,\r\n wasCartCaptured,\r\n clearCartCaptured,\r\n} from \"./utils/captured-state\"\r\n","export type HttpOptions = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n /**\r\n * `credentials` mode for every request. Defaults to \"include\" (the\r\n * historical behavior, required when the backend sits behind cookie-based\r\n * gateways like Cloudflare Access). Set to \"omit\" or \"same-origin\" when the\r\n * backend answers with `Access-Control-Allow-Origin: *` — browsers reject\r\n * credentialed requests against a wildcard CORS origin outright.\r\n */\r\n credentials?: RequestCredentials\r\n}\r\n\r\nexport type RequestOptions = {\r\n /**\r\n * Number of extra attempts on transient failures (network error, timeout,\r\n * HTTP 429/5xx). Only use for idempotent calls — the PayPal capture/complete\r\n * endpoints are idempotent server-side, so a retried request after a network\r\n * blip re-uses the existing result instead of duplicating work. Default 0.\r\n */\r\n retries?: number\r\n}\r\n\r\nclass HttpError extends Error {\r\n status: number\r\n constructor(message: string, status: number) {\r\n super(message)\r\n this.name = \"HttpError\"\r\n this.status = status\r\n }\r\n}\r\n\r\nconst RETRY_BASE_DELAY_MS = 400\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return status === 429 || status >= 500\r\n}\r\n\r\nfunction isRetryableError(err: unknown): boolean {\r\n // Network failures and our own timeout error are safe to retry.\r\n return err instanceof Error && !(err instanceof HttpError)\r\n}\r\n\r\nconst wait = (ms: number) => new Promise((r) => setTimeout(r, ms))\r\n\r\n/** Best-effort extraction of a `{ message: string }` payload from a response body. */\r\nfunction extractJsonMessage(text: string): string | null {\r\n if (!text) return null\r\n try {\r\n const parsed = JSON.parse(text)\r\n const message = parsed?.message\r\n if (typeof message === \"string\" && message.trim()) {\r\n return message.trim().slice(0, 500)\r\n }\r\n } catch {\r\n // not JSON — caller falls back to the raw text\r\n }\r\n return null\r\n}\r\n\r\nfunction toHeaderRecord(headers?: RequestInit[\"headers\"]): Record<string, string> {\r\n if (!headers) {\r\n return {}\r\n }\r\n\r\n if (headers instanceof Headers) {\r\n return Object.fromEntries(headers.entries())\r\n }\r\n\r\n if (Array.isArray(headers)) {\r\n return Object.fromEntries(headers)\r\n }\r\n\r\n return { ...headers }\r\n}\r\n\r\nexport function createHttpClient(opts: HttpOptions) {\r\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\r\n\r\n async function attempt<T>(path: string, init?: RequestInit): Promise<T> {\r\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\r\n const headers: Record<string, string> = {\r\n Accept: \"application/json\",\r\n ...toHeaderRecord(init?.headers),\r\n }\r\n\r\n if (opts.publishableApiKey) {\r\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\r\n }\r\n\r\n // Always arm the timeout — a caller-supplied signal composes with it\r\n // rather than replacing it. Without this, hook-issued requests (which\r\n // always pass an abort signal) could hang forever on a stalled\r\n // connection. The timer also covers reading the body: a server that sends\r\n // headers then stalls the response stream would otherwise hang the\r\n // request indefinitely with the old header-only timeout.\r\n const timeoutMs = 30_000\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\r\n const callerSignal = init?.signal ?? null\r\n const onCallerAbort = () => controller.abort()\r\n if (callerSignal) {\r\n if (callerSignal.aborted) controller.abort()\r\n else callerSignal.addEventListener(\"abort\", onCallerAbort)\r\n }\r\n let res: Response\r\n let text: string\r\n try {\r\n res = await fetch(url, {\r\n ...init,\r\n headers,\r\n credentials: opts.credentials ?? \"include\",\r\n signal: controller.signal,\r\n })\r\n text = await res.text().catch(() => \"\")\r\n } catch (err) {\r\n if (\r\n err instanceof Error &&\r\n err.name === \"AbortError\" &&\r\n !(callerSignal && callerSignal.aborted)\r\n ) {\r\n throw new Error(`[PayPal] Request to ${path} timed out after ${timeoutMs / 1000}s`)\r\n }\r\n throw err\r\n } finally {\r\n clearTimeout(timeoutId)\r\n if (callerSignal) callerSignal.removeEventListener(\"abort\", onCallerAbort)\r\n }\r\n\r\n if (!res.ok) {\r\n // Backend routes return structured JSON errors ({ message }) written for\r\n // the buyer (e.g. unsupported currency, rate-limit, \"payment processed\r\n // but order not finalized\"). Prefer that message over raw response text\r\n // or a generic hint so the user sees something actionable instead of a\r\n // JSON blob.\r\n const parsedMessage = extractJsonMessage(text)\r\n if (res.status === 401) {\r\n throw new HttpError(\r\n parsedMessage ||\r\n \"[PayPal] Unauthorized (401) — check that your publishable API key is correct and set in NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY\",\r\n 401\r\n )\r\n }\r\n if (res.status === 403) {\r\n throw new HttpError(\r\n parsedMessage ||\r\n \"[PayPal] Forbidden (403) — this request is not allowed. Check your CORS and API key settings.\",\r\n 403\r\n )\r\n }\r\n throw new HttpError(\r\n parsedMessage ||\r\n text.slice(0, 500).replace(/<[^>]*>/g, \"\") ||\r\n `Request failed (${res.status})`,\r\n res.status\r\n )\r\n }\r\n if (!text) {\r\n throw new HttpError(`[PayPal] Empty response body from ${path} (${res.status})`, res.status)\r\n }\r\n\r\n const contentType = res.headers.get(\"content-type\") || \"\"\r\n if (!contentType.includes(\"application/json\")) {\r\n throw new Error(\r\n `[PayPal] Unexpected non-JSON response (${contentType}) from ${path}`\r\n )\r\n }\r\n\r\n try {\r\n return JSON.parse(text) as T\r\n } catch {\r\n throw new Error(`[PayPal] Failed to parse JSON response from ${path}`)\r\n }\r\n }\r\n\r\n async function request<T>(\r\n path: string,\r\n init?: RequestInit,\r\n reqOpts?: RequestOptions\r\n ): Promise<T> {\r\n const retries = Math.max(0, reqOpts?.retries ?? 0)\r\n let lastError: unknown\r\n for (let i = 0; i <= retries; i++) {\r\n try {\r\n return await attempt<T>(path, init)\r\n } catch (err) {\r\n lastError = err\r\n const transient =\r\n (err instanceof HttpError && isRetryableStatus(err.status)) ||\r\n isRetryableError(err)\r\n // Don't retry a caller-supplied AbortSignal cancellation.\r\n const aborted =\r\n err instanceof Error && err.name === \"AbortError\" && !!init?.signal\r\n if (i >= retries || !transient || aborted) {\r\n throw err\r\n }\r\n await wait(RETRY_BASE_DELAY_MS * Math.pow(2, i) + Math.random() * RETRY_BASE_DELAY_MS)\r\n }\r\n }\r\n throw lastError\r\n }\r\n\r\n return { request }\r\n}\r\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\r\nimport { createHttpClient, type HttpOptions } from \"./http\"\r\n\r\n/**\r\n * Fresh idempotency key per create-order ATTEMPT (i.e. per buyer click).\r\n *\r\n * The backend derives the PayPal-Request-Id from this header. It must be\r\n * unique per attempt: PayPal replays the cached response for a reused request\r\n * id, so a key stable across cart changes would hand back the ORIGINAL order —\r\n * at the original total — after the buyer edits the cart, charging a stale\r\n * amount. Reuse/dedup of an unchanged order is handled server-side by the\r\n * stored-order staleness check, not by this key.\r\n */\r\nexport function generateIdempotencyKey(): string {\r\n try {\r\n const c = (globalThis as { crypto?: Crypto }).crypto\r\n if (c?.randomUUID) return c.randomUUID()\r\n } catch {\r\n // fall through\r\n }\r\n return `pp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`\r\n}\r\n\r\nexport async function markPaymentComplete(\r\n baseUrl: string,\r\n cartId: string,\r\n publishableApiKey?: string\r\n): Promise<Record<string, unknown>> {\r\n const http = createHttpClient({ baseUrl, publishableApiKey })\r\n // Retry transient failures: /store/paypal-complete is idempotent (it returns\r\n // already_completed for a finished cart), so a network blip right after\r\n // capture — the classic \"captured but cart not completed\" gap — is retried\r\n // instead of stranding a paid-but-unfinalized order.\r\n return http.request<Record<string, unknown>>(\r\n `/store/paypal-complete`,\r\n {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ cart_id: cartId }),\r\n },\r\n { retries: 3 }\r\n )\r\n}\r\n\r\nexport function createPayPalStoreApi(opts: HttpOptions) {\r\n const http = createHttpClient(opts)\r\n\r\n return {\r\n getConfig(cartId?: string, signal?: AbortSignal) {\r\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\r\n return http.request<PayPalConfig>(`/store/paypal/config${q}`, { signal })\r\n },\r\n\r\n getSettings() {\r\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`)\r\n },\r\n\r\n createOrder(cartId: string, isCardPayment = false) {\r\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n // One key per attempt — see generateIdempotencyKey. Deliberately NOT\r\n // sent for capture-order: there the server's deterministic\r\n // per-order-id fallback is the correct idempotency scope.\r\n \"Idempotency-Key\": generateIdempotencyKey(),\r\n },\r\n body: JSON.stringify({ cart_id: cartId, is_card_payment: isCardPayment }),\r\n })\r\n },\r\n\r\n captureOrder(cartId: string, orderId: string) {\r\n // Retry transient failures: capture-order is idempotent server-side (it\r\n // short-circuits on an existing capture and PayPal dedupes by request id),\r\n // so a network blip during capture doesn't leave the buyer's funds\r\n // authorized-but-not-captured with no recovery.\r\n return http.request<Record<string, unknown>>(\r\n `/store/paypal/capture-order`,\r\n {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\r\n },\r\n { retries: 2 }\r\n )\r\n },\r\n }\r\n}\r\n","\"use client\"\r\n\r\nimport { useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { createPayPalStoreApi } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\ntype Args = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId?: string\r\n enabled?: boolean\r\n}\r\n\r\nconst MAX_CACHE_ENTRIES = 50\r\nconst _cache = new Map<string, { config: PayPalConfig; at: number }>()\r\nconst CACHE_TTL = 5 * 60 * 1000\r\n\r\nfunction cacheSet(key: string, value: { config: PayPalConfig; at: number }) {\r\n if (_cache.size >= MAX_CACHE_ENTRIES) {\r\n const oldest = _cache.keys().next().value\r\n if (oldest !== undefined) _cache.delete(oldest)\r\n }\r\n _cache.set(key, value)\r\n}\r\n\r\nfunction cacheKey(baseUrl: string, cartId?: string) {\r\n return `${baseUrl}::${cartId ?? \"\"}`\r\n}\r\n\r\nexport function usePayPalConfig({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled = true,\r\n}: Args) {\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const key = cacheKey(baseUrl, cartId)\r\n const hit = _cache.get(key)\r\n const seedConfig = hit && Date.now() - hit.at < CACHE_TTL ? hit.config : null\r\n\r\n const [config, setConfig] = useState<PayPalConfig | null>(seedConfig)\r\n const [loading, setLoading] = useState<boolean>(seedConfig === null && enabled)\r\n const [error, setError] = useState<string | null>(null)\r\n\r\n const fetchIdRef = useRef(0)\r\n\r\n useEffect(() => {\r\n if (!enabled) {\r\n setLoading(false)\r\n setError(null)\r\n return\r\n }\r\n\r\n const k = cacheKey(baseUrl, cartId)\r\n const cached = _cache.get(k)\r\n if (cached && Date.now() - cached.at < CACHE_TTL) {\r\n setConfig(cached.config)\r\n setLoading(false)\r\n setError(null)\r\n return\r\n }\r\n\r\n const id = ++fetchIdRef.current\r\n let mounted = true\r\n const controller = new AbortController()\r\n\r\n setLoading(true)\r\n setError(null)\r\n\r\n ;(async () => {\r\n try {\r\n const cfg = await api.getConfig(cartId, controller.signal)\r\n if (!mounted || id !== fetchIdRef.current) return\r\n cacheSet(k, { config: cfg, at: Date.now() })\r\n setConfig(cfg)\r\n } catch (e: unknown) {\r\n if (e instanceof Error && e.name === \"AbortError\") return\r\n if (!mounted || id !== fetchIdRef.current) return\r\n setError(e instanceof Error ? e.message : \"Failed to load PayPal config\")\r\n } finally {\r\n if (mounted && id === fetchIdRef.current) setLoading(false)\r\n }\r\n })()\r\n\r\n return () => {\r\n mounted = false\r\n controller.abort()\r\n }\r\n }, [api, baseUrl, cartId, enabled])\r\n\r\n return { config, loading, error }\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useMemo } from \"react\"\r\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\r\nimport type { ReactPayPalScriptOptions } from \"@paypal/react-paypal-js\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\nconst BN_CODE = \"MBJTechnolabs_SI_SPB\"\r\n\r\nexport function PayPalProvider(props: {\r\n config: PayPalConfig\r\n intent?: \"capture\" | \"authorize\"\r\n disableFunding?: string\r\n children: React.ReactNode\r\n}) {\r\n const { config, intent = \"capture\", disableFunding, children } = props\r\n\r\n const options = useMemo((): ReactPayPalScriptOptions => {\r\n return {\r\n clientId: config.client_id,\r\n currency: config.currency,\r\n intent,\r\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\r\n \"data-client-token\": config.client_token || undefined,\r\n \"disable-funding\": disableFunding,\r\n \"data-partner-attribution-id\": BN_CODE,\r\n }\r\n }, [config.client_id, config.currency, config.client_token, intent, disableFunding])\r\n\r\n return (\r\n <PayPalScriptProvider\r\n key={`${options.clientId}-${options[\"data-client-token\"] ?? \"no-token\"}`}\r\n options={options}\r\n >\r\n {children}\r\n </PayPalScriptProvider>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport React from \"react\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\n\r\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\r\n if (config.currency_supported) return null\r\n\r\n return (\r\n <div role=\"alert\" style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\r\n <div style={{ fontWeight: 600, marginBottom: 6 }}>PayPal currency issue</div>\r\n <ul style={{ margin: 0, paddingLeft: 18 }}>\r\n {(config.currency_errors || []).map((e) => (\r\n <li key={e}>{e}</li>\r\n ))}\r\n </ul>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { PayPalButtons, usePayPalScriptReducer } from \"@paypal/react-paypal-js\"\r\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\nimport {\r\n clearCartCaptured,\r\n markCartCaptured,\r\n wasCartCaptured,\r\n} from \"../utils/captured-state\"\r\nimport { isNextRouterError } from \"../utils/next-errors\"\r\nimport { showProcessingOverlay, hideProcessingOverlay } from \"../utils/processing-overlay\"\r\n\r\nconst SPIN_STYLE = `\r\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n`\r\n\r\nconst BUTTON_WIDTH_MAP: Record<string, string> = {\r\n small: \"300px\",\r\n medium: \"400px\",\r\n large: \"500px\",\r\n responsive: \"100%\",\r\n}\r\n\r\nexport function PayPalSmartButtons(props: {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId: string\r\n config: PayPalConfig\r\n onPaid?: (result: Record<string, unknown>) => void\r\n onError?: (message: string) => void\r\n}) {\r\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const [error, setError] = useState<string | null>(null)\r\n const [processing, setProcessing] = useState(false)\r\n const [buttonsReady, setButtonsReady] = useState(false)\r\n const [loadTimedOut, setLoadTimedOut] = useState(false)\r\n // Once a capture succeeded, the buyer's money is taken — any later failure\r\n // (order finalization, consumer callback) must retry ONLY the finalization,\r\n // never a fresh createOrder/capture, or a retry click would charge again.\r\n const capturedRef = useRef<Record<string, unknown> | null>(null)\r\n const [completionPending, setCompletionPending] = useState(false)\r\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\r\n\r\n const handleInit = useCallback(() => {\r\n setButtonsReady(true)\r\n }, [])\r\n\r\n // bfcache restore (Back button after a redirect) revives this page with the\r\n // old React state — clear the processing flag so the buyer isn't stuck\r\n // behind the in-component overlay.\r\n useEffect(() => {\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) setProcessing(false)\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n return () => window.removeEventListener(\"pageshow\", onPageShow)\r\n }, [])\r\n\r\n // A reload/crash between capture and finalization loses the in-memory\r\n // capturedRef — restore it from the persisted per-cart flag so the buyer\r\n // gets the finalize-only Retry button instead of payment buttons that would\r\n // fail confusingly against an already-captured PayPal order.\r\n useEffect(() => {\r\n if (capturedRef.current || !wasCartCaptured(cartId)) return\r\n capturedRef.current = {}\r\n setCompletionPending(true)\r\n const msg =\r\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\r\n setError(msg)\r\n }, [cartId])\r\n\r\n // The PayPal SDK never calls onInit when the buttons are ineligible (wrong\r\n // country/currency/funding) — it silently renders nothing. Without a\r\n // fallback the buyer stares at \"Loading PayPal…\" forever.\r\n useEffect(() => {\r\n if (!isResolved || buttonsReady) {\r\n return\r\n }\r\n const t = setTimeout(() => setLoadTimedOut(true), 10_000)\r\n return () => clearTimeout(t)\r\n }, [isResolved, buttonsReady])\r\n\r\n const finalizeCapturedPayment = useCallback(async () => {\r\n const captured = capturedRef.current\r\n if (!captured) return\r\n setProcessing(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n try {\r\n const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey)\r\n // The order is finalized — the persisted \"captured\" flag has served its\r\n // purpose. Clear it before the consumer callback (which may redirect).\r\n clearCartCaptured(cartId)\r\n await onPaid?.({ ...captured, ...completeResult })\r\n setCompletionPending(false)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n setCompletionPending(true)\r\n const msg =\r\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\r\n setError(msg)\r\n onError?.(msg)\r\n }\r\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError])\r\n\r\n const showSpinner = (isPending || (isResolved && !buttonsReady)) && !loadTimedOut\r\n\r\n if (!config.currency_supported) return null\r\n\r\n const containerWidth = BUTTON_WIDTH_MAP[config.button_width ?? \"responsive\"] ?? \"100%\"\r\n\r\n return (\r\n <div style={{ width: containerWidth, position: \"relative\" }}>\r\n <style>{SPIN_STYLE}</style>\r\n\r\n {processing && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Processing payment\"\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n zIndex: 9999,\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 20,\r\n }}\r\n >\r\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid #e5e7eb\",\r\n }}\r\n />\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid transparent\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .8s linear infinite\",\r\n }}\r\n />\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#0070ba\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{\r\n position: \"absolute\",\r\n top: \"50%\",\r\n left: \"50%\",\r\n transform: \"translate(-50%, -50%)\",\r\n width: 24,\r\n height: 24,\r\n }}\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n </div>\r\n <div style={{ textAlign: \"center\" }}>\r\n <div style={{ fontSize: 18, fontWeight: 600, color: \"#111827\", letterSpacing: \"-0.01em\" }}>\r\n Processing your payment\r\n </div>\r\n <div style={{ fontSize: 14, color: \"#6b7280\", marginTop: 6, lineHeight: 1.5 }}>\r\n This may take a few moments. Please do not close<br />\r\n or refresh this page.\r\n </div>\r\n </div>\r\n <div\r\n style={{\r\n width: 200,\r\n height: 3,\r\n background: \"#e5e7eb\",\r\n borderRadius: 3,\r\n overflow: \"hidden\",\r\n marginTop: 4,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: \"40%\",\r\n height: \"100%\",\r\n background: \"linear-gradient(90deg, #0070ba, #003087)\",\r\n borderRadius: 3,\r\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\r\n }}\r\n />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {showSpinner && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Loading PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 10,\r\n padding: \"18px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 8,\r\n minHeight: 55,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\r\n Loading PayPal…\r\n </div>\r\n </div>\r\n )}\r\n\r\n {loadTimedOut && !buttonsReady && !isRejected && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal is not available for this purchase. Please try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {isRejected && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal failed to load. Please refresh the page or try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {config.environment === \"sandbox\" && buttonsReady && (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#eff6ff\",\r\n border: \"1px solid #bfdbfe\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#1e40af\",\r\n lineHeight: 1.5,\r\n marginBottom: 10,\r\n }}\r\n >\r\n <svg\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#1e40af\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n style={{ flexShrink: 0, marginTop: 1 }}\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <path d=\"M12 8v4M12 16h.01\" />\r\n </svg>\r\n <span>\r\n Sandbox mode — you will not be charged. Use your PayPal sandbox\r\n account to complete the payment.\r\n </span>\r\n </div>\r\n )}\r\n\r\n {isResolved && !completionPending && (\r\n <div style={buttonsReady ? undefined : { position: \"absolute\", left: -9999, opacity: 0, pointerEvents: \"none\" }}>\r\n <PayPalButtons\r\n forceReRender={[config.currency, config.intent, cartId]}\r\n onInit={handleInit}\r\n style={{\r\n layout: \"vertical\",\r\n color: config.button_color,\r\n shape: config.button_shape,\r\n label: config.button_label,\r\n height: config.button_height,\r\n }}\r\n createOrder={async () => {\r\n if (processing) throw new Error(\"Payment already processing\")\r\n if (capturedRef.current) {\r\n // Money was already captured for this cart — retry the order\r\n // finalization instead of creating (and charging) a new order.\r\n void finalizeCapturedPayment()\r\n throw new Error(\"Your payment was already received — finalizing your order.\")\r\n }\r\n setError(null)\r\n setProcessing(true)\r\n try {\r\n const r = await api.createOrder(cartId)\r\n return r.id\r\n } catch (e: unknown) {\r\n setProcessing(false)\r\n throw e\r\n }\r\n }}\r\n onApprove={async (data: { orderID?: string }) => {\r\n try {\r\n setProcessing(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n const orderId = String(data?.orderID || \"\")\r\n if (!orderId) throw new Error(\"PayPal order ID is missing from approval response\")\r\n const result = await api.captureOrder(cartId, orderId)\r\n capturedRef.current = (result || {}) as Record<string, unknown>\r\n // Persist across reloads: from here on, only finalization may\r\n // ever be retried for this cart — never a fresh payment.\r\n markCartCaptured(cartId)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n const msg = e instanceof Error ? e.message : \"Payment capture failed\"\r\n setError(msg)\r\n onError?.(msg)\r\n return\r\n }\r\n // Past this point the buyer has been charged: completion failures\r\n // surface a finalize-only Retry, never a fresh payment.\r\n await finalizeCapturedPayment()\r\n }}\r\n onCancel={() => {\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n }}\r\n onError={(err: Error | { message?: string }) => {\r\n hideProcessingOverlay()\r\n setProcessing(false)\r\n const msg = err instanceof Error ? err.message : err?.message || \"PayPal error\"\r\n setError(msg)\r\n onError?.(msg)\r\n }}\r\n />\r\n </div>\r\n )}\r\n\r\n {completionPending && (\r\n <button\r\n type=\"button\"\r\n onClick={() => void finalizeCapturedPayment()}\r\n disabled={processing}\r\n aria-busy={processing}\r\n style={{\r\n width: \"100%\",\r\n padding: \"12px 16px\",\r\n marginTop: 4,\r\n background: \"#0070ba\",\r\n color: \"#ffffff\",\r\n border: \"none\",\r\n borderRadius: 8,\r\n fontSize: 14,\r\n fontWeight: 600,\r\n cursor: processing ? \"not-allowed\" : \"pointer\",\r\n opacity: processing ? 0.7 : 1,\r\n }}\r\n >\r\n Retry — finish placing my order\r\n </button>\r\n )}\r\n\r\n {error ? (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n marginTop: 10,\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>{error}</span>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n}\r\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","/**\r\n * Detect Next.js router errors (redirect / notFound) that must be re-thrown.\r\n *\r\n * Next.js implements redirect() and notFound() by throwing special errors with\r\n * a `digest` property starting with \"NEXT_REDIRECT\" or \"NEXT_NOT_FOUND\".\r\n * Catching these in user-land try/catch blocks prevents the navigation from\r\n * happening. Because this package can't import from `next` (it's a peer dep),\r\n * we detect them by duck-typing the digest.\r\n */\r\nexport function isNextRouterError(e: unknown): boolean {\r\n if (typeof e !== \"object\" || e === null || !(\"digest\" in e)) return false\r\n const digest = (e as { digest: unknown }).digest\r\n return (\r\n typeof digest === \"string\" &&\r\n (digest.startsWith(\"NEXT_REDIRECT\") ||\r\n digest.startsWith(\"NEXT_NOT_FOUND\") ||\r\n // Next.js 15: notFound()/forbidden()/unauthorized() throw\r\n // HTTPAccessFallbackError with digest \"NEXT_HTTP_ERROR_FALLBACK;<status>\".\r\n digest.startsWith(\"NEXT_HTTP_ERROR_FALLBACK\"))\r\n )\r\n}\r\n","const OVERLAY_ID = \"__pp_processing_overlay\"\r\n\r\nlet cleanupNavListener: (() => void) | null = null\r\n\r\nexport function showProcessingOverlay() {\r\n if (typeof document === \"undefined\") return\r\n if (document.getElementById(OVERLAY_ID)) return\r\n\r\n const overlay = document.createElement(\"div\")\r\n overlay.id = OVERLAY_ID\r\n overlay.setAttribute(\"role\", \"status\")\r\n overlay.setAttribute(\"aria-label\", \"Processing payment\")\r\n\r\n overlay.innerHTML = `\r\n <style>\r\n @keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n @keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n </style>\r\n <div style=\"position:relative;width:56px;height:56px\">\r\n <div style=\"position:absolute;inset:0;border-radius:50%;border:3px solid #e5e7eb\"></div>\r\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>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0070ba\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n style=\"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:24px;height:24px\">\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>\r\n </svg>\r\n </div>\r\n <div style=\"text-align:center\">\r\n <div style=\"font-size:18px;font-weight:600;color:#111827;letter-spacing:-0.01em\">Processing your payment</div>\r\n <div style=\"font-size:14px;color:#6b7280;margin-top:6px;line-height:1.5\">\r\n This may take a few moments. Please do not close<br>or refresh this page.\r\n </div>\r\n </div>\r\n <div style=\"width:200px;height:3px;background:#e5e7eb;border-radius:3px;overflow:hidden;margin-top:4px\">\r\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>\r\n </div>\r\n `\r\n\r\n Object.assign(overlay.style, {\r\n position: \"fixed\",\r\n inset: \"0\",\r\n zIndex: \"99999\",\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: \"20px\",\r\n fontFamily: \"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif\",\r\n })\r\n\r\n document.body.appendChild(overlay)\r\n\r\n // Auto-remove on client-side navigation (Next.js App Router uses\r\n // pushState/replaceState for soft navigations, not full reloads).\r\n const startUrl = location.href\r\n const onNav = () => {\r\n if (location.href !== startUrl) hideProcessingOverlay()\r\n }\r\n window.addEventListener(\"popstate\", onNav)\r\n\r\n const origPush = history.pushState.bind(history)\r\n const origReplace = history.replaceState.bind(history)\r\n history.pushState = function (...args) {\r\n origPush(...args)\r\n onNav()\r\n }\r\n history.replaceState = function (...args) {\r\n origReplace(...args)\r\n onNav()\r\n }\r\n\r\n // bfcache restore: the overlay intentionally survives the unload of a\r\n // full-page navigation (that's its purpose), but when the buyer presses\r\n // Back the browser restores this page from the back/forward cache with the\r\n // overlay element still in the DOM and the URL equal to startUrl — no nav\r\n // listener ever fires, leaving checkout permanently covered. `pageshow`\r\n // with `persisted: true` is exactly that restore.\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) hideProcessingOverlay()\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n\r\n cleanupNavListener = () => {\r\n window.removeEventListener(\"popstate\", onNav)\r\n window.removeEventListener(\"pageshow\", onPageShow)\r\n history.pushState = origPush\r\n history.replaceState = origReplace\r\n }\r\n}\r\n\r\nexport function hideProcessingOverlay() {\r\n if (typeof document === \"undefined\") return\r\n cleanupNavListener?.()\r\n cleanupNavListener = null\r\n document.getElementById(OVERLAY_ID)?.remove()\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useMemo, useRef, useState } from \"react\"\r\nimport {\r\n PayPalCardFieldsProvider,\r\n PayPalNumberField,\r\n PayPalExpiryField,\r\n PayPalCVVField,\r\n usePayPalCardFields,\r\n usePayPalScriptReducer,\r\n} from \"@paypal/react-paypal-js\"\r\n\r\nimport { createPayPalStoreApi, markPaymentComplete } from \"../client/paypal\"\r\nimport type { PayPalConfig } from \"../client/types\"\r\nimport {\r\n clearCartCaptured,\r\n markCartCaptured,\r\n wasCartCaptured,\r\n} from \"../utils/captured-state\"\r\nimport { isNextRouterError } from \"../utils/next-errors\"\r\nimport { showProcessingOverlay, hideProcessingOverlay } from \"../utils/processing-overlay\"\r\n\r\nconst SPIN_STYLE = `\r\n@keyframes _pp_spin { to { transform: rotate(360deg) } }\r\n@keyframes _pp_progress { 0% { transform: translateX(-100%) } 100% { transform: translateX(350%) } }\r\n`\r\n\r\nconst cardStyle = {\r\n input: {\r\n \"font-size\": \"15px\",\r\n \"font-family\": \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n \"font-weight\": \"400\",\r\n color: \"#111827\",\r\n padding: \"0 14px\",\r\n height: \"42px\",\r\n \"border-radius\": \"8px\",\r\n border: \"1px solid #d1d5db\",\r\n background: \"#ffffff\",\r\n \"box-shadow\": \"none\",\r\n transition: \"border-color 0.15s ease\",\r\n },\r\n \"::placeholder\": {\r\n color: \"#9ca3af\",\r\n },\r\n \".invalid\": {\r\n color: \"#dc2626\",\r\n border: \"1px solid #fca5a5\",\r\n background: \"#fff7f7\",\r\n \"box-shadow\": \"none\",\r\n },\r\n \".valid\": {\r\n color: \"#111827\",\r\n border: \"1px solid #d1d5db\",\r\n \"box-shadow\": \"none\",\r\n },\r\n \"input:focus\": {\r\n outline: \"none\",\r\n border: \"1px solid #2563eb\",\r\n \"box-shadow\": \"0 0 0 3px rgba(37,99,235,0.12)\",\r\n },\r\n}\r\n\r\nconst labelStyle: React.CSSProperties = {\r\n display: \"block\",\r\n fontSize: 13,\r\n fontWeight: 500,\r\n color: \"#374151\",\r\n marginBottom: 6,\r\n letterSpacing: \"0.01em\",\r\n}\r\n\r\nfunction SubmitButton({\r\n disabled,\r\n label,\r\n onSubmit,\r\n onSubmitError,\r\n}: {\r\n disabled: boolean\r\n label: string\r\n onSubmit: () => void\r\n onSubmitError: (message: string) => void\r\n}) {\r\n const { cardFieldsForm } = usePayPalCardFields()\r\n const isDisabled = disabled || !cardFieldsForm\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n disabled={isDisabled}\r\n aria-busy={disabled}\r\n onClick={() => {\r\n onSubmit()\r\n // submit() returns a promise and its rejection is NOT routed to the\r\n // provider's onError — PayPal's contract is that the caller catches\r\n // it. A sync try/catch here would miss it entirely, leaving the buyer\r\n // stuck under the full-screen processing overlay forever (e.g. on a\r\n // card-field validation error).\r\n Promise.resolve(cardFieldsForm?.submit()).catch((e: unknown) => {\r\n const msg =\r\n e instanceof Error && e.message\r\n ? e.message\r\n : \"Card payment could not be submitted. Please check your card details.\"\r\n onSubmitError(msg)\r\n })\r\n }}\r\n style={{\r\n width: \"100%\",\r\n height: 48,\r\n padding: \"0 20px\",\r\n borderRadius: 8,\r\n border: \"none\",\r\n background: isDisabled\r\n ? \"#e5e7eb\"\r\n : \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\",\r\n color: isDisabled ? \"#9ca3af\" : \"#ffffff\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n fontFamily: \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n cursor: isDisabled ? \"not-allowed\" : \"pointer\",\r\n letterSpacing: \"0.01em\",\r\n boxShadow: isDisabled\r\n ? \"none\"\r\n : \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\",\r\n transition: \"all 0.15s ease\",\r\n }}\r\n onMouseEnter={(e) => {\r\n if (!isDisabled) {\r\n ;(e.target as HTMLButtonElement).style.background =\r\n \"linear-gradient(180deg, #1d4ed8 0%, #1e40af 100%)\"\r\n ;(e.target as HTMLButtonElement).style.boxShadow =\r\n \"0 4px 6px rgba(37,99,235,0.35), 0 2px 4px rgba(0,0,0,0.06)\"\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isDisabled) {\r\n ;(e.target as HTMLButtonElement).style.background =\r\n \"linear-gradient(180deg, #2563eb 0%, #1d4ed8 100%)\"\r\n ;(e.target as HTMLButtonElement).style.boxShadow =\r\n \"0 1px 3px rgba(37,99,235,0.3), 0 1px 2px rgba(0,0,0,0.06)\"\r\n }\r\n }}\r\n >\r\n {label}\r\n </button>\r\n )\r\n}\r\n\r\nexport function PayPalAdvancedCard(props: {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId: string\r\n config: PayPalConfig\r\n onPaid?: (result: Record<string, unknown>) => void\r\n onError?: (message: string) => void\r\n}) {\r\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\r\n\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const [error, setError] = useState<string | null>(null)\r\n const [submitting, setSubmitting] = useState(false)\r\n const submittingRef = useRef(false)\r\n const creatingOrderRef = useRef(false)\r\n // Once a capture succeeded the buyer's money is taken: any later failure\r\n // must retry ONLY the order finalization, never a fresh order/capture.\r\n const capturedRef = useRef<Record<string, unknown> | null>(null)\r\n const [completionPending, setCompletionPending] = useState(false)\r\n const [{ isPending, isResolved, isRejected }] = usePayPalScriptReducer()\r\n\r\n const resetSubmitState = React.useCallback(() => {\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }, [])\r\n\r\n // bfcache restore (Back button after a redirect) revives this page with the\r\n // old React state — clear the submitting flag so the buyer isn't stuck\r\n // behind the in-component overlay.\r\n React.useEffect(() => {\r\n const onPageShow = (e: PageTransitionEvent) => {\r\n if (e.persisted) {\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }\r\n }\r\n window.addEventListener(\"pageshow\", onPageShow)\r\n return () => window.removeEventListener(\"pageshow\", onPageShow)\r\n }, [])\r\n\r\n // A reload/crash between capture and finalization loses the in-memory\r\n // capturedRef — restore it from the persisted per-cart flag so the buyer\r\n // gets the finalize-only Retry button instead of card fields that would\r\n // charge (or confusingly fail) again.\r\n React.useEffect(() => {\r\n if (capturedRef.current || !wasCartCaptured(cartId)) return\r\n capturedRef.current = {}\r\n setCompletionPending(true)\r\n setError(\r\n \"Your payment was already received for this cart. Please use the button below to finish placing your order — do not pay again.\"\r\n )\r\n }, [cartId])\r\n\r\n const finalizeCapturedPayment = React.useCallback(async () => {\r\n const captured = capturedRef.current\r\n if (!captured) return\r\n setSubmitting(true)\r\n showProcessingOverlay()\r\n setError(null)\r\n try {\r\n const completeResult = await markPaymentComplete(baseUrl, cartId, publishableApiKey)\r\n // The order is finalized — the persisted \"captured\" flag has served its\r\n // purpose. Clear it before the consumer callback (which may redirect).\r\n clearCartCaptured(cartId)\r\n await onPaid?.({ ...captured, ...completeResult })\r\n setCompletionPending(false)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n resetSubmitState()\r\n setCompletionPending(true)\r\n const msg =\r\n \"Your payment was received, but finalizing your order failed. Please use the Retry button below — do not pay again.\"\r\n setError(msg)\r\n onError?.(msg)\r\n }\r\n }, [baseUrl, cartId, publishableApiKey, onPaid, onError, resetSubmitState])\r\n\r\n if (!config.currency_supported) return null\r\n\r\n if (isRejected) {\r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 8,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, fontSize: 15 }}>⚠️</span>\r\n <span>\r\n PayPal failed to load. Please refresh the page or try a different\r\n payment method.\r\n </span>\r\n </div>\r\n )\r\n }\r\n\r\n if (!config.client_token) {\r\n return (\r\n <div\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#fefce8\",\r\n border: \"1px solid #fde68a\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#92400e\",\r\n }}\r\n >\r\n Card fields unavailable — missing client token from backend.\r\n </div>\r\n )\r\n }\r\n\r\n const isSandbox = config.environment === \"sandbox\"\r\n\r\n if (isPending) {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Loading PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 10,\r\n padding: \"18px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 8,\r\n minHeight: 55,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#6b7280\" }}>\r\n Loading card fields…\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n if (!isResolved) return null\r\n\r\n return (\r\n <div style={{ position: \"relative\" }}>\r\n <style>{SPIN_STYLE}</style>\r\n\r\n {submitting && (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Processing payment\"\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n zIndex: 9999,\r\n background: \"rgba(255,255,255,0.96)\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n gap: 20,\r\n }}\r\n >\r\n <div style={{ position: \"relative\", width: 56, height: 56 }}>\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid #e5e7eb\",\r\n }}\r\n />\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n inset: 0,\r\n borderRadius: \"50%\",\r\n border: \"3px solid transparent\",\r\n borderTopColor: \"#2563eb\",\r\n animation: \"_pp_spin .8s linear infinite\",\r\n }}\r\n />\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#2563eb\"\r\n strokeWidth=\"1.8\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{\r\n position: \"absolute\",\r\n top: \"50%\",\r\n left: \"50%\",\r\n transform: \"translate(-50%, -50%)\",\r\n width: 24,\r\n height: 24,\r\n }}\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n </div>\r\n <div style={{ textAlign: \"center\" }}>\r\n <div style={{ fontSize: 18, fontWeight: 600, color: \"#111827\", letterSpacing: \"-0.01em\" }}>\r\n Processing your payment\r\n </div>\r\n <div style={{ fontSize: 14, color: \"#6b7280\", marginTop: 6, lineHeight: 1.5 }}>\r\n This may take a few moments. Please do not close<br />\r\n or refresh this page.\r\n </div>\r\n </div>\r\n <div\r\n style={{\r\n width: 200,\r\n height: 3,\r\n background: \"#e5e7eb\",\r\n borderRadius: 3,\r\n overflow: \"hidden\",\r\n marginTop: 4,\r\n }}\r\n >\r\n <div\r\n style={{\r\n width: \"40%\",\r\n height: \"100%\",\r\n background: \"linear-gradient(90deg, #2563eb, #1d4ed8)\",\r\n borderRadius: 3,\r\n animation: \"_pp_progress 1.5s ease-in-out infinite\",\r\n }}\r\n />\r\n </div>\r\n </div>\r\n )}\r\n\r\n <PayPalCardFieldsProvider\r\n style={cardStyle}\r\n createOrder={async () => {\r\n if (creatingOrderRef.current) throw new Error(\"Payment already processing\")\r\n if (capturedRef.current) {\r\n // Money was already captured for this cart — retry the order\r\n // finalization instead of creating (and charging) a new order.\r\n void finalizeCapturedPayment()\r\n throw new Error(\"Your payment was already received — finalizing your order.\")\r\n }\r\n creatingOrderRef.current = true\r\n try {\r\n setError(null)\r\n const r = await api.createOrder(cartId, true)\r\n return r.id\r\n } catch (e) {\r\n creatingOrderRef.current = false\r\n throw e\r\n }\r\n }}\r\n onApprove={async (data: { orderID?: string }) => {\r\n try {\r\n setError(null)\r\n showProcessingOverlay()\r\n const orderId = String(data?.orderID || \"\")\r\n if (!orderId) throw new Error(\"PayPal order ID is missing from approval response\")\r\n const result = await api.captureOrder(cartId, orderId)\r\n capturedRef.current = (result || {}) as Record<string, unknown>\r\n // Persist across reloads: from here on, only finalization may\r\n // ever be retried for this cart — never a fresh payment.\r\n markCartCaptured(cartId)\r\n } catch (e: unknown) {\r\n if (isNextRouterError(e)) return\r\n resetSubmitState()\r\n const msg = e instanceof Error ? e.message : \"Card payment failed\"\r\n setError(msg)\r\n onError?.(msg)\r\n return\r\n }\r\n // Past this point the buyer has been charged: completion failures\r\n // surface a finalize-only Retry, never a fresh payment.\r\n await finalizeCapturedPayment()\r\n }}\r\n onCancel={() => {\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }}\r\n onError={(e: Error | { message?: string }) => {\r\n const msg = e instanceof Error ? e.message : e?.message || \"CardFields error\"\r\n setError(msg)\r\n onError?.(msg)\r\n hideProcessingOverlay()\r\n creatingOrderRef.current = false\r\n submittingRef.current = false\r\n setSubmitting(false)\r\n }}\r\n >\r\n <div\r\n style={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: 16,\r\n width: \"100%\",\r\n }}\r\n >\r\n {isSandbox && (\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 10,\r\n padding: \"10px 14px\",\r\n background: \"#eff6ff\",\r\n border: \"1px solid #bfdbfe\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#1e40af\",\r\n lineHeight: 1.55,\r\n }}\r\n >\r\n <span style={{ fontSize: 15, flexShrink: 0, marginTop: 1 }}>🧪</span>\r\n <span>\r\n Sandbox mode — use test card{\" \"}\r\n <strong style={{ fontFamily: \"monospace\", letterSpacing: \"0.05em\" }}>\r\n 4111 1111 1111 1111\r\n </strong>{\" \"}\r\n with any future date and any CVV.\r\n </span>\r\n </div>\r\n )}\r\n\r\n <div>\r\n <label style={labelStyle}>Card number</label>\r\n <PayPalNumberField />\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"1fr 1fr\",\r\n gap: 16,\r\n }}\r\n >\r\n <div>\r\n <label style={labelStyle}>Expiration date</label>\r\n <PayPalExpiryField />\r\n </div>\r\n <div>\r\n <label style={labelStyle}>Security code</label>\r\n <PayPalCVVField />\r\n </div>\r\n </div>\r\n\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 6,\r\n fontSize: 12,\r\n color: \"#6b7280\",\r\n }}\r\n >\r\n <svg\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"#10b981\"\r\n strokeWidth=\"2.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\r\n </svg>\r\n <span>Your payment is secured with 256-bit SSL encryption</span>\r\n </div>\r\n\r\n {completionPending ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => void finalizeCapturedPayment()}\r\n disabled={submitting}\r\n aria-busy={submitting}\r\n style={{\r\n width: \"100%\",\r\n height: 48,\r\n padding: \"0 20px\",\r\n borderRadius: 8,\r\n border: \"none\",\r\n background: \"#0070ba\",\r\n color: \"#ffffff\",\r\n fontSize: 15,\r\n fontWeight: 600,\r\n cursor: submitting ? \"not-allowed\" : \"pointer\",\r\n opacity: submitting ? 0.7 : 1,\r\n }}\r\n >\r\n Retry — finish placing my order\r\n </button>\r\n ) : (\r\n <SubmitButton\r\n disabled={submitting}\r\n label={submitting ? \"Processing…\" : \"Pay by Card\"}\r\n onSubmit={() => {\r\n if (submittingRef.current) return\r\n submittingRef.current = true\r\n setError(null)\r\n setSubmitting(true)\r\n showProcessingOverlay()\r\n }}\r\n onSubmitError={(msg) => {\r\n resetSubmitState()\r\n setError(msg)\r\n onError?.(msg)\r\n }}\r\n />\r\n )}\r\n\r\n {error && (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"flex-start\",\r\n gap: 10,\r\n padding: \"10px 14px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 8,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n lineHeight: 1.5,\r\n }}\r\n >\r\n <span style={{ flexShrink: 0, marginTop: 1 }}>⚠️</span>\r\n <span>{error}</span>\r\n </div>\r\n )}\r\n </div>\r\n </PayPalCardFieldsProvider>\r\n </div>\r\n )\r\n}\r\n","\"use client\"\r\n\r\nimport React, { useCallback } from \"react\"\r\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\r\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\r\nimport { PayPalProvider } from \"../components/PayPalProvider\"\r\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\r\nimport {\r\n PAYPAL_WALLET_PROVIDER_ID as DEFAULT_PAYPAL_PROVIDER_ID,\r\n PAYPAL_CARD_PROVIDER_ID as DEFAULT_PAYPAL_CARD_PROVIDER_ID,\r\n} from \"../constants\"\r\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\r\n\r\nconst SPIN_STYLE = `@keyframes _pp_spin { to { transform: rotate(360deg) } }`\r\n\r\nfunction PayPalLoadingCard() {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Connecting to PayPal\"\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 12,\r\n padding: \"14px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 10,\r\n }}\r\n >\r\n <style>{SPIN_STYLE}</style>\r\n <div\r\n style={{\r\n width: 22,\r\n height: 22,\r\n borderRadius: \"50%\",\r\n border: \"2.5px solid #e5e7eb\",\r\n borderTopColor: \"#0070ba\",\r\n animation: \"_pp_spin .7s linear infinite\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n <div>\r\n <div style={{ fontSize: 13, fontWeight: 500, color: \"#111827\" }}>\r\n Connecting to PayPal…\r\n </div>\r\n <div style={{ fontSize: 12, color: \"#6b7280\", marginTop: 2 }}>\r\n Setting up secure payment\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction PayPalErrorCard({ message }: { message: string }) {\r\n return (\r\n <div\r\n role=\"alert\"\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#fef2f2\",\r\n border: \"1px solid #fecaca\",\r\n borderRadius: 10,\r\n fontSize: 13,\r\n color: \"#b91c1c\",\r\n }}\r\n >\r\n {message}\r\n </div>\r\n )\r\n}\r\n\r\n/**\r\n * Shown when the merchant has disabled the selected PayPal method in admin\r\n * settings. Rendering nothing here (the old behavior) left the buyer staring\r\n * at blank space under a selected payment option.\r\n */\r\nfunction PayPalUnavailableCard({ label }: { label: string }) {\r\n return (\r\n <div\r\n role=\"status\"\r\n style={{\r\n padding: \"12px 16px\",\r\n background: \"#f9fafb\",\r\n border: \"1px solid #e5e7eb\",\r\n borderRadius: 10,\r\n fontSize: 13,\r\n color: \"#6b7280\",\r\n }}\r\n >\r\n {label} is currently unavailable. Please choose a different payment\r\n method.\r\n </div>\r\n )\r\n}\r\n\r\nexport type MedusaNextPayPalAdapterProps = {\r\n cartId: string\r\n selectedProviderId: string | null | undefined\r\n baseUrl: string\r\n publishableApiKey?: string\r\n providerIds?: {\r\n paypal?: string\r\n paypalCard?: string\r\n }\r\n onSuccess?: (cartId: string) => void\r\n onError?: (message: string) => void\r\n onPaid?: (result: unknown) => void\r\n}\r\n\r\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\r\n const {\r\n cartId,\r\n selectedProviderId,\r\n baseUrl,\r\n publishableApiKey,\r\n providerIds,\r\n onSuccess,\r\n onError,\r\n onPaid,\r\n } = props\r\n\r\n const paypalProviderId = providerIds?.paypal || DEFAULT_PAYPAL_PROVIDER_ID\r\n const paypalCardProviderId = providerIds?.paypalCard || DEFAULT_PAYPAL_CARD_PROVIDER_ID\r\n\r\n const shouldRender =\r\n selectedProviderId === paypalProviderId ||\r\n selectedProviderId === paypalCardProviderId\r\n\r\n const { config, loading, error } = usePayPalConfig({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled: shouldRender,\r\n })\r\n\r\n const handlePaid = useCallback(\r\n async (captureResult: unknown) => {\r\n onPaid?.(captureResult)\r\n await onSuccess?.(cartId)\r\n },\r\n [cartId, onPaid, onSuccess]\r\n )\r\n\r\n if (!shouldRender) return null\r\n\r\n if (loading) return <PayPalLoadingCard />\r\n\r\n if (error) return <PayPalErrorCard message={error} />\r\n\r\n if (!config) return null\r\n\r\n const isCardProvider = selectedProviderId === paypalCardProviderId\r\n if (config.paypal_enabled === false && !isCardProvider) {\r\n return <PayPalUnavailableCard label={config.paypal_title || \"PayPal\"} />\r\n }\r\n if (isCardProvider && config.card_enabled === false) {\r\n return <PayPalUnavailableCard label={config.card_title || \"Card payment\"} />\r\n }\r\n\r\n const disableFunding = Array.isArray(config.disable_buttons)\r\n ? config.disable_buttons.join(\",\")\r\n : undefined\r\n\r\n return (\r\n <div key={selectedProviderId} style={{ display: \"grid\", gap: 12 }}>\r\n <PayPalCurrencyNotice config={config} />\r\n <PayPalProvider\r\n config={config}\r\n intent={config.intent === \"authorize\" ? \"authorize\" : \"capture\"}\r\n disableFunding={disableFunding}\r\n >\r\n {isCardProvider ? (\r\n <PayPalAdvancedCard\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n ) : (\r\n <PayPalSmartButtons\r\n baseUrl={baseUrl}\r\n publishableApiKey={publishableApiKey}\r\n cartId={cartId}\r\n config={config}\r\n onPaid={handlePaid}\r\n onError={onError}\r\n />\r\n )}\r\n </PayPalProvider>\r\n </div>\r\n )\r\n}\r\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\n/** True when the provider id belongs to this PayPal plugin. */\nexport function isPayPalProviderId(providerId?: string | null): boolean {\n if (!providerId) return false\n return PAYPAL_PROVIDER_IDS.includes(\n providerId as (typeof PAYPAL_PROVIDER_IDS)[number]\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 { PAYPAL_WALLET_PROVIDER_ID, PAYPAL_CARD_PROVIDER_ID, isPayPalProviderId }\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\"\r\n\r\n\r\nimport { useEffect, useMemo, useRef, useState } from \"react\"\r\nimport { createPayPalStoreApi } from \"../client/paypal\"\r\n\r\ntype Args = {\r\n baseUrl: string\r\n publishableApiKey?: string\r\n cartId?: string\r\n enabled?: boolean\r\n}\r\n\r\ntype Result = {\r\n paypalEnabled: boolean\r\n paypalTitle: string\r\n cardEnabled: boolean\r\n cardTitle: string\r\n loading: boolean\r\n /**\r\n * Non-null when the config fetch failed and the returned flags are the\r\n * optimistic defaults rather than the merchant's real settings. Storefronts\r\n * can use this to hide or annotate the PayPal options instead of advertising\r\n * methods that will fail once selected.\r\n */\r\n error: string | null\r\n}\r\n\r\nconst MAX_CACHE_ENTRIES = 50\r\nconst _cache = new Map<string, { result: Result; at: number }>()\r\nconst CACHE_TTL = 5 * 60 * 1000\r\n\r\nfunction cacheSet(key: string, value: { result: Result; at: number }) {\r\n if (_cache.size >= MAX_CACHE_ENTRIES) {\r\n const oldest = _cache.keys().next().value\r\n if (oldest !== undefined) _cache.delete(oldest)\r\n }\r\n _cache.set(key, value)\r\n}\r\n\r\nfunction cacheKey(baseUrl: string, cartId?: string) {\r\n return `ppm::${baseUrl}::${cartId ?? \"\"}`\r\n}\r\n\r\nconst DEFAULT_RESULT: Result = {\r\n paypalEnabled: true,\r\n paypalTitle: \"PayPal\",\r\n cardEnabled: true,\r\n cardTitle: \"Credit or Debit Card\",\r\n loading: false,\r\n error: null,\r\n}\r\n\r\nexport function usePayPalPaymentMethods({\r\n baseUrl,\r\n publishableApiKey,\r\n cartId,\r\n enabled = true,\r\n}: Args): Result {\r\n const api = useMemo(\r\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\r\n [baseUrl, publishableApiKey]\r\n )\r\n\r\n const key = cacheKey(baseUrl, cartId)\r\n const hit = _cache.get(key)\r\n const seed = hit && Date.now() - hit.at < CACHE_TTL ? hit.result : null\r\n\r\n const [result, setResult] = useState<Result>(seed ?? { ...DEFAULT_RESULT, loading: enabled })\r\n const fetchIdRef = useRef(0)\r\n\r\n useEffect(() => {\r\n if (!enabled) {\r\n setResult((prev) => ({ ...prev, loading: false }))\r\n return\r\n }\r\n\r\n const k = cacheKey(baseUrl, cartId)\r\n const cached = _cache.get(k)\r\n if (cached && Date.now() - cached.at < CACHE_TTL) {\r\n setResult(cached.result)\r\n return\r\n }\r\n\r\n const id = ++fetchIdRef.current\r\n let mounted = true\r\n const controller = new AbortController()\r\n\r\n setResult((prev) => ({ ...prev, loading: true }))\r\n\r\n ;(async () => {\r\n try {\r\n const cfg = await api.getConfig(cartId, controller.signal)\r\n if (!mounted || id !== fetchIdRef.current) return\r\n\r\n const next: Result = {\r\n paypalEnabled: cfg.paypal_enabled !== false,\r\n paypalTitle:\r\n typeof cfg.paypal_title === \"string\" && cfg.paypal_title\r\n ? cfg.paypal_title\r\n : \"PayPal\",\r\n cardEnabled: cfg.card_enabled !== false,\r\n cardTitle:\r\n typeof cfg.card_title === \"string\" && cfg.card_title\r\n ? cfg.card_title\r\n : \"Credit or Debit Card\",\r\n loading: false,\r\n error: null,\r\n }\r\n\r\n cacheSet(k, { result: next, at: Date.now() })\r\n setResult(next)\r\n } catch (e: unknown) {\r\n const msg = e instanceof Error ? e.message : \"\"\r\n if (e instanceof Error && e.name === \"AbortError\") return\r\n if (!mounted || id !== fetchIdRef.current) return\r\n\r\n if (msg.includes(\"403\") || msg.includes(\"Forbidden\")) {\r\n const disabled: Result = {\r\n ...DEFAULT_RESULT,\r\n paypalEnabled: false,\r\n cardEnabled: false,\r\n loading: false,\r\n error: msg || \"PayPal is disabled\",\r\n }\r\n setResult(disabled)\r\n return\r\n }\r\n\r\n setResult({\r\n ...DEFAULT_RESULT,\r\n loading: false,\r\n error: msg || \"Failed to load PayPal payment methods\",\r\n })\r\n }\r\n })()\r\n\r\n return () => {\r\n mounted = false\r\n controller.abort()\r\n }\r\n }, [api, baseUrl, cartId, enabled])\r\n\r\n return result\r\n}\r\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"]}
|