Skip to content

Commit

Permalink
add stripe api
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorVation committed Jun 2, 2023
1 parent 322a373 commit 0090700
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 0 deletions.
60 changes: 60 additions & 0 deletions app/(introducty)/api/users/stripe/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { z } from "zod";
import { fromZodError } from "zod-validation-error";
import getUser from "~/lib/getUser";

import { stripe } from "~/lib/stripe";
import { getUserSubscriptionPlan } from "~/lib/getUserSubscriptionPlan";
// import { absoluteUrl } from "@/lib/utils";

const billingUrl = `${process.env.NEXT_PUBLIC_BASE_URL}/dashboard/billing`;

export async function GET(req: Request) {
try {
const authUser = await getUser();
if (!authUser) {
return new Response(null, { status: 403 });
}

const subscriptionPlan = await getUserSubscriptionPlan(authUser.id);

// The user is on the pro plan.
// Create a portal session to manage subscription.
if (subscriptionPlan.isPro && subscriptionPlan.stripeCustomerId) {
const stripeSession = await stripe.billingPortal.sessions.create({
customer: subscriptionPlan.stripeCustomerId,
return_url: billingUrl,
});

return new Response(JSON.stringify({ url: stripeSession.url }));
}

// The user is on the free plan.
// Create a checkout session to upgrade.
const stripeSession = await stripe.checkout.sessions.create({
success_url:
billingUrl + "/?success=true&session_id={CHECKOUT_SESSION_ID}",
cancel_url: billingUrl + "/?canceled=true",
payment_method_types: ["card"],
mode: "subscription",
billing_address_collection: "auto",
customer_email: authUser.email,
line_items: [
{
price: "price_1NBkWwFCei1YZE2rb3mHzq4t",
quantity: 1,
},
],
metadata: {
userId: authUser.id,
},
});

return new Response(JSON.stringify({ url: stripeSession.url }));
} catch (error) {
if (error instanceof z.ZodError) {
return new Response(fromZodError(error).message, { status: 422 });
}
console.error(error);
return new Response(null, { status: 500 });
}
}
73 changes: 73 additions & 0 deletions app/(introducty)/api/webhooks/stripe/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { headers } from "next/headers";
import Stripe from "stripe";

import { stripe } from "~/lib/stripe";

export async function POST(req: Request) {
const body = await req.text();
const signature = headers().get("Stripe-Signature") as string;

let event: Stripe.Event;

try {
event = stripe.webhooks.constructEvent(
body,
signature,
"whsec_22b544a4d87bb0239b97f65fd97494d7946d368f9b8850b14a43d8f854b74f5c"
);
} catch (error) {
return new Response(`Webhook Error: ${error.message}`, { status: 400 });
}

const session = event.data.object as Stripe.Checkout.Session;

if (event.type === "checkout.session.completed") {
// Retrieve the subscription details from Stripe.
const subscription = await stripe.subscriptions.retrieve(
session.subscription as string
);

console.log(subscription);

// Update the user stripe into in our database.
// Since this is the initial subscription, we need to update
// the subscription id and customer id.

// await db.user.update({
// where: {
// id: session?.metadata?.userId,
// },
// data: {
// stripeSubscriptionId: subscription.id,
// stripeCustomerId: subscription.customer as string,
// stripePriceId: subscription.items.data[0].price.id,
// stripeCurrentPeriodEnd: new Date(
// subscription.current_period_end * 1000
// ),
// },
// });
}

if (event.type === "invoice.payment_succeeded") {
// Retrieve the subscription details from Stripe.
const subscription = await stripe.subscriptions.retrieve(
session.subscription as string
);
console.log(subscription);

// Update the price id and set the new period end.
// await db.user.update({
// where: {
// stripeSubscriptionId: subscription.id,
// },
// data: {
// stripePriceId: subscription.items.data[0].price.id,
// stripeCurrentPeriodEnd: new Date(
// subscription.current_period_end * 1000
// ),
// },
// });
}

return new Response(null, { status: 200 });
}
6 changes: 6 additions & 0 deletions lib/stripe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Stripe from "stripe";

export const stripe = new Stripe(process.env.STRIPE_API_KEY, {
apiVersion: "2022-11-15",
typescript: true,
});
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"react-hot-toast": "^2.4.1",
"react-qr-code": "^2.0.11",
"short-uuid": "^4.2.2",
"stripe": "^12.7.0",
"tailwind-merge": "^1.12.0",
"tailwindcss": "3.3.1",
"tailwindcss-animate": "^1.0.5",
Expand Down

0 comments on commit 0090700

Please sign in to comment.