示例#1
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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());
        }
示例#7
0
        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());
        }
示例#10
0
 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);
 }
示例#11
0
 private static void PrintProcessedPaymentFee(ProcessedPayment payment)
 {
     Console.WriteLine($"{payment.Date:yyyy-MM-dd} {payment.MerchantName} {String.Format("{0:0.00}", payment.Fee)}");
 }