/// <summary>
        /// Send transaction to server
        /// </summary>
        /// <param name="card">The card information</param>
        /// <param name="command">The definition of the request is for payment or refund</param>
        /// <param name="amount">The amount of transaction</param>
        /// <param name="date">Date time transaction processed</param>
        /// <param name="transactionContent">Note of transaction</param>
        /// <param name="_version">Version of API, default 1.0.1</param>
        /// <returns>The transaction response information</returns>
        public static async Task <ProcessTransactionResponse> ProcessTransaction(Card card, COMMAND command, int amount, DateTime date,
                                                                                 string transactionContent, string _version = "1.0.1")
        {
            TransactionInfo info = new TransactionInfo
            {
                command            = command == COMMAND.PAY ? "pay" : "refund",
                cardCode           = card.CardCode,
                owner              = card.Owners,
                cvvCode            = card.CVV,
                dateExpired        = card.DateExpired,
                transactionContent = transactionContent,
                amount             = amount,
                createdAt          = Utilities.ConvertDateToString(date)
            };
            ProcessTransactionRequest body = new ProcessTransactionRequest()
            {
                version     = _version,
                transaction = info,
                appCode     = card.AppCode,
                hashCode    = Utilities.MD5Hash(JsonConvert.SerializeObject(new
                {
                    secretKey   = card.SecurityKey,
                    transaction = info
                }))
            };
            string result = await Utilities.GetWebContent(Config.API_INFO.BASE_URL + Config.API_INFO.PROCESS_URL,
                                                          HttpMethod.Patch, JsonConvert.SerializeObject(body));

            ProcessTransactionResponse response = JsonConvert.DeserializeObject <ProcessTransactionResponse>(result);

            return(response);
        }
        /// <summary>
        /// Handle click event PermitBut when process pay rental money transaction
        /// </summary>
        private async void PermitButWhenPay()
        {
            Config.RENT_BIKE_STATUS = Config.RENT_BIKE.RENT_BIKE;
            ProcessTransactionResponse response = null;

            if (this.deposit < this.rentalMoney)
            {
                response = await InterbankService.ProcessTransaction(Config.CARD_INFO, API_INFO.COMMAND.PAY, this.rentalMoney - this.deposit,
                                                                     DateTime.Now, "Pay Rental Money");
            }
            else if (this.deposit > this.rentalMoney)
            {
                response = await InterbankService.ProcessTransaction(Config.CARD_INFO, API_INFO.COMMAND.REFUND, this.deposit - this.rentalMoney,
                                                                     DateTime.Now, "Refund deposit");
            }
            string error = response.errorCode;

            if (error == "00")
            {
                Transaction transaction = returnBikeController.UpdatePaymentTransaction(transactionId, this.rentalMoney);
                returnBikeController.UpdateStationAfterReturnbike(this.stationId, RENTAL_BIKE_CATEGORY);
                MessageBox.Show("giao dịch thành công", "Thông Báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                homePageForm.Show(this);
            }
            this.Hide();
        }
        /// <summary>
        /// Handle click event PermitBut when process rent bike transaction
        /// </summary>
        private async void PermitButWhenRentBike()
        {
            Config.RENT_BIKE_STATUS = Config.RENT_BIKE.RENTING_BIKE;
            ProcessTransactionResponse result = await InterbankService.ProcessTransaction(Config.CARD_INFO, Config.API_INFO.COMMAND.PAY, this.deposit, DateTime.Now,
                                                                                          noteTxt.Text == ""? "Transaction content" : noteTxt.Text);

            string error = result.errorCode;

            if (error == "00")
            {
                Transaction transaction = rentBikeController.CreateDepositTransaction(1, Config.RENTAL_BIKE.QRCode, this.deposit);
                if (transaction == null)
                {
                    MessageBox.Show("Hệ thống không thể lưu thông tin giao dịch", "Thông Báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                this.transactionId = transaction.TransactionId;
                rentBikeForm.FillRentingBikeForm();
                rentBikeController.BeginRentingBike(Config.RENTAL_BIKE.BikeId);
                rentBikeForm.Show(this, Config.RENT_BIKE_STATUS);
            }
            else if (error == "01" || error == "02" || error == "05")
            {
                MessageBox.Show(API_INFO.ERROR_CODE[result.errorCode], "Thông Báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                cardInformationForm.Show(this);
            }
            else
            {
                MessageBox.Show(API_INFO.ERROR_CODE[result.errorCode], "Thông Báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            this.Hide();
        }
        public void ProcessTransactionNotEnoughMoneyTest()
        {
            Task <ProcessTransactionResponse> response = InterbankService.ProcessTransaction(testCard, COMMAND.PAY, 700000, DateTime.Now, "Pay Deposit");

            response.Wait();
            ProcessTransactionResponse result = response.Result;

            Assert.AreEqual("02", result.errorCode);
        }
        public IMovilwayApiResponse PerformOperation(IMovilwayApiRequest requestObject)
        {
            var request  = (ProcessExternalTransactionRequestBody)requestObject;
            var response = new ProcessExternalTransactionResponseBody();

            // Get a session for the configured super user
            var balance = new ServiceExecutionDelegator <GetBalanceResponseBody, GetBalanceRequestBody>().ResolveRequest(
                new GetBalanceRequestBody
            {
                AuthenticationData = new AuthenticationData()
                {
                    Username = ConfigurationManager.AppSettings["ProincoLogin"],
                    Password = ConfigurationManager.AppSettings["ProincoPwd"]
                },
                DeviceType = int.Parse(ConfigurationManager.AppSettings["ProincoDeviceType"]),
                Platform   = request.Platform
            }, ApiTargetPlatform.Kinacu, ApiServiceName.GetBalance);

            if ((balance.ResponseCode ?? -1) != 0)
            {
                response.ResponseCode    = 96;
                response.ResponseMessage = (balance.ResponseCode ?? 0) + "-Su transaccion no pudo ser procesada por problemas al consultar el stock";
                return(response);
            }

            if (balance.StockBalance < request.Amount)
            {
                response.ResponseCode    = 97;
                response.ResponseMessage = "Su transaccion no pudo ser procesada por falta de stock";
                return(response);
            }

            var ibankClient = GetProviderForEntity(request.TargetEntity);

            logger.InfoLow("Comienza el ProcessExternalTransaction");

            string myAgent = new Utils().GetAgentPdv(request.Agent);
            // Need to get the national ID:
            var agentInfo = new ServiceExecutionDelegator <GetAgentInfoResponseBody, GetAgentInfoRequestBody>().ResolveRequest(
                new GetAgentInfoRequestBody()
            {
                AuthenticationData = request.AuthenticationData,
                Agent      = request.Agent,
                DeviceType = request.DeviceType
            }, ApiTargetPlatform.Kinacu, ApiServiceName.GetAgentInfo);

            logger.InfoLow("Params: " + request.Agent + " - " + agentInfo.AgentInfo.NationalID + " - " + request.Amount + " - " + request.ExternalTransactionReference);

            var petr = new API.IBank.ProcessTransactionRequest
            {
                Agent                = request.Agent,
                AgentNationalID      = agentInfo.AgentInfo.NationalID,
                Amount               = request.Amount,
                TransactionType      = "transfer", //request.TransactionType,
                TransactionReference = request.ExternalTransactionReference
            };

            if (request.AdditionalData != null && request.AdditionalData.Any())
            {
                petr.AdditionalData = new API.IBank.AdditionalData();
                foreach (var item in request.AdditionalData)
                {
                    petr.AdditionalData.Add(item.Key, item.Value);
                }
            }

            logger.InfoLow("request " + petr.Amount + " - " + petr.TransactionReference);

            ProcessTransactionResponse processExternalTransactionResponse = new ProcessTransactionResponse();

            try
            {
                processExternalTransactionResponse = ibankClient.ProcessTransaction(petr);
            }
            catch (Exception ex)
            {
                logger.InfoLow("EX " + ex.Message + " - " + ex.StackTrace);
            }
            logger.InfoLow("response " + processExternalTransactionResponse.ResponseCode + " - " + processExternalTransactionResponse.ResponseMessage);

            if (processExternalTransactionResponse != null)
            {
                if (int.Parse(processExternalTransactionResponse.ResponseCode) == 1)
                {
                    var config          = ConfigurationManager.GetSection("Movilway.API.Config") as ApiConfiguration;
                    var adjustmentsUser = config.ManagementUsers["adjustmentsAgent"];

                    string myAutorization = "", myMessage = "", myResponseCode = "";

                    var externalTransferResponse = new Utils().Externaltransfer(decimal.Parse(agentInfo.AgentInfo.BranchID.ToString()), ConfigurationManager.AppSettings["AccountProinco"], int.Parse(ConfigurationManager.AppSettings["ProincoUser"]), double.Parse(request.Amount.ToString()), request.ExternalTransactionReference, DateTime.Now, ref myAutorization, ref myMessage, ref myResponseCode);

                    if (myResponseCode == "00")
                    {
                        response.ResponseCode    = 0;
                        response.ResponseMessage = myMessage;
                        response.ExternalTransactionReference = myAutorization;
                    }
                    else
                    {
                        response.ResponseCode    = int.Parse(myResponseCode);
                        response.ResponseMessage = myMessage;
                        response.ExternalTransactionReference = myAutorization;
                    }
                }
                else
                {
                    response.ResponseCode    = int.Parse(processExternalTransactionResponse.ResponseCode);
                    response.ResponseMessage = processExternalTransactionResponse.ResponseMessage;
                    response.ExternalTransactionReference = processExternalTransactionResponse.ExternalTransactionReference;
                }
            }
            else
            {
                response.ResponseCode    = 99;
                response.ResponseMessage = "Su transaccion no pudo ser procesada";
            }
            return(response);
        }