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/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",