示例#1
0
        public async Task <IActionResult> Post([FromBody] CreateChargeRequest request)
        {
            // Note that explicitly checking ModelState is not required for controllers with the [ApiController]
            // attribute, so there is no code here for that here.

            var entity = new Charge
            {
                IdempotentKey = request.IdempotentKey,
                CreatedOn     = DateTimeOffset.UtcNow,
                Status        = ChargeStatus.Pending,
                Amount        = request.Amount,
                Currency      = request.Currency,
                Description   = request.Description,
                CardNumber    = request.CardNumber,
                Cvv           = request.Cvv,
                ExpiryMonth   = request.ExpiryMonth,
                ExpiryYear    = request.ExpiryYear
            };

            _db.Charges.Add(entity);

            try
            {
                await _db.SaveChangesAsync();
            }
            catch (DbUpdateException exception) when(exception.IsViolationOfUniqueIndex())
            {
                // This handles the case where someone is double-posting a charge with the same IdempotentKey.

                _logger.LogWarning("A charge with idempotency key {IdempotentKey} attempted to double post.", request.IdempotentKey);
                return(Conflict());
            }

            var acquiringBankRequest = new AcquiringBankRequest
            {
                Amount      = entity.Amount,
                Currency    = entity.Currency,
                CardNumber  = entity.CardNumber,
                Cvv         = entity.Cvv,
                ExpiryMonth = entity.ExpiryMonth,
                ExpiryYear  = entity.ExpiryYear
            };

            var success = await _bank.TrySendAsync(acquiringBankRequest, out var bankChargeId);

            if (!success)
            {
                _logger.LogError("The acquiring bank for charge id {Id} rejected the payment.", entity.Id);
            }

            entity.Status       = success ? ChargeStatus.Success : ChargeStatus.Failed;
            entity.BankChargeId = bankChargeId;

            await _db.SaveChangesAsync();

            var result = new GetChargeResponse(entity);

            return(CreatedAtAction("Get", new { id = entity.Id }, result));
        }
 /// <summary>
 /// Sends a payment request to a bank service and returns a response indicating whether successful.
 /// </summary>
 /// <param name="request"></param>
 /// <returns></returns>
 public Task <AcquiringBankResponse> SendPayment(AcquiringBankRequest request)
 {
     // faked result
     return(Task.Run(() => new AcquiringBankResponse
     {
         Status = AcquiringBankResponseStatus.Success,
         PaymentId = new Random().Next()
     }));
 }
        public PaymentResponse ProcessPayment(ProcessPaymentRequest request, string merchantApiKey)
        {
            //Get merchant
            var merchant = _merchantDao.GetMerchantBasedOnApiKey(merchantApiKey);

            if (merchant == null)
            {
                Logger.Info("Request from an unknown merchant received");
                throw new RequestValidationException("Unknown Merchant");
            }

            if (string.IsNullOrWhiteSpace(request.CardNumber))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Number");
                throw new RequestValidationException("Missing Card Number");
            }

            if (!(request.CardNumber.Length == 19 || request.CardNumber.Length == 16))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Number");
                throw new RequestValidationException("Invalid Card Number");
            }

            if (string.IsNullOrWhiteSpace(request.CardCvv))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card CVV Number");
                throw new RequestValidationException("Missing Card CVV Number");
            }

            if (request.CardCvv.Length != 4)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Card CVV Number");
                throw new RequestValidationException("Invalid Card Card CVV Number");
            }

            if (request.PaymentAmount == 0)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Payment Amount");
                throw new RequestValidationException("Payment Amount should be greater than zero");
            }

            if (string.IsNullOrWhiteSpace(request.ExpiryDate))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Expiry Date");
                throw new RequestValidationException("Missing Card Card Expiry Date");
            }

            DateTime expiryDate;

            try
            {
                expiryDate = DateTime.ParseExact(request.ExpiryDate, _expiryDateFormat, CultureInfo.InvariantCulture);
            }
            catch (Exception e)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid ExpiryDate provided");
                throw new RequestValidationException("Invalid ExpiryDate provided");
            }

            if (string.IsNullOrWhiteSpace(request.Currency))
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Currency");
                throw new RequestValidationException("Missing Currency");
            }



            var currency = GetCurrency(request);

            if (currency == null)
            {
                Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Unknown currency");
                throw new RequestValidationException("Unknown Currency");
            }



            var card = GetOrCreateCard(request, expiryDate);

            var paymentRequest = new PaymentRequest
            {
                MerchantId    = merchant.ID,
                CardId        = card.ID,
                CurrencyId    = currency.ID,
                Amount        = request.PaymentAmount,
                DateTimeAdded = DateTime.UtcNow
            };

            _paymentRequestDao.InsertPaymentRequest(paymentRequest);

            paymentRequest =
                _paymentRequestDao.GetPaymentRequestBasedOnMerchantIdCardIdCurrencyIdAndAmount(paymentRequest);
            Logger.Info($"Payment request from Merchant: {merchant.ID} logged. PaymentRequestId : {paymentRequest.Id}");

            var acquiringBankRequest = new  AcquiringBankRequest
            {
                CardNumber    = request.CardNumber,
                CardCvv       = request.CardCvv,
                PaymentAmount = request.PaymentAmount,
                ExpiryDate    = request.ExpiryDate,
                Currency      = request.Currency,
                MerchantId    = merchant.ID
            };
            var response = _acquiringBankService.ProcessPayment(acquiringBankRequest);

            var bankPaymentResponse = new BankPaymentResponse
            {
                PaymentRequestId      = paymentRequest.Id,
                Status                = response.PaymentStatus,
                BankPaymentIdentifier = response.PaymentIdentifier,
                DateTimeAdded         = DateTime.UtcNow
            };

            _bankPaymentResponseDao.InsertBankPaymentResponse(bankPaymentResponse);

            return(new PaymentResponse
            {
                Status = response.PaymentStatus,
                PaymentUniqueId = response.PaymentIdentifier
            });
        }