nopSolutions/nopCommerce · warning · NopException

Unable to assign tracking information to orders in {order.St

Error message

Unable to assign tracking information to orders in {order.Status} status

What it means

Thrown inside SetTrackingAsync after retrieving the PayPal order via the GetOrder API. PayPal only allows adding tracking information to orders in COMPLETED status. If the order is in any other status (e.g. APPROVED, CREATED, VOIDED), assigning shipment tracking is rejected. The order.Status is interpolated into the message for diagnostics.

Source

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

            if (string.IsNullOrEmpty(carrier))
                return false;

            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);

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Verify the PayPal order status in the PayPal dashboard — it must show COMPLETED
  2. If the capture is still pending, wait for it to settle and retry tracking sync
  3. If the payment was never captured, complete the capture first then sync tracking
  4. For voided/refunded orders, skip tracking sync as PayPal will not accept it

Example fix

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

// after — check PayPal order status before attempting tracking
var paypalOrder = await _httpClient.RequestAsync<GetOrderRequest, GetOrderResponse>(
    new GetOrderRequest { OrderId = paypalOrderId }, settings) as Order;
if (paypalOrder?.Status?.ToUpper() != OrderStatusType.COMPLETED.ToString())
{
    _logger.Information($"PayPal order in {paypalOrder?.Status} status; deferring tracking sync");
    // retry later via a scheduled task
    return;
}
var (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);
Defensive patterns

Strategy: fallback

Try / catch

// HandleFunctionAsync catches internally; use the error to decide fallback behavior
var (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);
if (!string.IsNullOrEmpty(error) && error.Contains("status"))
{
    // PayPal order not in COMPLETED status — defer and retry later
    await ScheduleTrackingRetryAsync(shipment.Id, delayMinutes: 30);
}

Prevention

When it happens

Trigger: The PayPal order retrieved via GetOrderRequest returns a Status that is not OrderStatusType.COMPLETED (e.g. APPROVED but not yet captured, or VOIDED).

Common situations: The payment was authorized but not yet captured when the shipment is created; the PayPal order was partially captured and is in a transitional state; an order was refunded/voided before shipment; timing issue where shipment creation fires before payment capture completes.

Related errors


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