DEV Community

Cover image for Bkash Payment with NextJS & TypeScript
Arfatur Rahman
Arfatur Rahman

Posted on • Edited on

Bkash Payment with NextJS & TypeScript

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"
Enter fullscreen mode Exit fullscreen mode
  • 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

  1. 3 page(Home, success, callback)
  2. 1 API middleware (/create/bkash_auth)
  3. 2 api(/create , /callback)
  4. 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Callback page

"use client";
import CallBackComponent from "@/component/callback-component";
import React, { Suspense } from "react";

const CallBackPage = () => {
  return (
    <Suspense>
      <CallBackComponent />
    </Suspense>
  );
};

export default CallBackPage;
Enter fullscreen mode Exit fullscreen mode

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,
    });
  }
Enter fullscreen mode Exit fullscreen mode

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 });
  }
}

Enter fullscreen mode Exit fullscreen mode

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 });
  }
}

Enter fullscreen mode Exit fullscreen mode

After adding codes run bellow command

  • Run npm i
  • Then npm run dev

Top comments (0)