Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion client/prebuiltPages/react/oneTimePayment/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
</head>
<body>
<div id="root"></div>
<script src="https://www.sandbox.paypal.com/web-sdk/v6/core"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1 change: 1 addition & 0 deletions client/prebuiltPages/react/oneTimePayment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"typecheck": "tsc --build --noEmit"
},
"dependencies": {
"@paypal/react-paypal-js": "^8.9.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-error-boundary": "6.0.0"
Expand Down
14 changes: 7 additions & 7 deletions client/prebuiltPages/react/oneTimePayment/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect, useState } from "react";

import { PayPalSDKProvider } from "./context/sdkContext";
import { PayPalProvider } from "@paypal/react-paypal-js/sdk-v6";

Check failure on line 2 in client/prebuiltPages/react/oneTimePayment/src/App.tsx

View workflow job for this annotation

GitHub Actions / main

Unable to resolve path to module '@paypal/react-paypal-js/sdk-v6'
import { ErrorBoundary, useErrorBoundary } from "react-error-boundary";

import { getBrowserSafeClientToken } from "./utils";
Expand Down Expand Up @@ -36,18 +35,19 @@
getClientToken();
}, []);

return (
return clientToken ? (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<PayPalSDKProvider
clientToken={clientToken}
<PayPalProvider
components={["paypal-payments", "venmo-payments"]}
clientToken={clientToken}
pageType="checkout"
scriptOptions={{ environment: "sandbox" }}
>
<h1>React One-Time Payment Recommended Integration</h1>
<SoccerBall />
</PayPalSDKProvider>
</PayPalProvider>
</ErrorBoundary>
);
) : null;
}

export default App;
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import React, { useContext, useRef, useEffect } from "react";
import { PayPalSDKContext } from "../context/sdkContext";
import React, { useRef, useEffect, useMemo } from "react";

import { createOrder } from "../utils";
import { PaymentSessionOptions, SessionOutput } from "../types/paypal";
import { useErrorBoundary } from "react-error-boundary";
import { usePayPal } from "@paypal/react-paypal-js/sdk-v6";

Check failure on line 5 in client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx

View workflow job for this annotation

GitHub Actions / main

Unable to resolve path to module '@paypal/react-paypal-js/sdk-v6'
import type {
PayPalOneTimePaymentSessionOptions,
OneTimePaymentSession,
} from "@paypal/react-paypal-js/sdk-v6";

const PayPalButton: React.FC<PaymentSessionOptions> = (
const PayPalButton: React.FC<PayPalOneTimePaymentSessionOptions> = (
paymentSessionOptions,
) => {
const { sdkInstance } = useContext(PayPalSDKContext);
const { sdkInstance } = usePayPal();
const { showBoundary } = useErrorBoundary();
const paypalSession = useRef<SessionOutput>(null);
const paypalSession = useRef<OneTimePaymentSession>(null);

// Memoize the payment session options to prevent unnecessary re-creation
const memoizedOptions = useMemo(
() => paymentSessionOptions,
[

Check warning on line 21 in client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx

View workflow job for this annotation

GitHub Actions / main

React Hook useMemo has a missing dependency: 'paymentSessionOptions'. Either include it or remove the dependency array
// Add specific dependencies here based on what properties of paymentSessionOptions should trigger re-creation
// For example: paymentSessionOptions.amount, paymentSessionOptions.currency, etc.
JSON.stringify(paymentSessionOptions),

Check warning on line 24 in client/prebuiltPages/react/oneTimePayment/src/components/PayPalButton.tsx

View workflow job for this annotation

GitHub Actions / main

React Hook useMemo has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked
],
);

useEffect(() => {
if (sdkInstance) {
paypalSession.current = sdkInstance.createPayPalOneTimePaymentSession(
paymentSessionOptions,
);
paypalSession.current =
sdkInstance.createPayPalOneTimePaymentSession(memoizedOptions);
}
}, [sdkInstance, paymentSessionOptions]);
}, [sdkInstance, memoizedOptions]);

const payPalOnClickHandler = async () => {
if (!paypalSession.current) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import React, { useContext, useEffect, useRef } from "react";
import { PayPalSDKContext } from "../context/sdkContext";
import React, { useEffect, useMemo, useRef } from "react";
import { createOrder } from "../utils";
import { PaymentSessionOptions, SessionOutput } from "../types/paypal";
import { useErrorBoundary } from "react-error-boundary";
import { usePayPal } from "@paypal/react-paypal-js/sdk-v6";

Check failure on line 4 in client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx

View workflow job for this annotation

GitHub Actions / main

Unable to resolve path to module '@paypal/react-paypal-js/sdk-v6'
import type {
VenmoOneTimePaymentSession,
VenmoOneTimePaymentSessionOptions,
} from "@paypal/react-paypal-js/sdk-v6";

const VenmoButton: React.FC<PaymentSessionOptions> = (
const VenmoButton: React.FC<VenmoOneTimePaymentSessionOptions> = (
paymentSessionOptions,
) => {
const { sdkInstance } = useContext(PayPalSDKContext);
const { sdkInstance } = usePayPal();
const { showBoundary } = useErrorBoundary();
const venmoSession = useRef<SessionOutput>(null);
const venmoSession = useRef<VenmoOneTimePaymentSession>(null);

// Memoize the payment session options to prevent unnecessary re-creation
const memoizedOptions = useMemo(
() => paymentSessionOptions,
[

Check warning on line 20 in client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx

View workflow job for this annotation

GitHub Actions / main

React Hook useMemo has a missing dependency: 'paymentSessionOptions'. Either include it or remove the dependency array
// Add specific dependencies here based on what properties of paymentSessionOptions should trigger re-creation
JSON.stringify(paymentSessionOptions),

Check warning on line 22 in client/prebuiltPages/react/oneTimePayment/src/components/VenmoButton.tsx

View workflow job for this annotation

GitHub Actions / main

React Hook useMemo has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked
],
);

useEffect(() => {
if (sdkInstance) {
venmoSession.current = sdkInstance.createVenmoOneTimePaymentSession(
paymentSessionOptions,
);
venmoSession.current =
sdkInstance.createVenmoOneTimePaymentSession(memoizedOptions);
}
}, [sdkInstance, paymentSessionOptions]);
}, [sdkInstance, memoizedOptions]);

const venmoOnClickHandler = async () => {
if (!venmoSession.current) return;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useContext, useState, useCallback } from "react";
import { PayPalSDKContext } from "../context/sdkContext";
import React, { useState, useCallback } from "react";
import PayPalButton from "../components/PayPalButton";
import VenmoButton from "../components/VenmoButton";
import { PaymentSessionOptions, OnApproveData } from "../types/paypal";
import ProductDisplay from "../components/ProductDisplay";
import PaymentModal from "../components/PaymentModal";

import soccerBallImage from "../static/images/world-cup.jpg";
import { captureOrder } from "../utils";
import "../static/styles/SoccerBall.css";
import "../static/styles/Modal.css";
import { usePayPal } from "@paypal/react-paypal-js/sdk-v6";

Check failure on line 11 in client/prebuiltPages/react/oneTimePayment/src/sections/SoccerBall.tsx

View workflow job for this annotation

GitHub Actions / main

Unable to resolve path to module '@paypal/react-paypal-js/sdk-v6'
import type { PayPalOneTimePaymentSessionOptions } from "@paypal/react-paypal-js/sdk-v6";

// Types
type ModalType = "success" | "cancel" | "error" | null;
Expand All @@ -29,12 +29,12 @@
} as const;

const SoccerBall: React.FC = () => {
const { sdkInstance, eligiblePaymentMethods } = useContext(PayPalSDKContext);
const { sdkInstance, eligiblePaymentMethods } = usePayPal();
const [modalState, setModalState] = useState<ModalType>(null);

// Payment handlers
const handlePaymentCallbacks: PaymentSessionOptions = {
onApprove: async (data: OnApproveData) => {
const handlePaymentCallbacks: PayPalOneTimePaymentSessionOptions = {
onApprove: async (data) => {
console.log("Payment approved:", data);
const captureResult = await captureOrder({ orderId: data.orderId });
console.log("Payment capture result:", captureResult);
Expand Down
73 changes: 6 additions & 67 deletions client/prebuiltPages/react/oneTimePayment/src/types/paypal.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// src/types/paypal.d.ts

import type {
CreateInstanceOptions,
SdkInstance,
} from "@paypal/react-paypal-js/sdk-v6";

declare global {
interface Window {
paypal: {
Expand All @@ -18,73 +24,6 @@ declare module "react" {
}
}

export type Component = "paypal-payments" | "venmo-payments";
export type PageType =
| "cart"
| "checkout"
| "mini-cart"
| "product-details"
| "product-listing"
| "search-results";

type CreateInstanceOptions = {
clientMetadataId?: string;
clientToken: string;
components?: Component[];
locale?: string;
pageType?: PageType;
partnerAttributionId?: string;
};

export interface EligiblePaymentMethods {
isEligible: (paymentMethod: string) => boolean;
}

export interface ButtonProps extends React.HTMLAttributes<HTMLElement> {
type: string;
}

export type PaymentSessionOptions = {
onApprove?: (data: OnApproveData) => Promise<void>;
onCancel?: (data?: { orderId: string }) => void;
onError?: (data: Error) => void;
};

type OnApproveData = {
orderId: string;
payerId: string;
};

export type SdkInstance = {
// "paypal-payments" component
createPayPalOneTimePaymentSession: (
paymentSessionOptions: PaymentSessionOptions,
) => SessionOutput;
// "venmo-payments" component
createVenmoOneTimePaymentSession: (
paymentSessionOptions: PaymentSessionOptions,
) => SessionOutput;
findEligibleMethods: (
findEligibleMethodsOptions: FindEligibleMethodsOptions,
) => Promise<EligiblePaymentMethods>;
};

type FindEligibleMethodsOptions = {
currencyCode?: string;
};

type SessionOutput = {
start: (
options: StartSessionInput,
orderIdPromise: Promise<{ orderId: string }>,
) => Promise<void>;
destroy: () => void;
cancel: () => void;
};

type StartSessionInput = {
presentationMode?: "auto" | "popup" | "modal" | "payment-handler";
fullPageOverlay?: {
enabled?: boolean;
};
};
Loading