public static void Prueba()
{
Comprobante cfd = new Comprobante();
// ...
// Llenar datos del comprobante.
// ...
cfd.Emisor = new ComprobanteEmisor();
// ...
// Llenar datos del emisor.
// ...
cfd.Emisor.DomicilioFiscal = new t_UbicacionFiscal();
// ...
// Llenar datos del domicilio fiscal.
// ...
cfd.Receptor = new ComprobanteReceptor();
// ...
// Llenar datos del receptor.
// ...
cfd.Receptor.Domicilio = new t_Ubicacion();
// ...
// Llenar datos del domicilio.
// ...
cfd.Conceptos = new ComprobanteConcepto[n];
cfd.Conceptos[i] = new ComprobanteConcepto();
// ...
// Llenar datos de cada concepto.
// ...
cfd.Impuestos = new ComprobanteImpuestos();
// ...
// Llenar datos de impuestos.
// ...
// Obtener la cadena original.
string co = GenerarCadenaOriginal(cfd);
// DIGESTION MD5 <- Ignoro para que sirva, pero como se ve, Copy / Paste de uno de los posts.
MD5 md5 = new MD5CryptoServiceProvider();
byte[] data = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(co));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i <= data.Length - 1; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
string cadmd5 = sBuilder.ToString();
// Obtener el archivo *.p12 como se menciono en algun post.
X509C.X509Certificate2 _MiCertificado = new X509C.X509Certificate2(@"x:\micert.p12", "mipass");
RSACryptoServiceProvider RSA = (RSACryptoServiceProvider)_MiCertificado.PrivateKey;
MD5CryptoServiceProvider hasher = new MD5CryptoServiceProvider();
byte[] bytesFirmados = RSA.SignData(System.Text.Encoding.UTF8.GetBytes(co), hasher);
string sello = Convert.ToBase64String(bytesFirmados);
// Agregamos el sello.
cfd.sello = sello;
// ...
// De igual manera, conseguir el numero de certificado.
// ...
// Generar el comprobante fiscal digital
GenerarCfd(cfd, @"x:\cfd.xml");
}
/// <summary>
/// Genera la cadena original a partir
/// </summary>
/// <param name="cfd">Instancia de la clase Comprobante con la informacion del Comprobante Fiscal Digital.</param>
/// <returns>Un valor de tipo string con el valor de la cadena original.</returns>
public static string GenerarCadenaOriginal(Comprobante cfd)
{
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
MemoryStream xmlCadenaOriginal = new MemoryStream();
XmlTextWriter xmlTextWriter = new XmlTextWriter(xmlCadenaOriginal, Encoding.UTF8);
xmlTextWriter.Formatting = Formatting.Indented;
XmlSerializer xs = new XmlSerializer(typeof(Comprobante));
xs.Serialize(xmlTextWriter, cfd, xmlNameSpace);
xmlCadenaOriginal.Position = 0;
XPathDocument xpathdoc = new XPathDocument(xmlCadenaOriginal);
XslTransform xsltrans = new XslTransform();
xsltrans.Load("E:\\cadenaoriginal_2_0.xslt");
MemoryStream strCadenaOriginal = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(strCadenaOriginal, null);
xsltrans.Transform(xpathdoc, null, writer);
strCadenaOriginal.Position = 0;
StreamReader sr = new StreamReader(strCadenaOriginal);
string cadenaOriginal = sr.ReadToEnd();
sr.Close();
sr.Dispose();
sr = null;
writer.Close();
writer = null;
xmlTextWriter.Close();
xmlTextWriter = null;
xmlCadenaOriginal.Close();
xmlCadenaOriginal.Dispose();
xmlCadenaOriginal = null;
return cadenaOriginal;
}
/// <summary>
/// Genera el Comprobante Fiscal Digital.
/// </summary>
/// <param name="cfd">Instancia de la clase Comprobante con la informacion del Comprobante Fiscal Digital.</param>
/// <param name="archivo">Ubicacion del archivo a generar.</param>
public static void GenerarCfd(Comprobante cfd, String archivo)
{
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XmlTextWriter xmlTextWriter = new XmlTextWriter(archivo, Encoding.UTF8);
xmlTextWriter.Formatting = Formatting.Indented;
XmlSerializer xs = new XmlSerializer(typeof(Comprobante));
xs.Serialize(xmlTextWriter, cfd, xmlNameSpace);
xmlTextWriter.Close();
xmlTextWriter = null;
}