public async Task <Either <ProcessPaymentResponseDTO, ErrorResponseDTO> > Handle(ProcessPaymentRequest request, CancellationToken cancellationToken) { // build a hashed key based on the values of the request var requestCacheKey = BuildCacheKey(request); // check if the cache already has this key, if so throw exception if (_cache.TryGetValue(requestCacheKey, out _)) { return(new ErrorResponseDTO { Message = "Multiple same requests detected", StatusCode = HttpStatusCode.TooManyRequests }); } _logger.Information("Verifying payment with acquiring bank"); // use the acqbank to send payment var bankResponse = await _acquiringBank.SendPayment(new AcquiringBankRequest { CardNumber = request.CardNumber, Amount = request.Amount, Currency = request.Currency, CVV = request.CVV, Expiry = request.Expiry }); // save response to newPayment var newPayment = new ProcessedPayment { Id = bankResponse.PaymentId, PaymentResult = bankResponse.Status.ToString().Replace("_", " "), // mask all but last 4 digits with * CardNumber = new string('*', request.CardNumber.Length - 4) + request.CardNumber.Substring(request.CardNumber.Length - 4), // mask full length with asterisks CVV = new string('*', request.CVV.Length), Expiry = new DateTime(request.Expiry.Year, request.Expiry.Month + 1, 1).AddDays(-1), Amount = request.Amount, Created = _nowProvider.Now, Currency = request.Currency, Owner = request.Owner }; _logger.Information("Storing payment record with id {Id} for client {Owner}", newPayment.Id, newPayment.Owner); // add new payment to DB _context.ProcessedPayments.Add(newPayment); await _context.SaveChangesAsync(); // add to cache, with TTL so it eventually is removed // using this instead of .Set() so we can mock it easier SetCacheForRequest( requestCacheKey, DateTimeOffset.UtcNow.AddMinutes(_cachingOptions.ProccessedPaymentTTLMinutes)); // return response dto with new payment id and result return(new ProcessPaymentResponseDTO { PaymentId = newPayment.Id, Success = bankResponse.Status == AcquiringBankResponseStatus.Success }); }
public void GetProcessedPayment_ShouldWork_WhenSignatureIsValidAndPayIsNotPerformed() { var merchantParamenters = "eyJEc19EYXRlIjoiMTkvMDgvMjAxNSIsIkRzX0hvdXIiOiIxMjo0OSIsIkRzX0Ftb3VudCI6IjEyMzQ1IiwiRHNfQ3VycmVuY3kiOiI5NzgiLCJEc19PcmRlciI6Ijk5OTkxMTExMjIyMiIsIkRzX01lcmNoYW50Q29kZSI6IjAxMjM0NTYiLCJEc19UZXJtaW5hbCI6IjIiLCJEc19SZXNwb25zZSI6IjEwMSIsIkRzX01lcmNoYW50RGF0YSI6IiIsIkRzX1NlY3VyZVBheW1lbnQiOiIxIiwiRHNfVHJhbnNhY3Rpb25UeXBlIjoiMCIsIkRzX0NhcmRfQ291bnRyeSI6IiIsIkRzX0F1dGhvcmlzYXRpb25Db2RlIjoiMCIsIkRzX0NvbnN1bWVyTGFuZ3VhZ2UiOiIwIiwiRHNfQ2FyZF9UeXBlIjoiRCJ9"; string merchantKey = "Mk9m98IfEblmPfrpsawt7BmxObt98Jev"; string platformSignature = "iRNNn9pg2j6LIaLtlm15998hp/li7e2ptwVyfmO5JAY="; IPaymentResponseService paymentResponseService = new PaymentResponseService(); ProcessedPayment result = paymentResponseService.GetProcessedPayment(merchantParamenters, merchantKey, platformSignature); Assert.IsTrue(result.IsValidSignature == true); Assert.IsFalse(result.IsPaymentPerformed.DefaultIfEmpty(false).Single()); Assert.IsNotNull(result.PaymentResponse); Assert.IsTrue(result.PaymentResponse.Ds_Amount == 123.45M); Assert.IsTrue(result.PaymentResponse.Ds_AuthorisationCode == "0"); Assert.IsTrue(result.PaymentResponse.Ds_Card_Country == ""); Assert.IsTrue(result.PaymentResponse.Ds_Card_Type == "D"); Assert.IsTrue(result.PaymentResponse.Ds_ConsumerLanguage == Language.Defect); Assert.IsTrue(result.PaymentResponse.Ds_Currency == Currency.EUR); Assert.IsTrue(result.PaymentResponse.Ds_Date == "19/08/2015"); Assert.IsTrue(result.PaymentResponse.Ds_Hour == "12:49"); Assert.IsTrue(result.PaymentResponse.Ds_MerchantCode == "0123456"); Assert.IsTrue(result.PaymentResponse.Ds_MerchantData == ""); Assert.IsTrue(result.PaymentResponse.Ds_Order == "999911112222"); Assert.IsTrue(result.PaymentResponse.Ds_Response == "101"); Assert.IsTrue(result.PaymentResponse.Ds_SecurePayment == "1"); Assert.IsTrue(result.PaymentResponse.Ds_Terminal == "2"); Assert.IsTrue(result.PaymentResponse.Ds_TransactionType == Enums.TransactionType.Authorization); }
public void GetProcessedPayment_ShouldWork_WhenSignatureIsValidAndPayIsPerformed() { var merchantParamenters = "eyJEc19EYXRlIjoiMTkvMDgvMjAxNSIsIkRzX0hvdXIiOiIxMjo0OSIsIkRzX0Ftb3VudCI6IjEyMzQ1IiwiRHNfQ3VycmVuY3kiOiI5NzgiLCJEc19PcmRlciI6Ijk5OTkxMTExMjIyMiIsIkRzX01lcmNoYW50Q29kZSI6IjAxMjM0NTYiLCJEc19UZXJtaW5hbCI6IjIiLCJEc19SZXNwb25zZSI6IjAiLCJEc19NZXJjaGFudERhdGEiOiIiLCJEc19TZWN1cmVQYXltZW50IjoiMSIsIkRzX1RyYW5zYWN0aW9uVHlwZSI6IjAiLCJEc19DYXJkX0NvdW50cnkiOiIiLCJEc19BdXRob3Jpc2F0aW9uQ29kZSI6IjAiLCJEc19Db25zdW1lckxhbmd1YWdlIjoiMCIsIkRzX0NhcmRfVHlwZSI6IkQifQ=="; string merchantKey = "Mk9m98IfEblmPfrpsawt7BmxObt98Jev"; string platformSignature = "UpSJaiLH6mMZZkXQAyMgImD4LaJZLInbHaN7zzKbYr4="; IPaymentResponseService paymentResponseService = new PaymentResponseService(); ProcessedPayment result = paymentResponseService.GetProcessedPayment(merchantParamenters, merchantKey, platformSignature); Assert.IsTrue(result.IsValidSignature == true); Assert.IsTrue(result.IsPaymentPerformed.DefaultIfEmpty(false).Single()); Assert.IsNotNull(result.PaymentResponse); Assert.IsTrue(result.PaymentResponse.Ds_Amount == 123.45M); Assert.IsTrue(result.PaymentResponse.Ds_AuthorisationCode == "0"); Assert.IsTrue(result.PaymentResponse.Ds_Card_Country == ""); Assert.IsTrue(result.PaymentResponse.Ds_Card_Type == "D"); Assert.IsTrue(result.PaymentResponse.Ds_ConsumerLanguage == Language.Defect); Assert.IsTrue(result.PaymentResponse.Ds_Currency == Currency.EUR); Assert.IsTrue(result.PaymentResponse.Ds_Date == "19/08/2015"); Assert.IsTrue(result.PaymentResponse.Ds_Hour == "12:49"); Assert.IsTrue(result.PaymentResponse.Ds_MerchantCode == "0123456"); Assert.IsTrue(result.PaymentResponse.Ds_MerchantData == ""); Assert.IsTrue(result.PaymentResponse.Ds_Order == "999911112222"); Assert.IsTrue(result.PaymentResponse.Ds_Response == "0"); Assert.IsTrue(result.PaymentResponse.Ds_SecurePayment == "1"); Assert.IsTrue(result.PaymentResponse.Ds_Terminal == "2"); Assert.IsTrue(result.PaymentResponse.Ds_TransactionType == Enums.TransactionType.Authorization); }
public IProcessedPayment CreateProcessedPayment(IUnprocessedPayment unprocessedPayment, IAcquiringBankResponse acquiringBankResponse) { if (unprocessedPayment == null) { throw new ArgumentNullException(nameof(unprocessedPayment)); } var processedPayment = new ProcessedPayment { Id = unprocessedPayment.Id, CardNumber = unprocessedPayment.CardNumber, CardCvv = unprocessedPayment.CardCvv, CardExpiryMonth = unprocessedPayment.CardExpiryMonth, CardExpiryYear = unprocessedPayment.CardExpiryYear, Amount = unprocessedPayment.Amount, Currency = unprocessedPayment.Currency, UserId = unprocessedPayment.UserId, User = unprocessedPayment.User, CreatedAt = unprocessedPayment.CreatedAt }; if (acquiringBankResponse == null) { return(processedPayment); } processedPayment.Success = acquiringBankResponse.Success; processedPayment.AcquiringBankPaymentId = acquiringBankResponse.PaymentId; return(processedPayment); }
public ProcessedPayment GetProcessedPayment(string merchantParameters, string merchantKey, string providedSignature) { var paymentResponse = merchantParamentersManager.GetPaymentResponse(merchantParameters); var expectedSignature = signatureManager.GetSignature(merchantParameters, paymentResponse.Ds_Order, merchantKey); var isValidSignature = signatureComparer.ValidateResponseSignature(expectedSignature, providedSignature); var result = new ProcessedPayment(paymentResponse, isValidSignature); return(result); }
public void GetProcessedPayment_ShouldWork_WhenSignatureIsNotValid() { var merchantParamenters = "eyJEc19EYXRlIjoiMTkvMDgvMjAxNSIsIkRzX0hvdXIiOiIxMjo0OSIsIkRzX0Ftb3VudCI6IjEyMzQ1IiwiRHNfQ3VycmVuY3kiOiI5NzgiLCJEc19PcmRlciI6Ijk5OTkxMTExMjIyMiIsIkRzX01lcmNoYW50Q29kZSI6IjAxMjM0NTYiLCJEc19UZXJtaW5hbCI6IjIiLCJEc19SZXNwb25zZSI6IjAiLCJEc19NZXJjaGFudERhdGEiOiIiLCJEc19TZWN1cmVQYXltZW50IjoiMSIsIkRzX1RyYW5zYWN0aW9uVHlwZSI6IjAiLCJEc19DYXJkX0NvdW50cnkiOiIiLCJEc19BdXRob3Jpc2F0aW9uQ29kZSI6IjAiLCJEc19Db25zdW1lckxhbmd1YWdlIjoiMCIsIkRzX0NhcmRfVHlwZSI6IkQifQ=="; string merchantKey = "Mk9m98IfEblmPfrpsawt7BmxObt98Jev"; string platformSignature = "xxxxxx"; IPaymentResponseService paymentResponseService = new PaymentResponseService(); ProcessedPayment result = paymentResponseService.GetProcessedPayment(merchantParamenters, merchantKey, platformSignature); Assert.IsTrue(result.IsValidSignature == false); Assert.IsFalse(result.IsPaymentPerformed.Any()); }
public async Task <SavePaymentResult> Save(ProcessedPayment processedPayment) { var paymentEntity = new PaymentEntity( identityGenerator.NewId, processedPayment.CardNumber, processedPayment.ExpiryYear, processedPayment.ExpiryMonth, processedPayment.Amount, processedPayment.Currency, processedPayment.AcquirerPaymentId, processedPayment.IsPaymentSuccessful); db.Add(paymentEntity.Key, paymentEntity); return(await Task.FromResult(new SavePaymentResult(paymentEntity.Key))); }
public void ProcessedPayment_ShouldNotBePerformed_IfSignatureIsValidAndOrderHasNotBeenPaid() { ProcessedPayment processedPayment = new ProcessedPayment(Build.PaymentResponse(paid: false), true); Assert.IsFalse(processedPayment.IsPaymentPerformed.DefaultIfEmpty(false).Single()); }
public void ProcessedPayment_ShouldNotHave_AnInvalidState() { ProcessedPayment processedPayment = new ProcessedPayment(Build.PaymentResponse(paid: true), false); Assert.IsFalse(processedPayment.IsPaymentPerformed.Any()); }
private static void AssertFeeFields(string dateString, string merchantName, decimal paymentAmount, decimal expectedFeeAmount, ProcessedPayment processedPayment) { Assert.Equal(dateString, processedPayment.Date.ToString("yyyy-MM-dd")); Assert.Equal(merchantName, processedPayment.MerchantName); Assert.Equal(paymentAmount, processedPayment.Amount); Assert.Equal(expectedFeeAmount, processedPayment.Fee); }
private static void PrintProcessedPaymentFee(ProcessedPayment payment) { Console.WriteLine($"{payment.Date:yyyy-MM-dd} {payment.MerchantName} {String.Format("{0:0.00}", payment.Fee)}"); }