From d321232ce8cb1006d97f05f5d950635bfe9bbb08 Mon Sep 17 00:00:00 2001 From: Prashant Varma Date: Wed, 16 Oct 2024 21:07:29 +0530 Subject: [PATCH] feat: cashfree integration --- apps/client/app/api/payment/initiate/route.ts | 47 +++++++++++++++++++ .../api/payment/status/[order_id]/route.ts | 27 +++++++++++ apps/client/app/globals.css | 17 +++++++ apps/client/lib/cashfree.js | 4 ++ package-lock.json | 10 ++++ 5 files changed, 105 insertions(+) create mode 100644 apps/client/app/api/payment/initiate/route.ts create mode 100644 apps/client/app/api/payment/status/[order_id]/route.ts create mode 100644 apps/client/lib/cashfree.js diff --git a/apps/client/app/api/payment/initiate/route.ts b/apps/client/app/api/payment/initiate/route.ts new file mode 100644 index 00000000..4ed4e16b --- /dev/null +++ b/apps/client/app/api/payment/initiate/route.ts @@ -0,0 +1,47 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const response = await fetch("https://sandbox.cashfree.com/pg/orders", { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + "x-api-version": "2023-08-01", + "x-client-id": process.env.CASHFREE_CLIENT_ID as string, + "x-client-secret": process.env.CASHFREE_CLIENT_SECRET as string, + }, + body: JSON.stringify({ + customer_details: { + customer_id: body.customer_id, + customer_phone: body.customer_phone, + }, + order_id: body.order_id, + order_amount: body.order_amount, + order_currency: "INR", + order_meta: { + notify_url: "https://webhook.site/41583a44-713e-4ba7-a4f1-4a954d84cf08", // TODO: add a webhook + payment_methods: "cc,dc,upi", + }, + }), + }); + + const data = await response.json(); + + if (!response.ok) { + return NextResponse.json( + { message: data.message }, + { status: response.status } + ); + } + + return NextResponse.json(data, { status: 200 }); + } catch (error) { + return NextResponse.json( + { message: "Something went wrong", error }, + { status: 500 } + ); + } +} diff --git a/apps/client/app/api/payment/status/[order_id]/route.ts b/apps/client/app/api/payment/status/[order_id]/route.ts new file mode 100644 index 00000000..6fbd52dd --- /dev/null +++ b/apps/client/app/api/payment/status/[order_id]/route.ts @@ -0,0 +1,27 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET( + req: NextRequest, + { params }: { params: { order_id: string } } +) { + const { order_id } = params; + const response = await fetch( + `https://sandbox.cashfree.com/pg/orders/${order_id}`, + { + method: "GET", + headers: { + accept: "application/json", + "content-type": "application/json", + "x-api-version": "2023-08-01", + "x-client-id": process.env.CASHFREE_CLIENT_ID as string, + "x-client-secret": process.env.CASHFREE_CLIENT_SECRET as string, + }, + } + ); + const data = await response.json(); + if (data.order_status === "PAID") { + return NextResponse.redirect(new URL("/", req.url)); + } else { + return NextResponse.redirect(new URL("/404", req.url)); + } +} diff --git a/apps/client/app/globals.css b/apps/client/app/globals.css index 55673c52..8b2a2637 100644 --- a/apps/client/app/globals.css +++ b/apps/client/app/globals.css @@ -116,4 +116,21 @@ body { ); border-image-slice: 1; border-image-width: 1 1 1 0; +<<<<<<< Updated upstream +======= +} */ + + + +@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap'); + +@tailwind base; +@tailwind components; +@tailwind utilities; +body{ + overflow-x: hidden +} +html { + @apply bg-gray-100; +>>>>>>> Stashed changes } \ No newline at end of file diff --git a/apps/client/lib/cashfree.js b/apps/client/lib/cashfree.js new file mode 100644 index 00000000..ea521493 --- /dev/null +++ b/apps/client/lib/cashfree.js @@ -0,0 +1,4 @@ +import {load} from '@cashfreepayments/cashfree-js'; +export const cashfree = await load({ + mode: "sandbox" //or production +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1bfc584c..631dfc56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "react-dom": "^18", "react-hook-form": "^7.53.0", "react-hot-toast": "^2.4.1", + "react-icons": "^5.3.0", "react-wrap-balancer": "^1.1.1", "recharts": "^2.12.7", "tailwind-merge": "^2.5.2", @@ -10870,6 +10871,15 @@ "react-dom": ">=16" } }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",