Improved the way the PayPal integration works

This commit is contained in:
Tiago Ribeiro
2023-11-26 23:16:26 +00:00
parent 0fe2e0d393
commit 9de39485de
4 changed files with 46 additions and 55 deletions

View File

@@ -1,11 +1,12 @@
import {DurationUnit} from "@/interfaces/paypal"; import {DurationUnit} from "@/interfaces/paypal";
import {CreateOrderActions, CreateOrderData, OnApproveActions, OnApproveData, OnCancelledActions, OrderResponseBody} from "@paypal/paypal-js"; import {CreateOrderActions, CreateOrderData, OnApproveActions, OnApproveData, OnCancelledActions, OrderResponseBody} from "@paypal/paypal-js";
import {PayPalButtons, usePayPalScriptReducer} from "@paypal/react-paypal-js"; import {PayPalButtons, PayPalScriptProvider, usePayPalScriptReducer} from "@paypal/react-paypal-js";
import axios from "axios"; import axios from "axios";
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {toast} from "react-toastify"; import {toast} from "react-toastify";
interface Props { interface Props {
clientID: string;
currency: string; currency: string;
price: number; price: number;
duration: number; duration: number;
@@ -14,20 +15,7 @@ interface Props {
onSuccess: (duration: number, duration_unit: DurationUnit) => void; onSuccess: (duration: number, duration_unit: DurationUnit) => void;
} }
export default function PayPalPayment({price, currency, duration, duration_unit, setIsLoading, onSuccess}: Props) { export default function PayPalPayment({clientID, price, currency, duration, duration_unit, setIsLoading, onSuccess}: Props) {
const [{options}, dispatch] = usePayPalScriptReducer();
useEffect(() => {
dispatch({
type: "resetOptions",
value: {
...options,
currency,
},
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currency]);
const createOrder = async (data: CreateOrderData, actions: CreateOrderActions): Promise<string> => { const createOrder = async (data: CreateOrderData, actions: CreateOrderActions): Promise<string> => {
setIsLoading(true); setIsLoading(true);
@@ -58,6 +46,14 @@ export default function PayPalPayment({price, currency, duration, duration_unit,
}; };
return ( return (
<PayPalScriptProvider
options={{
clientId: clientID,
currency,
intent: "capture",
commit: true,
vault: true,
}}>
<PayPalButtons <PayPalButtons
className="w-full" className="w-full"
style={{layout: "vertical"}} style={{layout: "vertical"}}
@@ -65,5 +61,6 @@ export default function PayPalPayment({price, currency, duration, duration_unit,
onApprove={onApprove} onApprove={onApprove}
onCancel={onCancel} onCancel={onCancel}
onError={onError}></PayPalButtons> onError={onError}></PayPalButtons>
</PayPalScriptProvider>
); );
} }

View File

@@ -1,25 +1,23 @@
/* eslint-disable @next/next/no-img-element */ /* eslint-disable @next/next/no-img-element */
import Layout from "@/components/High/Layout"; import Layout from "@/components/High/Layout";
import PayPalPayment from "@/components/PayPalPayment"; import PayPalPayment from "@/components/PayPalPayment";
import ProfileSummary from "@/components/ProfileSummary";
import useGroups from "@/hooks/useGroups"; import useGroups from "@/hooks/useGroups";
import usePackages from "@/hooks/usePackages"; import usePackages from "@/hooks/usePackages";
import useStats from "@/hooks/useStats";
import useUsers from "@/hooks/useUsers"; import useUsers from "@/hooks/useUsers";
import {Package} from "@/interfaces/paypal";
import {User} from "@/interfaces/user"; import {User} from "@/interfaces/user";
import {averageScore, groupBySession} from "@/utils/stats";
import clsx from "clsx"; import clsx from "clsx";
import {capitalize} from "lodash"; import {capitalize} from "lodash";
import Head from "next/head";
import {useState} from "react"; import {useState} from "react";
import {BsFileEarmarkText, BsPencil, BsStar} from "react-icons/bs";
import getSymbolFromCurrency from "currency-symbol-map"; import getSymbolFromCurrency from "currency-symbol-map";
import {Divider} from "primereact/divider";
import Input from "@/components/Low/Input";
import Button from "@/components/Low/Button";
export default function PaymentDue({user, hasExpired, reload}: {user: User; hasExpired?: boolean; reload: () => void}) { interface Props {
user: User;
hasExpired?: boolean;
clientID: string;
reload: () => void;
}
export default function PaymentDue({user, hasExpired = false, clientID, reload}: Props) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const {packages} = usePackages(); const {packages} = usePackages();
@@ -74,9 +72,11 @@ export default function PaymentDue({user, hasExpired, reload}: {user: User; hasE
{getSymbolFromCurrency(p.currency)} {getSymbolFromCurrency(p.currency)}
</span> </span>
<PayPalPayment <PayPalPayment
key={clientID}
{...p} {...p}
clientID={clientID}
setIsLoading={setIsLoading} setIsLoading={setIsLoading}
onSuccess={(duration, duration_unit) => { onSuccess={() => {
setTimeout(reload, 500); setTimeout(reload, 500);
}} }}
/> />
@@ -110,12 +110,14 @@ export default function PaymentDue({user, hasExpired, reload}: {user: User; hasE
{getSymbolFromCurrency(user.corporateInformation.payment.currency)} {getSymbolFromCurrency(user.corporateInformation.payment.currency)}
</span> </span>
<PayPalPayment <PayPalPayment
key={clientID}
clientID={clientID}
setIsLoading={setIsLoading} setIsLoading={setIsLoading}
currency={user.corporateInformation.payment.currency} currency={user.corporateInformation.payment.currency}
price={user.corporateInformation.payment.value} price={user.corporateInformation.payment.value}
duration={user.corporateInformation.monthlyDuration} duration={user.corporateInformation.monthlyDuration}
duration_unit="months" duration_unit="months"
onSuccess={(duration, duration_unit) => { onSuccess={() => {
setIsLoading(false); setIsLoading(false);
setTimeout(reload, 500); setTimeout(reload, 500);
}} }}

View File

@@ -102,16 +102,13 @@ export default function Home({envVariables}: {envVariables: {[key: string]: stri
</Layout> </Layout>
)} )}
{(user.status === "paymentDue" || checkIfUserExpired()) && ( {(user.status === "paymentDue" || checkIfUserExpired()) && (
<PayPalScriptProvider <PaymentDue
options={{ key={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"]}
clientId: envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || "", hasExpired
currency: "EUR", user={user}
intent: "capture", reload={router.reload}
commit: true, clientID={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || ""}
vault: true, />
}}>
<PaymentDue hasExpired user={user} reload={router.reload} />
</PayPalScriptProvider>
)} )}
</> </>
); );

View File

@@ -5,7 +5,6 @@ import {sessionOptions} from "@/lib/session";
import useUser from "@/hooks/useUser"; import useUser from "@/hooks/useUser";
import PaymentDue from "./(status)/PaymentDue"; import PaymentDue from "./(status)/PaymentDue";
import {useRouter} from "next/router"; import {useRouter} from "next/router";
import {PayPalScriptProvider} from "@paypal/react-paypal-js";
export const getServerSideProps = withIronSessionSsr(({req, res}) => { export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user; const user = req.session.user;
@@ -50,16 +49,12 @@ export default function Home({envVariables}: {envVariables: {[key: string]: stri
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
</Head> </Head>
{user && ( {user && (
<PayPalScriptProvider <PaymentDue
options={{ key={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"]}
clientId: envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || "", clientID={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || ""}
currency: "EUR", user={user}
intent: "capture", reload={router.reload}
commit: true, />
vault: true,
}}>
<PaymentDue user={user} reload={router.reload} />
</PayPalScriptProvider>
)} )}
</> </>
); );