public async Task <bool> Handle(PartiallyRefundOfflineCommand command, CancellationToken cancellationToken)
        {
            var paymentTransaction = command.PaymentTransaction;

            if (paymentTransaction == null)
            {
                throw new ArgumentNullException(nameof(command.PaymentTransaction));
            }

            var amountToRefund = command.AmountToRefund;

            var canPartiallyRefundOffline = await _mediator.Send(new CanPartiallyRefundOfflineQuery()
            {
                PaymentTransaction = paymentTransaction, AmountToRefund = amountToRefund
            });

            if (!canPartiallyRefundOffline)
            {
                throw new GrandException("You can't partially refund (offline) this order");
            }

            paymentTransaction.RefundedAmount   += amountToRefund;
            paymentTransaction.TransactionStatus = paymentTransaction.RefundedAmount >= paymentTransaction.TransactionAmount ? TransactionStatus.Refunded : TransactionStatus.PartiallyRefunded;
            await _paymentTransactionService.UpdatePaymentTransaction(paymentTransaction);

            var order = await _orderService.GetOrderByGuid(paymentTransaction.OrderGuid);

            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            //total amount refunded
            decimal totalAmountRefunded = order.RefundedAmount + amountToRefund;

            //update order info
            order.RefundedAmount  = totalAmountRefunded;
            order.PaymentStatusId = order.RefundedAmount >= order.OrderTotal ? PaymentStatus.Refunded : PaymentStatus.PartiallyRefunded;
            await _orderService.UpdateOrder(order);


            //check order status
            await _mediator.Send(new CheckOrderStatusCommand()
            {
                Order = order
            });

            //notifications
            _ = await _messageProviderService.SendOrderRefundedStoreOwnerMessage(order, amountToRefund, _languageSettings.DefaultAdminLanguageId);

            _ = await _messageProviderService.SendOrderRefundedCustomerMessage(order, amountToRefund, order.CustomerLanguageId);

            //raise event
            await _mediator.Publish(new PaymentTransactionRefundedEvent(paymentTransaction, amountToRefund));

            return(true);
        }
        public async Task <IList <string> > Handle(RefundCommand command, CancellationToken cancellationToken)
        {
            var paymentTransaction = command.PaymentTransaction;

            if (paymentTransaction == null)
            {
                throw new ArgumentNullException(nameof(command.PaymentTransaction));
            }

            //if (!await CanRefund(order))
            //    throw new GrandException("Cannot do refund for order.");

            var request = new RefundPaymentRequest();
            RefundPaymentResult result = null;

            try
            {
                request.PaymentTransaction = paymentTransaction;
                request.AmountToRefund     = paymentTransaction.PaidAmount;
                request.IsPartialRefund    = false;
                result = await _paymentService.Refund(request);

                if (result.Success)
                {
                    paymentTransaction.TransactionStatus = result.NewTransactionStatus;
                    paymentTransaction.RefundedAmount   += request.AmountToRefund;
                    await _paymentTransactionService.UpdatePaymentTransaction(paymentTransaction);

                    var order = await _orderService.GetOrderByGuid(paymentTransaction.OrderGuid);

                    if (order == null)
                    {
                        throw new ArgumentNullException(nameof(order));
                    }

                    decimal totalAmountRefunded = order.RefundedAmount + request.AmountToRefund;

                    //update order info
                    order.RefundedAmount  = totalAmountRefunded;
                    order.PaymentStatusId = order.RefundedAmount == order.OrderTotal ? Domain.Payments.PaymentStatus.Refunded : Domain.Payments.PaymentStatus.PartiallyRefunded;
                    await _orderService.UpdateOrder(order);

                    //check order status
                    await _mediator.Send(new CheckOrderStatusCommand()
                    {
                        Order = order
                    });

                    //notifications
                    var orderRefundedStoreOwnerNotificationQueuedEmailId = await _messageProviderService.SendOrderRefundedStoreOwnerMessage(order, request.AmountToRefund, _languageSettings.DefaultAdminLanguageId);

                    if (orderRefundedStoreOwnerNotificationQueuedEmailId > 0)
                    {
                        await _orderService.InsertOrderNote(new OrderNote
                        {
                            Note = "Order refunded email (to store owner) has been queued.",
                            DisplayToCustomer = false,
                            CreatedOnUtc      = DateTime.UtcNow,
                            OrderId           = order.Id,
                        });
                    }

                    //notifications
                    var orderRefundedCustomerNotificationQueuedEmailId = await _messageProviderService.SendOrderRefundedCustomerMessage(order, request.AmountToRefund, order.CustomerLanguageId);

                    if (orderRefundedCustomerNotificationQueuedEmailId > 0)
                    {
                        await _orderService.InsertOrderNote(new OrderNote
                        {
                            Note = "Order refunded email (to customer) has been queued.",
                            DisplayToCustomer = false,
                            CreatedOnUtc      = DateTime.UtcNow,
                            OrderId           = order.Id,
                        });
                    }

                    //raise event
                    await _mediator.Publish(new PaymentTransactionRefundedEvent(paymentTransaction, request.AmountToRefund));
                }
            }
            catch (Exception exc)
            {
                if (result == null)
                {
                    result = new RefundPaymentResult();
                }
                result.AddError(string.Format("Error: {0}. Full exception: {1}", exc.Message, exc.ToString()));
            }

            //process errors
            string error = "";

            for (int i = 0; i < result.Errors.Count; i++)
            {
                error += string.Format("Error {0}: {1}", i, result.Errors[i]);
                if (i != result.Errors.Count - 1)
                {
                    error += ". ";
                }
            }
            if (!String.IsNullOrEmpty(error))
            {
                //log it
                string logError = string.Format("Error refunding order #{0}. Error: {1}", paymentTransaction.OrderCode, error);
                await _logger.InsertLog(LogLevel.Error, logError, logError);
            }
            return(result.Errors);
        }
示例#3
0
        public async Task <bool> Handle(RefundOfflineCommand request, CancellationToken cancellationToken)
        {
            var paymentTransaction = request.PaymentTransaction;

            if (paymentTransaction == null)
            {
                throw new ArgumentNullException(nameof(request.PaymentTransaction));
            }

            var canRefundOffline = await _mediator.Send(new CanRefundOfflineQuery()
            {
                PaymentTransaction = paymentTransaction
            });

            if (!canRefundOffline)
            {
                throw new GrandException("You can't refund this payment transaction");
            }

            paymentTransaction.RefundedAmount   += paymentTransaction.TransactionAmount;
            paymentTransaction.TransactionStatus = paymentTransaction.RefundedAmount >= paymentTransaction.TransactionAmount ? TransactionStatus.Refunded : TransactionStatus.PartiallyRefunded;
            await _paymentTransactionService.UpdatePaymentTransaction(paymentTransaction);


            var order = await _orderService.GetOrderByGuid(paymentTransaction.OrderGuid);

            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            //amout to refund
            decimal amountToRefund = order.OrderTotal;

            //total amount refunded
            decimal totalAmountRefunded = order.RefundedAmount + amountToRefund;

            //update order info
            order.RefundedAmount  = totalAmountRefunded;
            order.PaymentStatusId = order.RefundedAmount >= order.OrderTotal ? PaymentStatus.Refunded : PaymentStatus.PartiallyRefunded;

            await _orderService.UpdateOrder(order);


            //check order status
            await _mediator.Send(new CheckOrderStatusCommand()
            {
                Order = order
            });

            //notifications
            var orderRefundedStoreOwnerNotificationQueuedEmailId = await _messageProviderService.SendOrderRefundedStoreOwnerMessage(order, amountToRefund, _languageSettings.DefaultAdminLanguageId);

            if (orderRefundedStoreOwnerNotificationQueuedEmailId > 0)
            {
                await _orderService.InsertOrderNote(new OrderNote
                {
                    Note = "Order refunded email (to store owner) has been queued.",
                    DisplayToCustomer = false,
                    CreatedOnUtc      = DateTime.UtcNow,
                    OrderId           = order.Id,
                });
            }


            var orderRefundedCustomerNotificationQueuedEmailId = await _messageProviderService.SendOrderRefundedCustomerMessage(order, amountToRefund, order.CustomerLanguageId);

            if (orderRefundedCustomerNotificationQueuedEmailId > 0)
            {
                await _orderService.InsertOrderNote(new OrderNote
                {
                    Note = "\"Order refunded\" email (to customer) has been queued.",
                    DisplayToCustomer = false,
                    CreatedOnUtc      = DateTime.UtcNow,
                    OrderId           = order.Id,
                });
            }

            //raise event
            await _mediator.Publish(new PaymentTransactionRefundedEvent(paymentTransaction, amountToRefund));

            return(true);
        }