Skip to content

Commit

Permalink
change stripe subscription to one-time products
Browse files Browse the repository at this point in the history
  • Loading branch information
PregoBS committed Oct 25, 2024
1 parent 9c38f0f commit 343511c
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 33 deletions.
6 changes: 3 additions & 3 deletions app/(login)/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
} from "@/lib/auth/session";
import { redirect } from "next/navigation";
import { cookies } from "next/headers";
import { createCheckoutSession } from "@/lib/payments/stripe";
import { createProductCheckoutSession } from "@/lib/payments/stripe";
import { getUser, getUserWithTeam } from "@/lib/db/queries";
import {
validatedAction,
Expand Down Expand Up @@ -103,7 +103,7 @@ export const signIn = validatedAction(signInSchema, async (data, formData) => {
const redirectTo = formData.get("redirect") as string | null;
if (redirectTo === "checkout") {
const priceId = formData.get("priceId") as string;
return createCheckoutSession({ team: foundTeam, priceId });
return createProductCheckoutSession({ team: foundTeam, priceId });
}

redirect("/dashboard");
Expand Down Expand Up @@ -225,7 +225,7 @@ export const signUp = validatedAction(signUpSchema, async (data, formData) => {
const redirectTo = formData.get("redirect") as string | null;
if (redirectTo === "checkout") {
const priceId = formData.get("priceId") as string;
return createCheckoutSession({ team: createdTeam, priceId });
return createProductCheckoutSession({ team: createdTeam, priceId });
}

redirect("/dashboard");
Expand Down
71 changes: 44 additions & 27 deletions app/api/stripe/checkout/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function GET(request: NextRequest) {

try {
const session = await stripe.checkout.sessions.retrieve(sessionId, {
expand: ["customer", "subscription", "payment_intent", "line_items"],
expand: ['customer', 'line_items.data.price.product'],
});

// Check if customer is a string or null
Expand All @@ -26,33 +26,50 @@ export async function GET(request: NextRequest) {
return NextResponse.redirect(new URL("/dashboard", request.url));
}

const paymentStatus = session.payment_status;
console.log("Payment Status:", paymentStatus);
const paymentIntent = session.payment_intent;
if (typeof paymentIntent === "string" || !paymentIntent) {
throw new Error("Invalid payment intent data from Stripe.");
const lineItems = session.line_items?.data;
if (!lineItems || lineItems.length === 0) {
throw new Error('No line items found for this session.');
}
const customerId = session.customer.id;

const subscriptionId =
typeof session.subscription === "string"
? session.subscription
: session.subscription?.id;

let productId, plan;
if (subscriptionId) {
const subscription = await stripe.subscriptions.retrieve(subscriptionId, {
expand: ["items.data.price.product"],
});
plan = subscription.items.data[0]?.price;
productId = (plan.product as Stripe.Product).id;
if (!productId) {
console.warn("No product ID found for this subscription.");
// Handle logic for sessions without a product ID, if applicable
return NextResponse.redirect(new URL("/dashboard", request.url));
}
console.log("lineitems:", JSON.stringify(lineItems, null, 4));
const product = lineItems[0].price?.product;
if (!product) {
throw new Error('No product found for this session.');
}

const productId =
typeof product === 'string'
? product
: product?.id;

console.log("productId:", productId);

const customerId = session.customer.id;
// const subscriptionId =
// typeof session.subscription === 'string'
// ? session.subscription
// : session.subscription?.id;

// if (!subscriptionId) {
// throw new Error('No subscription found for this session.');
// }

// const subscription = await stripe.subscriptions.retrieve(subscriptionId, {
// expand: ['items.data.price.product'],
// });

// const plan = subscription.items.data[0]?.price;

// if (!plan) {
// throw new Error('No plan found for this subscription.');
// }

// const productId = (plan.product as Stripe.Product).id;

// if (!productId) {
// throw new Error('No product ID found for this subscription.');
// }

const userId = session.client_reference_id;
if (!userId) {
console.warn("No user ID found in session's client_reference_id.");
Expand Down Expand Up @@ -90,10 +107,10 @@ export async function GET(request: NextRequest) {
.update(teams)
.set({
stripeCustomerId: customerId,
stripeSubscriptionId: subscriptionId,
stripeSubscriptionId: null, //subscriptionId,
stripeProductId: productId,
planName: plan?.nickname || "",
subscriptionStatus: paymentIntent.status,
planName: null, //(plan.product as Stripe.Product).name,
subscriptionStatus: null, //subscription.status,
updatedAt: new Date(),
})
.where(eq(teams.id, userTeam[0].teamId));
Expand Down
4 changes: 2 additions & 2 deletions lib/payments/actions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use server";

import { redirect } from "next/navigation";
import { createCheckoutSession, createCustomerPortalSession } from "./stripe";
import { createProductCheckoutSession, createCustomerPortalSession } from "./stripe";
import { withTeam } from "@/lib/auth/middleware";

export const checkoutAction = withTeam(async (formData, team) => {
const priceId = formData.get("priceId") as string;
await createCheckoutSession({ team: team, priceId });
await createProductCheckoutSession({ team: team, priceId });
});

export const customerPortalAction = withTeam(async (_, team) => {
Expand Down
34 changes: 33 additions & 1 deletion lib/payments/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: "2024-06-20",
});

export async function createCheckoutSession({
export async function createSubscriptionCheckoutSession({
team,
priceId,
}: {
Expand Down Expand Up @@ -49,6 +49,38 @@ export async function createCheckoutSession({
}
}

export async function createProductCheckoutSession({
team,
priceId,
}: {
team: Team | null;
priceId: string;
}) {
const user = await getUser();

if (!team || !user) {
redirect(`/sign-up?redirect=checkout&priceId=${priceId}`);
}

const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
line_items: [
{
price: priceId,
quantity: 1,
},
],
mode: "payment",
success_url: `${process.env.BASE_URL}/api/stripe/checkout?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.BASE_URL}/pricing`,
customer: team.stripeCustomerId || undefined,
client_reference_id: user.id.toString(),
allow_promotion_codes: true,
});

redirect(session.url!);
}

export async function createCustomerPortalSession(team: Team | null) {
if (!team || !team.stripeCustomerId || !team.stripeProductId) {
redirect("/pricing");
Expand Down

0 comments on commit 343511c

Please sign in to comment.