diff --git a/next.config.js b/next.config.js
index 12f79d42..5f730dc6 100644
--- a/next.config.js
+++ b/next.config.js
@@ -37,7 +37,10 @@ const scheme =
     : "https";
 
 let APPUrl;
-if (process.env.NEXT_PUBLIC_VERCEL_ENV === "preview") {
+if (
+  process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" &&
+  process.env.DISABLE_VERCEL_REDIRECT !== "true"
+) {
   APPUrl = `${scheme}://${process.env.VERCEL_URL}`;
 } else {
   APPUrl = process.env.APP_URL;
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 3cf51bfd..3d87e1d9 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -134,6 +134,7 @@
   "billingAddress": "Contact Details",
   "treesInCountry": "{{treeCount}} trees, Plant-for-the-Planet",
   "fundingPaymentLabel": "Donate {{amount}}, Plant-for-the-Planet",
+  "pcashPaymentLabel": "Load {{amount}} PlanetCash, Plant-for-the-Planet",
   "bouquetPaymentLabel": "Donate {{amount}}, Plant-for-the-Planet",
   "errorOccurred": "Something went wrong. Please feel free to take a screenshot and email us at support@plant-for-the-planet.org.",
   "dedicatedTo": "Dedicated to",
diff --git a/src/Common/Types/QueryParamContextInterface.ts b/src/Common/Types/QueryParamContextInterface.ts
index 1648409d..e93aa8bf 100644
--- a/src/Common/Types/QueryParamContextInterface.ts
+++ b/src/Common/Types/QueryParamContextInterface.ts
@@ -109,8 +109,8 @@ export default interface QueryParamContextInterface {
     paymentSetupCountry: string;
     shouldSetPaymentDetails?: boolean;
   }) => Promise<void>;
-  isPlanetCashActive: boolean;
-  setIsPlanetCashActive: Dispatch<SetStateAction<boolean>>;
+  isPlanetCashActive: boolean | null;
+  setIsPlanetCashActive: Dispatch<SetStateAction<boolean | null>>;
   onBehalf: boolean;
   setOnBehalf: Dispatch<SetStateAction<boolean>>;
   onBehalfDonor: OnBehalfDonor;
diff --git a/src/Donations/Components/DonationsForm.tsx b/src/Donations/Components/DonationsForm.tsx
index cab3ba5d..b26266f7 100644
--- a/src/Donations/Components/DonationsForm.tsx
+++ b/src/Donations/Components/DonationsForm.tsx
@@ -68,6 +68,7 @@ function DonationsForm(): ReactElement {
     utmMedium,
     utmSource,
     isPackageWanted,
+    setPaymentRequest,
   } = React.useContext(QueryParamContext);
   const { t, i18n } = useTranslation(["common", "country", "donate"]);
 
@@ -78,6 +79,16 @@ function DonationsForm(): ReactElement {
     React.useState(false);
   const router = useRouter();
 
+  React.useEffect(() => {
+    setPaymentRequest(null);
+  }, []);
+
+  React.useEffect(() => {
+    if (isPlanetCashActive) {
+      setPaymentRequest(null);
+    }
+  }, [isPlanetCashActive]);
+
   React.useEffect(() => {
     setMinAmt(getMinimumAmountForCurrency(currency));
   }, [currency]);
@@ -241,6 +252,15 @@ function DonationsForm(): ReactElement {
           ),
         });
         break;
+      case "planet-cash":
+        paymentLabel = t("pcashPaymentLabel", {
+          amount: getFormatedCurrency(
+            i18n.language,
+            currency,
+            paymentSetup.unitCost * quantity
+          ),
+        });
+        break;
       case "bouquet":
       case "conservation":
         paymentLabel = t("bouquetPaymentLabel", {
diff --git a/src/Donations/Components/PaymentsForm.tsx b/src/Donations/Components/PaymentsForm.tsx
index de990ca3..0045585b 100644
--- a/src/Donations/Components/PaymentsForm.tsx
+++ b/src/Donations/Components/PaymentsForm.tsx
@@ -82,6 +82,7 @@ function PaymentsForm(): ReactElement {
     utmMedium,
     utmSource,
     isPackageWanted,
+    setPaymentRequest,
   } = React.useContext(QueryParamContext);
 
   const [stripePromise, setStripePromise] =
@@ -100,6 +101,7 @@ function PaymentsForm(): ReactElement {
 
   React.useEffect(() => {
     setPaymentType("CARD");
+    setPaymentRequest(null);
   }, []);
 
   const sofortCountries = ["AT", "BE", "DE", "IT", "NL", "ES"];
@@ -111,7 +113,7 @@ function PaymentsForm(): ReactElement {
       | string
       | PaymentMethod
       | PaypalApproveData
-      | PaypalErrorData,
+      | PaypalErrorData
   ) => {
     if (!paymentSetup || !donationID) {
       console.log("Missing payment options"); //TODOO - better error handling
@@ -144,7 +146,7 @@ function PaymentsForm(): ReactElement {
   // Seems to work only for native pay. Should this be removed?
   const onPaymentFunction = async (
     paymentMethod: PaymentMethod,
-    paymentRequest: PaymentRequest,
+    paymentRequest: PaymentRequest
   ) => {
     setPaymentType(paymentRequest._activeBackingLibraryName); //TODOO --_activeBackingLibraryName is a private variable?
     const gateway = "stripe";
@@ -289,7 +291,7 @@ function PaymentsForm(): ReactElement {
                       query: { ...router.query, step: CONTACT },
                     },
                     undefined,
-                    { shallow: true },
+                    { shallow: true }
                   );
                 }}
                 className="d-flex"
@@ -420,7 +422,7 @@ function PaymentsForm(): ReactElement {
                     totalCost={getFormatedCurrency(
                       i18n.language,
                       currency,
-                      paymentSetup?.unitCost * quantity,
+                      paymentSetup?.unitCost * quantity
                     )}
                     onPaymentFunction={(providerObject: PaymentMethod) =>
                       onSubmitPayment("stripe", "card", providerObject)
diff --git a/src/Donations/Micros/PlanetCashSelector.tsx b/src/Donations/Micros/PlanetCashSelector.tsx
index eadba14a..15cdeacb 100644
--- a/src/Donations/Micros/PlanetCashSelector.tsx
+++ b/src/Donations/Micros/PlanetCashSelector.tsx
@@ -19,7 +19,6 @@ const PlanetCashSelector: FC = () => {
     country,
     setcountry,
     frequency,
-    paymentRequest,
   } = useContext(QueryParamContext);
   const router = useRouter();
 
@@ -37,20 +36,28 @@ const PlanetCashSelector: FC = () => {
   }, [paymentSetup?.unitCost, quantity, setIsPlanetCashActive]);
 
   useEffect(() => {
-    // On Load If selected country is planetCash Country and balance is sufficient activate planetCash.
-
-    if (
-      country === profile?.planetCash?.country &&
-      paymentSetup &&
-      paymentSetup.unitCost * quantity <=
-        profile.planetCash.balance / 100 + profile.planetCash.creditLimit / 100
-    ) {
-      setIsPlanetCashActive(true);
-    }
-    if (frequency !== "once") {
+    if (frequency !== "once" && isPlanetCashActive !== null) {
       setIsPlanetCashActive(false);
+    } else {
+      if (
+        isPlanetCashActive === null &&
+        country === profile?.planetCash?.country &&
+        paymentSetup &&
+        paymentSetup.unitCost * quantity <=
+          (profile.planetCash.balance + profile.planetCash.creditLimit) / 100
+      ) {
+        setIsPlanetCashActive(true);
+      }
     }
-  }, [paymentRequest, frequency]);
+  }, [
+    country,
+    profile,
+    paymentSetup,
+    quantity,
+    frequency,
+    isPlanetCashActive,
+    frequency,
+  ]);
 
   useEffect(() => {
     // This is done to lock the transaction with PlanetCash in a single currency.
@@ -208,11 +215,13 @@ const PlanetCashSelector: FC = () => {
         </div>
         <div title={disabledReason() ? disabledReason() : ""}>
           <ToggleSwitch
-            checked={isPlanetCashActive}
+            checked={isPlanetCashActive === true}
             disabled={shouldPlanetCashDisable()}
-            onChange={() =>
-              setIsPlanetCashActive((isPlanetCashActive) => !isPlanetCashActive)
-            }
+            onChange={() => {
+              setIsPlanetCashActive(
+                (isPlanetCashActive) => !isPlanetCashActive
+              );
+            }}
           />
         </div>
       </div>
diff --git a/src/Donations/PaymentMethods/PaymentMethodTabs.tsx b/src/Donations/PaymentMethods/PaymentMethodTabs.tsx
index 9e735a13..f60a22fd 100644
--- a/src/Donations/PaymentMethods/PaymentMethodTabs.tsx
+++ b/src/Donations/PaymentMethods/PaymentMethodTabs.tsx
@@ -111,6 +111,15 @@ export default function PaymentMethodTabs({
           ),
         });
         break;
+      case "planet-cash":
+        paymentLabel = t("pcashPaymentLabel", {
+          amount: getFormatedCurrency(
+            i18n.language,
+            currency,
+            paymentSetup.unitCost * quantity
+          ),
+        });
+        break;
       case "bouquet":
       case "conservation":
         paymentLabel = t("bouquetPaymentLabel", {
diff --git a/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx b/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx
index 376175f0..11682608 100644
--- a/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx
+++ b/src/Donations/PaymentMethods/PaymentRequestCustomButton.tsx
@@ -15,6 +15,7 @@ import {
 } from "@stripe/stripe-js/types/stripe-js/payment-request";
 import { PaymentMethod } from "@stripe/stripe-js/types/api/payment-methods";
 import { Stripe } from "@stripe/stripe-js/types/stripe-js/stripe";
+import Skeleton from "@mui/material/Skeleton";
 
 interface PaymentButtonProps {
   country: string;
@@ -50,10 +51,8 @@ export const PaymentRequestCustomButton = ({
   const stripe = useStripe();
   const [canMakePayment, setCanMakePayment] = useState(false);
   const [paymentLoading, setPaymentLoading] = useState(false);
-
-  useEffect(() => {
-    setPaymentRequest(null);
-  }, []);
+  // Tracks if native pay buttons were shown at least once to prevent layout jerks
+  const [wasNativePayInit, setWasNativePayInit] = useState(false);
 
   useEffect(() => {
     if (
@@ -75,17 +74,16 @@ export const PaymentRequestCustomButton = ({
       pr.canMakePayment().then((result) => {
         if (result) {
           setPaymentRequest(pr);
+          setWasNativePayInit(true);
         }
       });
     }
   }, [stripe, paymentRequest, country, currency, amount]);
 
   useEffect(() => {
-    if (stripe && paymentRequest) {
-      setPaymentRequest(null);
-      setCanMakePayment(false);
-      setPaymentLoading(false);
-    }
+    setPaymentRequest(null);
+    setCanMakePayment(false);
+    setPaymentLoading(false);
   }, [country, currency, amount]);
 
   useEffect(() => {
@@ -121,7 +119,10 @@ export const PaymentRequestCustomButton = ({
       );
     }
     return () => {
-      if (paymentRequest && !paymentLoading) {
+      if (
+        paymentRequest &&
+        paymentRequest.hasRegisteredListener("paymentmethod")
+      ) {
         paymentRequest.off("paymentmethod", () => {
           setPaymentLoading(false);
         });
@@ -194,8 +195,25 @@ export const PaymentRequestCustomButton = ({
               <div className="separator-text mb-10">{t("or")}</div>
             )}
           </div>
-        ) : null
-      ) : null}
+        ) : (
+          <></>
+        )
+      ) : wasNativePayInit ? (
+        //Loader shown if native pay was initiated at least once to avoid a jerky effect when payment details change
+        <div className="w-100">
+          <Skeleton
+            className="mb-10"
+            variant="rectangular"
+            width={"100%"}
+            height={40}
+          />
+          {!isPaymentPage && (
+            <div className="separator-text mb-10">{t("or")}</div>
+          )}
+        </div>
+      ) : (
+        <></>
+      )}
 
       {!isPaymentPage && (
         <button
diff --git a/src/Layout/QueryParamContext.tsx b/src/Layout/QueryParamContext.tsx
index a738e250..0e068f50 100644
--- a/src/Layout/QueryParamContext.tsx
+++ b/src/Layout/QueryParamContext.tsx
@@ -138,7 +138,9 @@ const QueryParamProvider: FC = ({ children }) => {
   const [transferDetails, setTransferDetails] =
     useState<BankTransferDetails | null>(null);
 
-  const [isPlanetCashActive, setIsPlanetCashActive] = useState(false);
+  const [isPlanetCashActive, setIsPlanetCashActive] = useState<boolean | null>(
+    null
+  );
 
   // Only used when planetCash is active
   const [onBehalf, setOnBehalf] = useState(false);
@@ -151,7 +153,7 @@ const QueryParamProvider: FC = ({ children }) => {
 
   const [donation, setDonation] = useState<Donation | null>(null);
   const [paymentRequest, setPaymentRequest] = useState<PaymentRequest | null>(
-    null,
+    null
   );
 
   const [errors, setErrors] = React.useState<SerializedError[] | null>(null);
@@ -163,8 +165,9 @@ const QueryParamProvider: FC = ({ children }) => {
         setshowErrorCard,
         shouldQueryParamAdd: false,
       };
-      const response: { data: Record<string, string> } =
-        await apiRequest(requestParams);
+      const response: { data: Record<string, string> } = await apiRequest(
+        requestParams
+      );
       setEnabledCurrencies(response.data);
     } catch (err) {
       console.log(err);
@@ -198,7 +201,7 @@ const QueryParamProvider: FC = ({ children }) => {
 
   function testURL(url: string) {
     const pattern = new RegExp(
-      /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g,
+      /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g
     );
     // regex source https://tutorial.eyehunts.com/js/url-regex-validation-javascript-example-code/
     return !!pattern.test(url);
@@ -242,7 +245,7 @@ const QueryParamProvider: FC = ({ children }) => {
       const projects = response.data as Project[];
       if (projects) {
         const allowedDonationsProjects = projects.filter(
-          (project) => project.properties.allowDonations === true,
+          (project) => project.properties.allowDonations === true
         );
         setAllProjects(allowedDonationsProjects);
         if (allowedDonationsProjects?.length < 6) {
@@ -373,7 +376,7 @@ const QueryParamProvider: FC = ({ children }) => {
           const found = countriesData.some(
             (arrayCountry) =>
               arrayCountry.countryCode?.toUpperCase() ===
-              config.data.country?.toUpperCase(),
+              config.data.country?.toUpperCase()
           );
           if (found) {
             // This is to make sure donations which are already created with some country do not get affected by country from user config
@@ -492,8 +495,9 @@ const QueryParamProvider: FC = ({ children }) => {
         tenant,
         locale: i18n.language,
       };
-      const paymentSetupData: { data: PaymentOptions } =
-        await apiRequest(requestParams);
+      const paymentSetupData: { data: PaymentOptions } = await apiRequest(
+        requestParams
+      );
       if (paymentSetupData.data) {
         const paymentSetup = paymentSetupData.data;
         if (shouldSetPaymentDetails) {