Razorpay Subscription Based Model Integration in CrossPostHub
CrossPostHub is a platform that allows users to cross-post content to multiple social media platforms. In this guide, we will walk through the process of integrating a subscription-based model in CrossPostHub using Razorpay. To implement this, I saved all the subscription plans in the database and fetched them on the client side to display to the user. Once a user selects a plan, a subscription is created on the server side using the Razorpay API. Additionally, I set up a webhook to listen to subscription events and update the user's subscription status in the database.
Integration
So there are three main parts to this integration:
- Displaying Subscription Plans: Fetch the subscription plans from the database and display them to the user.
- Creating a Subscription: When a user selects a plan, create a subscription using the Razorpay API.
- Webhook for Subscription Events: Set up a webhook to listen to subscription events and update the user's subscription status in the database.
Displaying Subscription Plans
To display the subscription plans, I fetched them from the database and rendered them on the client side. Here's a code example what it looks like:
// Fetch subscription plans from the server side and cache them for 24 hours using Redis for faster retrieval
export async function GET(request: NextRequest) {
try {
const cachedPricingPlansKey = "pricingPlans";
const cachedPricingPlans = await redis.get(cachedPricingPlansKey);
if (cachedPricingPlans) {
console.log("Returning cached pricing plans");
return NextResponse.json(
{ pricingPlans: JSON.parse(cachedPricingPlans) },
{ status: 200 }
);
}
const pricingPlans = await prisma.plan.findMany();
// Cache the pricing plans for 24 hours
await redis.set(cachedPricingPlansKey, JSON.stringify(pricingPlans), {
EX: 24 * 60 * 60,
});
return NextResponse.json({ pricingPlans }, { status: 200 });
} catch (error) {
return NextResponse.json({ error: "An error occurred" }, { status: 500 });
}
}
// Fetch subscription plans from the client side
fetchPricingPlans: async () => {
try {
const { data } = await axios.get("/api/payment/pricing");
set({ pricingPlans: data.pricingPlans });
} catch (error: any) {
console.error("Fetch Pricing Plan Error:", error);
} finally {
set({ isFetchingPlans: false });
}
},
Creating a Subscription
I Created a SubscriptionButton component that accepts planId as a prop and when user clicks on it, it creates a subscription using the Razorpay API.
const response = await axios.post("/api/payment/subscribe", {
planId,
userId: data.user.id,
});
const { short_url, subscriptionId } = response.data;
if (!short_url) {
toast({
title: "An error occurred",
description:
response.data.error ||
"Failed to initiate subscription. Please try again.",
});
router.push("/payment/failed");
return;
}
// Redirect the user to the Razorpay checkout page
window.location.href = short_url;
Webhook for Subscription Events
I set up a webhook to listen to subscription events from Razorpay and update the user's subscription status in the database. The events I listened to were: subscription.activated, subscription.charged, subscription.completed, subscription.failed, subscription.pending