Facturación Electrónica SUNAT Perú para .NET
Port completo de Greenter PHP con paridad 100%.
| Capa | Proyecto | Responsabilidad |
|---|---|---|
| Package | Khipu.Net |
Metapaquete NuGet que agrupa todo |
| Validation | Khipu.Validator |
33 constraint loaders, field validators, engine |
| Business | Khipu.Core |
Builder, Factory, TaxCalculator, XmlSigner, HtmlReport, QR, PDF |
| XML | Khipu.Xml |
9 builders UBL 2.1 + 8 parsers XML-to-object |
| Services | Khipu.Ws |
SOAP client, GRE REST client, CDR reader, 1710 error codes |
| Models | Khipu.Data |
9 document types, entities, enums, generators (zero dependencies) |
dotnet add package Khipu.Netusing Khipu.Core.Builder;
using Khipu.Core.Services;
using Khipu.Core.Security;
using Khipu.Data.Entities;
using Khipu.Data.Documents;
using Khipu.Data.Enums;
using Khipu.Ws.Constants;
// Construir factura con calculo automatico de impuestos
var invoice = new InvoiceBuilder()
.WithCompany(new Company
{
Ruc = "20123456789",
RazonSocial = "MI EMPRESA SAC",
Address = new Address
{
Ubigeo = "150101", Direccion = "AV. PRINCIPAL 123",
Departamento = "LIMA", Provincia = "LIMA",
Distrito = "LIMA", CodigoLocal = "0000"
}
})
.WithClient(new Client
{
TipoDoc = DocumentType.Ruc,
NumDoc = "20987654321",
RznSocial = "CLIENTE SRL"
})
.WithSerie("F001")
.WithCorrelativo(1)
.WithFechaEmision(DateTime.Today)
.AddDetail(new SaleDetail
{
Codigo = "PROD001",
Descripcion = "Laptop HP ProBook",
Unidad = "NIU",
Cantidad = 1,
MtoValorUnitario = 2500,
MtoValorVenta = 2500,
PrecioVenta = 2950,
TipoAfectacionIgv = TaxType.Gravado
})
.Build();
// Firmar y enviar a SUNAT
var signer = XmlSigner.FromPfx("certificado.pfx", "password");
var service = new SunatService("20123456789MODDATOS", "clavesol", SunatEndpoints.Beta, signer);
var response = await service.SendInvoiceAsync(invoice);Los 9 tipos de comprobante electronico de SUNAT:
await service.SendInvoiceAsync(invoice); // Factura (01)
await service.SendReceiptAsync(receipt); // Boleta (03)
await service.SendCreditNoteAsync(creditNote); // Nota de Credito (07)
await service.SendDebitNoteAsync(debitNote); // Nota de Debito (08)
await service.SendDespatchAsync(despatch); // Guia de Remision (09)
await service.SendSummaryAsync(summary); // Resumen Diario
await service.SendVoidedAsync(voided); // Comunicacion de Baja
// Percepcion y Retencion: generar XML + enviar manualmenteKhipu.Net soporta ambos protocolos de SUNAT. Ambos implementan ISunatClient y son intercambiables.
var client = new SunatSoapClient("20123456789MODDATOS", "clavesol", SunatEndpoints.Beta);
var service = new SunatService(client, signer);SUNAT esta migrando hacia esta API REST con OAuth2. Usa endpoints separados para autenticacion y envio de CPE.
var client = new GreClient(
clientId: "mi-client-id",
clientSecret: "mi-client-secret",
ruc: "20123456789",
solUser: "MODDATOS",
solPassword: "clavesol"
);
var service = new SunatService(client, signer);SunatSoapClient |
GreClient |
|
|---|---|---|
| Protocolo | SOAP/XML | REST/JSON |
| Auth | HTTP Basic | OAuth2 Bearer (JWT) |
| Token | No | Auto-refresh con cache thread-safe |
| Envio | SOAP envelope + ZIP base64 | POST JSON + ZIP base64 + SHA256 |
| Auth endpoint | N/A | api-seguridad.sunat.gob.pe/v1 |
| CPE endpoint | e-factura.sunat.gob.pe/.../billService |
api-cpe.sunat.gob.pe/v1 |
| Consulta CDR | getStatusCdr directo |
Via ticket con getStatus |
| Estado | Estable, legacy | Moderno, recomendado por SUNAT |
using Khipu.Xml.Builder;
var builder = new InvoiceXmlBuilder();
string xml = builder.Build(invoice);
string fileName = builder.GetFileName(invoice);
// "20123456789-01-F001-00000001.xml"9 builders: InvoiceXmlBuilder, ReceiptXmlBuilder, CreditNoteXmlBuilder, DebitNoteXmlBuilder, DespatchXmlBuilder, PerceptionXmlBuilder, RetentionXmlBuilder, SummaryXmlBuilder, VoidedXmlBuilder.
using Khipu.Xml.Parser;
Invoice invoice = XmlDocumentParser.ParseInvoice(xml);
CreditNote note = XmlDocumentParser.ParseCreditNote(xml);
Despatch despatch = XmlDocumentParser.ParseDespatch(xml);
Perception perception = XmlDocumentParser.ParsePerception(xml);
Retention retention = XmlDocumentParser.ParseRetention(xml);
Summary summary = XmlDocumentParser.ParseSummary(xml);
Voided voided = XmlDocumentParser.ParseVoided(xml);using Khipu.Ws.Reader;
var cdr = CdrReader.ParseFromZip(response.CdrZip);
if (cdr.IsAccepted) // codigo 0 o >= 4000
Console.WriteLine($"Aceptado: {cdr.Description}");
else
Console.WriteLine($"Rechazado [{cdr.Code}]: {cdr.Description}");using Khipu.Ws.Constants;
string msg = SunatErrorCodes.GetMessage("2017");
bool accepted = SunatErrorCodes.IsAccepted("4001"); // true
bool rejected = SunatErrorCodes.IsRejection("2017"); // true
string cat = SunatErrorCodes.GetCategory("0306"); // "XML/Parsing"
int total = SunatErrorCodes.Count; // 1710using Khipu.Core.Report;
var report = new HtmlReport();
string html = report.RenderInvoice(invoice, new ReportParameters
{
LogoBase64 = Convert.ToBase64String(File.ReadAllBytes("logo.png")),
Hash = signatureHash
});9 metodos: RenderInvoice, RenderReceipt, RenderCreditNote, RenderDebitNote, RenderDespatch, RenderPerception, RenderRetention, RenderSummary, RenderVoided.
byte[] pdf = await PdfExporter.HtmlToPdfAsync(html);
await PdfExporter.SavePdfAsync(html, "factura.pdf");string svg = QrGenerator.GenerateInvoiceQrSvg(invoice, hash);
string dataUri = QrGenerator.GenerateInvoiceQrBase64(invoice);
byte[] png = QrGenerator.GenerateQrPng("contenido");using Khipu.Validator.Engine;
var engine = new DocumentValidationEngine();
var result = engine.ValidateInvoice(invoice);
if (!result.IsValid)
foreach (var e in result.Errors)
Console.WriteLine($"[{e.Code}] {e.Path}: {e.Message}");Valida: Invoice, CreditNote, DebitNote, Despatch, Perception, Retention, Summary, Voided.
using Khipu.Validator.Rules;
var errors = FieldValidators.ValidateInvoiceDeep(invoice);
var errors = FieldValidators.ValidateDespatchDeep(despatch);
var errors = FieldValidators.ValidatePerceptionDeep(perception);var errors = ConstraintLoaders.LoadInvoice(invoice);
var errors = ConstraintLoaders.LoadDespatch(despatch);
var errors = ConstraintLoaders.LoadClient(client);
var errors = ConstraintLoaders.LoadCompany(company);33 loaders: Company, Client, Address, Invoice, CreditNote, DebitNote, SaleDetail, Despatch, DespatchDetail, Direction, Transportist, Perception, PerceptionDetail, Retention, RetentionDetail, Summary, SummaryDetail, Voided, VoidedDetail, Cuota, Detraction, Document, Legend, Prepayment, Payment, SalePerception, SummaryPerception, FormaPagoContado, FormaPagoCredito, Charge.
using Khipu.Core.Algorithms;
decimal igv = TaxCalculator.CalculateIgv(1000); // 180
decimal precio = TaxCalculator.CalculateSalePrice(1000, TaxType.Gravado); // 1180
decimal detraccion = TaxCalculator.CalculateDetraction(1000); // 100
decimal valor = TaxCalculator.CalculateUnitValue(1180, TaxType.Gravado); // 1000
// Monto en letras
string letras = AmountInWordsEsPe.Convert(1180.50m, Currency.Pen);
// "SON: MIL CIENTO OCHENTA CON 50/100 SOLES"
// Redondeo SUNAT (2 decimales, AwayFromZero)
decimal rounded = RoundingPolicy.RoundSunat(10.005m); // 10.01using Khipu.Data.Generators;
var invoice = DocumentGenerator.CreateInvoice();
var receipt = DocumentGenerator.CreateReceipt();
var creditNote = DocumentGenerator.CreateCreditNote();
var debitNote = DocumentGenerator.CreateDebitNote();
var despatch = DocumentGenerator.CreateDespatch();
var perception = DocumentGenerator.CreatePerception();
var retention = DocumentGenerator.CreateRetention();
var summary = DocumentGenerator.CreateSummary();
var voided = DocumentGenerator.CreateVoided();| Componente | Greenter PHP | Khipu.Net | Paridad |
|---|---|---|---|
| Modelos (9 tipos) | 286 archivos | 87 archivos | 100% |
| XML Builders | 8 (Twig) | 9 (XDocument) | 100% |
| XML Parsers | 8 | 8 | 100% |
| CDR Parser | DomCdrReader | CdrReader | 100% |
| Error Codes | 1710 (XML) | 1710 (embedded) | 100% |
| SOAP Client | BillSender | SunatSoapClient | 100% |
| GRE REST API | Api + GreSender | GreClient | 100% |
| Firma Digital | XMLSecLibs | System.Security | 100% |
| Tax Calculator | Implicito | Explicito | 100% |
| Validacion | 43 Symfony loaders | 33 loaders + field | 100% |
| HTML Reports | 6 Twig templates | 9 metodos | 100% |
| HTML to PDF | phpwkhtmltopdf | PdfExporter | 100% |
| QR Code | BaconQrCode | QRCoder | 100% |
| Data Generators | 19 archivos | 9 factory methods | 100% |
| Tests | PHPUnit | 409 xUnit | 100% |
dotnet test
# 409 tests passing, 0 errors, 0 warnings| Guia | Descripcion |
|---|---|
| Getting Started | Instalacion, configuracion, primer envio |
| Invoices | Facturas, boletas, Factory y Builder patterns |
| Credit/Debit Notes | Notas de credito y debito con catalogos SUNAT |
| Summaries | Resumenes diarios, comunicaciones de baja, polling CDR |
| Tax Calculator | IGV, ISC, IVAP, detracciones, monto en letras |
| Signing & Sending | Firma X.509, SOAP, GRE REST, endpoints |
| Validation | Engine, field validators, constraint loaders |
| API Reference | Referencia completa de namespaces y clases |
Este proyecto soporta el estandar llms.txt:
llms.txt- Indice para LLMsllms-full.txt- Documentacion completa inline
MIT
- Greenter PHP - Proyecto original de Giansalex
Khipu - nombrado en honor al antiguo sistema de contabilidad inca