O. Shehab
O. Shehab

Reputation: 81

`@paypal/react-paypal-js` keeps triggering a CORS error and not loading the buttons

I'm trying to integrate paypal into a Next.js website I'm working on. I'm using @paypal/react-paypal-js, the code seems fine but the buttons don't load and I keep getting this error

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.sandbox.paypal.com/xoplatform/logger/api/logger?disableSetCookie=true. (Reason: CORS request did not succeed). Status code: (null).

This error is causing the buttons to never load and go into an infinite reload (the buttons themselves keep reloading not the page). I tried using the --experimental-https flag, no use. I tried setting the headers in the next.config.ts to accept all origins no use. I tried it in an actual domain, but no use. I even temporarily disabled the cors protection in my browser, but still getting the same error. This is driving me insane. I know about this question, but with him he is getting a preflight response, I'm not and his question hasn't been answered anyway.

Here is the PayPalSubscribeButton.tsxcomponent:

// app/components/PayPalSubscribeButton.tsx
"use client";
import {
  DISPATCH_ACTION,
  usePayPalScriptReducer,
  PayPalButtons,
  //   useSubscription,
} from "@paypal/react-paypal-js";
import { type FC, useEffect } from "react";
import { Spinner, Alert } from "@/components";
import checkDevelopment from "@/utils/checkDevelopment";
interface PayPalSubscribeButtonProps {
  planId: string;
  primary?: boolean;
}
const PayPalSubscribeButton: FC<PayPalSubscribeButtonProps> = ({
  planId,
  primary,
}) => {
  const [{ isPending, isResolved, isRejected }, dispatch] =
    usePayPalScriptReducer();
  //   const { createSubscription, onApprove, onError } = useSubscription();
  useEffect(() => {
    if (isResolved) {
      dispatch({
        type: DISPATCH_ACTION.RESET_OPTIONS,
        value: {
          clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || "",
          vault: true,
          intent: "subscription",
          currency: "USD",
          environment: checkDevelopment() ? "sandbox" : "production",
          disableFunding: ["credit", "paylater"],
          components: ["buttons"]
        },
      });
    }
  }, [isResolved, dispatch]);
  return (
    <div>
      {isPending && (
        <div className="flex items-center gap-3">
          <Spinner size="sm" variant="spinner" />
          <span>Loading</span>
        </div>
      )}
      {isRejected && <Alert color="danger" title="Something went wrong" />}
      {isResolved && (
        <PayPalButtons
          createSubscription={(data, actions) => {
            console.log("Create Subscription data:", data);
            return actions.subscription.create({
              plan_id: planId,
            });
          }}
          // @ts-expect-error
          onApprove={(data, actions) => {
            console.log("On Approve data:", data);
            // Capture the subscription details
            return actions?.subscription?.get().then((details) => {
              alert(
                `You have successfully created a subscription! Subscription ID: ${data.subscriptionID}`
              );
              console.log("Subscription details:", details);
              // Here you would typically send the subscription ID and details to your server
              // to store in your database and perform any necessary actions.
            });
          }}
          onCancel={(data) => {
            console.log("onCancel data:", data);
          }}
          onError={(err) => {
            console.error("Error creating subscription:", err);
            alert("An error occurred during the subscription process.");
          }}
          style={{
            layout: "horizontal",
            label: "subscribe",
            shape: "rect",
            color: primary ? "blue" : "white",
            tagline: false,
          }} // Optional styling
        />
      )}
    </div>
  );
};
export default PayPalSubscribeButton;

And here is the PayPalScriptProvider code:

<PayPalScriptProvider
          // deferLoading
          options={{
            clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || "",
            vault: true,
            intent: "subscription",
            currency: "USD",
            environment: checkDevelopment() ? "sandbox" : "production",
            disableFunding: ["credit", "paylater"],
            components: ["buttons"]
          }}
        >
            {children}
        </PayPalScriptProvider>

No AI agent is able to figure it out, so please anyone help me fix it.

Edit: Removing the useEffect from the PayPalSubscribeButton.tsx Component, stop the infinite button reloading and allowed the buttons to show up. When I click on the button, I get the popup and I can login and and choose a card.

However, when I confirm the payment I get the same CORS error.

Upvotes: 0

Views: 20

Answers (0)

Related Questions