public async Task GivenASubmitPaymentRequest_WhenValidPayment_ShouldReturn200SuccessCode() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = 12345 }; var jsonRequest = JsonConvert.SerializeObject(submitPaymentRequest); // when var submitPaymentResponse = await _httpClient.PostAsync("https://localhost:9901/paymentgateway", new StringContent(jsonRequest, Encoding.UTF8, "application/json")); // then submitPaymentResponse.IsSuccessStatusCode.ShouldBeTrue(); var responseContent = await submitPaymentResponse.Content.ReadAsStringAsync(); var paymentInformation = JsonConvert.DeserializeObject <SubmitPaymentResponse>(responseContent); paymentInformation.PaymentId.ShouldBeOfType <Guid>(); paymentInformation.PaymentResponseStatus.ShouldBe("Successful"); }
public async Task <ActionResult <SubmitPaymentResponse> > CreatePaymentSync([FromBody] SubmitPaymentRequest paymentRequest) { Console.WriteLine($"Recieved message: {paymentRequest}"); Payment payment = new Payment(paymentRequest.PaymentId, paymentRequest.AccountNumber, paymentRequest.PaymentAmount); // save payment to cache var cache = this._cacheConnection.GetDatabase(); await cache.StringSetAsync($"payment.{payment.Id}", JsonConvert.SerializeObject(payment)); // synchronously wait for external payment gateway PaymentGatewaySubmitPaymentRequest gatewayRequest = new PaymentGatewaySubmitPaymentRequest(payment.Id, payment.AccountNumber, payment.Amount); var serviceResponse = await this._httpClient.PostAsJsonAsync(ExternalPaymentGatewayUri, gatewayRequest); if (!serviceResponse.IsSuccessStatusCode) { throw new Exception("Error processing payment"); } PaymentGatewaySubmitPaymentResponse gatewayResponse = await serviceResponse.Content.ReadAsAsync <PaymentGatewaySubmitPaymentResponse>();; // update payment in cache payment.Status = gatewayResponse.PaymentStatus; await cache.StringSetAsync($"payment.{payment.Id}", JsonConvert.SerializeObject(payment)); return(new SubmitPaymentResponse(payment.Id, payment.Status)); }
public async Task GivenASubmitPaymentRequest_WhenValidPayment_ShouldReturn200SuccessCode() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = 12345 }; // when var submitPaymentResponse = await _sut.Post(submitPaymentRequest); // then submitPaymentResponse.ShouldBeOfType <OkObjectResult>(); var paymentInformation = (submitPaymentResponse as OkObjectResult).Value as SubmitPaymentResponse; paymentInformation.PaymentId.ShouldBeOfType <Guid>(); paymentInformation.PaymentResponseStatus.ShouldBe("Successful"); }
public async Task GivenASubmitPaymentRequest_WhenPaymentUnsuccessful_ShouldReturn400() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = -1000 }; var jsonRequest = JsonConvert.SerializeObject(submitPaymentRequest); // when var submitPaymentResponse = await _httpClient.PostAsync("https://localhost:9901/paymentgateway", new StringContent(jsonRequest, Encoding.UTF8, "application/json")); // then submitPaymentResponse.StatusCode.ShouldBe(HttpStatusCode.BadRequest); }
public async Task GivenASubmitPaymentRequest_WhenUnsuccessful_ShouldReturn400() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = -10000 }; // when var submitPaymentResponse = await _sut.Post(submitPaymentRequest); // then submitPaymentResponse.ShouldBeOfType <BadRequestResult>(); }
public ActionResult <SubmitPaymentResponse> CreatePayment([FromBody] SubmitPaymentRequest paymentRequest) { // mock processing time Thread.Sleep(5000); // create response with "Completed" status var response = new SubmitPaymentResponse(paymentRequest.PaymentId, "Completed"); return(response); }
private BankPaymentRequest GenerateBankPaymentRequest(SubmitPaymentRequest submitPaymentRequest, string correlationId) { var cardDetails = new Services.Models.CardDetails(submitPaymentRequest.CardDetails.CardNumber, submitPaymentRequest.CardDetails.ExpiryDate, submitPaymentRequest.CardDetails.Currency, submitPaymentRequest.CardDetails.CVV); var merchantDetails = new Services.Models.MerchantDetails(submitPaymentRequest.MerchantDetails.MerchantId); return(new BankPaymentRequest(cardDetails, merchantDetails, submitPaymentRequest.Amount, correlationId)); }
public IActionResult SubmitPayment([FromBody] SubmitPaymentRequest submitPaymentRequest) { try { var result = this.xServerManager.SubmitPayment(submitPaymentRequest); return(Json(result)); } catch (Exception e) { this.logger.LogError("Exception occurred: {0}", e.ToString()); return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString())); } }
public async Task <IActionResult> SubmitPayment([FromBody] SubmitPaymentRequest submitPaymentRequest) { xServer.Stats.IncrementPublicRequest(); if (xServer.Stats.TierLevel == ServerNode.Tier.TierLevel.Three) { var submitPaymentResult = await priceFeature.SubmitPayment(submitPaymentRequest); return(Json(submitPaymentResult)); } else { return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "Tier 3 requirement not meet", "The node you requested is not a tier 3 node.")); } }
public async Task <SubmitPaymentResult> SubmitPayment(SubmitPaymentRequest submitPaymentRequest) { var result = new SubmitPaymentResult(); if (Guid.TryParse(submitPaymentRequest.PriceLockId, out Guid validPriceLockId)) { var payeeValidationResult = await ValidateNewPriceLockPayee(submitPaymentRequest); if (payeeValidationResult == PaymentErrorCodes.None) { using (X42DbContext dbContext = new X42DbContext(databaseSettings.ConnectionString)) { var priceLock = dbContext.PriceLocks.Where(p => p.PriceLockId == validPriceLockId).FirstOrDefault(); if (priceLock != null) { if (priceLock.Status == (int)Status.New) { priceLock.PayeeSignature = submitPaymentRequest.PayeeSignature; priceLock.TransactionId = submitPaymentRequest.TransactionId; priceLock.Status = (int)Status.WaitingForConfirmation; priceLock.Relayed = false; dbContext.SaveChanges(); if (!string.IsNullOrEmpty(submitPaymentRequest.TransactionHex)) { await networkFeatures.SendTransaction(submitPaymentRequest.TransactionHex); } result.Success = true; } else { result.ErrorCode = (int)PaymentErrorCodes.NotNew; } } else { result.ErrorCode = (int)PaymentErrorCodes.PriceLockNotFound; } } } else { result.ErrorCode = (int)payeeValidationResult; } } return(result); }
public async Task <ActionResult <SubmitPaymentResponse> > CreatePaymentAsync([FromBody] SubmitPaymentRequest paymentRequest) { PaymentProcessorSubmitPaymentRequest paymentProcessorRequest = new PaymentProcessorSubmitPaymentRequest(paymentRequest.AccountNumber, paymentRequest.PaymentAmount); var request = new HttpRequestMessage(HttpMethod.Post, AmqpSidecarUri); request.Content = new ObjectContent <PaymentProcessorSubmitPaymentRequest>(paymentProcessorRequest, new JsonMediaTypeFormatter()); var serviceResponse = await this._httpClient.SendAsync(request); if (!serviceResponse.IsSuccessStatusCode) { Console.WriteLine($"Error in request: {serviceResponse}"); return(new SubmitPaymentResponse(String.Empty, "Error")); } // an asynchronous call is marked here as Pending because we don't know the result. downstream services will handle updating return(new SubmitPaymentResponse(paymentProcessorRequest.PaymentId, "Pending")); }
public async Task <bool> UpdatePriceLock(PriceLockResult priceLockData) { bool result = false; if (Guid.TryParse(priceLockData.PriceLockId, out Guid validPriceLockId)) { // Create price lock if it doesn't exist. var priceLock = networkFeatures.GetPriceLockData(validPriceLockId); if (priceLock == null) { var priceLockCreateRequest = new CreatePriceLockRequest() { DestinationAddress = priceLockData.DestinationAddress, ExpireBlock = priceLockData.ExpireBlock, RequestAmount = priceLockData.RequestAmount, RequestAmountPair = priceLockData.RequestAmountPair }; var createResult = await CreatePriceLock(priceLockCreateRequest, validPriceLockId.ToString()); if (!createResult.Success) { return(false); } } // Update payment information. if (!string.IsNullOrEmpty(priceLockData.TransactionId) && !string.IsNullOrEmpty(priceLockData.PayeeSignature)) { var paymentSubmit = new SubmitPaymentRequest() { PayeeSignature = priceLockData.PayeeSignature, PriceLockId = priceLockData.PriceLockId, TransactionId = priceLockData.TransactionId }; var submitPaymentResult = await SubmitPayment(paymentSubmit); if (!submitPaymentResult.Success) { result = true; } } } return(result); }
public async Task GivenAPaymentRequest_WhenPaymentExists_ShouldReturn200SuccessCodeAndPaymentInformation() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = 12345 }; var jsonRequest = JsonConvert.SerializeObject(submitPaymentRequest); var submitPaymentResponse = await _httpClient.PostAsync("https://localhost:9901/paymentgateway", new StringContent(jsonRequest, Encoding.UTF8, "application/json")); var responseContent = await submitPaymentResponse.Content.ReadAsStringAsync(); var paymentInformation = JsonConvert.DeserializeObject <SubmitPaymentResponse>(responseContent); // when var retrievePaymentResponse = await _httpClient.GetAsync($"https://localhost:9901/paymentgateway?paymentId={paymentInformation.PaymentId}&merchantId={submitPaymentRequest.MerchantDetails.MerchantId}"); // then retrievePaymentResponse.IsSuccessStatusCode.ShouldBeTrue(); var content = await retrievePaymentResponse.Content.ReadAsStringAsync(); var retrievedPayment = JsonConvert.DeserializeObject <RetrievePaymentResponse>(content); retrievedPayment.Amount.ShouldBe(submitPaymentRequest.Amount); retrievedPayment.CVV.ShouldBe("***"); retrievedPayment.CardNumber.ShouldBe("1234********3456"); retrievedPayment.ExpiryDate.ShouldBe(submitPaymentRequest.CardDetails.ExpiryDate); retrievedPayment.Currency.ShouldBe(submitPaymentRequest.CardDetails.Currency); retrievedPayment.PaymentResponseStatus.ShouldBe("Successful"); }
public async Task <ActionResult <SubmitPaymentResponse> > CreatePaymentSync([FromBody] SubmitPaymentRequest paymentRequest) { PaymentProcessorSubmitPaymentRequest paymentProcessorRequest = new PaymentProcessorSubmitPaymentRequest(paymentRequest.AccountNumber, paymentRequest.PaymentAmount); var request = new HttpRequestMessage(HttpMethod.Post, PaymentProcessorUri); request.Content = new ObjectContent <PaymentProcessorSubmitPaymentRequest>(paymentProcessorRequest, new JsonMediaTypeFormatter()); var serviceResponse = await this._httpClient.SendAsync(request); if (!serviceResponse.IsSuccessStatusCode) { Console.WriteLine($"Error in request: {serviceResponse}"); return(new SubmitPaymentResponse(String.Empty, "Error")); } // because this call is synchronous, we can return the actual values from the finished process PaymentProcessorSubmitPaymentResponse paymentProcessorResponse = await serviceResponse.Content.ReadAsAsync <PaymentProcessorSubmitPaymentResponse>(); return(new SubmitPaymentResponse(paymentProcessorResponse.PaymentId, paymentProcessorResponse.PaymentStatus)); }
public async Task <IActionResult> Post([FromBody] SubmitPaymentRequest submitPaymentRequest, [FromHeader] string correlationId = null) { _logger.LogInformation($"Submit Payment request with correlationId {correlationId} received"); var bankPaymentRequest = GenerateBankPaymentRequest(submitPaymentRequest, correlationId); var bankPaymentResponse = _paymentOrchestrator.ProcessPayment(bankPaymentRequest); if (bankPaymentResponse.BankPaymentResponseStatus == BankPaymentResponseStatus.Successful) { return(Ok(new SubmitPaymentResponse { PaymentId = bankPaymentResponse.PaymentId, PaymentResponseStatus = bankPaymentResponse.BankPaymentResponseStatus.ToString() })); } else { return(BadRequest()); } }
/// <inheritdoc /> public SubmitPaymentResult SubmitPayment(SubmitPaymentRequest submitPaymentRequest) { var result = new SubmitPaymentResult(); var t3Node = this.xServerPeerList.GetPeers().Where(n => n.Tier == (int)TierLevel.Three).OrderBy(n => n.ResponseTime).FirstOrDefault(); if (t3Node != null) { string xServerURL = Utils.GetServerUrl(t3Node.NetworkProtocol, t3Node.NetworkAddress, t3Node.NetworkPort); var client = new RestClient(xServerURL); client.UseNewtonsoftJson(); var paymentRequest = new RestRequest("/submitpayment", Method.POST); var request = JsonConvert.SerializeObject(submitPaymentRequest); paymentRequest.AddParameter("application/json; charset=utf-8", request, ParameterType.RequestBody); paymentRequest.RequestFormat = DataFormat.Json; var submitPaymentResult = client.Execute <SubmitPaymentResult>(paymentRequest); if (submitPaymentResult.StatusCode == HttpStatusCode.OK) { result = submitPaymentResult.Data; } else { var errorResponse = JsonConvert.DeserializeObject <ErrorResponse>(submitPaymentResult.Content); if (errorResponse != null) { result.ResultMessage = errorResponse.errors[0].message; } else { result.ResultMessage = "Failed to access xServer"; } result.Success = false; } } else { result.ResultMessage = "Not connected to any tier 3 servers"; } return(result); }
public async Task GivenAPaymentRequest_WhenPaymentExists_ShouldReturn200SuccessCodeAndPaymentInformation() { // given var submitPaymentRequest = new SubmitPaymentRequest { CardDetails = new CardDetails { CVV = 123, Currency = "Pound", ExpiryDate = "01/2020", CardNumber = 1234567890123456 }, MerchantDetails = new MerchantDetails { MerchantId = Guid.NewGuid() }, Amount = 12345 }; var response = await _sut.Post(submitPaymentRequest); var submitPaymentResponse = (response as OkObjectResult).Value as SubmitPaymentResponse; // when var retrievePaymentResponse = await _sut.Get(new RetrievePaymentRequest { PaymentId = submitPaymentResponse.PaymentId, MerchantId = submitPaymentRequest.MerchantDetails.MerchantId }); // then retrievePaymentResponse.ShouldBeOfType <OkObjectResult>(); var retrievedPayment = (retrievePaymentResponse as OkObjectResult).Value as RetrievePaymentResponse; retrievedPayment.Amount.ShouldBe(submitPaymentRequest.Amount); retrievedPayment.CVV.ShouldBe("***"); retrievedPayment.CardNumber.ShouldBe("1234********3456"); retrievedPayment.ExpiryDate.ShouldBe(submitPaymentRequest.CardDetails.ExpiryDate); retrievedPayment.Currency.ShouldBe(submitPaymentRequest.CardDetails.Currency); retrievedPayment.PaymentResponseStatus.ShouldBe("Successful"); }
public void PublishMessageBodyWithNullParmaters( [Values("", "payments", "")] string exchange, [Values("", "", "payments.create")] string routingKey) { // arrange var controller = new amqp_sidecar.Controllers.Controller(this._connectionfactory.CreateConnection(), new HttpClient()); var messageBody = new SubmitPaymentRequest { AccountNumber = "12345", PaymentAmount = 100 }; // act ActionResult <string> actionResult = controller.EnqueueMessage(messageBody, exchange, routingKey); // assert var result = actionResult.Result as BadRequestObjectResult; Assert.That(result, Is.Not.Null, "Result is not BadRequestObjectResult"); Assert.That(result.StatusCode, Is.EqualTo((int)HttpStatusCode.BadRequest), "Result should be status code 400"); Assert.That(this._rabbitServer.Exchanges.ContainsKey(exchange), Is.EqualTo(false), "Exchange should not be created"); }
/// <summary> /// Submits a payment /// </summary> /// <param name="client">A RippleRestClient used for this request.</param> /// <param name="payment">Payment object</param> /// <returns>Original Payment object with Client Resource Id filled</returns> /// <exception cref="RippleRestException">Request failed.</exception> public Payment SubmitPayment(RippleRestClient client, Payment payment) { payment.ClientResourceId = client.GenerateUUID(); payment.SourceAccount = this.Address; var data = new SubmitPaymentRequest { Payment = payment, Secret = this.Secret, ClientResourceId = payment.ClientResourceId }; var result = client.RestClient.Execute<SubmitPaymentResponse>(client.CreatePostRequest(data, "v1/payments", Address)); client.HandleRestResponseErrors(result); payment.ClientResourceId = result.Data.ClientResourceId; return payment; }
public async Task <PaymentErrorCodes> ValidateNewPriceLockPayee(SubmitPaymentRequest submitPaymentRequest) { PaymentErrorCodes result; var priceLockData = networkFeatures.GetPriceLockData(new Guid(submitPaymentRequest.PriceLockId)); if (priceLockData != null) { if (priceLockData.TransactionId == null && priceLockData.PayeeSignature == null) { RawTransactionResponse paymentTransaction; if (string.IsNullOrEmpty(submitPaymentRequest.TransactionHex)) { paymentTransaction = await networkFeatures.GetRawTransaction(submitPaymentRequest.TransactionId, true); } else { paymentTransaction = await networkFeatures.DecodeRawTransaction(submitPaymentRequest.TransactionHex); } if (paymentTransaction != null) { bool validDestinationFound = false; bool validFeeFound = false; foreach (var output in paymentTransaction.VOut) { if (output.ScriptPubKey.Addresses.Count() == 1 && output.ScriptPubKey.Addresses[0] == priceLockData.DestinationAddress && output.Value == priceLockData.DestinationAmount) { validDestinationFound = true; } else if (output.ScriptPubKey.Addresses.Count() == 1 && output.ScriptPubKey.Addresses[0] == priceLockData.FeeAddress && output.Value == priceLockData.FeeAmount) { validFeeFound = true; } } if (!validDestinationFound) { return(PaymentErrorCodes.TransactionDestNotFound); } if (!validFeeFound) { return(PaymentErrorCodes.TransactionFeeNotFound); } var isPayeeValid = await priceLockValidation.IsPayeeSignatureValid(paymentTransaction, submitPaymentRequest.PriceLockId, submitPaymentRequest.PayeeSignature); if (isPayeeValid) { result = PaymentErrorCodes.None; } else { result = PaymentErrorCodes.InvalidSignature; } } else { result = PaymentErrorCodes.TransactionError; } } else { result = PaymentErrorCodes.AlreadyExists; } } else { result = PaymentErrorCodes.PriceLockNotFound; } return(result); }