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 }); }