Ejemplos de uso
Los siguientes ejemplos asumen que el servidor está corriendo en http://localhost:8000.
Crear una Factura
Sección titulada «Crear una Factura»import httpx
from openubl.models import Invoice, Proveedor, Cliente, DocumentoVentaDetalle
invoice = Invoice( serie="F001", numero=1, proveedor=Proveedor( ruc="20100111111", razonSocial="Mi Empresa S.A.C.", ), cliente=Cliente( nombre="Juan Perez", numeroDocumentoIdentidad="12345678", tipoDocumentoIdentidad="1", ), detalles=[ DocumentoVentaDetalle( descripcion="Producto A", cantidad=2, precio=100.00, ) ], moneda="PEN",)
with httpx.Client(base_url="http://localhost:8000") as client: r = client.post("/api/v1/invoice/create", json=invoice.model_dump(mode="json")) r.raise_for_status() print(r.json()["xml"])import { createInvoice } from "@openubl/sdk";import { zInvoice } from "@openubl/sdk/zod.gen";
const invoice = zInvoice.parse({serie: "F001",numero: 1,tipoOperacion: "0101",moneda: "PEN",proveedor: { ruc: "20100111111", razonSocial: "Mi Empresa S.A.C.",},cliente: { nombre: "Juan Perez", numeroDocumentoIdentidad: "12345678", tipoDocumentoIdentidad: "1",},detalles: [ { descripcion: "Producto A", cantidad: 2, precio: 100.00, unidadMedida: "NIU", tipoAfectacionIGV: "10", },],});
const { data, error } = await createInvoice({body: invoice,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST http://localhost:8000/api/v1/invoice/create -H "Content-Type: application/json" -d '{ "serie": "F001", "numero": 1, "tipoOperacion": "0101", "moneda": "PEN", "proveedor": { "ruc": "20100111111", "razonSocial": "Mi Empresa S.A.C." }, "cliente": { "nombre": "Juan Perez", "numeroDocumentoIdentidad": "12345678", "tipoDocumentoIdentidad": "1" }, "detalles": [ { "descripcion": "Producto A", "cantidad": 2, "precio": 100.00, "unidadMedida": "NIU", "tipoAfectacionIGV": "10" } ]}'Respuesta esperada:
{ "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."}Para omitir la validación SUNAT, añade ?validate=false a la URL.
Firmar un XML
Sección titulada «Firmar un XML»import osimport httpx
xml = "<?xml version="1.0" encoding="UTF-8"?>..."
with httpx.Client(base_url="http://localhost:8000") as client: r = client.post( "/api/v1/sign", json={ "xml": xml, "cert_pem": os.getenv("CERT_PEM", ""), "key_pem": os.getenv("KEY_PEM", ""), "signature_id": "SignSUNAT", }, ) r.raise_for_status() print(r.json()["signed_xml"])import { signXml } from "@openubl/sdk";import { zSignXmlBody } from "@openubl/sdk/zod.gen";
const body = zSignXmlBody.parse({xml: "<?xml version="1.0" encoding="UTF-8"?>...",cert_pem: process.env.CERT_PEM,key_pem: process.env.KEY_PEM,signature_id: "SignSUNAT",});
const { data, error } = await signXml({body,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.signed_xml);curl -X POST http://localhost:8000/api/v1/sign -H "Content-Type: application/json" -d '{ "xml": "<?xml version="1.0"?>...", "cert_pem": "-----BEGIN CERTIFICATE-----MIIC...-----END CERTIFICATE-----", "key_pem": "-----BEGIN PRIVATE KEY-----MIIE...-----END PRIVATE KEY-----", "signature_id": "SignSUNAT"}'Respuesta esperada:
{ "signed_xml": "<?xml version=\"1.0\"?>...<ds:Signature>..."}Crear otra nota de crédito
Sección titulada «Crear otra nota de crédito»import httpx
from openubl.models import CreditNote, Proveedor, Cliente, DocumentoVentaDetalle
credit_note = CreditNote( serie="BC01", numero=1, comprobanteAfectadoSerieNumero="F001-1", sustentoDescripcion="Anulación de venta", proveedor=Proveedor( ruc="20100111111", razonSocial="Mi Empresa S.A.C.", ), cliente=Cliente( nombre="Juan Perez", numeroDocumentoIdentidad="12345678", tipoDocumentoIdentidad="1", ), detalles=[ DocumentoVentaDetalle( descripcion="Producto A", cantidad=2, precio=100.00, ) ], moneda="PEN",)
with httpx.Client(base_url="http://localhost:8000") as client: r = client.post("/api/v1/credit-note/create", json=credit_note.model_dump(mode="json")) r.raise_for_status() print(r.json()["xml"])import { createCreditNote } from "@openubl/sdk";import { zCreditNote } from "@openubl/sdk/zod.gen";
const creditNote = zCreditNote.parse({serie: "BC01",numero: 1,comprobanteAfectadoSerieNumero: "F001-1",sustentoDescripcion: "Anulación de venta",moneda: "PEN",proveedor: { ruc: "20100111111", razonSocial: "Mi Empresa S.A.C.",},cliente: { nombre: "Juan Perez", numeroDocumentoIdentidad: "12345678", tipoDocumentoIdentidad: "1",},detalles: [ { descripcion: "Producto A", cantidad: 2, precio: 100.00, unidadMedida: "NIU", tipoAfectacionIGV: "10", },],});
const { data, error } = await createCreditNote({body: creditNote,});
if (error) {throw new Error(JSON.stringify(error));}
console.log(data.xml);curl -X POST http://localhost:8000/api/v1/credit-note/create -H "Content-Type: application/json" -d '{ "serie": "BC01", "numero": 1, "comprobanteAfectadoSerieNumero": "F001-1", "sustentoDescripcion": "Anulación de venta", "moneda": "PEN", "proveedor": { "ruc": "20100111111", "razonSocial": "Mi Empresa S.A.C." }, "cliente": { "nombre": "Juan Perez", "numeroDocumentoIdentidad": "12345678", "tipoDocumentoIdentidad": "1" }, "detalles": [ { "descripcion": "Producto A", "cantidad": 2, "precio": 100.00, "unidadMedida": "NIU", "tipoAfectacionIGV": "10" } ]}'Guardar la respuesta en un archivo
Sección titulada «Guardar la respuesta en un archivo»Puedes redirigir la salida y extraer el XML con jq:
import httpximport json
with httpx.Client(base_url="http://localhost:8000") as client: r = client.post( "/api/v1/invoice/create", json=json.load(open("invoice.json")), ) r.raise_for_status() with open("invoice.xml", "w", encoding="utf-8") as f: f.write(r.json()["xml"])import { createInvoice } from "@openubl/sdk";import { zInvoice } from "@openubl/sdk/zod.gen";import fs from "node:fs/promises";
const invoice = zInvoice.parse(JSON.parse(await fs.readFile("invoice.json", "utf-8")));
const { data, error } = await createInvoice({body: invoice,});
if (error) {throw new Error(JSON.stringify(error));}
await fs.writeFile("invoice.xml", data.xml);curl -s http://localhost:8000/api/v1/invoice/create -H "Content-Type: application/json" -d @invoice.json | jq -r '.xml' > invoice.xml