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); }
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); }
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.")); }
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); }
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)); } }
/// <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); }
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"); }
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); }
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); }
public async Task <int> SavePaymentAsync(PaymentRequestDto payment) { _logger.LogInformation( "Saving payment to database: {@payment}", payment); await _ctx.AddAsync(payment.MapToEntity()); return(await _ctx.SaveChangesAsync()); }
/// <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; }
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(); }
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))); }
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); }
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)); }
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 }); }
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() }) )); }
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)); }