Exemplo n.º 1
0
        /// <inheritdoc />
        public virtual async Task <IPaymentRefundResult> RefundAsync(RefundInvoice invoice, CancellationToken cancellationToken = default)
        {
            if (invoice == null)
            {
                throw new ArgumentNullException(nameof(invoice));
            }

            Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is started."));

            var payment = await _storageManager.GetPaymentByTrackingNumberAsync(invoice.TrackingNumber, cancellationToken).ConfigureAwaitFalse();

            if (payment == null)
            {
                Log(logger => logger.LogError(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is failed. The operation is not valid. No payment found with the tracking number {invoice.TrackingNumber}"));

                throw new InvoiceNotFoundException(invoice.TrackingNumber);
            }

            if (!payment.IsCompleted)
            {
                var message = $"{_options.Messages.OnlyCompletedPaymentCanBeRefunded} Tracking number: {invoice.TrackingNumber}.";

                Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished. {message}"));

                return(PaymentRefundResult.Failed(message));
            }

            Money amountToRefund;

            if (invoice.Amount == 0)
            {
                amountToRefund = payment.Amount;
            }
            else if (invoice.Amount > payment.Amount)
            {
                throw new Exception("Amount cannot be greater than the amount of the paid payment.");
            }
            else
            {
                amountToRefund = invoice.Amount;
            }

            var gateway = _gatewayProvider.Provide(payment.GatewayName);

            var transactions = await _storageManager.GetTransactionsAsync(payment, cancellationToken).ConfigureAwaitFalse();

            var verifyContext = new InvoiceContext(payment, transactions);

            PaymentRefundResult refundResult;

            try
            {
                refundResult = await gateway
                               .RefundAsync(verifyContext, amountToRefund, cancellationToken)
                               .ConfigureAwaitFalse() as PaymentRefundResult;
            }
            catch (Exception exception)
            {
                Log(logger => logger.LogError(exception, "Parbad exception. An error occurred during requesting."));
                throw;
            }

            if (refundResult == null)
            {
                throw new Exception($"Gateway {gateway.GetCompleteGatewayName()} returns null instead of a result.");
            }

            refundResult.TrackingNumber     = payment.TrackingNumber;
            refundResult.Amount             = amountToRefund;
            refundResult.GatewayName        = payment.GatewayName;
            refundResult.GatewayAccountName = payment.GatewayAccountName;

            var newtTransaction = new Transaction
            {
                Amount         = refundResult.Amount,
                Type           = TransactionType.Refund,
                IsSucceed      = refundResult.IsSucceed,
                Message        = refundResult.Message,
                AdditionalData = AdditionalDataConverter.ToJson(refundResult),
                PaymentId      = payment.Id
            };

            await _storageManager.CreateTransactionAsync(newtTransaction, cancellationToken).ConfigureAwaitFalse();

            Log(logger => logger.LogInformation(LoggingEvents.RefundPayment, $"Refunding the invoice {invoice.TrackingNumber} is finished."));

            return(refundResult);
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public virtual async Task <IPaymentRefundResult> RefundAsync(RefundInvoice invoice, CancellationToken cancellationToken = default)
        {
            if (invoice == null)
            {
                throw new ArgumentNullException(nameof(invoice));
            }

            _logger.LogInformation(LoggingEvents.RefundPayment, $"Refund starts for the payment with tracking number {invoice.TrackingNumber}.");

            //var payment = await _database.Payments
            //    .Include(model => model.Transactions)
            //    .SingleOrDefaultAsync(model => model.TrackingNumber == invoice.TrackingNumber, cancellationToken)
            //    .ConfigureAwaitFalse();

            var payment = await _storageManager.GetPaymentByTrackingNumberAsync(invoice.TrackingNumber, cancellationToken).ConfigureAwaitFalse();

            if (payment == null)
            {
                var message = $"The operation is not valid. No payment found with the tracking number {invoice.TrackingNumber}.";

                _logger.LogError(LoggingEvents.RefundPayment, message);

                return(PaymentRefundResult.Failed(message));
            }

            if (!payment.IsCompleted)
            {
                var message = $"The payment with the tracking number {invoice.TrackingNumber} is not completed yet. Only a completed payment can be refund.";

                _logger.LogError(LoggingEvents.RefundPayment, message);

                return(PaymentRefundResult.Failed(message));
            }

            Money amountToRefund;

            if (invoice.Amount == 0)
            {
                amountToRefund = payment.Amount;
            }
            else if (invoice.Amount > payment.Amount)
            {
                throw new Exception("Amount cannot be greater than the amount of the paid payment.");
            }
            else
            {
                amountToRefund = payment.Amount;
            }

            var gateway = _gatewayProvider.Provide(payment.GatewayName);

            var transactions = await _storageManager.GetTransactionsAsync(payment, cancellationToken).ConfigureAwaitFalse();

            var verifyContext = new VerifyContext(payment, transactions);

            PaymentRefundResult refundResult;

            try
            {
                refundResult = await gateway
                               .RefundAsync(verifyContext, amountToRefund, cancellationToken)
                               .ConfigureAwaitFalse() as PaymentRefundResult;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Parbad exception. An error occurred during requesting.");
                throw;
            }

            if (refundResult == null)
            {
                throw new Exception($"Gateway {gateway.GetName()} returns null instead of a result.");
            }

            refundResult.TrackingNumber     = payment.TrackingNumber;
            refundResult.Amount             = amountToRefund;
            refundResult.GatewayName        = payment.GatewayName;
            refundResult.GatewayAccountName = payment.GatewayAccountName;

            var newtTransaction = new Transaction
            {
                Amount         = refundResult.Amount,
                Type           = TransactionType.Refund,
                IsSucceed      = refundResult.IsSucceed,
                Message        = refundResult.Message,
                AdditionalData = AdditionalDataConverter.ToJson(refundResult),
                PaymentId      = payment.Id
            };

            await _storageManager.CreateTransactionAsync(newtTransaction, cancellationToken).ConfigureAwaitFalse();

            _logger.LogInformation(LoggingEvents.RefundPayment, "Refund ends.");

            return(refundResult);
        }