diff --git a/.changeset/rude-melons-wear.md b/.changeset/rude-melons-wear.md new file mode 100644 index 00000000..0f41af11 --- /dev/null +++ b/.changeset/rude-melons-wear.md @@ -0,0 +1,8 @@ +--- +"@paypal/react-paypal-js": patch +--- + +- Default `PayPalProvider` `components` to `["paypal-payments"]`. +- Update session hooks to check `loadingStatus` before returning an error for no `sdkInstance`. +- `PayPalContext` export was removed since merchants won't need to use that directly. +- Check only `window` for `isServer` SSR function. diff --git a/packages/react-paypal-js/src/v6/components/PayPalProvider.test.tsx b/packages/react-paypal-js/src/v6/components/PayPalProvider.test.tsx index 1600ba84..054c7b89 100644 --- a/packages/react-paypal-js/src/v6/components/PayPalProvider.test.tsx +++ b/packages/react-paypal-js/src/v6/components/PayPalProvider.test.tsx @@ -57,19 +57,26 @@ const createInstanceOptions: CreateInstanceOptions<["paypal-payments"]> = { }; function renderProvider( - instanceOptions = createInstanceOptions, - environment: "sandbox" | "production" = "sandbox", - debug = false, - children?: React.ReactNode, + props: Partial> = {}, ) { const { state, TestComponent } = setupTestComponent(); + const { + children, + clientToken = createInstanceOptions.clientToken, + components = createInstanceOptions.components, + debug = false, + environment = "sandbox", + ...restProps + } = props; + const result = render( {children} , @@ -184,7 +191,7 @@ describe("PayPalProvider", () => { return Promise.resolve(createMockPayPalNamespace()); }); - renderProvider(createInstanceOptions, environment); + renderProvider({ environment, ...createInstanceOptions }); expect(loadCoreSdkScript).toHaveBeenCalledWith({ environment, @@ -220,6 +227,29 @@ describe("PayPalProvider", () => { ); }); + test("should use default components array when not provided", async () => { + const mockCreateInstance = jest + .fn() + .mockResolvedValue(createMockSdkInstance()); + + (loadCoreSdkScript as jest.Mock).mockResolvedValue({ + createInstance: mockCreateInstance, + }); + + const { state } = renderProvider({ + clientToken: TEST_CLIENT_TOKEN, + }); + + await waitFor(() => expectResolvedState(state)); + + expect(mockCreateInstance).toHaveBeenCalledWith( + expect.objectContaining({ + components: ["paypal-payments"], + clientToken: TEST_CLIENT_TOKEN, + }), + ); + }); + test("should handle createInstance failure", async () => { const instanceError = new Error("Instance creation failed"); const mockCreateInstance = jest @@ -255,7 +285,6 @@ describe("PayPalProvider", () => { (loadCoreSdkScript as jest.Mock).mockResolvedValue({ createInstance: mockCreateInstance, }); - // @ts-expect-error renderProvider is typed for single component only const { state } = renderProvider(multiComponentOptions); await waitFor(() => expectResolvedState(state)); diff --git a/packages/react-paypal-js/src/v6/components/PayPalProvider.tsx b/packages/react-paypal-js/src/v6/components/PayPalProvider.tsx index 51a12bc0..989ab1c2 100644 --- a/packages/react-paypal-js/src/v6/components/PayPalProvider.tsx +++ b/packages/react-paypal-js/src/v6/components/PayPalProvider.tsx @@ -27,10 +27,12 @@ import type { import type { PayPalState } from "../context/PayPalProviderContext"; import type { usePayPal } from "../hooks/usePayPal"; -type PayPalProviderProps = CreateInstanceOptions< - readonly [Components, ...Components[]] +type PayPalProviderProps = Omit< + CreateInstanceOptions, + "components" > & LoadCoreSdkScriptOptions & { + components?: Components[]; eligibleMethodsResponse?: FindEligiblePaymentMethodsResponse; eligibleMethodsPayload?: FindEligiblePaymentMethodsRequestPayload; children: React.ReactNode; @@ -43,7 +45,7 @@ type PayPalProviderProps = CreateInstanceOptions< export const PayPalProvider: React.FC = ({ clientMetadataId, clientToken, - components, + components = ["paypal-payments"], locale, pageType, partnerAttributionId, diff --git a/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.test.ts b/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.test.ts index 761c016f..b8cbcb79 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.test.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.test.ts @@ -4,6 +4,7 @@ import { expectCurrentErrorValue } from "./useErrorTestUtil"; import { usePayPal } from "./usePayPal"; import { usePayLaterOneTimePaymentSession } from "./usePayLaterOneTimePaymentSession"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import type { OneTimePaymentSession } from "../types"; @@ -67,8 +68,16 @@ describe("usePayLaterOneTimePaymentSession", () => { }); }); - test("should error if there is no sdkInstance when called", () => { + test("should error if there is no sdkInstance when called and not create a session", () => { const mockOrderId = "123"; + const mockSession: OneTimePaymentSession = { + cancel: jest.fn(), + destroy: jest.fn(), + start: jest.fn(), + }; + const mockCreatePayLaterOneTimePaymentSession = jest + .fn() + .mockReturnValue(mockSession); (usePayPal as jest.Mock).mockReturnValue({ sdkInstance: null }); @@ -87,6 +96,74 @@ describe("usePayLaterOneTimePaymentSession", () => { expectCurrentErrorValue(error); expect(error).toEqual(new Error("no sdk instance available")); + expect(mockCreatePayLaterOneTimePaymentSession).not.toHaveBeenCalled(); + }); + + test("should not error if there is no sdkInstance but loading is still pending", () => { + const mockOrderId = "123"; + + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.PENDING, + }); + + const { + result: { + current: { error }, + }, + } = renderHook(() => + usePayLaterOneTimePaymentSession({ + presentationMode: "auto", + orderId: mockOrderId, + onApprove: jest.fn(), + }), + ); + + expect(error).toBeNull(); + }); + + test("should clear any sdkInstance related errors if the sdkInstance becomes available", () => { + const mockOrderId = "123"; + const mockSession: OneTimePaymentSession = { + cancel: jest.fn(), + destroy: jest.fn(), + start: jest.fn(), + }; + const mockCreatePayLaterOneTimePaymentSession = jest + .fn() + .mockReturnValue(mockSession); + + // First render: no sdkInstance, should error + (usePayPal as jest.Mock).mockReturnValueOnce({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, + }); + + const { result, rerender } = renderHook(() => + usePayLaterOneTimePaymentSession({ + presentationMode: "auto", + orderId: mockOrderId, + onApprove: jest.fn(), + }), + ); + + expectCurrentErrorValue(result.current.error); + expect(result.current.error).toEqual( + new Error("no sdk instance available"), + ); + + // Second render: sdkInstance becomes available, error should clear + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: { + createPayLaterOneTimePaymentSession: + mockCreatePayLaterOneTimePaymentSession, + }, + loadingStatus: INSTANCE_LOADING_STATE.RESOLVED, + }); + + rerender(); + + expect(result.current.error).toBeNull(); }); test("should provide a click handler that calls session start", async () => { diff --git a/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.ts b/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.ts index e01068c2..469cd630 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayLaterOneTimePaymentSession.ts @@ -4,6 +4,7 @@ import { usePayPal } from "./usePayPal"; import { useIsMountedRef } from "./useIsMounted"; import { useError } from "./useError"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import type { BasePaymentSessionReturn, @@ -33,7 +34,7 @@ export function usePayLaterOneTimePaymentSession({ orderId, ...callbacks }: PayLaterOneTimePaymentSessionProps): BasePaymentSessionReturn { - const { sdkInstance } = usePayPal(); + const { sdkInstance, loadingStatus } = usePayPal(); const isMountedRef = useIsMountedRef(); const sessionRef = useRef(null); // handle cleanup const proxyCallbacks = useProxyProps(callbacks); @@ -46,10 +47,12 @@ export function usePayLaterOneTimePaymentSession({ // Separate error reporting effect to avoid infinite loops with proxyCallbacks useEffect(() => { - if (!sdkInstance) { + if (sdkInstance) { + setError(null); + } else if (loadingStatus !== INSTANCE_LOADING_STATE.PENDING) { setError(new Error("no sdk instance available")); } - }, [sdkInstance, setError]); + }, [sdkInstance, setError, loadingStatus]); useEffect(() => { if (!sdkInstance) { diff --git a/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.test.ts b/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.test.ts index 13bf7b35..951e8ea2 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.test.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.test.ts @@ -53,10 +53,10 @@ describe("usePayPalOneTimePaymentSession", () => { }); describe("initialization", () => { - test("should error if there is no sdkInstance when called", () => { + test("should not create session when no SDK instance is available", () => { mockUsePayPal.mockReturnValue({ sdkInstance: null, - loadingStatus: INSTANCE_LOADING_STATE.PENDING, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, eligiblePaymentMethods: null, error: null, }); @@ -78,6 +78,73 @@ describe("usePayPalOneTimePaymentSession", () => { expectCurrentErrorValue(error); expect(error).toEqual(new Error("no sdk instance available")); + expect( + mockSdkInstance.createPayPalOneTimePaymentSession, + ).not.toHaveBeenCalled(); + }); + + test("should not error if there is no sdkInstance but loading is still pending", () => { + mockUsePayPal.mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.PENDING, + eligiblePaymentMethods: null, + error: null, + }); + + const props: UsePayPalOneTimePaymentSessionProps = { + presentationMode: "popup", + orderId: "test-order-id", + onApprove: jest.fn(), + }; + + const { + result: { + current: { error }, + }, + } = renderHook(() => usePayPalOneTimePaymentSession(props)); + + expect(error).toBeNull(); + }); + + test("should clear any sdkInstance related errors if the sdkInstance becomes available", () => { + const mockSession = createMockPayPalSession(); + const mockSdkInstanceNew = createMockSdkInstance(mockSession); + + // First render: no sdkInstance and not in PENDING state, should error + mockUsePayPal.mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, + eligiblePaymentMethods: null, + error: null, + }); + + const props: UsePayPalOneTimePaymentSessionProps = { + presentationMode: "popup", + orderId: "test-order-id", + onApprove: jest.fn(), + }; + + const { result, rerender } = renderHook(() => + usePayPalOneTimePaymentSession(props), + ); + + expectCurrentErrorValue(result.current.error); + expect(result.current.error).toEqual( + new Error("no sdk instance available"), + ); + + // Second render: sdkInstance becomes available, error should clear + mockUsePayPal.mockReturnValue({ + // @ts-expect-error mocking sdk instance + sdkInstance: mockSdkInstanceNew, + loadingStatus: INSTANCE_LOADING_STATE.RESOLVED, + eligiblePaymentMethods: null, + error: null, + }); + + rerender(); + + expect(result.current.error).toBeNull(); }); test("should create a PayPal payment session when the hook is called with orderId", () => { diff --git a/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.ts b/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.ts index 7bdce33c..c8a43543 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayPalOneTimePaymentSession.ts @@ -4,6 +4,7 @@ import { usePayPal } from "./usePayPal"; import { useIsMountedRef } from "./useIsMounted"; import { useError } from "./useError"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import { OneTimePaymentSession, PayPalPresentationModeOptions, @@ -31,7 +32,7 @@ export function usePayPalOneTimePaymentSession({ orderId, ...callbacks }: UsePayPalOneTimePaymentSessionProps): BasePaymentSessionReturn { - const { sdkInstance } = usePayPal(); + const { sdkInstance, loadingStatus } = usePayPal(); const isMountedRef = useIsMountedRef(); const sessionRef = useRef(null); const proxyCallbacks = useProxyProps(callbacks); @@ -48,10 +49,12 @@ export function usePayPalOneTimePaymentSession({ // Separate error reporting effect to avoid infinite loops with proxyCallbacks useEffect(() => { - if (!sdkInstance) { + if (sdkInstance) { + setError(null); + } else if (loadingStatus !== INSTANCE_LOADING_STATE.PENDING) { setError(new Error("no sdk instance available")); } - }, [sdkInstance, setError]); + }, [sdkInstance, setError, loadingStatus]); useEffect(() => { if (!sdkInstance) { diff --git a/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.test.ts b/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.test.ts index 07b46e65..882be4f2 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.test.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.test.ts @@ -4,6 +4,7 @@ import { expectCurrentErrorValue } from "./useErrorTestUtil"; import { usePayPal } from "./usePayPal"; import { usePayPalSavePaymentSession } from "./usePayPalSavePaymentSession"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import type { SavePaymentSession } from "../types"; @@ -112,10 +113,21 @@ describe("usePayPalSavePaymentSession", () => { }); }); - test("should error if there is no sdkInstance when called", () => { + test("should error if there is no sdkInstance when called and not create a session", () => { const mockVaultSetupToken = "vault-setup-token-123"; + const mockSession: SavePaymentSession = { + cancel: jest.fn(), + destroy: jest.fn(), + start: jest.fn(), + }; + const mockCreatePayPalSavePaymentSession = jest + .fn() + .mockReturnValue(mockSession); - (usePayPal as jest.Mock).mockReturnValue({ sdkInstance: null }); + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, + }); const { result: { @@ -132,6 +144,74 @@ describe("usePayPalSavePaymentSession", () => { expectCurrentErrorValue(error); expect(error).toEqual(new Error("no sdk instance available")); + expect(mockCreatePayPalSavePaymentSession).not.toHaveBeenCalled(); + }); + + test("should not error if there is no sdkInstance but loading is still pending", () => { + const mockVaultSetupToken = "vault-setup-token-123"; + + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.PENDING, + }); + + const { + result: { + current: { error }, + }, + } = renderHook(() => + usePayPalSavePaymentSession({ + presentationMode: "auto", + vaultSetupToken: mockVaultSetupToken, + onApprove: jest.fn(), + }), + ); + + expect(error).toBeNull(); + }); + + test("should clear any sdkInstance related errors if the sdkInstance becomes available", () => { + const mockVaultSetupToken = "vault-setup-token-123"; + const mockSession: SavePaymentSession = { + cancel: jest.fn(), + destroy: jest.fn(), + start: jest.fn(), + }; + const mockCreatePayPalSavePaymentSession = jest + .fn() + .mockReturnValue(mockSession); + + // First render: no sdkInstance and not in PENDING state, should error + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, + }); + + const { result, rerender } = renderHook(() => + usePayPalSavePaymentSession({ + presentationMode: "auto", + vaultSetupToken: mockVaultSetupToken, + onApprove: jest.fn(), + }), + ); + + expectCurrentErrorValue(result.current.error); + expect(result.current.error).toEqual( + new Error("no sdk instance available"), + ); + + // Second render: sdkInstance becomes available, error should clear + (usePayPal as jest.Mock).mockReturnValue({ + sdkInstance: { + createPayPalSavePaymentSession: + mockCreatePayPalSavePaymentSession, + }, + loadingStatus: INSTANCE_LOADING_STATE.RESOLVED, + }); + + rerender(); + + expect(result.current.error).toBeNull(); }); test("should provide a click handler that calls session start with vaultSetupToken", async () => { diff --git a/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.ts b/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.ts index bfed2285..f53fc2e4 100644 --- a/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.ts +++ b/packages/react-paypal-js/src/v6/hooks/usePayPalSavePaymentSession.ts @@ -4,6 +4,7 @@ import { usePayPal } from "./usePayPal"; import { useIsMountedRef } from "./useIsMounted"; import { useError } from "./useError"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import type { SavePaymentSession, @@ -32,7 +33,7 @@ export function usePayPalSavePaymentSession({ vaultSetupToken, ...callbacks }: PayPalSavePaymentSessionProps): BasePaymentSessionReturn { - const { sdkInstance } = usePayPal(); + const { sdkInstance, loadingStatus } = usePayPal(); const isMountedRef = useIsMountedRef(); const sessionRef = useRef(null); // handle cleanup const proxyCallbacks = useProxyProps(callbacks); @@ -45,10 +46,12 @@ export function usePayPalSavePaymentSession({ // Separate error reporting effect to avoid infinite loops with proxyCallbacks useEffect(() => { - if (!sdkInstance) { + if (sdkInstance) { + setError(null); + } else if (loadingStatus !== INSTANCE_LOADING_STATE.PENDING) { setError(new Error("no sdk instance available")); } - }, [sdkInstance, setError]); + }, [sdkInstance, setError, loadingStatus]); useEffect(() => { if (!sdkInstance) { diff --git a/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.test.ts b/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.test.ts index f9641aa6..75c500e0 100644 --- a/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.test.ts +++ b/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.test.ts @@ -59,7 +59,7 @@ describe("useVenmoOneTimePaymentSession", () => { test("should not create session when no SDK instance is available", () => { mockUsePayPal.mockReturnValue({ sdkInstance: null, - loadingStatus: INSTANCE_LOADING_STATE.PENDING, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, eligiblePaymentMethods: null, error: null, }); @@ -81,6 +81,73 @@ describe("useVenmoOneTimePaymentSession", () => { expectCurrentErrorValue(error); expect(error).toEqual(new Error("no sdk instance available")); + expect( + mockSdkInstance.createVenmoOneTimePaymentSession, + ).not.toHaveBeenCalled(); + }); + + test("should not error if there is no sdkInstance but loading is still pending", () => { + mockUsePayPal.mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.PENDING, + eligiblePaymentMethods: null, + error: null, + }); + + const props: UseVenmoOneTimePaymentSessionProps = { + presentationMode: "popup", + orderId: "test-order-id", + onApprove: jest.fn(), + }; + + const { + result: { + current: { error }, + }, + } = renderHook(() => useVenmoOneTimePaymentSession(props)); + + expect(error).toBeNull(); + }); + + test("should clear any sdkInstance related errors if the sdkInstance becomes available", () => { + const mockSession = createMockVenmoSession(); + const mockSdkInstanceNew = createMockSdkInstance(mockSession); + + // First render: no sdkInstance and not in PENDING state, should error + mockUsePayPal.mockReturnValue({ + sdkInstance: null, + loadingStatus: INSTANCE_LOADING_STATE.REJECTED, + eligiblePaymentMethods: null, + error: null, + }); + + const props: UseVenmoOneTimePaymentSessionProps = { + presentationMode: "popup", + orderId: "test-order-id", + onApprove: jest.fn(), + }; + + const { result, rerender } = renderHook(() => + useVenmoOneTimePaymentSession(props), + ); + + expectCurrentErrorValue(result.current.error); + expect(result.current.error).toEqual( + new Error("no sdk instance available"), + ); + + // Second render: sdkInstance becomes available, error should clear + mockUsePayPal.mockReturnValue({ + // @ts-expect-error mocking sdk instance + sdkInstance: mockSdkInstanceNew, + loadingStatus: INSTANCE_LOADING_STATE.RESOLVED, + eligiblePaymentMethods: null, + error: null, + }); + + rerender(); + + expect(result.current.error).toBeNull(); }); test("should create Venmo session with orderId when provided", () => { diff --git a/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.ts b/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.ts index 086f9c7b..fc175c37 100644 --- a/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.ts +++ b/packages/react-paypal-js/src/v6/hooks/useVenmoOneTimePaymentSession.ts @@ -4,6 +4,7 @@ import { usePayPal } from "./usePayPal"; import { useIsMountedRef } from "./useIsMounted"; import { useError } from "./useError"; import { useProxyProps } from "../utils"; +import { INSTANCE_LOADING_STATE } from "../types/PayPalProviderEnums"; import type { VenmoOneTimePaymentSession, @@ -33,7 +34,7 @@ export function useVenmoOneTimePaymentSession({ orderId, ...callbacks }: UseVenmoOneTimePaymentSessionProps): BasePaymentSessionReturn { - const { sdkInstance } = usePayPal(); + const { sdkInstance, loadingStatus } = usePayPal(); const isMountedRef = useIsMountedRef(); const sessionRef = useRef(null); const proxyCallbacks = useProxyProps(callbacks); @@ -46,10 +47,12 @@ export function useVenmoOneTimePaymentSession({ // Separate error reporting effect to avoid infinite loops with proxyCallbacks useEffect(() => { - if (!sdkInstance) { + if (sdkInstance) { + setError(null); + } else if (loadingStatus !== INSTANCE_LOADING_STATE.PENDING) { setError(new Error("no sdk instance available")); } - }, [sdkInstance, setError]); + }, [sdkInstance, setError, loadingStatus]); useEffect(() => { if (!sdkInstance) { diff --git a/packages/react-paypal-js/src/v6/index.ts b/packages/react-paypal-js/src/v6/index.ts index 66243977..5d7cd622 100644 --- a/packages/react-paypal-js/src/v6/index.ts +++ b/packages/react-paypal-js/src/v6/index.ts @@ -1,6 +1,5 @@ export * from "./types"; export { PayPalProvider } from "./components/PayPalProvider"; -export { PayPalContext } from "./context/PayPalProviderContext"; export { usePayPal } from "./hooks/usePayPal"; export { usePayLaterOneTimePaymentSession } from "./hooks/usePayLaterOneTimePaymentSession"; export { usePayPalOneTimePaymentSession } from "./hooks/usePayPalOneTimePaymentSession"; diff --git a/packages/react-paypal-js/src/v6/utils.ts b/packages/react-paypal-js/src/v6/utils.ts index 1f5b4d41..e24453fa 100644 --- a/packages/react-paypal-js/src/v6/utils.ts +++ b/packages/react-paypal-js/src/v6/utils.ts @@ -3,7 +3,7 @@ import { useRef } from "react"; import type { Components } from "./types"; export function isServer(): boolean { - return typeof window === "undefined" && typeof document === "undefined"; + return typeof window === "undefined"; } /**