@devlas/dte-sii 2.14.1 → 2.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cert/CertRunner.js +90 -5
- package/package.json +1 -1
package/cert/CertRunner.js
CHANGED
|
@@ -4081,6 +4081,41 @@ class CertRunner {
|
|
|
4081
4081
|
req.setTimeout(20000, () => { req.destroy(); reject(new Error('Timeout')); });
|
|
4082
4082
|
});
|
|
4083
4083
|
|
|
4084
|
+
const [rutNum, dvChar] = String(this.config.emisor.rut).replace(/\./g, '').split('-');
|
|
4085
|
+
|
|
4086
|
+
/** POST de formulario, para el segundo paso del timbraje. Se captura igual que el GET. */
|
|
4087
|
+
const postForm = (url, campos) => new Promise((resolve, reject) => {
|
|
4088
|
+
const cuerpo = Object.entries(campos)
|
|
4089
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v ?? '')}`).join('&');
|
|
4090
|
+
const u = new URL(url);
|
|
4091
|
+
const _t0 = Date.now();
|
|
4092
|
+
const req = https.request({
|
|
4093
|
+
hostname: u.hostname, path: u.pathname + u.search, method: 'POST',
|
|
4094
|
+
headers: {
|
|
4095
|
+
'Cookie': cookieStr,
|
|
4096
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
|
|
4097
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
4098
|
+
'Content-Length': Buffer.byteLength(cuerpo),
|
|
4099
|
+
},
|
|
4100
|
+
rejectUnauthorized: false,
|
|
4101
|
+
}, (res) => {
|
|
4102
|
+
const chunks = [];
|
|
4103
|
+
res.on('data', c => chunks.push(c));
|
|
4104
|
+
res.on('end', () => {
|
|
4105
|
+
const _body = Buffer.concat(chunks).toString('utf-8');
|
|
4106
|
+
registrarHttpDebug({
|
|
4107
|
+
url, method: 'POST', status: res.statusCode, headers: res.headers,
|
|
4108
|
+
body: _body, reqBody: cuerpo, ms: Date.now() - _t0,
|
|
4109
|
+
cliente: 'verificarAutorizacionBoleta',
|
|
4110
|
+
});
|
|
4111
|
+
resolve(_body);
|
|
4112
|
+
});
|
|
4113
|
+
});
|
|
4114
|
+
req.on('error', reject);
|
|
4115
|
+
req.setTimeout(20000, () => { req.destroy(); reject(new Error('Timeout')); });
|
|
4116
|
+
req.write(cuerpo); req.end();
|
|
4117
|
+
});
|
|
4118
|
+
|
|
4084
4119
|
const result = {
|
|
4085
4120
|
autorizadaProduccion: false,
|
|
4086
4121
|
autorizadaCertificacion: false,
|
|
@@ -4090,8 +4125,37 @@ class CertRunner {
|
|
|
4090
4125
|
};
|
|
4091
4126
|
|
|
4092
4127
|
// ── 1. Verificar producción: of_solicita_folios_dcto en palena ─────────
|
|
4128
|
+
//
|
|
4129
|
+
// ⚠️ Son DOS pasos, no uno. `of_solicita_folios_dcto` es la segunda pantalla del
|
|
4130
|
+
// formulario de timbraje: entrar con un GET pelado, sin el POST previo que lleva
|
|
4131
|
+
// RUT_EMP/DV_EMP, hace que el SII responda 200 con una página de error genérica
|
|
4132
|
+
// ("No ha sido posible completar su solicitud... LIBRUD-OFSF-DTE-3-1-02") que no
|
|
4133
|
+
// trae ningún <select>.
|
|
4134
|
+
//
|
|
4135
|
+
// Como el parser buscaba <option value="39">, esa página vacía se leía como "no
|
|
4136
|
+
// autorizada". Es la secuencia que ya usa CafSolicitor._processMultiStepFlow() para
|
|
4137
|
+
// pedir folios de verdad, y por eso ESE camino sí funciona.
|
|
4138
|
+
//
|
|
4139
|
+
// Caso real (17/08/2026, RUT 78441936-3): el flujo reportaba "Boleta NO autorizada"
|
|
4140
|
+
// mientras el SII tenía a la empresa como FACTURADOR ELECTRONICO con BOLETA
|
|
4141
|
+
// ELECTRONICA autorizada hasta el folio 103009 desde el 12/07/2026, y palena le
|
|
4142
|
+
// entregaba folios reales de factura por el camino bien armado. Un comercio ya
|
|
4143
|
+
// habilitado quedaba viendo "esperando al SII" para siempre.
|
|
4093
4144
|
try {
|
|
4094
|
-
const
|
|
4145
|
+
const SiiSession = require('../SiiSession');
|
|
4146
|
+
const htmlPaso1 = await fetchHtml('https://palena.sii.cl/cvc_cgi/dte/of_solicita_folios');
|
|
4147
|
+
const accion = SiiSession.extractFormAction(htmlPaso1) || '/cvc_cgi/dte/of_solicita_folios_dcto';
|
|
4148
|
+
const campos = {
|
|
4149
|
+
...SiiSession.extractInputValues(htmlPaso1),
|
|
4150
|
+
RUT_EMP: rutNum,
|
|
4151
|
+
DV_EMP: dvChar,
|
|
4152
|
+
};
|
|
4153
|
+
// El `action` del form puede venir absoluto, con barra inicial, o relativo.
|
|
4154
|
+
const BASE_PALENA = 'https://palena.sii.cl';
|
|
4155
|
+
const urlPaso2 = accion.startsWith('http') ? accion
|
|
4156
|
+
: accion.startsWith('/') ? `${BASE_PALENA}${accion}`
|
|
4157
|
+
: `${BASE_PALENA}/cvc_cgi/dte/${accion}`;
|
|
4158
|
+
const htmlProd = await postForm(urlPaso2, campos);
|
|
4095
4159
|
if (this.config.debugDir) {
|
|
4096
4160
|
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
4097
4161
|
fs.writeFileSync(
|
|
@@ -4099,10 +4163,31 @@ class CertRunner {
|
|
|
4099
4163
|
htmlProd, 'utf-8'
|
|
4100
4164
|
);
|
|
4101
4165
|
}
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4166
|
+
// ⚠️ "No hay <option> con el 39" NO significa "no está autorizada". El SII también
|
|
4167
|
+
// responde 200 con una página de error que no trae ningún select, y ahí el parser
|
|
4168
|
+
// veía cero tipos y concluía "no autorizada" — un dato inventado, indistinguible
|
|
4169
|
+
// de la respuesta real.
|
|
4170
|
+
//
|
|
4171
|
+
// Visto el 17/08/2026 (RUT 78441936-3): palena devolvió 3377 bytes con
|
|
4172
|
+
// "No ha sido posible completar su solicitud... código LIBRUD-OFSF-DTE-3-1-02" y
|
|
4173
|
+
// el flujo venía reportando "certificación incompleta" desde hacía días.
|
|
4174
|
+
//
|
|
4175
|
+
// Se distingue por la ausencia de select, no por el texto del error: cualquier
|
|
4176
|
+
// fallo del portal que no pinte el formulario cae acá.
|
|
4177
|
+
const hayFormulario = /<select[^>]*>/i.test(htmlProd);
|
|
4178
|
+
if (!hayFormulario) {
|
|
4179
|
+
const codigo = (htmlProd.match(/([A-Z]{4,}-[A-Z]{3,}-[A-Z0-9-]{4,})/) || [])[1] || null;
|
|
4180
|
+
result.consultaFallida = true;
|
|
4181
|
+
result.errorConsultaProduccion = codigo
|
|
4182
|
+
? `El portal del SII no entregó el formulario de timbraje (código ${codigo})`
|
|
4183
|
+
: 'El portal del SII no entregó el formulario de timbraje';
|
|
4184
|
+
console.log(` [!] Producción — ${result.errorConsultaProduccion}. NO se puede afirmar si está autorizada.`);
|
|
4185
|
+
} else {
|
|
4186
|
+
const matches = [...htmlProd.matchAll(/<option[^>]+value="(\d+)"[^>]*>/gi)];
|
|
4187
|
+
result.tiposDisponiblesProduccion = matches.map(m => parseInt(m[1], 10)).filter(n => n > 0);
|
|
4188
|
+
result.autorizadaProduccion = result.tiposDisponiblesProduccion.includes(39);
|
|
4189
|
+
console.log(` ✓ Producción — tipos disponibles: [${result.tiposDisponiblesProduccion.join(', ')}] | Boleta 39: ${result.autorizadaProduccion ? '✅ SÍ' : '❌ NO'}`);
|
|
4190
|
+
}
|
|
4106
4191
|
} catch (e) {
|
|
4107
4192
|
console.log(` [!] No se pudo verificar producción: ${e.message}`);
|
|
4108
4193
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devlas/dte-sii",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.2",
|
|
4
4
|
"description": "Facturación y boletas electrónicas para el SII de Chile. Genera, timbra, firma y envía DTEs, libros electrónicos y automatiza la certificación.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "dte-sii.d.ts",
|