public static string BuildQRCode(this string xml, string QRCodeTokenID, string QRCodeTokenCsc, DateTime?ContingencyDate) { AssertionConcern.AssertArgumentNotNullEmpty(xml, "XML obrigatório para gerar o QRCode"); var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(xml); var ns = new XmlNamespaceManager(xmlDocument.NameTable); ns.AddNamespace("nfe", "http://www.portalfiscal.inf.br/nfe"); ns.AddNamespace("sign", "http://www.w3.org/2000/09/xmldsig#"); var model = xmlDocument.SelectSingleNode("//*[local-name()='mod']"); //AssertionConcern.AssertArgumentNotNull(model, "Não foi possível encontrar o node \"mod\" no XML da NF para poder montar o QRCode"); if (model?.InnerText != "65") { return(xml); } var tokenID = QRCodeTokenID; var tokenCsc = QRCodeTokenCsc; AssertionConcern.AssertArgumentFalse((string.IsNullOrEmpty(tokenID) || string.IsNullOrEmpty(tokenCsc)), "QrCode Token e QrCode Token Csc são obrigatórios para NFCe"); var qrcodeUrl = xmlDocument.SelectSingleNode("//*[local-name()='qrCode']"); AssertionConcern.AssertArgumentNotNull(qrcodeUrl, "Não foi possível encontrar o node \"qrCode\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:infNFe", ns), "Não foi possível encontrar o node \"infNFe\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:tpAmb", ns), "Não foi possível encontrar o node \"tpAmb\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:ide/nfe:dhEmi", ns), "Não foi possível encontrar o node \"dhEmi\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vNF", ns), "Não foi possível encontrar o node \"vNF\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vICMS", ns), "Não foi possível encontrar o node \"vICMS\" no XML da NF para poder montar o QRCode"); AssertionConcern.AssertArgumentNotNull(xmlDocument.SelectSingleNode("//nfe:enviNFe/nfe:NFe/sign:Signature/sign:SignedInfo/sign:Reference/sign:DigestValue", ns), "Não foi possível encontrar o node \"DigestValue\" no XML da NF para poder montar o QRCode"); var tpEmis = xmlDocument.SelectSingleNode("//nfe:tpEmis", ns).InnerText; //[44 exatos] - chNFe -- Chave de Acesso da NFCe //ex: NFe13140213998916000124650010000003461000003464 var chNFe = xmlDocument.SelectSingleNode("//nfe:infNFe", ns).Attributes["Id"].InnerText.Substring(3); //Remove "NFe" do início //[3 exatos] nVersao -- Versão do QR Code -- Nessa versão informar "100" const string nVersao = "2"; //[1 exato] tpAmb -- Identificação do Ambiente (1 – Produção, 2 –Homologação) var tpAmb = xmlDocument.SelectSingleNode("//nfe:tpAmb", ns).InnerText; //[11-20] cDest -- Documento de Identificação do Consumidor (CNPJ/CPF/ID Estrangeiro) var cDest = ""; if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:CNPJ", ns) != null) { cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:CNPJ", ns).InnerText.PadLeft(14, '0'); } else if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:CPF", ns) != null) { cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:CPF", ns).InnerText.PadLeft(11, '0'); } else if (xmlDocument.SelectSingleNode("//nfe:dest/nfe:idEstrangeiro", ns) != null) { cDest = xmlDocument.SelectSingleNode("//nfe:dest/nfe:idEstrangeiro", ns).InnerText.PadLeft(11, '0'); } //Identificação do cliente não é obrigatória para NFCe //[50 convertido para hex] dhEmi -- Data e Hora de Emissão da NFC-e DateTime dEmi; DateTime.TryParse(xmlDocument.SelectSingleNode("//nfe:ide/nfe:dhEmi", ns).InnerText, out dEmi); var dhEmi = dEmi.ToString("dd"); //[15] vNF -- Valor Total da NFC-e var vNF = xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vNF", ns).InnerText; //[15] vICMS -- Valor Total ICMS na NFC-e var vICMS = xmlDocument.SelectSingleNode("//nfe:total/nfe:ICMSTot/nfe:vICMS", ns).InnerText; //[56 exatos convertido para hex] digVal -- Digest Value da NFC-e var digVal = xmlDocument.SelectSingleNode("//nfe:enviNFe/nfe:NFe/sign:Signature/sign:SignedInfo/sign:Reference/sign:DigestValue", ns).InnerText; digVal = digVal.ToHexString(); var sb = new StringBuilder(); int tokenIDSignificantNumber; if (!int.TryParse(tokenID, out tokenIDSignificantNumber)) { throw new InvalidOperationException(string.Format("Código identificador do CSC é inválido. Devem ser informados apenas números. Valor: {0}", tokenID)); } var qrCodeTemplate = string.Empty; if (ContingencyDate.HasValue) { qrCodeTemplate = "{0}|{1}|{2}|{3}|{4}|{5}|{6}"; } else { qrCodeTemplate = "{0}|{1}|{2}|{6}"; } sb.AppendFormat(qrCodeTemplate, chNFe, nVersao, tpAmb, dhEmi, vNF, digVal, tokenIDSignificantNumber); var hash = string.Concat(sb.ToString(), tokenCsc).GenerateHash(); sb.AppendFormat("|{0}", hash); var qrCode = string.Format(qrcodeUrl.InnerText.IndexOf('?') > -1 ? "{0}&p={1}" : "{0}?p={1}", qrcodeUrl.InnerText, sb); xmlDocument.SelectSingleNode("//*[local-name()='qrCode']").InnerText = "{QRCODE}"; xmlDocument.InnerXml = xmlDocument.OuterXml.Replace("{QRCODE}", string.Format("<![CDATA[{0}]]>", qrCode)); return(xmlDocument.OuterXml); }