{"record":{"id":"43798a3608043a09","repo":"nopSolutions/nopCommerce","slug":"unable-to-assign-tracking-information-to-orders-in","errorCode":null,"errorMessage":"Unable to assign tracking information to orders in {order.Status} status","messagePattern":"Unable to assign tracking information to orders in (.+?) status","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"warning","filePath":"src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs","lineNumber":2930,"sourceCode":"            if (string.IsNullOrEmpty(carrier))\n                return false;\n\n            var nopOrder = await _orderService.GetOrderByIdAsync(shipment?.OrderId ?? 0)\n                ?? throw new NopException(\"Order cannot be loaded\");\n\n            if (!string.Equals(nopOrder.PaymentMethodSystemName, PayPalCommerceDefaults.SystemName, StringComparison.InvariantCultureIgnoreCase))\n                return false;\n\n            var customValues = new CustomValues();\n            customValues.FillByXml(nopOrder.CustomValuesXml);\n            var orderIdKey = await _localizationService.GetResourceAsync(\"Plugins.Payments.PayPalCommerce.Order.Id\");\n            if (!customValues.TryGetValue(orderIdKey, out var orderIdValue))\n                throw new NopException(\"Failed to get PayPal order info\");\n\n            var order = await _httpClient\n                .RequestAsync<GetOrderRequest, GetOrderResponse>(new GetOrderRequest { OrderId = orderIdValue.Value }, settings) as Order;\n            if (order.Status?.ToUpper() != OrderStatusType.COMPLETED.ToString())\n                throw new NopException($\"Unable to assign tracking information to orders in {order.Status} status\");\n\n            if (order.PurchaseUnits?.FirstOrDefault() is not PurchaseUnit unit || unit.Shipping is null)\n                throw new NopException(\"No shipping info found for PayPal order\");\n\n            if (unit.Payments?.Captures?.FirstOrDefault() is not Capture capture ||\n                (capture.Status?.ToUpper() != CaptureStatusType.COMPLETED.ToString() &&\n                capture.Status?.ToUpper() != CaptureStatusType.PARTIALLY_REFUNDED.ToString() &&\n                capture.Status?.ToUpper() != CaptureStatusType.PENDING.ToString()))\n            {\n                throw new NopException($\"Unable to assign tracking information to orders with the payment in {order.Status} status\");\n            }\n\n            var shipmentItems = await _shipmentService.GetShipmentItemsByShipmentIdAsync(shipment.Id);\n            var items = await shipmentItems.SelectAwait(async shipmentItem =>\n            {\n                var orderItem = await _orderService.GetOrderItemByIdAsync(shipmentItem.OrderItemId);\n                var product = await _productService.GetProductByIdAsync(orderItem.ProductId);\n                var sku = await _productService.FormatSkuAsync(product, orderItem.AttributesXml);","sourceCodeStart":2912,"sourceCodeEnd":2948,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs#L2912-L2948","documentation":"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.","triggerScenarios":"The PayPal order retrieved via GetOrderRequest returns a Status that is not OrderStatusType.COMPLETED (e.g. APPROVED but not yet captured, or VOIDED).","commonSituations":"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.","solutions":["Verify the PayPal order status in the PayPal dashboard — it must show COMPLETED","If the capture is still pending, wait for it to settle and retry tracking sync","If the payment was never captured, complete the capture first then sync tracking","For voided/refunded orders, skip tracking sync as PayPal will not accept it"],"exampleFix":"// before\nvar (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);\n\n// after — check PayPal order status before attempting tracking\nvar paypalOrder = await _httpClient.RequestAsync<GetOrderRequest, GetOrderResponse>(\n    new GetOrderRequest { OrderId = paypalOrderId }, settings) as Order;\nif (paypalOrder?.Status?.ToUpper() != OrderStatusType.COMPLETED.ToString())\n{\n    _logger.Information($\"PayPal order in {paypalOrder?.Status} status; deferring tracking sync\");\n    // retry later via a scheduled task\n    return;\n}\nvar (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// HandleFunctionAsync catches internally; use the error to decide fallback behavior\nvar (result, error) = await _serviceManager.SetTrackingAsync(settings, shipment);\nif (!string.IsNullOrEmpty(error) && error.Contains(\"status\"))\n{\n    // PayPal order not in COMPLETED status — defer and retry later\n    await ScheduleTrackingRetryAsync(shipment.Id, delayMinutes: 30);\n}","preventionTips":["Schedule tracking sync as a deferred/retryable task rather than inline during shipment creation","Ensure payment capture completes before triggering shipment workflows","Monitor deferred tracking sync failures and alert when retries are exhausted","Consider a scheduled task that retries pending tracking syncs for orders whose PayPal status transitions to COMPLETED"],"tags":["paypal","order-status","shipment-tracking","payment-capture","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}