nopSolutions/nopCommerce · warning · NopException

No shipping info found for PayPal order

Error message

No shipping info found for PayPal order

What it means

Thrown inside SetTrackingAsync when the retrieved PayPal order has no purchasable shipping context. The code checks that order.PurchaseUnits has at least one PurchaseUnit and that unit.Shipping is not null. Without shipping info on the PayPal order, there is no recipient address to attach tracking data to.

Source

Thrown at src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs:2933

            var nopOrder = await _orderService.GetOrderByIdAsync(shipment?.OrderId ?? 0)
                ?? throw new NopException("Order cannot be loaded");

            if (!string.Equals(nopOrder.PaymentMethodSystemName, PayPalCommerceDefaults.SystemName, StringComparison.InvariantCultureIgnoreCase))
                return false;

            var customValues = new CustomValues();
            customValues.FillByXml(nopOrder.CustomValuesXml);
            var orderIdKey = await _localizationService.GetResourceAsync("Plugins.Payments.PayPalCommerce.Order.Id");
            if (!customValues.TryGetValue(orderIdKey, out var orderIdValue))
                throw new NopException("Failed to get PayPal order info");

            var order = await _httpClient
                .RequestAsync<GetOrderRequest, GetOrderResponse>(new GetOrderRequest { OrderId = orderIdValue.Value }, settings) as Order;
            if (order.Status?.ToUpper() != OrderStatusType.COMPLETED.ToString())
                throw new NopException($"Unable to assign tracking information to orders in {order.Status} status");

            if (order.PurchaseUnits?.FirstOrDefault() is not PurchaseUnit unit || unit.Shipping is null)
                throw new NopException("No shipping info found for PayPal order");

            if (unit.Payments?.Captures?.FirstOrDefault() is not Capture capture ||
                (capture.Status?.ToUpper() != CaptureStatusType.COMPLETED.ToString() &&
                capture.Status?.ToUpper() != CaptureStatusType.PARTIALLY_REFUNDED.ToString() &&
                capture.Status?.ToUpper() != CaptureStatusType.PENDING.ToString()))
            {
                throw new NopException($"Unable to assign tracking information to orders with the payment in {order.Status} status");
            }

            var shipmentItems = await _shipmentService.GetShipmentItemsByShipmentIdAsync(shipment.Id);
            var items = await shipmentItems.SelectAwait(async shipmentItem =>
            {
                var orderItem = await _orderService.GetOrderItemByIdAsync(shipmentItem.OrderItemId);
                var product = await _productService.GetProductByIdAsync(orderItem.ProductId);
                var sku = await _productService.FormatSkuAsync(product, orderItem.AttributesXml);
                var url = await _nopUrlHelper.RouteGenericUrlAsync(product, _webHelper.GetCurrentRequestProtocol());
                var picture = await _pictureService.GetProductPictureAsync(product, orderItem.AttributesXml);
                var (imageUrl, _) = await _pictureService.GetPictureUrlAsync(picture);

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Check whether the order contains shippable items — if not, PayPal tracking sync is unnecessary
  2. If the order should have shipping info, verify the PayPal order creation flow includes the shipping address in the PurchaseUnit
  3. Inspect the PayPal order JSON via the dashboard to confirm whether shipping_address is present
  4. For orders missing shipping info on PayPal's side, the tracking cannot be added — skip sync for these orders

Example fix

// before
var (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);

// after — check if PayPal order has shipping before calling
if (paypalOrder.PurchaseUnits?.FirstOrDefault() is not PurchaseUnit unit || unit.Shipping is null)
{
    _logger.Information($"PayPal order {paypalOrderId} has no shipping info; skipping tracking sync");
    return;
}
var (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);
Defensive patterns

Strategy: fallback

Try / catch

// HandleFunctionAsync catches internally; skip tracking for orders without shipping
var (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);
if (!string.IsNullOrEmpty(error) && error.Contains("No shipping info"))
    _logger.Information($"PayPal order for shipment {shipment.Id} has no shipping info; skipping");

Prevention

When it happens

Trigger: order.PurchaseUnits is null or empty, or the first PurchaseUnit's Shipping property is null — meaning the PayPal order was created without shipping details (e.g. digital goods, services, or the shipping address was not passed during PayPal order creation).

Common situations: The original order contained only digital/downloadable products so no shipping address was sent to PayPal; the PayPal order was created via an API call that omitted the shipping_address field; a custom checkout flow bypassed the standard shipping address collection; order was created via PayPal buttons without shipping preference set.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/430a0121eaf7181b. Report an issue: GitHub.