public void PostPaymentDetails_Executes_ReturnsPaymentDetails()
        {
            Merchant merchant = new Merchant()
            {
                UserName = "******",
                Email    = "*****@*****.**"
            };

            PaymentRequestDto paymentRequestDto = new PaymentRequestDto()
            {
                Amount = 1000,
                Card   = new CardDto()
                {
                    CardNumber  = "1234567890123456",
                    Cvv         = "111",
                    ExpiryMonth = 1,
                    ExpiryYear  = 2020
                },
                Currency = "euro"
            };

            string bankUrl = "http://localhost:8080";

            var result = paymentService.PostPayment(paymentRequestDto, merchant, bankUrl);

            Assert.IsType <Task <BankResponseDto> >(result);
        }
Exemplo n.º 2
0
        public void PostAndGetPayment_ShouldAcceptAndRetrieve()
        {
            CardDto card = GenerateRandomCard();

            PaymentRequestDto paymentRequest = new PaymentRequestDto();

            paymentRequest.MerchantId = 1;
            paymentRequest.Amount     = 25.99;
            paymentRequest.Currency   = "CAD";
            paymentRequest.Card       = card;

            var postResult = _paymentsController.Post(paymentRequest);

            Assert.IsType <OkObjectResult>(postResult.Result);
            OkObjectResult objectResult = postResult.Result as OkObjectResult;

            Assert.IsType <PaymentResponseDto>(objectResult.Value);
            PaymentResponseDto paymentResponse = objectResult.Value as PaymentResponseDto;

            Assert.True(paymentResponse.Id > 0);
            Assert.NotNull(paymentResponse.Status);

            int paymentId = paymentResponse.Id;
            var getResult = _paymentsController.Get(paymentId);

            Assert.IsType <OkObjectResult>(getResult.Result);
            OkObjectResult getObjectResult = getResult.Result as OkObjectResult;

            Assert.IsType <PaymentInformationDto>(getObjectResult.Value);
            PaymentInformationDto paymentInformation = getObjectResult.Value as PaymentInformationDto;

            Assert.Equal(paymentRequest.Amount, paymentInformation.Amount);
            Assert.Equal(paymentRequest.Currency, paymentInformation.Currency);
        }
Exemplo n.º 3
0
        public async Task <ActionResult <PaymentResponseDto> > Process(PaymentRequestDto paymentRequestDto)
        {
            try
            {
                var paymentRequest = new PaymentRequest(
                    paymentRequestDto.MerchantId,
                    paymentRequestDto.CardHolderName,
                    paymentRequestDto.CardNumber,
                    paymentRequestDto.ExpiryDate,
                    new Money(paymentRequestDto.Amount, paymentRequestDto.Currency),
                    paymentRequestDto.CVV);

                var payment = await paymentRequestProcessor.Process(paymentRequest);

                var result = new PaymentResponseDto
                {
                    AcquiringBankPaymentId = payment.AcquiringBankPaymentId,
                    Status    = payment.Status.ToString(),
                    Timestamp = payment.Timestamp
                };

                return(this.Ok(result));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error processing payment.");
            }

            return(this.Problem("Error processing payment."));
        }
Exemplo n.º 4
0
        private async Task <Guid> UpdatePaymentData(PaymentRequestDto dto, ResponseDto result)
        {
            Card card = _context.Cards.Include(x => x.Client)
                        .SingleOrDefault(x => x.CardNumber == dto.CardNumber.Encrypt());

            Merchant merchant = _context.Merchants
                                .SingleOrDefault(x => x.MerchantUniqueToken == dto.MerchantUniqueToken);

            if (card is null)
            {
                //create new card and new client
            }

            Payment payment = new Payment
            {
                MerchantId      = merchant.Id,
                CardId          = card.Id,
                BankOperationId = result.OperationId,
                Amount          = dto.Amount,
                PaymentStatus   = result.Status,
                TimeStamp       = DateTime.Now
            };
            await _context.Payments.AddAsync(payment);

            await _context.SaveChangesAsync();

            return(payment.Id);
        }
        public void ValidateRequestModelDtoUsingModelState()
        {
            var paymentRequest = new PaymentRequestDto();
            var paymentModel   = new PaymentDetail();
            var mapperMock     = new Mock <IMapper>();

            mapperMock.Setup(c => c.Map <PaymentDetail>(paymentRequest)).Returns(paymentModel);
            var mockService = new Mock <IPaymentDetailService>();

            mockService.Setup(repo => repo.ProcessPayment(paymentModel, 2))
            .Returns(new Response <Dtos.PaymentResponseDto> {
                Code = ResponseCodes.OK
            });
            var controller = new PaymentController(mapperMock.Object, mockService.Object);


            // controller.ModelState.AddModelError("Invalid Parameter", "Required");
            var req = new PaymentRequestDto {
                Amount = 20, CardHolder = "Olamide", ExpirationDate = DateTime.Now
            };

            // Act
            var result = controller.ProcessPayment(req);

            // Assert
            var badRequestResult = Assert.IsType <BadRequestObjectResult>(result);

            Assert.Equal("Request is Invalid", badRequestResult.Value);
        }
        public async Task <IActionResult> Post(PaymentRequestDto paymentRequest)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var paymentState = await _paymentRequestService.Pay(paymentRequest);

                    var paymentResponse = new PaymentResponseDto()
                    {
                        IsProcessed = paymentState.PaymentState == PaymentStateEnum.Processed
                        ,
                        PaymentState = paymentState
                    };

                    if (!paymentResponse.IsProcessed)
                    {
                        return(StatusCode(500, new { error = "Payment could not be processed" }));
                    }
                    return(Ok(paymentResponse));
                }
                else
                {
                    return(BadRequest(ModelState));
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                return(StatusCode(500));
            }
        }
        public async Task <PaymentGatewayResponseDto> Process(PaymentRequestDto dto)
        {
            string merchantUniqueToken = _configuration[Constants.PaymentGatewayUniqueToken];

            RequestToPaymentProviderDto requestToPaymentGateway = new RequestToPaymentProviderDto
            {
                MerchantUniqueToken = new Guid(merchantUniqueToken),
                CardHolderName      = dto.CardHolderName,
                CardNumber          = dto.CardNumber,
                Cvc            = dto.Cvc,
                ExpirationDate = dto.ExpirationDate,
                Amount         = dto.Amount,
                TimeStamp      = DateTime.Now
            };

            string        json = JsonSerializer.Serialize(requestToPaymentGateway);
            StringContent data = new StringContent(json, Encoding.UTF8, "application/json");

            using var response = await _httpClient.PostAsync("Payments", data);

            if (!response.IsSuccessStatusCode)
            {
                var exMessage = await response.Content.ReadAsStringAsync();

                throw new Exception(exMessage);
            }

            using var stream = await response.Content.ReadAsStreamAsync();

            PaymentGatewayResponseDto result = await JsonSerializer.DeserializeAsync <PaymentGatewayResponseDto>(stream,
                                                                                                                 new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            return(result);
        }
Exemplo n.º 8
0
        public async Task <IActionResult> MakePayment(PaymentRequestDto paymentRequest)
        {
            IActionResult result;

            try {
                if (paymentRequest == null || !paymentRequestValidator.IsValid(paymentRequest))
                {
                    return(BadRequest(paymentRequest));
                }

                var bankResponse = await Task.Run(() => { return(acquiringBank.PaymentIsApproved(paymentRequest)); });

                await Task.Run(() => { paymentStorage.Store(bankResponse.id, new PaymentStorageObject(paymentRequest, bankResponse.status)); });

                if (bankResponse.status)
                {
                    result = Ok(new PaymentResponseDto(paymentRequest, bankResponse));
                }
                else
                {
                    result = StatusCode(StatusCodes.Status401Unauthorized);
                }

                return(result);
            } catch (Exception e) {
                return(StatusCode(StatusCodes.Status500InternalServerError, e.Message));
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Processes a payment request, verifying payment details with the bank and returning the result of the payment request
        /// </summary>
        /// <param name="paymentDto">The DTO representing a PaymentRequestDto</param>
        /// <returns>A PaymentResponseDto, which contains the payment identifier and status.</returns>
        public PaymentResponseDto MakePayment(PaymentRequestDto paymentDto)
        {
            _logger.LogInformation("Received a Payment request for " + paymentDto.Amount.ToString() + " " + paymentDto.Currency + ".");

            Payment payment = _mapper.Map <Payment>(paymentDto);

            payment.Card = _cardService.FindOrCreateCard(payment.Card);

            BankPaymentRequestDto  bankPaymentRequest  = _mapper.Map <BankPaymentRequestDto>(payment);
            BankPaymentResponseDto bankPaymentResponse = _bankService.PostPayment(bankPaymentRequest);

            if (bankPaymentResponse.ReasonCode == -1)
            {
                _logger.LogInformation("Payment rejected by bank.");

                payment.Status = PaymentStatus.Failed;
            }
            else
            {
                _logger.LogInformation("Payment accepted by bank!");

                payment.Status = PaymentStatus.Success;
            }

            payment.BankTransactionId = bankPaymentResponse.BankTransactionId;
            payment.PaymentDate       = DateTime.Now;
            Payment newPayment = _paymentRepository.InsertPayment(payment);

            _logger.LogInformation("Payment successfully processed.");

            PaymentResponseDto newPaymentDto = _mapper.Map <PaymentResponseDto>(newPayment);

            return(newPaymentDto);
        }
Exemplo n.º 10
0
        public async Task <IActionResult> ProcessPayment(PaymentRequestDto paymentRequest)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var paymentState = await _paymentRequestService.Pay(paymentRequest);

                    if (!(paymentState.PaymentState == PaymentStateEnum.Processed))
                    {
                        return(StatusCode(400, "400 bad request"));
                    }
                    return(StatusCode(200, "200 Ok"));
                }
                else
                {
                    return(StatusCode(400, "400 bad request"));
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                return(StatusCode(500, "500 internal server error"));
            }
        }
        public void MapperMapsRequestDtoToRequest()
        {
            var paymentRequest = new PaymentRequestDto
            {
                Amount   = 1,
                Currency = "GBP",
                Card     = new CardDto
                {
                    CardNumber  = "1234123412341234",
                    Cvv         = 123,
                    ExpiryMonth = 12,
                    ExpiryYear  = 20
                }
            };

            var mapper       = new PaymentRequestDtoMapper(new CardMapper());
            var mappedObject = mapper.Map(paymentRequest);

            mappedObject.Should().NotBeNull();
            mappedObject.Card.Should().NotBeNull();
            mappedObject.Card.Cvv.Should().Be(123);
            mappedObject.Card.CardNumber.Should().Be("1234123412341234");
            mappedObject.Card.ExpiryMonth.Should().Be(12);
            mappedObject.Card.ExpiryYear.Should().Be(20);
            mappedObject.Amount.Should().Be(1);
            mappedObject.Currency.Should().Be("GBP");
        }
Exemplo n.º 12
0
        public PaymentStateDto ProcessPayment(PaymentRequestDto paymentRequest)
        {
            Random rnd = new Random();
            var    num = rnd.Next(1, 12);

            if (num % 4 == 0 || num % 6 == 0)
            {
                throw new Exception("Call failed");
            }
            if (num % 2 == 0)
            {
                return new PaymentStateDto()
                       {
                           PaymentState = PaymentStateEnum.Failed, PaymentStateDate = DateTime.UtcNow
                       }
            }
            ;
            else
            {
                return new PaymentStateDto()
                       {
                           PaymentState = PaymentStateEnum.Processed, PaymentStateDate = DateTime.UtcNow
                       }
            };
        }
    }
        public async Task <IActionResult> MakePayment(PaymentRequestDto request)
        {
            _logger.LogInformation("Run endpoint {endpoint} {verb}", "/api/article-hit/most-viewed", "GET");
            var paymentResult = await _paymentProcessService.Process(request);

            return(Ok(paymentResult));
        }
        public async Task <ResponseDto> MakePayment(PaymentRequestDto dto)
        {
            var result = new ResponseDto();

            //validation of request data
            var paymentProvider = _context.PaymentProviders
                                  .SingleOrDefault(x => x.PaymentProviderUniqueToken == dto.PaymentProviderUniqueToken);

            if (paymentProvider is null)
            {
                result.Status     = PaymentStatus.Failed;
                result.ResultCode = ResultCode.PaymentProviderError;
                return(result);
            }

            var card = _context.Cards
                       .SingleOrDefault(x =>
                                        string.Format("{0} {1}", x.Client.FirstName, x.Client.LastName) == dto.CardHolderName &&
                                        x.CardNumber == x.CardNumber &&
                                        x.ExpirationDate == x.ExpirationDate &&
                                        x.Cvc == x.Cvc);

            if (card is null)
            {
                result.Status     = PaymentStatus.Failed;
                result.ResultCode = ResultCode.CardError;
                return(result);
            }
            else if (card.Balance < dto.Amount)
            {
                result.Status     = PaymentStatus.Failed;
                result.ResultCode = ResultCode.CardBalanceError;
                return(result);
            }
            card.Balance -= dto.Amount;

            //create and save new transaction in db
            var transaction = new Transaction
            {
                PaymentProvider      = dto.PaymentProviderUniqueToken,
                TimeStamp            = dto.TimeStamp,
                Amount               = dto.Amount,
                PaymentProviderToken = dto.PaymentProviderUniqueToken,
                CardId               = card.Id,
                Status               = result.Status,
                ResultCode           = result.ResultCode
            };

            _context.Transactions.Add(transaction);
            //update card data and save all changes in db
            await _context.MockSaveChangesAsync();

            //if all request data is valid, take paymeny amount from card's balance
            result.Status      = PaymentStatus.Paid;
            result.ResultCode  = ResultCode.Success;
            result.OperationId = Guid.NewGuid();//Mock transactionId

            return(result);
        }
        public void GivenInvalidDateTime_IsValid_ReturnsFalse(DateTime localTestEcpiryDate)
        {
            var testRequest = new PaymentRequestDto(testCardNumber, localTestEcpiryDate, testCurrency, testAmount, testCvv);

            var result = sut.IsValid(testRequest);

            Assert.IsFalse(result);
        }
Exemplo n.º 16
0
        public async Task <BankResponse> SubmitPaymentRequest(PaymentRequestDto paymentData)
        {
            //We can assume that the bank would need
            //a certain amount of time to process the payment
            await Task.Delay(2000);

            return(BankResponse.CreateResponse());
        }
        public void GivenInvalidCurrency_IsValid_ReturnsFalse(string localTestCurrency)
        {
            var testRequest = new PaymentRequestDto(testCardNumber, testExpiryDate, localTestCurrency, testAmount, testCvv);

            var result = sut.IsValid(testRequest);

            Assert.IsFalse(result);
        }
Exemplo n.º 18
0
        public async Task <int> SavePaymentAsync(PaymentRequestDto payment)
        {
            _logger.LogInformation(
                "Saving payment to database: {@payment}", payment);

            await _ctx.AddAsync(payment.MapToEntity());

            return(await _ctx.SaveChangesAsync());
        }
Exemplo n.º 19
0
 /// <inheritdoc />
 public BankResponse <Guid> SubmitPayment(PaymentRequestDto payment)
 {
     // This simulates a successful response.
     return(new BankResponse <Guid>
     {
         Response = Guid.NewGuid(),
         StatusCode = HttpStatusCode.OK
     });
 }
        public void GivenExpiredDateTime_IsValid_ReturnsFalse()
        {
            DateTime localTestEcpiryDate = DateTime.Now.AddDays(-1);
            var      testRequest         = new PaymentRequestDto(testCardNumber, localTestEcpiryDate, testCurrency, testAmount, testCvv);

            var result = sut.IsValid(testRequest);

            Assert.IsFalse(result);
        }
 public PaymentStorageObject(PaymentRequestDto paymentRequest, bool approved)
 {
     maskedCardNumber = "**** **** **** " + paymentRequest.cardNumber.Substring(paymentRequest.cardNumber.Length - 4);
     hashedCardNumber = paymentRequest.cardNumber.GetHashCode();
     expiryDate       = paymentRequest.expiryDate;
     amount           = paymentRequest.amount;
     currency         = paymentRequest.currency;
     this.approved    = approved;
     transactionTime  = DateTime.Now;
 }
Exemplo n.º 22
0
        public async Task <ResponseDto> Process(PaymentRequestDto dto)
        {
            string      paymentProviderUniqueToken = _configuration[Constants.PaymentProviderUniqueToken];
            ResponseDto result = new ResponseDto();

            //save request in Db
            Request request = _mapper.Map <Request>(dto);
            await _context.Requests.AddAsync(request);

            //validate merchant
            Merchant merchant = _context.Merchants.SingleOrDefault(x => x.MerchantUniqueToken == dto.MerchantUniqueToken);

            if (merchant is null)
            {
                result.Status     = PaymentStatus.Failed;
                result.ResultCode = ResultCode.PaymentProviderError;
                return(result);
            }

            //send request to bank
            BankPaymentRequestDto requestToBank = _mapper.Map <BankPaymentRequestDto>(dto);

            requestToBank.PaymentProviderUniqueToken = new Guid(paymentProviderUniqueToken);

            string        json = JsonSerializer.Serialize(requestToBank);
            StringContent data = new StringContent(json, Encoding.UTF8, "application/json");

            using var response = await _httpClient.PostAsync("Operations", data);

            if (!response.IsSuccessStatusCode)
            {
                var exMessage = await response.Content.ReadAsStringAsync();

                throw new Exception(exMessage);
            }

            using var stream = await response.Content.ReadAsStreamAsync();

            result = await JsonSerializer.DeserializeAsync <ResponseDto>(stream,
                                                                         new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            if (result.ResultCode != ResultCode.Success)
            {
                return(result);
            }

            //save changes in db
            Guid paymentId = await UpdatePaymentData(dto, result);

            request.Status = result.Status;
            await _context.SaveChangesAsync();

            result.OperationId = paymentId;
            return(result);
        }
        public void Setup()
        {
            testCardNumber        = "1234567890123456";
            testExpiryDate        = DateTime.Now.AddDays(1);
            testCurrency          = "GBP";
            testAmount            = new decimal(123.45);
            testCvv               = "123";
            testPaymentRequestDto = new PaymentRequestDto(testCardNumber, testExpiryDate, testCurrency, testAmount, testCvv);

            sut = new PaymentRequestValidator();
        }
Exemplo n.º 24
0
        public bool ValidateRequest(PaymentRequestDto paymentRequest)
        {
            _logger.LogInformation(
                "Validating request: {@paymentRequest}", paymentRequest);

            //Payment request validation logic could go here
            //An example of validation is implemented

            return paymentRequest.Amount >= 0 &&
                PaymentDataValidator.ValidateCurrency(paymentRequest.Currency) &&
                PaymentDataValidator.ValidateCreditCardNumber(paymentRequest.CardNumber);
        }
        public async Task <IActionResult> RequestPayment([FromBody] PaymentRequestDto paymentRequest)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(paymentRequest));
            }

            var serviceRequest  = _requestMapper.Map(paymentRequest);
            var serviceResponse = await _paymentService.ProcessPayment(serviceRequest);

            return(Ok(_responseMapper.Map(serviceResponse)));
        }
Exemplo n.º 26
0
        public async void ReturnBadRequestResult_WhenGivenInvalidPaymentData()
        {
            var request = new PaymentRequestDto();

            _fakeProcessor
            .Setup(x => x.ValidateRequest(null))
            .Returns(false);

            var expected = StatusCodes.Status400BadRequest;
            var actual   = await _sut.SubmitPayment(null) as BadRequestResult;

            Assert.Equal(expected, actual.StatusCode);
        }
Exemplo n.º 27
0
        public async Task <IActionResult> MakePayment(PaymentRequestDto request)
        {
            var paymentResult = await _paymentService.Process(request);

            var response = new ResponseDto
            {
                OperationId = paymentResult.OperationId,
                Status      = paymentResult.Status.ToString(),
                Result      = paymentResult.ResultCode.ToString()
            };

            return(Ok(response));
        }
Exemplo n.º 28
0
 public static Payment MapToEntity(
     this PaymentRequestDto request)
 {
     return(new Payment
     {
         PaymentIdentifier = request.PaymentIdentifier,
         Status = request.Status,
         CardHolderName = request.CardHolderName,
         CardNumber = request.CardNumber,
         CVV = request.CVV,
         Amount = request.Amount,
         Currency = request.Currency
     });
 }
Exemplo n.º 29
0
        public async Task <IActionResult> Post([FromBody][Required] PaymentRequestDto paymentRequestDto)
        {
            var command         = DtoConverter.CreateCommand(paymentRequestDto, _claimsPrincipal.Identity.Name);
            var paymentResponse = await _paymentGateway.ProcessPaymentRequestAsync(command);

            return(await paymentResponse.Match <IActionResult>(
                       result => new JsonResult(DtoConverter.ToDto(result)),
                       pr => Created(@"/api/payments", new PaymentResponseDto
            {
                PaymentId = pr.PaymentId,
                PaymentStatus = pr.PaymentStatus.ToString()
            })
                       ));
        }
Exemplo n.º 30
0
        public async void ReturnsPaymentRequest_WhenCalled()
        {
            var request = new PaymentRequestDto();

            _bankEndpoint
            .Setup(x => x.SubmitPaymentRequest(request))
            .Returns(Task.FromResult(BankResponse.CreateResponse()));

            var actual = await _sut.SubmitPaymentToBankAsync(request);

            Assert.NotNull(actual);
            Assert.IsType <PaymentRequestDto>(actual);
            Assert.False(string.IsNullOrWhiteSpace(actual.PaymentIdentifier));
            Assert.False(string.IsNullOrWhiteSpace(actual.Status));
        }