Why is stripe not working properly?
Unanswered
Erythrina gall wasp posted this in #help-forum

Erythrina gall waspOP
When the user is redirect to success page, they are logged out.
10 Replies

Erythrina gall waspOP
"use client";
import React, { useEffect, useState } from "react";
import { useStripe, useElements, PaymentElement } from "@stripe/react-stripe-js";
import convertToSubcurrency from "@/app/lib/convertToSubcurrency";
import { useSession } from "next-auth/react";
const CheckoutPage = ({ amount }: { amount: number }) => {
const stripe = useStripe();
const elements = useElements();
const [errorMessage, setErrorMessage] = useState<string>();
const [clientSecret, setClientSecret] = useState("");
const [loading, setLoading] = useState(false);
const { data: session } = useSession(); // Use session to get current user's info
useEffect(() => {
if (!session) return; // Only proceed if user is logged in
fetch("/api/create-payment-intent", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ amount: convertToSubcurrency(amount) }),
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, [amount, session]);
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setLoading(true);
if (!stripe || !elements) {
return;
}
const { error: submitError } = await elements.submit();
if (submitError) {
setErrorMessage(submitError.message);
setLoading(false);
return;
}
const { error } = await stripe.confirmPayment({
elements,
clientSecret,
confirmParams: {
return_url: `http://www.localhost:3000/payment-success?amount=${amount}`,
},
});
if (error) {
// This point is only reached if there's an immediate error when
// confirming the payment. Show the error to your customer (for example, payment details incomplete)
setErrorMessage(error.message);
}
setLoading(false);
};
if (!clientSecret || !stripe || !elements) {
return (
<div className="flex items-center justify-center">
<div
className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-e-transparent align-[-0.125em] text-surface motion-reduce:animate-[spin_1.5s_linear_infinite] dark:text-white"
role="status"
>
<span className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">
Loading...
</span>
</div>
</div>
);
}
return (
<form onSubmit={handleSubmit} className="bg-white p-2 rounded-md">
{clientSecret && <PaymentElement />}
{errorMessage && <div>{errorMessage}</div>}
<button
disabled={!stripe || loading}
className="text-white w-full p-5 bg-black mt-2 rounded-md font-bold disabled:opacity-50 disabled:animate-pulse"
>
{!loading ? `Pay $${amount}` : "Processing..."}
</button>
</form>
);
};
export default CheckoutPage;
export default function PaymentSuccess({
searchParams: { amount },
}: {
searchParams: { amount: string };
}) {
return (
<main className="max-w-6xl mx-auto p-10 text-white text-center border m-10 rounded-md bg-gradient-to-tr from-blue-500 to-purple-500">
<div className="mb-10">
<h1 className="text-4xl font-extrabold mb-2">Thank you!</h1>
<h2 className="text-2xl">You successfully sent</h2>
<div className="bg-white p-2 rounded-md text-purple-500 mt-5 text-4xl font-bold">
${amount}
</div>
</div>
</main>
);
}
"use client";
import CheckoutPage from "@/app/stripeComponents/CheckoutPage";
import convertToSubcurrency from "@/app/lib/convertToSubcurrency";
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
if (process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY === undefined) {
throw new Error("NEXT_PUBLIC_STRIPE_PUBLIC_KEY is not defined");
}
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY);
export default function Home() {
const amount = 4.99;
return (
<main className="max-w-6xl mx-auto p-10 text-white text-center border m-10 rounded-md bg-gradient-to-tr from-blue-500 to-purple-500">
<Elements
stripe={stripePromise}
options={{
mode: "payment",
amount: convertToSubcurrency(amount),
currency: "usd",
}}
>
<CheckoutPage amount={amount} />
</Elements>
</main>
);
}
<Link href={"/checkout"} target="_blank">
<button
className="mt-6 px-6 py-2 rounded-full bg-gradientButton text-buttonText font-semibold hover:bg-proFillLight dark:hover:bg-proFill"
>
Upgrade Now
</button>
</Link>
In pricing, we use this.
import { NextRequest, NextResponse } from "next/server";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(request: NextRequest) {
try {
const { amount } = await request.json();
const paymentIntent = await stripe.paymentIntents.create({
amount: amount,
currency: "usd",
automatic_payment_methods: { enabled: true },
});
return NextResponse.json({ clientSecret: paymentIntent.client_secret });
} catch (error) {
console.error("Internal Error:", error);
return NextResponse.json(
{ error: `Internal Server Error: ${error}` },
{ status: 500 }
);
}
}
this is route.ts, api/create-payment-intent/route.ts
Erythrina gall waspOP
I tried debugging,
"use client";
import { useSearchParams } from "next/navigation";
import React, { useEffect, useState } from "react";
import { getFirestore, doc, updateDoc } from "firebase/firestore";
import { useSession } from "next-auth/react";
const PaymentSuccess = () => {
const searchParams = useSearchParams();
const paymentIntent = searchParams.get("payment_intent"); // Get the payment intent ID from the URL
const redirectStatus = searchParams.get("redirect_status"); // Check if payment succeeded
const { data: session } = useSession(); // Get current user session
const [amount, setAmount] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const [subscriptionEndDateDisplay, setSubscriptionEndDateDisplay] = useState<string | null>(null);
const db = getFirestore();
useEffect(() => {
console.log("useEffect triggered with:", { paymentIntent, redirectStatus });
if (paymentIntent && redirectStatus === "succeeded") {
fetchPaymentDetails(paymentIntent); // Fetch payment details if payment succeeded
}
}, [paymentIntent, redirectStatus]);
// Fetch payment details from Stripe
const fetchPaymentDetails = async (paymentIntentId: string) => {
setLoading(true);
try {
console.log("Fetching payment details for:", paymentIntentId);
const response = await fetch(`/api/payment-success?payment_intent=${paymentIntentId}`);
console.log("Response status:", response.status);
const data = await response.json();
console.log("Received data:", data);
if (data.success) {
setAmount(data.amount);
if (session?.user?.email) {
console.log("Calling updateUserStatusToPro for:", session.user.email);
updateUserStatusToPro(session.user.email); // Upgrade user to Pro
} else {
console.error("Session user email is null. User not logged in?");
}
} else {
console.error("Error fetching payment details:", data.error);
}
} catch (error) {
console.error("Error fetching payment details:", error);
} finally {
setLoading(false);
}
};
// Function to update the user's status to 'pro'
const updateUserStatusToPro = async (userEmail: string): Promise<void> => {
console.log("updateUserStatusToPro function triggered for:", userEmail);
try {
const userRef = doc(db, "users", userEmail);
console.log("Firestore document reference:", userRef.path);
const subscriptionEndDate = new Date();
subscriptionEndDate.setDate(subscriptionEndDate.getDate() + 30); // 30-day subscription
await updateDoc(userRef, {
subscription_status: "pro",
subscription_end: subscriptionEndDate,
});
setSubscriptionEndDateDisplay(subscriptionEndDate.toDateString());
console.log("User status successfully updated to Pro.");
} catch (error) {
console.error("Error updating user status:", error);
}
};
console.log("Session user email:", session?.user?.email);
return (
<main className="max-w-6xl mx-auto p-10 text-white text-center border m-10 rounded-md bg-gradient-to-tr from-blue-500 to-purple-500">
<div className="mb-10">
<h1 className="text-4xl font-extrabold mb-2">Thank you!</h1>
<h2 className="text-2xl">Your payment was successful!</h2>
{loading ? (
<p>Loading payment details...</p>
) : (
amount && (
<div className="bg-white p-2 rounded-md text-purple-500 mt-5 text-4xl font-bold">
${amount}
</div>
)
)}
{subscriptionEndDateDisplay && (
<p className="text-lg mt-4">Your subscription is valid until: {subscriptionEndDateDisplay}</p>
)}
</div>
</main>
);
};
export default PaymentSuccess;
use effecr isnt even getting triggered