I get following error when I click checkout button
TRPCClientError at TRPCClientError.from (TRPCClientError-38f9a32a.mjs:33:20) at eval (httpBatchLink-d0f9eac9.mjs:204:105)
I am trying to integrate Razorpay in NextJS 14 website. I'm using MongoDB as database.
I have implemented a paymentRouter in tRPC. All code related to DB & order creation of Razorpay is in this file.
# payment-router.ts
import { z } from "zod";
import { privateProcedure, router } from "./trpc";
import { TRPCError } from "@trpc/server";
import { getPayloadClient } from "../lib/get-payload";
import shortid from "shortid";
import { NextResponse } from "next/server";
import { Orders } from "razorpay/dist/types/orders";
import Razorpay from "razorpay";
export const paymentRouter = router({
createSession: privateProcedure
.input(z.object({ productIds: z.array(z.string()) }))
.mutation(async ({ ctx, input }) => {
const { user } = ctx;
let { productIds } = input;
if (productIds.length === 0) {
throw new TRPCError({ code: "BAD_REQUEST" });
}
const payload = await getPayloadClient();
const razorpay = new Razorpay({
key_id: `${process.env.RAZORPAY_ID}`,
key_secret: `${process.env.RAZORPAY_KEY}`,
});
const { docs: products } = await payload.find({
collection: "products",
where: {
id: {
in: productIds,
},
},
});
const filteredProducts = products.filter((prod) => Boolean(prod.priceId));
const amount = filteredProducts.reduce(
(total, { price }) => total + price,
0
);
const options = {
amount: Math.round(amount * 100),
currency: "INR",
customer_id: user.id,
payment_capture: true,
receipt: shortid.generate(),
notes: {
// These notes will be added to your transaction. So you can search it within their dashboard.
// Also, it's included in webhooks as well. So you can automate it.
userId: `${user.id}`,
},
};
const razorpayOrder = razorpay.orders.create(options);
try {
const order: Orders.RazorpayOrder = await razorpayOrder;
return { order };
} catch (err) {
console.log(err);
const dummyOrder = {
amount: (await razorpayOrder).amount,
// id: (await razorpayOrder).id,
entity: (await razorpayOrder).entity,
amount_paid: (await razorpayOrder).amount_paid,
amount_due: (await razorpayOrder).amount_due,
status: (await razorpayOrder).status,
attempts: (await razorpayOrder).attempts,
created_at: (await razorpayOrder).created_at,
description: (await razorpayOrder).description,
token: (await razorpayOrder).token,
currency: (await razorpayOrder).currency,
receipt: (await razorpayOrder).receipt,
notes: (await razorpayOrder).notes,
};
return { order: dummyOrder };
}
}),
});
I'm returning the created order from this file to front-end & recieving it in page.tsx of Cart
# page.tsx (Cart)
const Page = () => {
const { items, removeItem } = useCart()
const productIds = items.map(({ product }) => product.id)
const { mutate: createCheckoutSession, isLoading, } = trpc.payment.createSession.useMutation({
onSuccess: async ({ order }) => {
// const key = process.env.RAZORPAY_KEY
console.log("amount:", order.amount)
const orderOptions = {
// key: key,
amount: order.amount,
currency: order.currency,
// orderId: order.id,
name: "test",
// payment_capture: order.payment_capture,
receipt: order.receipt,
notes: order.notes,
description: order.description,
}
const paymentObject = new (window as any).Razorpay(orderOptions);
paymentObject.open();
},
onError(error, variables, context) {
console.log(error, variables, context)
},
})
return (
<div className='mt-6'>
<Button
disabled={isLoading || items.length === 0}
className='w-full'
size='lg'
onClick={() => createCheckoutSession({ productIds })}
>
Checkout
{isLoading
? (<Loader2 className='h-4 w-4 animate-spin ml-1.5' />)
: null}
</Button>
</div>
)
What should I do?