/** * Método que verifica el código de autorización de folios * @return =true si está ok el XML cargado * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-10-30 */ public function check() { // validar firma del SII sobre los folios $firma = $this->getFirma(); $idk = $this->getIDK(); if (!$firma or !$idk) { return false; } $pub_key = \sasco\LibreDTE\Sii::cert($idk); if (!$pub_key or openssl_verify($this->xml->getFlattened('/AUTORIZACION/CAF/DA'), base64_decode($firma), $pub_key) !== 1) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::FOLIOS_ERROR_FIRMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::FOLIOS_ERROR_FIRMA)); return false; } // validar clave privada y pública proporcionada por el SII $private_key = $this->getPrivateKey(); if (!$private_key) { return false; } $plain = md5(date('U')); if (!openssl_private_encrypt($plain, $crypt, $private_key)) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::FOLIOS_ERROR_ENCRIPTAR, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::FOLIOS_ERROR_ENCRIPTAR)); return false; } $public_key = $this->getPublicKey(); if (!$public_key) { return false; } if (!openssl_public_decrypt($crypt, $plain_firmado, $public_key)) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::FOLIOS_ERROR_DESENCRIPTAR, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::FOLIOS_ERROR_DESENCRIPTAR)); return false; } return $plain === $plain_firmado; }
public function caso3() { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIO_USUARIO_INCORRECTO, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIO_USUARIO_INCORRECTO)); \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIO_ERROR_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIO_ERROR_XML, 'No hay XML')); \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::REQUEST_ERROR_BODY, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::REQUEST_ERROR_BODY, 'getToken', 10)); \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIO_NO_AUTENTICADO, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIO_NO_AUTENTICADO)); }
/** * Método que genera el XML para el envío de la respuesta al SII * @param caratula Arreglo con la carátula de la respuesta * @param Firma Objeto con la firma electrónica * @return XML con la respuesta firmada o =false si no se pudo generar o firmar la respuesta * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public function generar() { // si ya se había generado se entrega directamente if ($this->xml_data) { return $this->xml_data; } // si no hay respuestas para generar entregar falso if (!isset($this->recibos[0])) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIORECIBOS_FALTA_RECIBO, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIORECIBOS_FALTA_RECIBO)); return false; } // si no hay carátula error if (!$this->caratula) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIORECIBOS_FALTA_CARATULA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIORECIBOS_FALTA_CARATULA)); return false; } // crear arreglo de lo que se enviará $xmlEnvio = (new \sasco\LibreDTE\XML())->generate(['EnvioRecibos' => ['@attributes' => ['xmlns' => 'http://www.sii.cl/SiiDte', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.sii.cl/SiiDte EnvioRecibos_v10.xsd', 'version' => '1.0'], 'SetRecibos' => ['@attributes' => ['ID' => 'SetDteRecibidos'], 'Caratula' => $this->caratula, 'Recibo' => null]]])->saveXML(); // generar cada recibo y firmar $Recibos = []; foreach ($this->recibos as &$recibo) { $recibo_xml = new \sasco\LibreDTE\XML(); $recibo_xml->generate(['Recibo' => $recibo]); $recibo_firmado = $this->Firma ? $this->Firma->signXML($recibo_xml->saveXML(), '#' . $recibo['DocumentoRecibo']['@attributes']['ID'], 'DocumentoRecibo', true) : $recibo_xml->saveXML(); $Recibos[] = trim(str_replace('<?xml version="1.0" encoding="ISO-8859-1"?>', '', $recibo_firmado)); } // firmar XML del envío y entregar $xml = str_replace('<Recibo/>', implode("\n", $Recibos), $xmlEnvio); $this->xml_data = $this->Firma ? $this->Firma->signXML($xml, '#SetDteRecibidos', 'SetRecibos', true) : $xml; return $this->xml_data; }
/** * Método que realiza el envío del documento al SII * @return Track ID del envío o =false si hubo algún problema al enviar el documento * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-12-14 */ public function enviar() { // generar XML que se enviará if (!$this->xml_data) { $this->xml_data = $this->generar(); } if (!$this->xml_data) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_GENERAR_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_GENERAR_XML, substr(get_class($this), strrpos(get_class($this), '\\') + 1))); return false; } // validar schema del documento antes de enviar if (!$this->schemaValidate()) { return false; } // solicitar token $token = \sasco\LibreDTE\Sii\Autenticacion::getToken($this->Firma); if (!$token) { return false; } // enviar DTE $envia = $this->caratula['RutEnvia']; $emisor = !empty($this->caratula['RutEmisor']) ? $this->caratula['RutEmisor'] : $this->caratula['RutEmisorLibro']; $result = \sasco\LibreDTE\Sii::enviar($envia, $emisor, $this->xml_data, $token); if ($result === false) { return false; } if (!is_numeric((string) $result->TRACKID)) { return false; } return (int) (string) $result->TRACKID; }
/** * Método que valida el XML que se genera para la respuesta del envío * @return =true si el schema del documento del envío es válido, =null si no se pudo determinar * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public function schemaValidate() { if (!$this->xml_data) { return null; } $xsd = dirname(dirname(dirname(__FILE__))) . '/schemas/EnvioRecibos_v10.xsd'; $this->xml = new \sasco\LibreDTE\XML(); $this->xml->loadXML($this->xml_data); $result = $this->xml->schemaValidate($xsd); if (!$result) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIORECIBOS_ERROR_SCHEMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIORECIBOS_ERROR_SCHEMA, implode("\n", libxml_get_errors()))); } return $result; }
/** * 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]; }
/** * Método que realiza la firma del DTE * @param Firma objeto que representa la Firma Electrónca * @return =true si el DTE pudo ser fimado o =false si no se pudo firmar * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public function firmar(\sasco\LibreDTE\FirmaElectronica $Firma) { $parent = $this->xml->getElementsByTagName($this->tipo_general)->item(0); $this->xml->generate(['TmstFirma' => $this->timestamp], $parent); $xml = $Firma->signXML($this->xml->saveXML(), '#' . $this->id, $this->tipo_general); if (!$xml) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::DTE_ERROR_FIRMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::DTE_ERROR_FIRMA, $this->getID())); return false; } $this->loadXML($xml); return true; }
/** * Método que valida el XML que se genera para la respuesta del envío * @return =true si el schema del documento del envío es válido, =null si no se pudo determinar * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-18 */ public function schemaValidate() { if (!$this->xml_data) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::LIBROCOMPRAVENTA_FALTA_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::LIBROCOMPRAVENTA_FALTA_XML)); return null; } $xsd = dirname(dirname(dirname(__FILE__))) . '/schemas/LibroCVS_v10.xsd'; $this->xml = new \sasco\LibreDTE\XML(); $this->xml->loadXML($this->xml_data); $result = $this->xml->schemaValidate($xsd); if (!$result) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::LIBROCOMPRAVENTA_ERROR_SCHEMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::LIBROCOMPRAVENTA_ERROR_SCHEMA, implode("\n", $this->xml->getErrors()))); } return $result; }
/** * Método que valida el XML del documento * @return =true si el schema del documento del envío es válido, =null si no se pudo determinar * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-12-14 */ public function schemaValidate() { if (!$this->xml_data) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::DOCUMENTO_FALTA_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::DOCUMENTO_FALTA_XML, substr(get_class($this), strrpos(get_class($this), '\\') + 1))); return null; } $this->xml = new \sasco\LibreDTE\XML(); $this->xml->loadXML($this->xml_data); $xsd = dirname(dirname(dirname(dirname(__FILE__)))) . '/schemas/' . $this->xml->getSchema(); if (!is_readable($xsd)) { return null; } $result = $this->xml->schemaValidate($xsd); if (!$result) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_SCHEMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::DOCUMENTO_ERROR_SCHEMA, substr(get_class($this), strrpos(get_class($this), '\\') + 1), implode("\n", $this->xml->getErrors()))); } return $result; }
/** * Método que valida el XML que se genera para la respuesta del envío * @return =true si el schema del documento del envío es válido, =null si no se pudo determinar * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-18 */ public function schemaValidate() { if (!$this->xml_data) { return null; } $xsd = dirname(dirname(dirname(__FILE__))) . '/schemas/RespuestaEnvioDTE_v10.xsd'; $this->xml = new \sasco\LibreDTE\XML(); $this->xml->loadXML($this->xml_data); $result = $this->xml->schemaValidate($xsd); if (!$result) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::RESPUESTAENVIO_ERROR_SCHEMA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::RESPUESTAENVIO_ERROR_SCHEMA, implode("\n", $this->xml->getErrors()))); } return $result; }
/** * Método que entrega el arreglo con los objetos DTE del envío * @return Arreglo de objetos DTE * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public function getDocumentos() { // si no hay documentos se deben crear if (!$this->dtes) { // si no hay XML no se pueden crear los documentos if (!$this->xml) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::ENVIODTE_GETDOCUMENTOS_FALTA_XML, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::ENVIODTE_GETDOCUMENTOS_FALTA_XML)); return false; } // crear documentos a partir del XML $DTEs = $this->xml->getElementsByTagName('DTE'); foreach ($DTEs as $nodo_dte) { $this->dtes[] = new Dte($nodo_dte->C14N(), false); // cargar DTE sin normalizar } } return $this->dtes; }
/** * Método que genera el XML para el envío de la respuesta al SII * @param caratula Arreglo con la carátula de la respuesta * @param Firma Objeto con la firma electrónica * @return XML con la respuesta firmada o =false si no se pudo generar o firmar la respuesta * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) * @version 2015-09-17 */ public function generar() { // si ya se había generado se entrega directamente if ($this->xml_data) { return $this->xml_data; } // si no hay respuestas para generar entregar falso if (!isset($this->respuesta_envios[0]) and !isset($this->respuesta_documentos[0])) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::RESPUESTAENVIO_FALTA_RESPUESTA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::RESPUESTAENVIO_FALTA_RESPUESTA)); return false; } // si no hay carátula error if (!$this->caratula) { \sasco\LibreDTE\Log::write(\sasco\LibreDTE\Estado::RESPUESTAENVIO_FALTA_CARATULA, \sasco\LibreDTE\Estado::get(\sasco\LibreDTE\Estado::RESPUESTAENVIO_FALTA_CARATULA)); return false; } // crear arreglo de lo que se enviará $arreglo = ['RespuestaDTE' => ['@attributes' => ['xmlns' => 'http://www.sii.cl/SiiDte', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.sii.cl/SiiDte RespuestaEnvioDTE_v10.xsd', 'version' => '1.0'], 'Resultado' => ['@attributes' => ['ID' => 'ResultadoEnvio'], 'Caratula' => $this->caratula]]]; if (isset($this->respuesta_envios[0])) { $arreglo['RespuestaDTE']['Resultado']['RecepcionEnvio'] = $this->respuesta_envios; } else { $arreglo['RespuestaDTE']['Resultado']['ResultadoDTE'] = $this->respuesta_documentos; } // generar XML del envío $xmlEnvio = (new \sasco\LibreDTE\XML())->generate($arreglo)->saveXML(); // firmar XML del envío y entregar $this->xml_data = $this->Firma ? $this->Firma->signXML($xmlEnvio, '#ResultadoEnvio', 'Resultado', true) : $xmlEnvio; return $this->xml_data; }