Bkash Payment with NextJS & TypeScript
Arfatur Rahman
Posted on May 7, 2024
Run code from github
You can get and run code from here Bkash github repo
After donwloading code
- create an
.env
- Copy bellow code
# BKASH INTEGRESION
bkash_username = ''
bkash_password = ''
bkash_api_key = ''
bkash_secret_key = ''
bkash_grant_token_url = https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/checkout/token/grant
bkash_create_payment_url = https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/checkout/create
bkash_execute_payment_url = https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/checkout/execute
bkash_refund_transaction_url = https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized/checkout/payment/refund
bkash_base_url_for_api = "http://localhost:3000"
NEXT_PUBLIC_bkash_base_url_for_frontend = "http://localhost:3000"
- Run
npm i
- Then
npm run dev
Create your own
Create a new apps if you don't have any project ye by following NextJS with Tailwind
Necessary files
- 3 page(Home, success, callback)
- 1 API middleware (/create/bkash_auth)
- 2 api(/create , /callback)
- 3 component (callback-component, form-component, success-component)
Required Packages
- react-hot-toast
- uuid & @types/uuid
- zod
Creating 3 pages
Home page
import FormComponent from "@/component/form-component";
import { Metadata } from "next";
import { Suspense } from "react";
export const metadata: Metadata = {
title: "Home | Arfatur Rahman",
description: "Practice Bkash payment with sandbox",
};
export default function Home() {
return (
// Suspense is required for useSearchParams in component inside
<Suspense>
<FormComponent />
</Suspense>
);
}
Success page
import SuccessComponent from "@/component/success-component";
import { Metadata } from "next";
import React from "react";
export const metadata: Metadata = {
title: "Success | Arfatur Rahman",
description: "Practice Bkash payment with sandbox",
};
const SuccessPage = () => {
return <SuccessComponent />;
};
export default SuccessPage;
Callback page
"use client";
import CallBackComponent from "@/component/callback-component";
import React, { Suspense } from "react";
const CallBackPage = () => {
return (
<Suspense>
<CallBackComponent />
</Suspense>
);
};
export default CallBackPage;
API Middleware
bkash_auth
export const bkash_auth = async () => {
try {
const data = await fetch(process.env.bkash_grant_token_url as string, {
method: "POST",
body: JSON.stringify({
app_key: process.env.bkash_api_key,
app_secret: process.env.bkash_secret_key,
}),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
username: process.env.bkash_username as string,
password: process.env.bkash_password as string,
},
}).then((res) => res.json());
return data.id_token;
} catch (error) {
return new Response((error as any).message || "You're not authorized", {
status: 401,
});
}
Creating 2 API's
Create API
import { z } from "zod";
import { v4 as uuidv4 } from "uuid";
import { bkash_auth } from "./bkash-middleware";
export async function POST(req: Request) {
try {
const json = await req.json();
const { amount } = z
.object({
amount: z.string({ required_error: "amount must be string" }),
})
.parse(json);
const id_token = await bkash_auth();
const data = await fetch(process.env.bkash_create_payment_url as string, {
method: "POST",
body: JSON.stringify({
mode: "0011",
payerReference: " ",
callbackURL: `${process.env.bkash_base_url_for_api}/callback?id_token=${id_token}`,
amount: amount,
currency: "BDT",
intent: "sale",
merchantInvoiceNumber: "Inv" + uuidv4().substring(0, 5),
}),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
authorization: id_token,
"x-app-key": process.env.bkash_api_key as string,
},
}).then((bRes) => bRes.json());
if (!data.bkashURL) {
return new Response(JSON.stringify(data), {
status: 401,
});
}
return new Response(JSON.stringify({ bkashURL: data.bkashURL }), {
status: 201,
});
} catch (error) {
console.log(error, "from error");
if (error instanceof z.ZodError) {
return new Response(JSON.stringify(error.issues), { status: 422 });
}
return new Response(null, { status: 500 });
}
}
Callback API
import { z } from "zod";
export async function POST(req: Request) {
try {
const json = await req.json();
const { paymentID, id_token } = z
.object({
paymentID: z.string(),
id_token: z.string(),
})
.parse(json);
const data = await fetch(process.env.bkash_execute_payment_url as string, {
method: "POST",
body: JSON.stringify({
paymentID: paymentID as string,
}),
headers: {
"Content-Type": "application/json",
Accept: "application/json",
authorization: id_token,
"x-app-key": process.env.bkash_api_key as string,
},
})
.then((bRes) => {
return bRes.json();
})
.catch((e) => console.log(e, "Error from api"));
if (data && data.statusCode === "0000") {
// YOu can write your code here After successfully pay
return new Response(JSON.stringify({ success: true }), { status: 201 });
} else {
return new Response(JSON.stringify({ success: false }), { status: 201 });
}
} catch (error) {
console.log((error as any).message, "from error");
return new Response(null, { status: 500 });
}
}
After adding codes run bellow command
- Run
npm i
- Then
npm run dev
💖 💪 🙅 🚩
Arfatur Rahman
Posted on May 7, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.