{"record":{"id":"a4a02e4212f06188","repo":"nopSolutions/nopCommerce","slug":"failed-to-get-customer-s-certificates","errorCode":null,"errorMessage":"Failed to get customer's certificates","messagePattern":"Failed to get customer's certificates","errorType":"exception","errorClass":"NopException","httpStatus":null,"severity":"error","filePath":"src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs","lineNumber":1663,"sourceCode":"    /// The task result contains the list of certificates\n    /// </returns>\n    public async Task<CertificateModel> GetValidCertificatesAsync(Customer customer, int storeId)\n    {\n        return (await HandleFunctionAsync(async () =>\n        {\n            if (_avalaraTaxSettings.CompanyId is null)\n                throw new NopException(\"Company not selected\");\n\n            //create dummy order to get selected address\n            var order = new Order { CustomerId = customer.Id };\n            await PrepareOrderAddressesAsync(customer, order, storeId);\n            var address = await GetTaxAddressAsync(order);\n            var shipTo = await MapAddressAsync(address);\n\n            //check exemption status\n            var exemptionStatus = await ServiceClient\n                .ListValidCertificatesForCustomerAsync(_avalaraTaxSettings.CompanyId.Value, customer.Id.ToString(), shipTo.country, shipTo.region)\n                ?? throw new NopException(\"Failed to get customer's certificates\");\n\n            var exempt = string.Equals(exemptionStatus.status, \"Exempt\", StringComparison.InvariantCultureIgnoreCase);\n            return exempt ? exemptionStatus.certificate : null;\n        })).Result;\n    }\n\n    /// <summary>\n    /// Get all certificates linked to a customer\n    /// </summary>\n    /// <param name=\"customer\">Customer</param>\n    /// <returns>\n    /// A task that represents the asynchronous operation\n    /// The task result contains the list of certificates\n    /// </returns>\n    public async Task<List<CertificateModel>> GetCustomerCertificatesAsync(Customer customer)\n    {\n        return (await HandleFunctionAsync(async () =>\n        {","sourceCodeStart":1645,"sourceCodeEnd":1681,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Plugins/Nop.Plugin.Tax.Avalara/Services/AvalaraTaxManager.cs#L1645-L1681","documentation":"Thrown when ServiceClient.ListValidCertificatesForCustomerAsync(companyId, customerCode, country, region) returns null. Used to determine the customer's exemption status; a null result means Avalara gave no exemptionStatus payload, so exemption cannot be decided.","triggerScenarios":"Certificate lookup for a customer in a country/region where Avalara returns no exemption status object; shipTo address missing country/region so the query is malformed; transient SDK failure.","commonSituations":"International customers where Avalara has no exemption program for the region; address mapping (MapAddressAsync) produced null country/region; the customer has no certificates but Avalara still returns null instead of an empty status.","solutions":["Check the shipTo address produced by MapAddressAsync has valid country and region values.","Log the raw SDK response and HTTP status via HandleFunctionAsync to determine whether this is a not-found vs an API error.","Consider treating a null exemptionStatus as 'not exempt' (return null certificate) instead of throwing."],"exampleFix":"// before\nvar exemptionStatus = await ServiceClient\n    .ListValidCertificatesForCustomerAsync(_avalaraTaxSettings.CompanyId.Value, customer.Id.ToString(), shipTo.country, shipTo.region)\n    ?? throw new NopException(\"Failed to get customer's certificates\");\n\n// after — degrade to non-exempt on missing status\nvar exemptionStatus = await ServiceClient\n    .ListValidCertificatesForCustomerAsync(_avalaraTaxSettings.CompanyId.Value, customer.Id.ToString(), shipTo.country, shipTo.region);\nif (exemptionStatus is null) return null;","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(shipTo.country) || string.IsNullOrEmpty(shipTo.region))\n    return null; // cannot query exemptions without country/region","typeGuard":"static bool CanQueryExemptions(Address a) => !string.IsNullOrEmpty(a?.Country) && !string.IsNullOrEmpty(a.Region);","tryCatchPattern":"try { return await GetValidCertificatesAsync(customer, storeId); }\ncatch (NopException ex) when (ex.Message.Contains(\"certificates\"))\n{ _logger.LogWarning(ex, \"Exemption lookup failed; treating as non-exempt\"); return null; }","preventionTips":["Validate the shipTo address has country and region before calling ListValidCertificates.","Treat null exemption status as 'not exempt' rather than an exception.","Ensure MapAddressAsync never produces null country/region."],"tags":["avalara","certcapture","exemption","null-response","nopcommerce"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}