From 3f3508eb2ff985179a76a5262ed2f835eeaa1861 Mon Sep 17 00:00:00 2001 From: Shahriar Shojib Date: Thu, 17 Dec 2020 02:20:23 +0600 Subject: [PATCH] Updated Readme Added JSDoc Comments for all public methods Refactor Constructor to use an object instead of parameters Refactor header generation strategy to make the code cleaner --- README.md | 93 ++++++++++++++++++++++++++- package.json | 2 +- src/index.ts | 106 +++++++++++++++++++++++-------- src/interfaces/main.interface.ts | 7 ++ src/utils/request.ts | 4 +- 5 files changed, 179 insertions(+), 33 deletions(-) create mode 100644 src/interfaces/main.interface.ts diff --git a/README.md b/README.md index e40bbe7..f4ac38e 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,98 @@ Nodejs library to accept bkash payments on your backend application -## How to use +--- -`Coming soon` +# How to use + +## Initializing the library + +### `javascript` + +> file `bkash.js` + +```javascript +const BkashGateway = require('bkash-payment-gateway'); + +const bkashConfig = { + baseURL: 'https://checkout.sandbox.bka.sh/v1.2.0-beta', //do not add a trailing slash + key: 'abcdxx2369', + username: 'bkashTest', + password: 'bkashPassword1', + secret: 'bkashSup3rS3cRet', +}; + +const bkash = new BkashGateway(config); +module.exports = bkash; +``` + +### `typescript` + +> file `bkash.ts` + +```typescript +import BkashGateway, { ICreatePayment } from 'bkash-payment-gatway'; + +const bkashConfig: ICreatePayment = { + //get intellisense here + baseURL: 'https://checkout.sandbox.bka.sh/v1.2.0-beta', //do not add a trailing slash + key: 'abcdxx2369', + username: 'bkashTest', + password: 'bkashPassword1', + secret: 'bkashSup3rS3cRet', +}; + +const bkash = new BkashGateway(config); +export default bkash; +``` + +--- + +## Create a payment + +```javascript +const paymentRequest = { + amount: 1000, + orderID: 'ORD1020069', + intent: 'sale', +}; + +const result = await bkash.createPayment(); +console.log(result); +``` + +--- + +## Execute a payment with payment ID + +```javascript +const result = await bkash.executePayment(''); +``` + +--- + +## Query a payment with payment ID + +```javascript +const result = await bkash.queryPayment(''); +``` + +--- + +### Contributing + +- Please Follow the code style and use the prettier config and eslint config provided in the repository +- Feel free to open `issues` or `pull request` for any issues and bugfixes +- If you want to implement new features or write documentation about existing features feel free to do it as well +- To see a list of missing features or to-do's, please visit the `project` section of the github repository + +--- + +### License + +> MIT + +> DISCLAIMER: This software comes with absolutely no warranty and is not affiliated with the company **`Bkash`** in any way. Use at your own risk. Author and Contributors are not responsible for any financial damages, outages etc. ### Author diff --git a/package.json b/package.json index 000b960..fece6e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bkash-payment-gateway", - "version": "1.0.0", + "version": "1.1.0", "description": "Bkash Payment Gateway Library to accept payments on your node.js backend", "main": "dist", "files": [ diff --git a/src/index.ts b/src/index.ts index 79ac895..e9cd7c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,21 @@ import { get, post } from './utils/request'; import { diffSeconds } from './utils/diffSeconds'; import { IHeaders } from './interfaces/headers.interface'; + import { IBkashCreatePaymentResponse, IBkashExecutePaymentResponse, IBkashQueryPaymentResponse, IBkashTokenResponse, } from './interfaces/bkashResponse.interface'; + import { BkashException } from './exceptions/bkashException'; import { ICreatePayment } from './interfaces/createPayment.interface'; +import { IBkashConstructor } from './interfaces/main.interface'; +/** + * Bkash Payment Gateway Main Entrypoint + */ class BkashGateway { private token: string; private refreshToken: string; @@ -18,8 +24,26 @@ class BkashGateway { private readonly key: string; private readonly baseURL: string; private headers: IHeaders; + /** + * + * @param config config object required by the `bkash-payment-gateway` package + * @example + * ``` + * const bkashConfig = { + * baseURL: 'https://checkout.sandbox.bka.sh/v1.2.0-beta/', + * key: 'abcdxx2369', + * username: 'bkashTest', + * password: 'bkashPassword1', + * secret: 'bkashSup3rS3cRet', + * } + * const bkash = new BkashGateway(config) + * ``` + * + */ + + constructor(config: IBkashConstructor) { + const { baseURL, key, password, secret, username } = config; - constructor(baseURL: string, key: string, secret: string, username: string, password: string) { this.baseURL = baseURL; this.key = key; this.secret = secret; @@ -29,8 +53,21 @@ class BkashGateway { }; } - async createPayment(paymentDetails: ICreatePayment): Promise { - const token = await this.getToken(); + /** + * + * @param paymentDetails Information required to start a payment flow + * + * @returns Promise of Bkash Create payment Response + * @example + * ``` + * const result = await bkash.createPayment({ + * amount: 1000, + * orderID: 'ORD1020069', + * intent: 'sale', + * }); + * ``` + */ + createPayment = async (paymentDetails: ICreatePayment): Promise => { const { amount, intent, orderID, merchantAssociationInfo } = paymentDetails; const payload = { @@ -41,37 +78,49 @@ class BkashGateway { merchantAssociationInfo: merchantAssociationInfo ?? '', }; - const headers = { - authorization: token, - 'x-app-key': this.key, - }; + const headers = await this.createTokenHeader(); return await post(`${this.baseURL}/checkout/payment/create`, payload, headers); - } - - async executePayment(paymentID: string): Promise { + }; + + /** + * Execute a payment after an user has completed bkash auth flow + * @param paymentID - Payment ID to Execute + * @example + * ``` + * const result = await bkash.executePayment(paymentID); + * ``` + */ + executePayment = async (paymentID: string): Promise => { try { - const token = await this.getToken(); - const headers = { - authorization: token, - 'x-app-key': this.key, - }; - + const headers = await this.createTokenHeader(); return await post(`${this.baseURL}/checkout/payment/execute/${paymentID}`, null, headers); } catch (error) { throw new BkashException('Timeout of 30 Seconds Exceeded While Executing Payment, Please Query the Payment'); } - } + }; + + /** + * Query Payment From Bkash + * @param paymentID - Payment ID to Query + * + * @example + * ``` + * const result = await bkash.queryPayment(paymentID); + * ``` + */ + queryPayment = async (paymentID: string): Promise => { + const headers = await this.createTokenHeader(); + return await get(`${this.baseURL}/checkout/payment/query/${paymentID}`, headers); + }; - async queryPayment(paymentID: string): Promise { + private createTokenHeader = async (): Promise => { const token = await this.getToken(); - const headers = { + return { authorization: token, 'x-app-key': this.key, }; - return await get(`${this.baseURL}/checkout/payment/query/${paymentID}`, headers); - } - - async getToken(): Promise { + }; + private getToken = async (): Promise => { if (this.token) { const diff = diffSeconds(this.tokenIssueTime); if (diff > 3500) { @@ -99,9 +148,9 @@ class BkashGateway { this.tokenIssueTime = Date.now(); return this.token; } - } + }; - private getInitialToken(): Promise { + private getInitialToken = (): Promise => { return post( `${this.baseURL}/checkout/token/grant`, { @@ -110,9 +159,9 @@ class BkashGateway { }, this.headers ); - } + }; - private newToken(refresh: string): Promise { + private newToken = (refresh: string): Promise => { return post( `${this.baseURL}/checkout/token/refresh`, { @@ -122,6 +171,7 @@ class BkashGateway { }, this.headers ); - } + }; } + export default BkashGateway; diff --git a/src/interfaces/main.interface.ts b/src/interfaces/main.interface.ts new file mode 100644 index 0000000..3b8147f --- /dev/null +++ b/src/interfaces/main.interface.ts @@ -0,0 +1,7 @@ +export interface IBkashConstructor { + baseURL: string; + key: string; + secret: string; + username: string; + password: string; +} diff --git a/src/utils/request.ts b/src/utils/request.ts index 0f3944b..57bd800 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -7,7 +7,7 @@ interface IPayload { [key: string]: unknown; } -export function get(url: string, additionalHeaders: IHeaders, returnsJSON = true): Promise { +export function get(url: string, additionalHeaders: IHeaders): Promise { return fetch(url, { method: 'GET', headers: { @@ -15,7 +15,7 @@ export function get(url: string, additionalHeaders: IHeaders, returnsJSON = t Accept: 'application/json', ...additionalHeaders, }, - }).then((r) => (returnsJSON ? r.json() : r.text())); + }).then((r) => r.json()); } export async function post(url: string, payload: IPayload = {}, additionalHeaders: IHeaders): Promise {