/// <summary>
        /// Makes an STK Push payment request to MPESA API Server.
        /// </summary>
        /// <param name="lipaNaMpesaOnline">
        /// Data transfer object containing properties for the Lipa Na Mpesa Online API endpoint.
        /// </param>
        /// <param name="accesstoken">Acccesstoken retrieved by the <c>GetAuthTokenAsync</c> method.</param>
        /// <param name="mpesaRequestEndpoint">Set to <c>MpesaRequestEndpoint.LipaNaMpesaOnline</c></param>
        /// <param name="cancellationToken">Cancellation Token</param>
        /// <returns>A JSON string containing LNMO response data from MPESA API Server</returns>
        public LipaNaMpesaOnlinePushStkResponse MakeLipaNaMpesaOnlinePayment(LipaNaMpesaOnline lipaNaMpesaOnline, string accesstoken, string mpesaRequestEndpoint, CancellationToken cancellationToken = default)
        {
            var validator = new LipaNaMpesaOnlineValidator();
            var results   = validator.Validate(lipaNaMpesaOnline);

            return(!results.IsValid
                ? throw new MpesaAPIException(HttpStatusCode.BadRequest, string.Join(Environment.NewLine, results.Errors.Select(x => x.ErrorMessage.ToString())))
                : MpesaPostRequestAsync <LipaNaMpesaOnlinePushStkResponse>(lipaNaMpesaOnline, accesstoken, mpesaRequestEndpoint, cancellationToken).GetAwaiter().GetResult());
        }
        private async Task ExecuteMpesaStkCommand()
        {
            try
            {
                var mpesaPayment = new LipaNaMpesaOnline
                                   (
                    businessShortCode: mpesaAPIConfiguration.LNMOshortCode,
                    timeStamp: DateTime.Now,
                    transactionType: Transaction_Type.CustomerPayBillOnline,
                    amount: Amount,
                    partyA: PhoneNumber,
                    partyB: mpesaAPIConfiguration.LNMOshortCode,
                    phoneNumber: PhoneNumber,
                    callBackUrl: mpesaAPIConfiguration.CallBackUrl.Replace("{requestId}", Guid.NewGuid().ToString()),
                    accountReference: AccountReference,
                    transactionDescription: TransactionDescription,
                    passkey: mpesaAPIConfiguration.PassKey
                                   );

                var stkResults = await _mpesaClient.MakeLipaNaMpesaOnlinePaymentAsync(mpesaPayment, await RetrieveAccessToken(), MpesaRequestEndpoint.LipaNaMpesaOnline);

                stkResults.PhoneNumber = PhoneNumber;

                var navigationParams = new NavigationParameters();
                navigationParams.Add("PushSTKResponse", JsonConvert.SerializeObject(stkResults));
                await _navigationService.NavigateAsync("MpesaResultsPage", navigationParams);
            }
            catch (MpesaAPIException ex)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    _dialogs.Alert(new AlertConfig()
                                   .SetMessage(ex.Message.ToString())
                                   .SetTitle(ex.StatusCode.ToString()));
                });
            }
            catch (Exception ex)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    _dialogs.Alert(new AlertConfig()
                                   .SetMessage(ex.Message.ToString())
                                   .SetTitle("Error"));
                });
            }
        }
        public async Task <IActionResult> MpesaPayment(LipaNaMpesaOnlineViewModel lipaNaMpesaOnline)
        {
            LipaNaMpesaOnlinePushStkResponse mpesaPaymentRequest;

            try
            {
#if DEBUG
                var generatedCallBackUrl = _mpesaApiConfiguration.CallBackUrl.Replace("{requestId}", Guid.NewGuid().ToString());
#else
                var generatedCallBackUrl = _linkGenerator.GetUriByAction(_httpContextAccessor.HttpContext,
                                                                         action: nameof(APIControllers.PaymentCallbackController.LipaNaMpesaCallback),
                                                                         controller: nameof(APIControllers.PaymentCallbackController).Replace("Controller", ""),
                                                                         values: new { requestId = Guid.NewGuid() },
                                                                         scheme: Request.Scheme);
#endif
                var mpesaPayment = new LipaNaMpesaOnline
                                   (
                    businessShortCode: _mpesaApiConfiguration.LNMOshortCode,
                    timeStamp: DateTime.Now,
                    transactionType: Transaction_Type.CustomerPayBillOnline,
                    amount: lipaNaMpesaOnline.Amount,
                    partyA: lipaNaMpesaOnline.PhoneNumber,
                    partyB: _mpesaApiConfiguration.LNMOshortCode,
                    phoneNumber: lipaNaMpesaOnline.PhoneNumber,
                    callBackUrl: generatedCallBackUrl,
                    accountReference: lipaNaMpesaOnline.AccountReference,
                    transactionDescription: lipaNaMpesaOnline.TransactionDesc,
                    passkey: _mpesaApiConfiguration.PassKey
                                   );

                mpesaPaymentRequest = await _mpesaClient.MakeLipaNaMpesaOnlinePaymentAsync(mpesaPayment, await RetrieveAccessToken(), MpesaRequestEndpoint.LipaNaMpesaOnline);
            }
            catch (MpesaAPIException ex)
            {
                _logger.LogError(ex, ex.Message);
                return(View().WithDanger("Error", ex.Message));
            }

            var pushStkResponse = mpesaPaymentRequest;
            pushStkResponse.PhoneNumber = lipaNaMpesaOnline.PhoneNumber;

            return(RedirectToAction(nameof(ShowMpesaResult), pushStkResponse).WithInfo("Info", "Please wait for confirmation message to arrive on your phone."));
        }