125 lines
2.8 KiB
TypeScript
125 lines
2.8 KiB
TypeScript
import { DurationUnit } from "@/interfaces/paypal";
|
|
import {
|
|
CreateOrderActions,
|
|
CreateOrderData,
|
|
OnApproveActions,
|
|
OnApproveData,
|
|
OnCancelledActions,
|
|
OrderResponseBody,
|
|
} from "@paypal/paypal-js";
|
|
import {
|
|
PayPalButtons,
|
|
PayPalScriptProvider,
|
|
usePayPalScriptReducer,
|
|
} from "@paypal/react-paypal-js";
|
|
import axios from "axios";
|
|
import { useState, useEffect } from "react";
|
|
import { toast } from "react-toastify";
|
|
|
|
interface Props {
|
|
clientID: string;
|
|
currency: string;
|
|
price: number;
|
|
duration: number;
|
|
duration_unit: DurationUnit;
|
|
loadScript?: boolean;
|
|
setIsLoading: (isLoading: boolean) => void;
|
|
onSuccess: (duration: number, duration_unit: DurationUnit) => void;
|
|
trackingId?: string;
|
|
}
|
|
|
|
export default function PayPalPayment({
|
|
clientID,
|
|
price,
|
|
currency,
|
|
duration,
|
|
duration_unit,
|
|
loadScript,
|
|
setIsLoading,
|
|
onSuccess,
|
|
trackingId,
|
|
}: Props) {
|
|
const createOrder = async (
|
|
data: CreateOrderData,
|
|
actions: CreateOrderActions
|
|
): Promise<string> => {
|
|
if (!trackingId) {
|
|
throw new Error("trackingId is not set");
|
|
}
|
|
setIsLoading(true);
|
|
|
|
return axios
|
|
.post<OrderResponseBody>("/api/paypal", {
|
|
currencyCode: currency,
|
|
price,
|
|
trackingId,
|
|
})
|
|
.then((response) => response.data)
|
|
.then((data) => data.id);
|
|
};
|
|
|
|
const onApprove = async (data: OnApproveData, actions: OnApproveActions) => {
|
|
if (!trackingId) {
|
|
throw new Error("trackingId is not set");
|
|
}
|
|
|
|
const request = await axios.post<{ ok: boolean; reason?: string }>(
|
|
"/api/paypal/approve",
|
|
{ id: data.orderID, duration, duration_unit, trackingId }
|
|
);
|
|
|
|
if (request.status !== 200) {
|
|
toast.error("Something went wrong, please try again later");
|
|
return;
|
|
}
|
|
|
|
toast.success("Your account has been credited more time!");
|
|
return onSuccess(duration, duration_unit);
|
|
};
|
|
|
|
const onError = async (data: Record<string, unknown>) => {
|
|
setIsLoading(false);
|
|
};
|
|
|
|
const onCancel = async (
|
|
data: Record<string, unknown>,
|
|
actions: OnCancelledActions
|
|
) => {
|
|
setIsLoading(false);
|
|
};
|
|
|
|
if (trackingId) {
|
|
return loadScript ? (
|
|
<PayPalScriptProvider
|
|
options={{
|
|
clientId: clientID,
|
|
currency,
|
|
intent: "capture",
|
|
commit: true,
|
|
vault: true,
|
|
}}
|
|
>
|
|
<PayPalButtons
|
|
className="w-full"
|
|
style={{ layout: "vertical" }}
|
|
createOrder={createOrder}
|
|
onApprove={onApprove}
|
|
onCancel={onCancel}
|
|
onError={onError}
|
|
/>
|
|
</PayPalScriptProvider>
|
|
) : (
|
|
<PayPalButtons
|
|
className="w-full"
|
|
style={{ layout: "vertical" }}
|
|
createOrder={createOrder}
|
|
onApprove={onApprove}
|
|
onCancel={onCancel}
|
|
onError={onError}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}
|