コード例 #1
0
        public VoidPaymentResult Void(VoidPaymentRequest voidPaymentRequest)
        {
            var order = voidPaymentRequest.Order;
            var result = new VoidPaymentResult();

            try
            {
                _klarnaCheckoutPaymentService.CancelPayment(order.AuthorizationTransactionId, order.Customer);

                result.NewPaymentStatus = PaymentStatus.Voided;

                order.OrderNotes.Add(new OrderNote
                {
                    Note = string.Format(CultureInfo.CurrentCulture, "KlarnaCheckout: The payment has been voided. Reservation: {0}",
                        order.AuthorizationTransactionId),
                    CreatedOnUtc = DateTime.UtcNow,
                    DisplayToCustomer = false
                });
                _orderService.UpdateOrder(order);
            }
            catch (KlarnaCheckoutException kce)
            {
                order.OrderNotes.Add(new OrderNote
                {
                    Note = "KlarnaCheckout: An error occurred when voiding the payment. See the error log for more information.",
                    CreatedOnUtc = DateTime.UtcNow,
                    DisplayToCustomer = false
                });
                _orderService.UpdateOrder(order);

                _logger.Error(string.Format(CultureInfo.CurrentCulture, "KlarnaCheckout: Error voiding payment. Order Id: {0}; Reservation: {1}",
                    order.Id, order.AuthorizationTransactionId),
                    exception: kce,
                    customer: order.Customer);

                result.AddError("An error occurred while voiding the order. See the error log for more information.");
            }

            return result;
        }
        private Order CreateOrderAndSyncWithKlarna(KlarnaCheckoutEntity klarnaRequest, Customer customer, KlarnaCheckoutOrder klarnaCheckoutOrder, Uri resourceUri)
        {
            SyncCartWithKlarnaOrder(customer, klarnaCheckoutOrder);

            var processPaymentRequest = new ProcessPaymentRequest
            {
                OrderGuid  = klarnaRequest.OrderGuid,
                CustomerId = customer.Id,
                StoreId    = _storeContext.CurrentStore.Id,
                PaymentMethodSystemName = KlarnaCheckoutProcessor.PaymentMethodSystemName
            };

            var placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest);

            // If you tamper with the cart after the klarna widget is rendered nop fails to create the order.
            if (!placeOrderResult.Success)
            {
                var errors = string.Join("; ", placeOrderResult.Errors);
                _logger.Error(string.Format(CultureInfo.CurrentCulture, "KlarnaCheckout: Klarna has been processed but order could not be created in Nop! Klarna ID={0}, ResourceURI={1}. Errors: {2}",
                                            klarnaCheckoutOrder.Id, klarnaRequest.KlarnaResourceUri, errors), customer: customer);

                _klarnaCheckoutPaymentService.CancelPayment(klarnaCheckoutOrder.Reservation, customer);

                throw new KlarnaCheckoutException("Error creating order: " + errors);
            }

            // Order was successfully created.
            var orderId       = placeOrderResult.PlacedOrder.Id;
            var nopOrder      = _orderService.GetOrderById(orderId);
            var klarnaPayment =
                _paymentService.LoadPaymentMethodBySystemName(KlarnaCheckoutProcessor.PaymentMethodSystemName);

            klarnaPayment.PostProcessPayment(new PostProcessPaymentRequest
            {
                Order = nopOrder
            });

            var orderTotalInCurrentCurrency = _currencyService.ConvertFromPrimaryStoreCurrency(nopOrder.OrderTotal, _workContext.WorkingCurrency);

            // Due to rounding when using prices contains more than 2 decimals (e.g. currency conversion), we allow
            // a slight diff in paid price and nop's reported price.
            // For example nop rounds the prices after _all_ cart item prices have been summed but when sending
            // items to Klarna, each price needs to be rounded separately (Klarna uses 2 decimals).

            // Assume a cart with two items.
            // 1.114 + 2.114 = 3.228 which nop rounds to 3.23.
            // 1.11 + 2.11 is sent to Klarna, which totals 3.22.

            var allowedPriceDiff = orderTotalInCurrentCurrency * 0.01m;
            var diff             = Math.Abs(orderTotalInCurrentCurrency - (klarnaCheckoutOrder.Cart.TotalPriceIncludingTax.Value / 100m));

            if (diff >= allowedPriceDiff)
            {
                var orderTotalInCents = _klarnaCheckoutHelper.ConvertToCents(orderTotalInCurrentCurrency);

                nopOrder.OrderNotes.Add(new OrderNote
                {
                    Note = string.Format(CultureInfo.CurrentCulture, "KlarnaCheckout: Order total differs from Klarna order. OrderTotal: {0}, OrderTotalInCents: {1}, KlarnaTotal: {2}, AllowedDiff: {3}, Diff: {4}, Uri: {5}",
                                         orderTotalInCurrentCurrency, orderTotalInCents, klarnaCheckoutOrder.Cart.TotalPriceIncludingTax, allowedPriceDiff, diff, resourceUri),
                    DisplayToCustomer = false,
                    CreatedOnUtc      = DateTime.UtcNow
                });
            }

            nopOrder.OrderNotes.Add(new OrderNote
            {
                Note = "KlarnaCheckout: Order acknowledged. Uri: " + resourceUri,
                DisplayToCustomer = false,
                CreatedOnUtc      = DateTime.UtcNow
            });
            _orderService.UpdateOrder(nopOrder);

            if (_orderProcessingService.CanMarkOrderAsAuthorized(nopOrder))
            {
                _orderProcessingService.MarkAsAuthorized(nopOrder);

                // Sometimes shipping isn't required, e.g. if only ordering virtual gift cards.
                // In those cases, make sure the Klarna order is activated.
                if (nopOrder.OrderStatus == OrderStatus.Complete || nopOrder.ShippingStatus == ShippingStatus.ShippingNotRequired)
                {
                    nopOrder.OrderNotes.Add(new OrderNote
                    {
                        Note              = "KlarnaCheckout: Order complete after payment, will try to capture payment.",
                        CreatedOnUtc      = DateTime.UtcNow,
                        DisplayToCustomer = false
                    });
                    _orderService.UpdateOrder(nopOrder);

                    if (_orderProcessingService.CanCapture(nopOrder))
                    {
                        _orderProcessingService.Capture(nopOrder);
                    }
                }
            }

            return(nopOrder);
        }