/** * Método para obtener el token de la sesión a través de una semilla * previamente firmada * * WSDL producción: https://palena.sii.cl/DTEWS/GetTokenFromSeed.jws?WSDL * WSDL certificación: https://maullin.sii.cl/DTEWS/GetTokenFromSeed.jws?WSDL * * @param Firma objeto de la Firma electrónica o arreglo con configuración de la misma * @return Token para autenticación en SII o =false si no se pudo obtener * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public static function getToken($Firma = []) { $semilla = self::getSeed(); if (!$semilla) { return false; } $requestFirmado = self::getTokenRequest($semilla, $Firma); if (!$requestFirmado) { return false; } $xml = \sasco\LibreDTE\Sii::request('GetTokenFromSeed', 'getToken', $requestFirmado); if ($xml === false or (string) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR/ESTADO')[0] !== '00') { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::AUTH_ERROR_TOKEN, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::AUTH_ERROR_TOKEN)); return false; } return (string) $xml->xpath('/SII:RESPUESTA/SII:RESP_BODY/TOKEN')[0]; }
*/ /** * @file 005-estado_envio_dte.php * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-16 */ // respuesta en texto plano header('Content-type: text/plain'); // incluir archivos php de la biblioteca y configuraciones include 'inc.php'; // solicitar token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($config['firma']); if (!$token) { foreach (\sasco\LibreDTE\Log::readAll() as $error) { echo $error, "\n"; } exit; } // consultar estado enviado $rut = ''; $dv = ''; $trackID = ''; $estado = \sasco\LibreDTE\Sii::request('QueryEstUp', 'getEstUp', [$rut, $dv, $trackID, $token]); // si el estado se pudo recuperar se muestra estado y glosa if ($estado !== false) { print_r(['codigo' => (string) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/ESTADO')[0], 'glosa' => (string) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/GLOSA')[0]]); } // mostrar error si hubo foreach (\sasco\LibreDTE\Log::readAll() as $error) { echo $error, "\n"; }
/** * Método que consulta al estado al SII del dte recibido * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-28 */ public function getEstado(\sasco\LibreDTE\FirmaElectronica $Firma) { // obtener token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma); if (!$token) { return false; } // consultar estado list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID()); list($Y, $m, $d) = explode('-', $this->fecha); $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $this->getEmisor()->rut, 'DvCompania' => $this->getEmisor()->dv, 'RutReceptor' => $this->getReceptor()->rut, 'DvReceptor' => $this->getReceptor()->dv, 'TipoDte' => $this->dte, 'FolioDte' => $this->folio, 'FechaEmisionDte' => $d . $m . $Y, 'MontoDte' => $this->total, 'token' => $token]); // si hubo error con el estado se muestra que no se pudo obtener if ($xml === false) { return false; } $estado = (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0]; return $estado['ESTADO'] == 'DOK' ? true : $estado['GLOSA_ERR']; }
/** * Acción que solicita se envíe una nueva revisión del DTE al email * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-25 */ public function solicitar_revision($dte, $folio) { $Emisor = $this->getContribuyente(); // obtener DTE emitido $DteEmitido = new Model_DteEmitido($Emisor->rut, $dte, $folio, (int) $Emisor->certificacion); if (!$DteEmitido->exists()) { \sowerphp\core\Model_Datasource_Session::message('No existe el DTE solicitado', 'error'); $this->redirect('/dte/dte_emitidos/listar'); } // si no tiene track id error if (!$DteEmitido->track_id) { \sowerphp\core\Model_Datasource_Session::message('DTE no tiene Track ID, primero debe enviarlo al SII', 'error'); $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request)); } // obtener firma $Firma = $Emisor->getFirma($this->Auth->User->id); if (!$Firma) { \sowerphp\core\Model_Datasource_Session::message('No hay firma electrónica asociada a la empresa (o bien no se pudo cargar), debe agregar su firma antes de generar DTE', 'error'); $this->redirect('/dte/admin/firma_electronicas'); } // obtener token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma); if (!$token) { \sowerphp\core\Model_Datasource_Session::message('No fue posible obtener el token para el SII<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error'); $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request)); } // solicitar envío de nueva revisión $estado = \sasco\LibreDTE\Sii::request('wsDTECorreo', 'reenvioCorreo', [$token, $Emisor->rut, $Emisor->dv, $DteEmitido->track_id]); if ($estado === false) { \sowerphp\core\Model_Datasource_Session::message('No fue posible solicitar una nueva revisión del DTE.<br/>' . implode('<br/>', \sasco\LibreDTE\Log::readAll()), 'error'); } else { if ((int) $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/SII:ESTADO')[0]) { \sowerphp\core\Model_Datasource_Session::message('No fue posible solicitar una nueva revisión del DTE: ' . $estado->xpath('/SII:RESPUESTA/SII:RESP_HDR/SII:GLOSA')[0], 'error'); } else { \sowerphp\core\Model_Datasource_Session::message('Se solicitó nueva revisión del DTE, verificar estado en unos segundos', 'ok'); } } // redireccionar $this->redirect(str_replace('solicitar_revision', 'ver', $this->request->request)); }
* En caso contrario, consulte <http://www.gnu.org/licenses/gpl.html>. */ /** * @file 003-estadoDte.php * Ejemplo de consulta del estado de un DTE * Referencia: http://www.sii.cl/factura_electronica/factura_mercado/estado_dte.pdf * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-16 */ // respuesta en texto plano header('Content-type: text/plain'); // incluir archivos php de la biblioteca y configuraciones include 'inc.php'; // solicitar token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($config['firma']); if (!$token) { foreach (\sasco\LibreDTE\Log::readAll() as $error) { echo $error, "\n"; } exit; } // consultar estado dte $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => '', 'DvConsultante' => '', 'RutCompania' => '', 'DvCompania' => '', 'RutReceptor' => '', 'DvReceptor' => '', 'TipoDte' => '', 'FolioDte' => '', 'FechaEmisionDte' => '', 'MontoDte' => '', 'token' => $token]); // si el estado se pudo recuperar se muestra if ($xml !== false) { print_r((array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0]); } // si hubo errores se muestran foreach (\sasco\LibreDTE\Log::readAll() as $error) { echo $error, "\n"; }
/** * Recurso de la API que permite validar el TED (timbre electrónico) * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-19 */ public function _api_verificar_ted_POST() { // verificar si se pasaron credenciales de un usuario $User = $this->Api->getAuthUser(); if (is_string($User)) { $this->Api->send($User, 401); } // obtener TED $TED = base64_decode($this->Api->data); if (strpos($TED, '<?xml') !== 0) { $TED = '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" . $TED; } // crear xml con el ted y obtener datos en arreglo $xml = new \sasco\LibreDTE\XML(); $xml->loadXML($TED); $datos = $xml->toArray(); // verificar firma del ted $DD = $xml->getFlattened('/TED/DD'); $FRMT = $datos['TED']['FRMT']; $pub_key = \sasco\LibreDTE\FirmaElectronica::getFromModulusExponent($datos['TED']['DD']['CAF']['DA']['RSAPK']['M'], $datos['TED']['DD']['CAF']['DA']['RSAPK']['E']); if (openssl_verify($DD, base64_decode($FRMT), $pub_key, OPENSSL_ALGO_SHA1) !== 1) { $this->Api->send('Firma del timbre incorrecta', 500); } // verificar que datos del timbre correspondan con datos del CAF if ($datos['TED']['DD']['RE'] != $datos['TED']['DD']['CAF']['DA']['RE']) { $this->Api->send('RUT del timbre no corresponde con RUT del CAF', 500); } if ($datos['TED']['DD']['TD'] != $datos['TED']['DD']['CAF']['DA']['TD']) { $this->Api->send('Tipo de DTE del timbre no corresponde con tipo de DTE del CAF', 500); } if ($datos['TED']['DD']['F'] < $datos['TED']['DD']['CAF']['DA']['RNG']['D'] or $datos['TED']['DD']['F'] > $datos['TED']['DD']['CAF']['DA']['RNG']['H']) { $this->Api->send('Folio del DTE del timbre fuera del rango del CAF', 500); } // definir si se consultará en certificación o producción define('_LibreDTE_CERTIFICACION_', $datos['TED']['DD']['CAF']['DA']['IDK'] == 100); // crear objeto firma $Firma = new \sasco\LibreDTE\FirmaElectronica(); // obtener token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma); if (!$token) { return $this->Api->send(\sasco\LibreDTE\Log::readAll(), 500); } // verificar estado del DTE con el SII list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID()); list($RutCompania, $DvCompania) = explode('-', $datos['TED']['DD']['RE']); list($RutReceptor, $DvReceptor) = explode('-', $datos['TED']['DD']['RR']); list($a, $m, $d) = explode('-', $datos['TED']['DD']['FE']); $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $RutCompania, 'DvCompania' => $DvCompania, 'RutReceptor' => $RutReceptor, 'DvReceptor' => $DvReceptor, 'TipoDte' => $datos['TED']['DD']['TD'], 'FolioDte' => $datos['TED']['DD']['F'], 'FechaEmisionDte' => $d . $m . $a, 'MontoDte' => $datos['TED']['DD']['MNT'], 'token' => $token]); if ($xml === false) { return $this->Api->send(\sasco\LibreDTE\Log::readAll(), 500); } return (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0]; }
/** * Método que obtiene el estado del DTE * @param Firma objeto que representa la Firma Electrónca * @return Arreglo con el estado del DTE * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-27 */ public function getEstado(\sasco\LibreDTE\FirmaElectronica $Firma) { // solicitar token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($Firma); if (!$token) { return false; } // consultar estado dte list($RutConsultante, $DvConsultante) = explode('-', $Firma->getID()); list($RutCompania, $DvCompania) = explode('-', $this->getEmisor()); list($RutReceptor, $DvReceptor) = explode('-', $this->getReceptor()); list($Y, $m, $d) = explode('-', $this->getFechaEmision()); $xml = \sasco\LibreDTE\Sii::request('QueryEstDte', 'getEstDte', ['RutConsultante' => $RutConsultante, 'DvConsultante' => $DvConsultante, 'RutCompania' => $RutCompania, 'DvCompania' => $DvCompania, 'RutReceptor' => $RutReceptor, 'DvReceptor' => $DvReceptor, 'TipoDte' => $this->getTipo(), 'FolioDte' => $this->getFolio(), 'FechaEmisionDte' => $d . $m . $Y, 'MontoDte' => $this->getMontoTotal(), 'token' => $token]); // si el estado se pudo recuperar se muestra if ($xml === false) { return false; } // entregar estado return (array) $xml->xpath('/SII:RESPUESTA/SII:RESP_HDR')[0]; }