En este post vamos a crear un pequeño script que pueda emitir facturas usando una API que recibe un JSON con los datos de la factura y la registre directamente en SUNAT. Para eso usaremos Billme que nos permitirá emitir la factura mediante una simple petición POST usando su API.
Creación de una empresa de prueba
Primero crearemos una cuenta gratuita en Billme para poder obtener el token que nos permitirá hacer el código de prueba. Para esto seguiremos la guía de su documentación.
Luego de tener una cuenta registraremos una empresa de prueba para poder obtener el token que nos permitirá usar su sandbox y probar la emisión en un entorno de prueba. Para esto dentro de la plataforma de Billme nos dirigimos a la opción de Empresas > Agregar. Completamos los datos requeridos y tendremos lista nuestra empresa de prueba. Ahora podemos hacer click en el siguiente ícono
para poder ver el token que nos permitirá comunicarnos con la API.
Factura de ejemplo
Para este ejemplo simularemos una factura con los siguientes datos:
- Cantidad de productos: 1
- Tipo: Factura
- Serie: F001
- Correlativo: 00321
- Moneda: PEN
- Tipo Pago: Contado
- Monto: 100
- Aplica IGV: Sí
Desarrollo del script
Para el script utilizaremos NodeJS con JavaScript. Utilizaremos la librería de fetch para realizar la petición HTTP. Nos ubicamos en una carpeta donde tendremos nuestro script y creamos el archivo llamado script.js
.
// Función que realiza la petición hacia la API
async function sendBillingToBillme() {
const url = "https://www.api.billmeperu.com/api/v1/Emission/EnviarBoletaFactura";
const token = 'tu-token-aqui';
const data = {
"tipoOperacion":"010",
"serie":"F001",
"correlativo":"00321",
"fechaEmision":"2025-06-20",
"horaEmision":"00:00:00",
"fechaVencimiento":"2025-06-20",
"codigoTipoOperacion":"0101",
"codigoTipoDocumento":"01",
"moneda":"PEN",
"montoCredito":0,
"formaPago":"Contado",
"igv":15.25,
"icbper":0,
"cuotas":[],
"emisor":{
"codigoTipoDocumento":"6",
"numDocumento":"20123456721",
"razonSocial":"EMISOR SAC",
"nombreComercial":"EMISOR SAC",
"ubigeo":"200610",
"ciudad":"PIURA",
"distrito":"PIURA",
"provincia":"PIURA",
"direccion":"DIRECCION EJEMPLO, CALLE 1"
},
"cliente":{
"codigoTipoDocumento":"1",
"numDocumento":"72314572",
"razonSocial":"RAZON SOCIAL CLIENTE",
"nombreComercial":"NOMBRE COMERCIAL CLIENTE",
"ubigeo":"",
"ciudad":"",
"distrito":"",
"provincia":"",
"direccion":""
},
"totales":{
"totalOpGravadas":84.75,
"totalOpInafectas":0,
"totalOpExoneradas":0,
"totalImpuestos":15.25,
"totalSinImpuestos":84.75,
"totalConImpuestos":100,
"totalPagar":100,
"totalDescuentoGlobal":0,
"totalDescuentoProductos":0
},
"productos":[
{
"unidades":1,
"codigoUnidad":"NIU",
"nombre":"Zapatillas fútbol",
"moneda":"PEN",
"precioUnitario":84.75,
"precioLista":"100.00",
"montoSinImpuesto":84.75,
"montoImpuestos":15.25,
"montoTotal":84.75,
"montoIcbper":0,
"factorIcbper":0,
"montoDescuento":0,
"codigoTipoPrecio":"01",
"impuestos":[
{
"monto":15.25,
"idCategoria":"S",
"porcentaje":18,
"codigoAfectacionIgv":"10",
"codigoInterTributo":"VAT",
"nombreTributo":"IGV",
"codigoTributo":"1000"
}
],
"id":"Z001",
"codigoClasificacion":"531117"
}
]
};
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'token': token,
'Accept': 'application/json'
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log('Respuesta de la emisión:', result);
} catch (error) {
console.error('Error:', error.message);
}
}
Ahora crearemos la función principal de nuestro script que invocará a la función que envía la factura usando Billme.
async function main() {
// Enviar la factura
console.log('Emitiendo factura...');
await sendBillingToBillme();
}
// Ejecutar el script
if (require.main === module) {
main();
}
Luego, desde la consola nos colocamos en la ruta donde tenemos nuestro script y ejecutamos el siguiente comando: node script.js
Finalmente, con esto veremos por consola el resultado del envío de nuestra factura. El código de nuestro script luciría así:
// Función que realiza la petición hacia la API
async function sendBillingToBillme() {
const url = "https://www.api.billmeperu.com/api/v1/Emission/EnviarBoletaFactura";
const token = 'tu-token-aqui';
const data = {
"tipoOperacion":"010",
"serie":"F001",
"correlativo":"00321",
"fechaEmision":"2025-06-20",
"horaEmision":"00:00:00",
"fechaVencimiento":"2025-06-20",
"codigoTipoOperacion":"0101",
"codigoTipoDocumento":"01",
"moneda":"PEN",
"montoCredito":0,
"formaPago":"Contado",
"igv":15.25,
"icbper":0,
"cuotas":[],
"emisor":{
"codigoTipoDocumento":"6",
"numDocumento":"20123456721",
"razonSocial":"EMISOR SAC",
"nombreComercial":"EMISOR SAC",
"ubigeo":"200610",
"ciudad":"PIURA",
"distrito":"PIURA",
"provincia":"PIURA",
"direccion":"DIRECCION EJEMPLO, CALLE 1"
},
"cliente":{
"codigoTipoDocumento":"1",
"numDocumento":"72314572",
"razonSocial":"RAZON SOCIAL CLIENTE",
"nombreComercial":"NOMBRE COMERCIAL CLIENTE",
"ubigeo":"",
"ciudad":"",
"distrito":"",
"provincia":"",
"direccion":""
},
"totales":{
"totalOpGravadas":84.75,
"totalOpInafectas":0,
"totalOpExoneradas":0,
"totalImpuestos":15.25,
"totalSinImpuestos":84.75,
"totalConImpuestos":100,
"totalPagar":100,
"totalDescuentoGlobal":0,
"totalDescuentoProductos":0
},
"productos":[
{
"unidades":1,
"codigoUnidad":"NIU",
"nombre":"Zapatillas fútbol",
"moneda":"PEN",
"precioUnitario":84.75,
"precioLista":"100.00",
"montoSinImpuesto":84.75,
"montoImpuestos":15.25,
"montoTotal":84.75,
"montoIcbper":0,
"factorIcbper":0,
"montoDescuento":0,
"codigoTipoPrecio":"01",
"impuestos":[
{
"monto":15.25,
"idCategoria":"S",
"porcentaje":18,
"codigoAfectacionIgv":"10",
"codigoInterTributo":"VAT",
"nombreTributo":"IGV",
"codigoTributo":"1000"
}
],
"id":"Z001",
"codigoClasificacion":"531117"
}
]
};
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'token': token,
'Accept': 'application/json'
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log('Respuesta de la emisión:', result);
} catch (error) {
console.error('Error:', error.message);
}
}
async function main() {
// Enviar la factura
console.log('Emitiendo factura...');
await sendBillingToBillme();
}
// Ejecutar el script
if (require.main === module) {
main();
}
Listo! Con este script de ejemplo puedes hacer pruebas y luego integrarlo a tus sistemas para que puedas emitir tus comprobantes electrónicos usando sólo una API. Happy coding 😉