private async Task <int> ProcessPaymentInternal(PaymentRequest paymentRequest)
        {
            if (paymentRequest.Amount <= 20)
            {
                return(await _cheapPaymentGateway.Process(paymentRequest));
            }

            if (paymentRequest.Amount >= 21 && paymentRequest.Amount <= 500)
            {
                if (_expensivePaymentGateway.IsAvailable())
                {
                    return(await _expensivePaymentGateway.Process(paymentRequest));
                }

                return(await _cheapPaymentGateway.Process(paymentRequest));
            }

            var retryPolicy = Policy
                              .Handle <Exception>()
                              .RetryAsync(RETRY_COUNT);

            return(await retryPolicy.ExecuteAsync(async() =>
            {
                return await _expensivePaymentGateway.Process(paymentRequest);
            }));
        }
        public async Task <string> ProcessAsync(PaymentDto payment)
        {
            try
            {
                PerformOperation(payment);
                return($"Your payment of £{payment.Amount} was successfully proccessed using {nameof(IExpensivePaymentGateway)}");
            }
            catch (WebException)
            {
                //log exception.
                string result = "";
                //Retry once using ICheapPaymentGateway.
                //exception will be thrown if failed.
                await AppHelper.RetryAsync(
                    () => { result = _cheapPaymentGateway.Process(payment); },
                    TimeSpan.FromSeconds(4),
                    1);

                //return the result of using cheapPaymentGateway.
                return(result);
            }
        }
Пример #3
0
 public override bool Process(Payment payment)
 {
     return(_cheapGateway.Process(payment));
 }
Пример #4
0
        public async Task <Response <Payment> > ProcessPayment(Payment payment)
        {
            var paymentDetails = new Payment();

            if (payment.Amount < 20)
            {
                await _cheapPaymentGateway.Process(payment);

                paymentDetails = await _cheapPaymentGateway.Update(payment.Id);

                var response = new Response <Payment>
                {
                    Data   = paymentDetails,
                    Status = paymentDetails.PaymentState.State
                };

                if (response.Status == PaymentStatus.processed.ToString())
                {
                    return(response);
                }
            }

            else if (payment.Amount > 21 && payment.Amount <= 500)
            {
                if (_expensivePaymentGateway is null)
                {
                    await _cheapPaymentGateway.Process(payment);

                    paymentDetails = await _cheapPaymentGateway.Update(payment.Id);

                    var response = new Response <Payment>
                    {
                        Data   = paymentDetails,
                        Status = paymentDetails.PaymentState.State
                    };

                    if (response.Status == PaymentStatus.processed.ToString())
                    {
                        return(response);
                    }
                }
                else
                {
                    await _expensivePaymentGateway.Process(payment);

                    paymentDetails = await _expensivePaymentGateway.Update(payment.Id);

                    var response = new Response <Payment>
                    {
                        Data   = paymentDetails,
                        Status = paymentDetails.PaymentState.State
                    };

                    if (response.Status == PaymentStatus.processed.ToString())
                    {
                        return(response);
                    }
                }
            }

            else if (payment.Amount > 500)
            {
                var i = 0;

                while (i < 3)
                {
                    await _premiumPaymentGateway.Process(payment);

                    paymentDetails = await _premiumPaymentGateway.Update(payment.Id);

                    var response = new Response <Payment>
                    {
                        Data   = paymentDetails,
                        Status = paymentDetails.PaymentState.State
                    };

                    if (response.Status == PaymentStatus.processed.ToString())
                    {
                        return(response);
                    }

                    i++;
                }
            }

            return(new Response <Payment>
            {
                Data = paymentDetails,
                Status = PaymentStatus.failed.ToString()
            });
        }
Пример #5
0
        /// <summary>
        /// Processes a payment after validating few cases. CHECKS FOR INNVALID CREDIT CARD AND VALID DATE ARE DONE
        /// AT THE CONTROLLER/DTO LEVEL.
        /// </summary>
        /// <param name="payment">The payment to be processed</param>
        /// <returns>A task that resolves to a string.</returns>
        public async Task <string> ProcessAsync(PaymentDto payment)
        {
            if (payment == null)
            {
                throw new ArgumentNullException(nameof(payment));
            }

            if (payment.Amount <= 0)
            {
                throw new ArgumentException($"£{nameof(payment.Amount)} is not a valid amount");
            }

            if (payment.Amount >= 20 && payment.Amount < 21)
            {
                throw new Exception($"Cannot process payment between £20.01 to £20.99");
            }

            PaymentState paymentState = null;
            string       result       = "";

            try
            {
                //Insert  into Payment Entity
                var newPayment = _mapper.Map <Payment>(payment);
                await _paymentRepo.InsertAsync(newPayment);

                paymentState = new PaymentState
                {
                    PaymentId = newPayment.Id,
                    State     = nameof(PaymentStateEnum.PENDING)
                };
                await _paymentStateRepo.InsertAsync(paymentState);

                //proceed to process payment...
                if (payment.Amount < 20)
                {
                    //use ICheapPaymentGateway to process the payment.
                    result = _cheapPaymentGateway.Process(payment);
                }
                else if (payment.Amount >= 21 && payment.Amount <= 500)
                {
                    //use IExpensivePaymentGateway to process the payment.
                    result = await _expensivePaymentGateway.ProcessAsync(payment);
                }
                else
                {
                    //use IPremiumPaymentGateway to process the payment.
                    result = await _premiumPaymentGateway.ProcessAsync(payment);
                }

                return(result);
            }
            finally
            {
                //paymentState could be null if the repository method never runs or
                //it threw an unexpected exception.
                //if that's the case, no need for cleanup.
                if (paymentState != null)
                {
                    if (result.Length > 1)
                    {
                        //there was no error
                        //update Payment State Entity to processed.
                        paymentState.State = nameof(PaymentStateEnum.PROCESSESD);
                    }
                    else
                    {
                        // update Payment State Entity
                        paymentState.State = nameof(PaymentStateEnum.FAILED);
                    }

                    await _paymentStateRepo.UpdateAsync(paymentState);
                }
            }
        }