public async Task <Payment> CapturePayment(Payment payment, TransactionUpdateDetails details) { if (payment.CreditCardDetails.CreditCardNumber == 4000000000000259) { throw new PaymentGatewayServiceException("Invalid credit card number for Capture"); } // Would these checks into a rule engine but for now hard coding due to time constaints if (payment.IsVoid) { throw new InvalidTransactionCaptureException("Payment is already void so should not capture", payment.Id); } ; if (payment.TransactionRefundDetails != default) { throw new InvalidTransactionCaptureException("Payment has been refunded", payment.Id); } if (details.Amount < 0) { throw new InvalidTransactionCaptureException("Amount can not be less than 0", payment.Id); } if (payment.PaymentCompletedDate != DateTime.MinValue) { throw new InvalidTransactionCaptureException("Payment has been fully paid", payment.Id); } if (payment.TransactionCaptureDetails == default) { payment.TransactionCaptureDetails = new List <TransactionUpdateDetails> { details }; } else { payment.TransactionCaptureDetails.Add(details); } var paidAmount = payment.TransactionCaptureDetails.Sum(x => x.Amount); if (payment.TransactionDetails.Amount - paidAmount < 0) { throw new InvalidTransactionCaptureException("Transaction will take total amount greater than what customer owes", payment.Id); } if (payment.TransactionDetails.Amount == paidAmount) { _logger.LogInformation("Payment amount owed is now 0. Do not capture any more money"); payment.PaymentCompletedDate = DateTime.UtcNow; } return(await _repository.Update(payment)); }
public async Task <Payment> RefundPayment(Payment payment, TransactionUpdateDetails details) { if (payment.CreditCardDetails.CreditCardNumber == 4000000000003238) { throw new PaymentGatewayServiceException("Invalid credit card number for Refund"); } if (payment.TransactionRefundDetails == default) { payment.TransactionRefundDetails = new List <TransactionUpdateDetails> { details }; } else { payment.TransactionRefundDetails.Add(details); } var refundAmount = payment.TransactionRefundDetails.Sum(x => x.Amount); decimal totalAmountCaptured = 0m; if (payment.TransactionCaptureDetails != default) { totalAmountCaptured = payment.TransactionCaptureDetails.Sum(x => x.Amount); } if (totalAmountCaptured - refundAmount < 0) { throw new InvalidTransactionCaptureException("This refund will give the customer back more than they paid", payment.Id); } if (totalAmountCaptured == refundAmount) { _logger.LogInformation($"Full payment has been refunded {payment.Id}"); payment.PaymentCompletedDate = DateTime.UtcNow; } return(await _repository.Update(payment)); }