{"record":{"id":"a1eff1af5fb7442f","repo":"nopSolutions/nopCommerce","slug":"setup-token-not-set","errorCode":null,"errorMessage":"Setup token not set","messagePattern":"Setup token not set","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs","lineNumber":2713,"sourceCode":"    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the created order; error message if exists\n    /// </returns>\n    public async Task<(Order Order, string Error)> CreateRecurringOrderAsync(PayPalCommerceSettings settings, string setupTokenId)\n    {\n        return await HandleFunctionAsync(async () =>\n        {\n            if (!IsConfigured(settings))\n                throw new NopException(\"Plugin not configured\");\n\n            if (string.IsNullOrEmpty(settings.MerchantId))\n                throw new NopException(\"Merchant PayPal ID not set\");\n\n            if (!settings.UseVault)\n                throw new NopException(\"Vault disabled\");\n\n            if (string.IsNullOrEmpty(setupTokenId))\n                throw new NopException(\"Setup token not set\");\n\n            var details = await PrepareCartDetailsAsync(ButtonPlacement.PaymentMethod);\n\n            if (!await _shoppingCartService.ShoppingCartIsRecurringAsync(details.Cart))\n                throw new NopException(\"Shopping cart has no recurring items\");\n\n            if (await _customerService.IsGuestAsync(details.Customer))\n                throw new NopException(\"Anonymous checkout disabled for recurring items\");\n\n            //try to create payment token by the approved setup token\n            var payer = await PrepareBillingDetailsAsync(settings, details);\n            var paymentTokenRequest = new CreatePaymentTokenRequest\n            {\n                Customer = payer,\n                PaymentSource = new()\n                {\n                    Token = new()\n                    {","sourceCodeStart":2695,"sourceCodeEnd":2731,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Payments.PayPalCommerce/Services/PayPalCommerceServiceManager.cs#L2695-L2731","documentation":"Thrown by CreateRecurringOrderAsync when the setupTokenId argument is null or empty. The recurring order is built from an approved setup token (the payer authenticated it), so the token id is required to create the payment token. This guard fires before cart preparation and is returned as the Error string.","triggerScenarios":"Calling CreateRecurringOrderAsync without the setup token id; the setup-token approval callback did not pass the token id forward; the token id was lost between the approval redirect and the order-creation step.","commonSituations":"Payer approved the setup token but the return URL/session did not carry setupTokenId; integration wired the wrong query/attribute name; approval webhook handled but id not persisted.","solutions":["Pass the setup token id returned/recorded from the setup-token approval step into CreateRecurringOrderAsync.","Validate !string.IsNullOrEmpty(setupTokenId) before the call and re-prompt/abort if missing.","Ensure the approval callback persists setupTokenId (e.g. in order generic attributes or session) before invoking order creation."],"exampleFix":"// before\nvar (order, err) = await _serviceManager.CreateRecurringOrderAsync(settings, setupTokenId);\n\n// after\nif (string.IsNullOrEmpty(setupTokenId))\n{\n    NotifyError(\"Missing approved setup token; restart the recurring payment flow\");\n    return;\n}\nvar (order, err) = await _serviceManager.CreateRecurringOrderAsync(settings, setupTokenId);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(setupTokenId))\n    return;","typeGuard":"static string SetupToken(string id) => string.IsNullOrEmpty(id) ? null : id;","tryCatchPattern":"var (order, error) = await mgr.CreateRecurringOrderAsync(settings, setupTokenId);\nif (!string.IsNullOrEmpty(error))\n    NotifyError(error);","preventionTips":["Persist the approved setup token id through the approval callback/session.","Validate setupTokenId before calling order creation.","Restart the setup-token flow if the id is missing."],"tags":["validation","payments","paypal-commerce","recurring","setup-token"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}