Skip to content

Commit

Permalink
Integrated Stripe successfully in test mode
Browse files Browse the repository at this point in the history
  • Loading branch information
hemantwasthere committed Jul 31, 2023
1 parent c718971 commit bea4749
Show file tree
Hide file tree
Showing 21 changed files with 310 additions and 43 deletions.
7 changes: 7 additions & 0 deletions app/(dashboard)/(routes)/settings/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as z from "zod";

export const formSchema = z.object({
prompt: z.string().min(1, {
message: "Prompt is required."
}),
});
31 changes: 31 additions & 0 deletions app/(dashboard)/(routes)/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Settings } from "lucide-react";

import { Heading } from "@/components/heading";
import { SubscriptionButton } from "@/components/subscription-button";
import { checkSubscription } from "@/lib/subscription";

const SettingsPage = async () => {
const isPro = await checkSubscription();

return (
<div>
<Heading
title="Settings"
description="Manage account settings."
icon={Settings}
iconColor="text-gray-700"
bgColor="bg-gray-700/1
0"
/>
<div className="px-4 lg:px-8 space-y-4">
<div className="text-muted-foreground text-sm">
{isPro ? "You are currently on a Pro plan." : "You are currently on a free plan."}
</div>
<SubscriptionButton isPro={isPro} />
</div>
</div>
);
}

export default SettingsPage;

4 changes: 3 additions & 1 deletion app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import Navbar from "@/components/navbar";
import { Sidebar } from "@/components/sidebar";
import { getApiLimitCount } from "@/lib/api-limit";
import { checkSubscription } from "@/lib/subscription";

const DashboardLayout = async ({ children }: { children: React.ReactNode }) => {
const apiLimitCount = await getApiLimitCount();
const isPro = await checkSubscription()

return (
<div className="h-full relative">
<div className="hidden h-full md:flex md:w-72 md:flex-col md:fixed md:inset-y-0 bg-gray-900">
<Sidebar apiLimitCount={apiLimitCount} />
<Sidebar isPro={isPro} apiLimitCount={apiLimitCount} />
</div>
<main className="md:pl-72 pb-10">
<Navbar />
Expand Down
12 changes: 6 additions & 6 deletions app/api/code/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";
import { ChatCompletionRequestMessage, Configuration, OpenAIApi } from "openai";

// import { checkSubscription } from "@/lib/subscription";
import { checkSubscription } from "@/lib/subscription";
import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit";

const configuration = new Configuration({
Expand Down Expand Up @@ -35,9 +35,9 @@ export async function POST(req: Request) {
}

const freeTrial = await checkApiLimit();
// const isPro = await checkSubscription();
const isPro = await checkSubscription();

if (!freeTrial) {
if (!freeTrial && !isPro) {
return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 });
}

Expand All @@ -46,9 +46,9 @@ export async function POST(req: Request) {
messages: [instructionMessage, ...messages]
});

// if (!isPro) {
await incrementApiLimit();
// }
if (!isPro) {
await incrementApiLimit();
}

return NextResponse.json(response.data.choices[0].message);
} catch (error) {
Expand Down
13 changes: 6 additions & 7 deletions app/api/conversation/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";
import { Configuration, OpenAIApi } from "openai";

// import { checkSubscription } from "@/lib/subscription";
import { checkSubscription } from "@/lib/subscription";
import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit";

const configuration = new Configuration({
Expand Down Expand Up @@ -31,10 +31,9 @@ export async function POST(req: Request) {
}

const freeTrial = await checkApiLimit();
// const isPro = await checkSubscription();
const isPro = await checkSubscription();

// if (!freeTrial && !isPro) {
if (!freeTrial) {
if (!freeTrial && !isPro) {
return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 });
}

Expand All @@ -43,9 +42,9 @@ export async function POST(req: Request) {
messages
});

// if (!isPro) {
await incrementApiLimit();
// }
if (!isPro) {
await incrementApiLimit();
}

return NextResponse.json(response.data.choices[0].message);
} catch (error) {
Expand Down
12 changes: 6 additions & 6 deletions app/api/image/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";
import { Configuration, OpenAIApi } from "openai";

// import { checkSubscription } from "@/lib/subscription";
import { checkSubscription } from "@/lib/subscription";
import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit";

const configuration = new Configuration({
Expand Down Expand Up @@ -38,9 +38,9 @@ export async function POST(req: Request) {
}

const freeTrial = await checkApiLimit();
// const isPro = await checkSubscription();
const isPro = await checkSubscription();

if (!freeTrial) {
if (!freeTrial && !isPro) {
return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 });
}

Expand All @@ -50,9 +50,9 @@ export async function POST(req: Request) {
size: resolution,
});

// if (!isPro) {
await incrementApiLimit();
// }
if (!isPro) {
await incrementApiLimit();
}

return NextResponse.json(response.data.data);
} catch (error) {
Expand Down
12 changes: 6 additions & 6 deletions app/api/music/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Replicate from "replicate";
import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";

// import { checkSubscription } from "@/lib/subscription";
import { checkSubscription } from "@/lib/subscription";
import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit";

const replicate = new Replicate({
Expand All @@ -24,9 +24,9 @@ export async function POST(req: Request) {
}

const freeTrial = await checkApiLimit();
// const isPro = await checkSubscription();
const isPro = await checkSubscription();

if (!freeTrial) {
if (!freeTrial && !isPro) {
return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 });
}

Expand All @@ -39,9 +39,9 @@ export async function POST(req: Request) {
}
);

// if (!isPro) {
await incrementApiLimit();
// }
if (!isPro) {
await incrementApiLimit();
}

return NextResponse.json(response);
} catch (error) {
Expand Down
67 changes: 67 additions & 0 deletions app/api/stripe/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { auth, currentUser } from "@clerk/nextjs";
import { NextResponse } from "next/server";

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

const settingsUrl = absoluteUrl("/settings");

export async function GET() {
try {
const { userId } = auth();
const user = await currentUser();

if (!userId || !user) {
return new NextResponse("Unauthorized", { status: 401 });
}

const userSubscription = await prismadb.userSubscription.findUnique({
where: {
userId
}
})

if (userSubscription && userSubscription.stripeCustomerId) {
const stripeSession = await stripe.billingPortal.sessions.create({
customer: userSubscription.stripeCustomerId,
return_url: settingsUrl,
})

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

const stripeSession = await stripe.checkout.sessions.create({
success_url: settingsUrl,
cancel_url: settingsUrl,
payment_method_types: ["card"],
mode: "subscription",
billing_address_collection: "auto",
customer_email: user.emailAddresses[0].emailAddress,
line_items: [
{
price_data: {
currency: "INR",
product_data: {
name: "Genius Pro",
description: "Unlimited AI Generations"
},
unit_amount: 200000,
recurring: {
interval: "month"
}
},
quantity: 1,
},
],
metadata: {
userId,
},
})

return new NextResponse(JSON.stringify({ url: stripeSession.url }))
} catch (error) {
console.log("[STRIPE_ERROR]", error);
return new NextResponse("Internal Error", { status: 500 });
}
};
12 changes: 6 additions & 6 deletions app/api/video/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";

import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit";
// import { checkSubscription } from "@/lib/subscription";
import { checkSubscription } from "@/lib/subscription";

const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN!,
Expand All @@ -24,9 +24,9 @@ export async function POST(req: Request) {
}

const freeTrial = await checkApiLimit();
// const isPro = await checkSubscription();
const isPro = await checkSubscription();

if (!freeTrial) {
if (!freeTrial && !isPro) {
return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 });
}

Expand All @@ -39,9 +39,9 @@ export async function POST(req: Request) {
}
);

// if (!isPro) {
await incrementApiLimit();
// }
if (!isPro) {
await incrementApiLimit();
}

return NextResponse.json(response);
} catch (error) {
Expand Down
67 changes: 67 additions & 0 deletions app/api/webhook/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Stripe from "stripe"
import { headers } from "next/headers"
import { NextResponse } from "next/server"

import prismadb from "@/lib/prismadb"
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,
process.env.STRIPE_WEBHOOK_SECRET!
)
} catch (error: any) {
return new NextResponse(`Webhook Error: ${error.message}`, { status: 400 })
}

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

if (event.type === "checkout.session.completed") {
const subscription = await stripe.subscriptions.retrieve(
session.subscription as string
)

if (!session?.metadata?.userId) {
return new NextResponse("User id is required", { status: 400 });
}

await prismadb.userSubscription.create({
data: {
userId: session?.metadata?.userId,
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") {
const subscription = await stripe.subscriptions.retrieve(
session.subscription as string
)

await prismadb.userSubscription.update({
where: {
stripeSubscriptionId: subscription.id,
},
data: {
stripePriceId: subscription.items.data[0].price.id,
stripeCurrentPeriodEnd: new Date(
subscription.current_period_end * 1000
),
},
})
}

return new NextResponse(null, { status: 200 })
};
2 changes: 1 addition & 1 deletion components/free-counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MAX_FREE_COUNTS } from "@/constants";
import { useProModal } from "@/hooks/use-pro-modal";

interface FreeCounterProps {
isPro?: boolean;
isPro: boolean;
apiLimitCount: number;
}

Expand Down
Loading

0 comments on commit bea4749

Please sign in to comment.