VXML 2.1.0
dotnet add package VXML --version 2.1.0
NuGet\Install-Package VXML -Version 2.1.0
<PackageReference Include="VXML" Version="2.1.0" />
<PackageVersion Include="VXML" Version="2.1.0" />
<PackageReference Include="VXML" />
paket add VXML --version 2.1.0
#r "nuget: VXML, 2.1.0"
#:package VXML@2.1.0
#addin nuget:?package=VXML&version=2.1.0
#tool nuget:?package=VXML&version=2.1.0
VXML
Librería para la generación y cancelación de CFDI 4.0 y de CFDI de Retenciones e Información de Pagos 2.0, incluidos todos los complementos vigentes. Incluye el proceso de firmado, Sellado y tambien el Timbrado por medio del servicio de VXML, de acuerdo a la especificación del SAT.
Incluye tambien el servicio de Descarga Masiva del SAT (XML o Metadata de los CFDI emitidos o recibidos en un periodo) y metodos complementarios para la administración de distribuidores y emisores.
Uso
Uso Basico
using VXML;
...
// Crear instancia de la clase VXML
var vxml = new VXML();
// Llamar los metodos para el llenado del CFDI
vxml.SetComprobanteInfo_cfdi40("A", "1", DateTime.Now.ToString("s"), "99", "Contado AÑA Comercial", "1000.00", "50.00", "MXN", "", "1102.00", "I", "PPD", "53050", "", "01");
vxml.AddCfdiRelacionados_cfdi40("04", "FF93C8BE-AF7B-4FC5-8854-6DAE18CFB5B4", "D8E18C2F-2859-4927-A0F0-EA3E93642DDC", "", "", "", "", "", "", "", "");
vxml.AddCfdiRelacionado_cfdi40("BE1D4B47-E167-47A3-8049-70D4D43BCBE8");
vxml.AddCfdiRelacionados_cfdi40("01", "FDBA380A-9732-4FB5-A6CB-5FB4BD831697", "", "", "", "", "", "", "", "", "");
vxml.SetEmisorInfo_cfdi40("EKU9003173C9", "ESCUELA KEMPER URGATE", "601", "");
// Tambien puede usarse de forma encadenada
vxml.SetReceptorInfo_cfdi40("CTE940531F58", "CIBERNETICA Y TECNOLOGIA", "", "", "G01", "53050", "601")
.AddConcepto_cfdi40("84111506", "SEFXXX Ñ", "1", "H87", "Unidad", "Paquete X - ObjetoImp2", "500.00", "500.00", "", "02")
.AddConceptoTraslado_cfdi40("500.00", "002", "Tasa", "0.160000", "80.00")
.AddConcepto_cfdi40("84111506", "SEFXXX &", "2", "H87", "Unidad", "Paquete X - ObjetoImp2", "250.00", "500.00", "50.00", "02")
.AddConceptoTraslado_cfdi40("450.00", "002", "Tasa", "0.160000", "72.00")
.SetImpuestosInfo_cfdi40("200.00", "300.0");
vxml.SetImpuestosInfo_cfdi40("152.00", "");
vxml.AddTraslado_cfdi40("002", "Tasa", "0.160000", "152.00", "950.00");
vxml.SetAddendaText_cfdi40("Texto simple como adenda");
// Finalmente, solicitar el timbrado
var resultado = await vxml.TimbraCFDI40("demo_cibertec", "EKU9003173C9", csdPath, keyPath, "12345678a", true, true, true, true);
// Evaluar el resultado
if (resultado.IsSuccess)
{
Console.WriteLine("UUID: {0}", resultado.uuid);
var rawXML = Encoding.UTF8.GetString(Convert.FromBase64String(resultado.xmltimbrado));
Console.WriteLine("XML: {0}", rawXML);
if (resultado.qrpng != null)
{
await File.WriteAllBytesAsync("Somewhere/Path/QR.png", resultado.qrpng);
Console.WriteLine("png QR written");
}
if (resultado.qrccp30png != null)
{
await File.WriteAllBytesAsync("Somewhere/Path/QRcpp.png", resultado.qrccp30png);
Console.WriteLine("QR de Complemento Carta Porte guardado");
}
}
else
{
Console.WriteLine("Algo fallo con codigo {0} y mensaje {1}", resultado.InnerExitCode, resultado.Message);
}
Ejemplos
Complemento Pagos20
var vxml = new Cfdi();
vxml.AddCfdiRelacionados_cfdi40("01", "", "00000000-0000-0000-0000-000000000002", "", "00000000-0000-0000-0000-000000000004", "", "00000000-0000-0000-0000-000000000006", "", "00000000-0000-0000-0000-000000000008", "", "00000000-0000-0000-0000-000000000010");
vxml.AddCfdiRelacionado_cfdi40("00000000-0000-0000-0000-111111111111");
vxml.AddCfdiRelacionados_cfdi40("02", "00000000-0000-0000-0000-000000000001", "", "00000000-0000-0000-0000-000000000003", "", "00000000-0000-0000-0000-000000000005", "", "00000000-0000-0000-0000-000000000007", "", "00000000-0000-0000-0000-000000000009", "");
vxml.AddCfdiRelacionado_cfdi40("00000000-0000-0000-0000-222222222222");
vxml.SetInformacionGlobal_cfdi40("01", "10", "2023");
vxml.SetComprobanteInfo_cfdi40("", "12629", DateTime.Now.ToString("s"), "", "", "0", "", "XXX", "", "0", "P", "", "53000", "", "01");
vxml.SetEmisorInfo_cfdi40("EKU9003173C9", "ESCUELA KEMPER URGATE", "601", "");
vxml.SetReceptorInfo_cfdi40("ESD140725UP8", "\"E-SI SOLUCIONES DIGITALES\"", "", "", "CP01", "53050", "601");
vxml.AddConcepto_cfdi40("84111506", "", "1", "ACT", "", "Pago", "0", "0", "", "01");
vxml.SetPagos20("", "", "", "", "", "", "", "", "", "", "34925.52");
vxml.Pagos20AddPago("2021-01-01T01:01:01", "03", "USD", "1.00", "13144.66", "0000842", "", "", "", "", "", "", "", "", "");
vxml.Pagos20AddPagoDoctoRelacionado("88888888-4444-4444-4444-121212121212", "Serie", "Folio", "USD", "1", "2", "13144.66", "13144.66", "0.00", "01");
vxml.Pagos20AddPago("2021-02-02T02:02:02", "03", "USD", "1.00", "21780.86", "0000842", "", "", "", "", "", "", "", "", "");
vxml.Pagos20AddPagoDoctoRelacionado("AAAAAAAA-0000-0000-0000-666666666666", "Serie2", "Folio2", "USD", "1", "3", "14430.86", "14430.86", "0.00", "01");
vxml.Pagos20AddPagoDoctoRelacionado("AAAAAAAA-BBBB-CCCC-DDDD-666666666666", "Serie3", "Folio3", "USD", "1", "4", "7350.00", "7350.00", "0.00", "03");
// Para uso de la addenda como XML, el nodo especificado en la funcion
// debera contener la declaracion de los namespaces en caso de usarlos
vxml.SetAddendaXml_cfdi40("<MyOwnNode name=\"CFDI40\"><AnyChildNode data=\"Pagos20\" /></MyOwnNode>");
// Custom Namespace
// vxml.SetAddendaXml_cfdi40("<MyOwnNode name=\"CFDI40\"><customNS:AnyChildNode data=\"Pagos20\" xmlns:customNS=\"http://acme.company.org\"/></MyOwnNode>");
Complemento Carta Porte 3.1
var vxml = new Cfdi();
vxml.SetComprobanteInfo_cfdi40("RogueOne", "HNFK231", DateTime.Now.ToString("s"), "01", "", "100.00", "", "MXN", "1", "100.00", "I", "PUE", "06300", "", "01");
vxml.SetEmisorInfo_cfdi40("EKU9003173C9", "ESCUELA KEMPER URGATE", "601", "");
vxml.SetReceptorInfo_cfdi40("ESD140725UP8", "\"E-SI SOLUCIONES DIGITALES\"", "", "", "CP01", "53050", "601");
vxml.AddConcepto_cfdi40("78101800", "UT421511", "1", "H87", "Pieza", "Transporte de carga por carretera", "100.00", "100.00", "", "01");
vxml.SetCartaPorte31("CCCBCD94-870A-4332-A52A-A52AA52AA52A", "No", "", "", "", "1", "Sí", "01", "01");
vxml.CartaPorte31AddUbicacion("Origen", "OR101010", "EKU9003173C9", "NombreRemitenteDestinatario1", "", "", "", "", "", "2023-08-01T00:00:00", "", "", "Calle1", "211", "212", "1957", "13", "casa blanca", "011", "CMX", "MEX", "13250");
vxml.CartaPorte31AddUbicacion("Destino", "DE202020", "EKU9003173C9", "NombreRemitenteDestinatario2", "", "", "", "", "", "2023-08-01T00:00:01", "", "1", "Calle2", "214", "215", "0347", "23", "casa negra", "004", "COA", "MEX", "25350");
vxml.CartaPorte31SetMercancias("1.0", "XBX", "1", "1", "", "Sí");
vxml.CartaPorte31AddMercancia("11121900", "", "Accesorios de equipo de telefonía", "1.0", "XBX", "", "", "No", "", "", "", "", "", "", "DenominacionGenericaProd1", "DenominacionDistintivaProd1", "Fabricante1", "2028-01-01", "LoteMedic1", "01", "01", "RegistroSanita1", "", "", "", "", "", "", "", "", "", "1", "", "", "", "", "", "");
vxml.CartaPorte31AddMercanciaCantidadTransporta("1", "OR101010", "DE202020", "");
vxml.CartaPorte31AddFiguraTransporteTiposFigura("01", "VAAM130719H60", "a234567890", "NombreFigura", "", "", "", "", "", "", "", "", "", "", "", "", "");
vxml.CartaPorte31SetMercanciasAutotransporte("TPAF01", "NumPermisoSCT1", "VL", "1", "plac892", "2020", "AseguraRespCivil", "123456789", "", "", "", "", "", "CTR004", "VL45K98", "", "");
vxml.SetAddendaXml_cfdi40("<MyOwnNode name=\"CFDI40\"><AnyChildNode data=\"CartaPorte31\" /></MyOwnNode>");
Complemento Concepto HidroYPetro10
var vxml = new Cfdi();
vxml.SetComprobanteInfo_cfdi40("A", "1", $"{DateTime.Now:s}", "99", "Contado AÑA Comercial", "50000.00", "", "MXN", "", "58000.00", "I", "PPD", "53050", "", "01");
vxml.AddCfdiRelacionados_cfdi40("04", "FF93C8BE-AF7B-4FC5-8854-6DAE18CFB5B4", "D8E18C2F-2859-4927-A0F0-EA3E93642DDC", "", "", "", "", "", "", "", "");
vxml.AddCfdiRelacionado_cfdi40("BE1D4B47-E167-47A3-8049-70D4D43BCBE8");
vxml.AddCfdiRelacionados_cfdi40("01", "FDBA380A-9732-4FB5-A6CB-5FB4BD831697", "", "", "", "", "", "", "", "", "");
vxml.SetEmisorInfo_cfdi40("EKU9003173C9", "ESCUELA KEMPER URGATE", "601", "");
vxml.SetReceptorInfo_cfdi40("ESD140725UP8", "\"E-SI SOLUCIONES DIGITALES\"", "", "", "CP01", "53050", "601");
vxml.AddConcepto_cfdi40("15101505", "COMB-001", "5000", "LTR", "Litro", "Gasolina regular", "10.00", "50000.00", "", "02");
vxml.AddConceptoTraslado_cfdi40("50000.00", "002", "Tasa", "0.160000", "8000.00");
vxml.AddConceptoComplementoHidroYPetro10("PER03", "PL/364/DIS/OM/2015", "15101505", "SP23");
vxml.AddTraslado_cfdi40("002", "Tasa", "0.160000", "8000.00", "50000.00");
vxml.SetImpuestosInfo_cfdi40("8000.00", "");
vxml.SetAddendaXml_cfdi40("<MyOwnNode name=\"CFDI40\"><AnyChildNode data=\"HidroYPetro10\" /></MyOwnNode>");
Cancelación de CFDI (esquema 2022)
Para cancelar un CFDI previamente timbrado se usa el metodo CancelaCFDI2022. La solicitud se firma localmente (tu llave privada y clave se usan localmente) y se envia al servicio de VXML en una sola fase.
using VXML;
...
var vxml = new Cfdi();
// CancelaCFDI2022(vxmlUser, rfcEmisor, uuid, motivo, foliosust, cer, key, passKey)
// - vxmlUser : usuario/cuenta de VXML que realiza la cancelacion
// - rfcEmisor: RFC del emisor que timbro el CFDI
// - uuid : UUID (Folio Fiscal) del CFDI a cancelar
// - motivo : clave de motivo del SAT (01, 02, 03, 04)
// - foliosust: UUID del CFDI que sustituye. Requerido cuando motivo es "01", en otro caso ""
// - cer/key : certificado y llave (CSD) como ruta de archivo o Base64
// - passKey : clave de la llave privada
var resultado = await vxml.CancelaCFDI2022(
"demo_cibertec",
"EKU9003173C9",
"FF93C8BE-AF7B-4FC5-8854-6DAE18CFB5B4",
"02",
"",
csdPath,
keyPath,
"12345678a");
// Evaluar el resultado
if (resultado.IsSuccess)
{
// InnerExitCode contiene el codigo del SAT: 201 (Aceptado) o 202 (Previamente aceptado)
Console.WriteLine("Cancelacion exitosa. Codigo SAT: {0}", resultado.InnerExitCode);
Console.WriteLine("UUID: {0}", resultado.uuid);
// Acuse contiene el XML de acuse de cancelacion del SAT
if (resultado.Acuse != null)
{
await File.WriteAllTextAsync("Somewhere/Path/AcuseCancelacion.xml", resultado.Acuse);
Console.WriteLine("Acuse de cancelacion guardado");
}
}
else
{
Console.WriteLine("Algo fallo con codigo {0} y mensaje {1}", resultado.InnerExitCode, resultado.Message);
}
Motivos de cancelación (SAT)
| Motivo | Descripción | FolioSustitución |
|---|---|---|
01 |
Comprobante emitido con errores con relación | Requerido (UUID del CFDI que sustituye) |
02 |
Comprobante emitido con errores sin relación | No aplica ("") |
03 |
No se llevó a cabo la operación | No aplica ("") |
04 |
Operación nominativa relacionada en una factura global | No aplica ("") |
Retenciones 2.0 (Timbrado)
La generación y timbrado de CFDI de Retenciones e Información de Pagos 2.0 se expone a traves de la clase Retencion (interfaz IRetencion). El llenado del documento usa el mismo patron de metodos encadenables que el CFDI 4.0 y el timbrado se solicita al final con TimbraRetencion20.
using VXML;
...
var retencion = new Retencion();
// Llenado del documento (ejemplo con complemento Dividendos)
retencion.SetRetencionesInfo_ret20("FolioInt", DateTime.Now.ToString("s"), "68025", "01", "DescRetenc")
.SetRetencionesEmisor_ret20("EKU9003173C9", "ESCUELA KEMPER URGATE", "601")
.SetRetencionesReceptor_ret20("Nacional", "CACX7605101P8", "XOCHILT CASAS CHAVEZ", "CACX760510MPLRRL05", "36257", "", "")
.SetRetencionesTotales_ret20("333333.33", "0.00", "333333.33", "33333.33", "", "")
.AddRetencionesTotalesImpRetenidos_ret20("233333.33", "001", "23333.33", "03")
.AddRetencionesTotalesImpRetenidos_ret20("100000.00", "001", "10000.00", "03")
.SetRetencionesPeriodo_ret20("12", "12", "2023")
.SetComplementoDividendos10("01", "142860.00", "0.00", "", "Sociedad Nacional", "", "", "", "");
// TimbraRetencion20(vxmlUser, rfcEmisor, cer, key, passKey, includeQRpng, includeQRbmp, includeQRjpg)
var resultado = await retencion.TimbraRetencion20("demo_cibertec", "EKU9003173C9", csdPath, keyPath, "12345678a", true, false, false);
// Evaluar el resultado
if (resultado.IsSuccess)
{
Console.WriteLine("UUID: {0}", resultado.uuid);
var rawXML = Encoding.UTF8.GetString(Convert.FromBase64String(resultado.xmltimbrado));
Console.WriteLine("XML: {0}", rawXML);
if (resultado.qrpng != null)
{
await File.WriteAllBytesAsync("Somewhere/Path/QR.png", resultado.qrpng);
Console.WriteLine("png QR written");
}
}
else
{
Console.WriteLine("Algo fallo con codigo {0} y mensaje {1}", resultado.InnerExitCode, resultado.Message);
}
Complementos de Retenciones disponibles:
SetComplementoDividendos10SetComplementoIntereses10SetComplementoIntereseshipotecarios10SetComplementoPagosaextranjeros10SetComplementoPlataformasTecnologicas10(+AddComplementoPlataformasTecnologicas10DetallesDelServicio)SetComplementoPremios10SetComplementoEnajenaciondeAcciones10SetComplementoArrendamientoenfideicomiso10SetComplementoFideicomisonoempresarial10SetComplementoOperacionesconderivados10SetComplementoPlanesderetiro11SetComplementoSectorFinanciero10
Cancelación de Retenciones (esquema 2022)
Para cancelar una Retencion previamente timbrada se usa el metodo CancelaRetencion2022. Al igual que en la cancelacion de CFDI, la solicitud se firma localmente y se envia al servicio de VXML en una sola fase. Los motivos del SAT son los mismos que en la cancelación de CFDI.
using VXML;
...
var retencion = new Retencion();
// CancelaRetencion2022(vxmlUser, rfcEmisor, uuid, motivo, foliosust, cer, key, passKey)
var resultado = await retencion.CancelaRetencion2022(
"demo_cibertec",
"EKU9003173C9",
"489BD24E-9395-44B1-83A2-F08236F56B75",
"02",
"",
csdPath,
keyPath,
"12345678a");
// Evaluar el resultado
if (resultado.IsSuccess)
{
// InnerExitCode contiene el codigo del SAT: 1201 (Aceptada) o 1202 (Previamente solicitada)
Console.WriteLine("Cancelacion exitosa. Codigo SAT: {0}", resultado.InnerExitCode);
Console.WriteLine("UUID: {0}", resultado.uuid);
// Acuse contiene el XML de acuse de cancelacion del SAT
if (resultado.Acuse != null)
{
await File.WriteAllTextAsync("Somewhere/Path/AcuseCancelacionRet.xml", resultado.Acuse);
}
}
else
{
Console.WriteLine("Algo fallo con codigo {0} y mensaje {1}", resultado.InnerExitCode, resultado.Message);
}
Descarga Masiva
El servicio de Descarga Masiva del SAT permite descargar los XML o la Metadata de los CFDI emitidos o recibidos en un periodo. Se expone a traves de la clase Masiva (interfaz IMasiva) y el proceso consta de 3 pasos:
- Solicitar la descarga con alguno de los metodos
MasivaSolicita*(devuelve unidsolicitud) - Verificar el estado de la solicitud con
MasivaVerificaSolicitudhasta que el SAT la termine (devuelve losidspaquetes) - Descargar cada paquete ZIP con
MasivaDescargaPaquete
IMPORTANTE: La Descarga Masiva requiere el certificado FIEL del contribuyente, no un CSD común. El archivo KEY y su clave solo se ocupan localmente para el firmado de las peticiones y NUNCA se envian.
using VXML;
...
var masiva = new Masiva();
// 1. Solicitar la descarga. Variantes: MasivaSolicitaEmitidosCFDI, MasivaSolicitaEmitidosMetadata,
// MasivaSolicitaRecibidosCFDI y MasivaSolicitaRecibidosMetadata.
// Los ultimos 6 parametros son filtros opcionales ("" = no aplicar):
// estadoComprobante (Todos|Vigente|Cancelado), rfcReceptor/rfcEmisor, tipoComprobante (I|E|T|N|P),
// complemento (ej. nomina12), rfcACuentaTerceros y uuid
var solicitud = await masiva.MasivaSolicitaEmitidosCFDI(
"demo_cibertec",
"EKU9003173C9",
fielCerPath,
fielKeyPath,
"claveFIEL",
"2026-01-01T00:00:00",
"2026-01-31T23:59:59",
"", "", "", "", "", "");
if (!solicitud.IsSuccess)
{
Console.WriteLine("Fallo con codigo {0}: {1}", solicitud.InnerExitCode, solicitud.Message);
return;
}
Console.WriteLine("Solicitud aceptada: {0}", solicitud.idsolicitud);
// 2. Verificar la solicitud. El SAT procesa de forma asincrona y puede tardar:
// mientras no este terminada, InnerExitCode reporta el estado de la solicitud
// (1: Aceptada | 2: En Proceso | 3: Terminada | 4: Error | 5: Rechazada | 6: Vencida)
// y debera reintentarse mas tarde. IsSuccess sera verdadero cuando haya paquetes listos.
var verificacion = await masiva.MasivaVerificaSolicitud(
"demo_cibertec", "EKU9003173C9", fielCerPath, fielKeyPath, "claveFIEL", solicitud.idsolicitud!);
if (!verificacion.IsSuccess)
{
Console.WriteLine("Aun no lista (codigo {0}): {1}", verificacion.InnerExitCode, verificacion.Message);
return;
}
Console.WriteLine("Solicitud terminada. {0} CFDI en {1} paquete(s)", verificacion.numerocfdis, verificacion.idspaquetes.Count);
// 3. Descargar cada paquete ZIP (el SAT permite maximo 2 descargas por paquete)
foreach (var idPaquete in verificacion.idspaquetes)
{
var descarga = await masiva.MasivaDescargaPaquete(
"demo_cibertec", "EKU9003173C9", fielCerPath, fielKeyPath, "claveFIEL", idPaquete);
if (descarga.IsSuccess && descarga.paquete != null)
{
await File.WriteAllBytesAsync($"Somewhere/Path/{idPaquete}.zip", descarga.paquete);
Console.WriteLine("Paquete {0} guardado ({1} bytes)", idPaquete, descarga.paquete.Length);
}
else
{
Console.WriteLine("Fallo la descarga de {0} con codigo {1}: {2}", idPaquete, descarga.InnerExitCode, descarga.Message);
}
}
| Metodo | Descripción |
|---|---|
MasivaSolicitaEmitidosCFDI |
Solicita los XML de los CFDI emitidos en un periodo |
MasivaSolicitaEmitidosMetadata |
Solicita la Metadata de los CFDI emitidos en un periodo |
MasivaSolicitaRecibidosCFDI |
Solicita los XML de los CFDI recibidos en un periodo (el SAT solo entrega recibidos Vigentes) |
MasivaSolicitaRecibidosMetadata |
Solicita la Metadata de los CFDI recibidos en un periodo |
MasivaVerificaSolicitud |
Verifica el estado de una solicitud; devuelve los idspaquetes cuando termina |
MasivaDescargaPaquete |
Descarga un paquete ZIP; los bytes llegan en el campo paquete |
Administración
Las operaciones administrativas permiten gestionar emisores y usuarios (distribuidores) dentro de una cuenta de VXML. Se exponen a traves de la clase Admin (interfaz IAdmin) y requieren una API key con privilegios de administracion. Todas devuelven un AdminResponseDto donde IsSuccess es verdadero cuando InnerExitCode == 0.
using VXML;
...
var admin = new Admin();
// Alta de un emisor bajo un usuario
var altaEmisor = await admin.AdminEmisorAdd(
"MI_API_KEY", // apiKey : API key de administracion
"demo_cibertec", // usuario : cuenta VXML que tendra al emisor
"EKU9003173C9", // rfcEmisor: RFC del emisor
"", // pwdConsulta: clave del portal de consultas ("" para no establecer)
"ESCUELA KEMPER URGATE", // razonSocial
"correo@dominio.mx", // email
"Persona de Contacto", // contacto
100, // asignacion : timbres asignados inicialmente
false, // suspendido : true impide timbrar sin importar saldo
true); // notificacion: habilitar notificaciones por correo
if (altaEmisor.IsSuccess)
Console.WriteLine("Emisor creado: {0}", altaEmisor.Message);
else
Console.WriteLine("Fallo con codigo {0}: {1}", altaEmisor.InnerExitCode, altaEmisor.Message);
// Actualizar un emisor existente (sin modificar la asignacion de timbres)
await admin.AdminEmisorUpd("MI_API_KEY", "demo_cibertec", "EKU9003173C9", "", "ESCUELA KEMPER URGATE", "correo@dominio.mx", "Persona de Contacto", false, true);
// Asignar timbres a un emisor
await admin.AdminEmisorAsigna("MI_API_KEY", "demo_cibertec", "EKU9003173C9", 500);
// Configurar autoasignacion: cuando los timbres disponibles bajen de 'threshold',
// se asignan 'asignacion' timbres, sin exceder 'limit' en total
await admin.AdminEmisorAutoasignacion("MI_API_KEY", "demo_cibertec", "EKU9003173C9", 1000, 100, 10000, true);
// Alta de un usuario (distribuidor)
await admin.AdminUsuarioAdd("MI_API_KEY", "demo_cibertec", "nuevo_distribuidor", "claveSegura", "Razon Social", "correo@dominio.mx", "Contacto", "XAXX010101000", 1000);
// Actualizar un usuario (distribuidor) ("" en pwd para no sobre-escribir la clave)
await admin.AdminUsuarioUpd("MI_API_KEY", "demo_cibertec", "nuevo_distribuidor", "", "Razon Social", "correo@dominio.mx", "Contacto", "XAXX010101000");
// Asignar timbres a un usuario (distribuidor)
await admin.AdminUsuarioAsigna("MI_API_KEY", "demo_cibertec", "nuevo_distribuidor", 500);
| Metodo | Descripción |
|---|---|
AdminEmisorAdd |
Registra un nuevo emisor bajo un usuario |
AdminEmisorUpd |
Actualiza los datos de un emisor existente |
AdminEmisorAsigna |
Asigna timbres a un emisor |
AdminEmisorAutoasignacion |
Configura la regla de autoasignacion de timbres de un emisor |
AdminUsuarioAdd |
Registra un nuevo usuario (distribuidor) |
AdminUsuarioUpd |
Actualiza los datos de un usuario (distribuidor) |
AdminUsuarioAsigna |
Asigna timbres a un usuario (distribuidor) |
Características
- Generación de CFDI 4.0
- Cancelación de CFDI 4.0 (esquema 2022)
- Generación de CFDI de Retenciones e Información de Pagos 2.0, con todos sus complementos
- Cancelación de Retenciones (esquema 2022)
- Descarga Masiva de XML y Metadata de CFDI emitidos y recibidos (requiere FIEL)
- Administración de emisores y distribuidores
- Generación de todos los complementos vigentes:
- [Complementos y Complementos Concepto]
- Generación de representacion impresa simple (PDF)
- Generación de Codigo de Barras Bidimensional en formatos: png, jpg y bmp
- Sellado local (tu llave privada y clave son usadas localmente)
- Manejo de errores y logging
Requisitos técnicos
- .NET 6.0 o superior
Requerimientos de servicio
- Contar con un CSD vigente (Certificado de Sello Digital).
- Contar con los archivos .cer, .key
- Contar con la clave del archivo .key
- En caso de desear timbrar con credenciales diferentes al demo; haber contratado un plan de timbres con VXML
NOTA: Los archivos .cer/.key de la FIEL no funcionan para el proceso de timbrado, deberan usarse los del CSD. Para la Descarga Masiva aplica lo contrario: se requiere la FIEL del contribuyente y un CSD sera rechazado por el SAT
Información DEMO
Estas credenciales pueden usarse sin necesidad de ningun tipo de registro
- usuario: demo_cibertec
- rfcemisor: EKU9003173C9
- Certificado Emisor: CSD_EKU9003173C9.cer
- Llave Privada Emisor: CSD_EKU9003173C9.key
- Clave Llave Privada: 12345678a
Contacto
- Correo electronico: soporte@ciber-tec.com
Licencia
Este proyecto se rige bajo la licencia MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Console (>= 6.0.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Console (>= 6.0.0)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Console (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Soporte para CFDI de Retenciones e Informacion de Pagos 2.0 (timbrado y cancelacion) y para el servicio de Descarga Masiva del SAT