private ValidationError ValidateCvv(ProcessPaymentCommandRequestModel request)
        {
            if (!string.IsNullOrWhiteSpace(request.CVV))
            {
                if (!request.CVV.All(Char.IsDigit))
                {
                    return(new ValidationError(nameof(request.CVV), "Invalid CVV"));
                }
                else if (request.CVV.Length != 3 && request.CVV.Length != 4)
                {
                    return(new ValidationError(nameof(request.CVV), "Invalid CVV"));
                }
            }

            return(null);
        }
        public IEnumerable <ValidationError> Validate(ProcessPaymentCommandRequestModel request)
        {
            if (request == null)
            {
                throw new ArgumentNullException();
            }

            if (!_creditCardNumberValidator.IsCreditCardNumberValid(request.CreditCardNumber))
            {
                yield return(new ValidationError(nameof(request.CreditCardNumber), "Credit card number is invalid"));
            }

            if (!_currencyValidator.IsCurrencySupported(request.Currency))
            {
                yield return(new ValidationError(nameof(request.Currency), "Currency not supported"));
            }

            var expiryDateValidationError = ValidateExpiryDate(request);

            if (expiryDateValidationError != null)
            {
                yield return(expiryDateValidationError);
            }

            var cvvValidationError = ValidateCvv(request);

            if (cvvValidationError != null)
            {
                yield return(cvvValidationError);
            }

            if (request.Amount <= 0)
            {
                yield return(new ValidationError(nameof(request.Amount), "Amount must be greater than zero"));
            }

            if (string.IsNullOrWhiteSpace(request.CustomerName))
            {
                yield return(new ValidationError(nameof(request.CustomerName), "Customer name must be provided"));
            }
        }
Ejemplo n.º 3
0
        public async Task <ProcessPaymentCommandResultModel> ExecuteAsync(ProcessPaymentCommandRequestModel request)
        {
            var errors = _processPaymentCommandRequestValidator.Validate(request);

            if (errors.Any())
            {
                return(new ProcessPaymentCommandResultModel
                {
                    Notification = new Notification(errors)
                });
            }

            var(bankTransactionId, status, bankError) = await PostRequestToBankAsync(request);

            var paymentRequest = new PaymentRequest
            {
                Amount           = request.Amount,
                CreditCardNumber = request.CreditCardNumber,
                Currency         = request.Currency,
                CustomerName     = request.CustomerName,
                CVV         = request.CVV,
                ExpiryMonth = request.ExpiryMonth,
                ExpiryYear  = request.ExpiryYear,
                Reference   = request.Reference,

                Status = status,

                BankErrorDescription = bankError,
                BankTransactionId    = bankTransactionId
            };

            _dbContext.PaymentRequests.Add(paymentRequest);

            await _dbContext.SaveChangesAsync();

            return(new ProcessPaymentCommandResultModel
            {
                PaymentRequestId = paymentRequest.Id,
                Status = status
            });
        }
        private ValidationError ValidateExpiryDate(ProcessPaymentCommandRequestModel request)
        {
            if (DateTime.TryParseExact($"{request.ExpiryYear:0000}-{request.ExpiryMonth:00}-01T00:00:00.0000000Z",
                                       "yyyy-MM-dd'T'HH:mm:ss.fffffff'Z'",
                                       CultureInfo.InvariantCulture,
                                       DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal,
                                       out DateTime expiryDate))
            {
                var now = _dateTimeProvider.UtcNow();
                var firstOfCurrentMonth = new DateTime(now.Year, now.Month, 1, 0, 0, 0, DateTimeKind.Utc);

                if (expiryDate.Date <= firstOfCurrentMonth.Date)
                {
                    return(new ValidationError(null, "Card has expired"));
                }
            }
            else
            {
                return(new ValidationError(null, "Invalid expiry date"));
            }

            return(null);
        }
Ejemplo n.º 5
0
        private async Task <(Guid?Id, PaymentRequestStatus Status, string Error)> PostRequestToBankAsync(ProcessPaymentCommandRequestModel request)
        {
            try
            {
                var bankResult = await _acmeBankApi.ProcessPayment(request.CreditCardNumber,
                                                                   request.CVV,
                                                                   request.ExpiryMonth,
                                                                   request.ExpiryYear,
                                                                   request.Amount,
                                                                   request.Currency,
                                                                   request.CustomerName);

                return(bankResult.Id,
                       bankResult.WasSuccessful ? PaymentRequestStatus.Successful : PaymentRequestStatus.Unsuccessful,
                       bankResult.Error);
            }
            catch (Exception)
            {
                return(null, PaymentRequestStatus.UnableToProcess, "Unable to process with bank");
            }
        }