Пример #1
0
        /// <summary>
        /// Processes a payment request
        /// </summary>
        /// <param name="paymentModel"></param>
        /// <returns></returns>
        public async Task <IExecutionResponse <PaymentResult> > ProcessPaymentAsync(PaymentModel paymentModel)
        {
            _logger.LogInformation($"Processing payment...");
            PaymentResult paymentResult;
            string        userName = GetLoggedInUser();

            if (paymentModel.Amount < 0)
            {
                _logger.LogInformation("Cannot process payment for amounts less than 0");
                paymentResult = PaymentResultMapping.CreateEntity(400, "An error occured");

                return(_responseFactory.ExecutionResponse <PaymentResult>("Cannot process payment for amounts less than 0", paymentResult, statusCode: 400));
            }

            // Default result
            PaymentResult thirdPartyResponse = new PaymentResult
            {
                Message    = "An error occurred",
                StatusCode = 500
            };

            if (paymentModel.Amount < 20)
            {
                // Use ICheapPaymentGateway. No retry
                thirdPartyResponse = _cheapPaymentGateway.BankTransfer(paymentModel);
            }
            else if (paymentModel.Amount >= 21 && paymentModel.Amount <= 500)
            {
                // Use IExpensivePaymentGateway and retry once with ICheapPaymentGateway
                thirdPartyResponse = RetryWithCheapPaymentGateway(paymentModel);
            }
            else if (paymentModel.Amount > 500)
            {
                // Use PremiumPaymentService and retry 3 times
                thirdPartyResponse = RetryThriceWithPremiumGateway(paymentModel);
            }

            var payment = PaymentMapping.CreateEntity(paymentModel, userName, userName);

            // Map response from third party
            var paymentState = UpdatePaymentStateFromThirdParty(payment, thirdPartyResponse.StatusCode);

            // Save to DB
            _commandRepostory.Add(payment);
            _paymentStateCommandRepostory.Add(paymentState);
            await _commandRepostory.SaveAsync();

            // Send thirdPartyResponse as the response data, in case an integrator wants to change transaction status based on status code
            _logger.LogInformation("Payment processed successfully.");
            return(_responseFactory.ExecutionResponse <PaymentResult>(thirdPartyResponse.Message, statusCode: thirdPartyResponse.StatusCode, data: thirdPartyResponse, status: true));
        }