bKash PGW : Checkout – Angular8, ASP.Net Core WebAPI

In this post we are going to see bKash PGW integration in Angular8, ASP.Net Core Webapi.

The Basic Flow:

  • Create Grant token by calling token API
  • Then call create payment API with information
  • Then invoke bKash wallet authentication iframe
  • Pass the authentication by providing Wallet number, OTP and PIN
  • Get a callback in execute
  • Then call execute API

Request for merchant credentials to bKash.

  • app_key : “YOUR_APP_KEY”
  • app_secret : “YOUR_SECRET_KEY”
  • username : “YOUR_MERCHANT_USERNAME”
  • password : “YOUR_MERCHANT_PASSWORD”

Back-End

Please overview: https://developer.bka.sh/docs also go through: https://developer.bka.sh/reference

Grant Token:

// GET api/bKash/getbKashToken
[HttpGet("[action]")]
public async Task getbKashToken()
{
    object result = null; object resdata = null;
    try
    {
        using (var httpClientHandler = new HttpClientHandler())
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (messages, cert, chain, errors) => { return true; };
            using (var objClient = new HttpClient(httpClientHandler))
            {
                objClient.DefaultRequestHeaders.TryAddWithoutValidation("username", _objCredentials.bk_username);
                objClient.DefaultRequestHeaders.TryAddWithoutValidation("password", _objCredentials.bk_password);

                string data = "{ " + '"' + "app_key" + '"' + ": " + '"' + _objCredentials.app_key + '"' + ", " + '"' + "app_secret" + '"' + ": " + '"' + _objCredentials.app_secret + '"' + " }";
                var content = new StringContent(data, Encoding.UTF8, "application/json");
                using (HttpResponseMessage res = await objClient.PostAsync(_objAPIs.grantTokenUrl, content))
                {
                    if (res.IsSuccessStatusCode)
                    {
                        var bkresult = res.Content.ReadAsStringAsync().Result;
                        bKmodel _objModel = new bKmodel()
                        {
                            authToken = bkresult,
                            appKey = _objCredentials.app_key,
                            currency = "BDT",
                            merchantInvoiceNumber = Common.genRandomNumber(11),
                            intent = "sale"
                        };

                        resdata = _objModel;
                    }
                }
            }
        }
    }
    catch (Exception) { }
    return result = new
    {
        resdata
    };
}

Create Payment:

// POST:  api/bKash/createPayment
[HttpPost("[action]")]
public async Task createPayment([FromBody]object model)
{
    object result = null; object resdata = null;
    try
    {
        bKmodel _bkModel = JsonConvert.DeserializeObject(model.ToString());
        if (_bkModel != null)
        {
            using (var httpClientHandler = new HttpClientHandler())
            {
                using (var objClient = new HttpClient(httpClientHandler))
                {
                    objClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", _bkModel.authToken);
                    objClient.DefaultRequestHeaders.TryAddWithoutValidation("x-app-key", _objCredentials.app_key);

                    string data = "{ " + '"' + "amount" + '"' + ": " + '"' + _bkModel.amount + '"' + ", " + '"' + "intent" + '"' + ": " + '"' + _bkModel.intent + '"' + ", " + '"' + "currency" + '"' + ": " + '"' + _bkModel.currency + '"' + ", " + '"' + "merchantInvoiceNumber" + '"' + ": " + '"' + _bkModel.merchantInvoiceNumber + '"' + " }";
                    var content = new StringContent(data, Encoding.UTF8, "application/json");
                    using (HttpResponseMessage res = await objClient.PostAsync(_objAPIs.createUrl, content))
                    {
                        if (res.IsSuccessStatusCode)
                        {
                            resdata = res.Content.ReadAsStringAsync().Result;
                        }
                    }
                }
            }
        }
    }
    catch (Exception) { }
    return result = new
    {
        resdata
    };
}

Execute Payment:

// POST: api/bKash/executePayment
[HttpPost("[action]")]
public async Task executePayment([FromBody]object model)
{
    object result = null; object resdata = null;
    try
    {
        bKmodel _bkModel = JsonConvert.DeserializeObject(model.ToString());
        if (_bkModel != null)
        {
            using (var httpClientHandler = new HttpClientHandler())
            {
                using (var objClient = new HttpClient(httpClientHandler))
                {
                    objClient.DefaultRequestHeaders.TryAddWithoutValidation("authorization", _bkModel.authToken);
                    objClient.DefaultRequestHeaders.TryAddWithoutValidation("x-app-key", _objCredentials.app_key);

                    string _exucuteUrl = _objAPIs.exucuteUrl + "/" + _bkModel.paymentID;
                    using (HttpResponseMessage res = await objClient.PostAsync(_exucuteUrl, null))
                    {
                        if (res.IsSuccessStatusCode)
                        {
                            resdata = res.Content.ReadAsStringAsync().Result;
                        }
                    }
                }
            }
        }
    }
    catch (Exception) { }
    return result = new
    {
        resdata
    };
}

Please follow:

Front-End

Generate authorization token by calling back-end.

//Generate bKash Authorization Token
genToken() {
    let result: any;
    this._dataService.get(this._genTokenUrl)
        .subscribe(response => {
            result = response;
            let resdata = result.resdata;
            if (resdata!= null)
                this.initBkash(resdata);            
        }, error => {
            console.log(error);
        });    
}

bKash checkout process.

//bKash Checkout
initBkash(resdata) {
    let dataService = this._dataService;
    let bkPayCreateUrl = this._bkPayCreateUrl;
    let bkPayExecuteUrl = this._bkPayExecuteUrl;

    //Pay Amount
    let amount = 231.00; //Change Amount

    //Authorization Token
    this.token = JSON.parse(resdata.authToken).id_token;

    //Create PaymentModel
    let createPayModel = {
        authToken: this.token,
        amount: amount,
        intent: resdata.intent,
        currency: resdata.currency,
        merchantInvoiceNumber: resdata.merchantInvoiceNumber
    };

    //Execute PaymentModel
    let executePayModel = {
        authToken: this.token,
        paymentID: null
    };

    //Init bKash
    bKash.init({
        paymentMode: 'checkout', 
        paymentRequest: {
            "amount": amount,
            "intent": resdata.intent,
            "currency": resdata.currency,
            "merchantInvoiceNumber": resdata.merchantInvoiceNumber
        },
        //Payment Process
        createRequest: function () {
            dataService.save(createPayModel, bkPayCreateUrl)
                .subscribe(response => {
                    var data = JSON.parse(response.resdata);
                    if (data && data.paymentID != null) {
                        executePayModel.paymentID = data.paymentID;

                        //Call iFrame
                        data.errorCode = null;
                        data.errorMessage = null;
                        bKash.create().onSuccess(data);
                    }
                    else {
                        bKash.create().onError(); 
                    }
                }, error => {
                    bKash.create().onError(); 
                });
        },
        //Payment Execute
        executeRequestOnAuthorization: function () {
            $('#payment_status').val('');
            dataService.save(executePayModel, bkPayExecuteUrl)
                .subscribe(response => {
                    $('#close_button').click();
                    this.result = JSON.parse(response.resdata);
                    if (this.result && this.result.paymentID != null) {
                        $('#bKashFrameWrapper').fadeOut(); 

                        //Save to Database
                        localStorage.setItem('paymentresult', JSON.stringify(this.result));
                        $('#hiddenButton').click();
                    } else {
                        bKash.execute().onError();                      
                    }
                }, error => {
                    bKash.execute().onError(); 
                });
        },
        //On Success
        onSuccess: function(){},
        //Close
        onClose: function () {}
    });

    $('#bKash_button').removeAttr('disabled'); 
}

Finally save transaction details to database

savePayment() {
    var paydata = JSON.parse(localStorage.getItem('paymentresult'));
    this.transResult = JSON.stringify(paydata);
    if(paydata!=null)
    {
        this._dataService.save(paydata, this._bkPaySaveUrl)
            .subscribe(response => {
                if(response != null) 
                    alert(response.resdata);
            }, error => {
                console.log(error);
            }); 
            
        localStorage.removeItem('paymentresult');
    }
}

Payment will complete after pass the authentication by providing wallet number, OTP, PIN.

Download/clone full source code from Hope this will help 🙂

Author:

Since March 2011, have 8+ years of professional experience on software development, currently working as Senior Software Engineer at s3 Innovate Pte Ltd.

3 thoughts on “bKash PGW : Checkout – Angular8, ASP.Net Core WebAPI”

Leave a Reply