';
echo 'CERTIFICADO DEL SELLO DIGITAL';
echo '';
echo '';
echo $certificado;
echo '
';
#== 11.12 Se continua con la integración de nodos ===========================
$root->setAttribute("Sello",$sello);
$root->setAttribute("Certificado",$certificado); # Certificado.
#== Fin de la integración de nodos =========================================
$NomArchCFDI = $SendaCFDI."PreCFDI-40_Factura_".$NoFac.".xml";
#=== 11.12 Se guarda el archivo .XML antes de ser timbrado =======================
$cfdi = $xml->saveXML();
$xml->formatOutput = true;
$xml->save($NomArchCFDI); // Guarda el archivo .XML (sin timbrar) en el directorio predeterminado.
unset($xml);
#=== 11.13 Se dan permisos de escritura al archivo .xml. =========================
chmod($NomArchCFDI, 0777);
##### FIN DE LA CREACIÓN DEL ARCHIVO .XML ANTES DE SER TIMBRADO ####################################################
### 12. PROCESO DE TIMBRADO ########################################################
require_once 'sw-sdk-php/SWSDK.php';
use SWServices\Authentication\AuthenticationService as Authentication;
use SWServices\Stamp\StampService as StampService;
use SWServices\Stamp\EmisionTimbrado as EmisionTimbrado;
use SWServices\Validation\ValidarXML as ValidarXML;
use SWServices\Validation\ValidaLco as ValidaLco;
use SWServices\Validation\ValidaLrfc as ValidaLrfc;
use SWServices\JSonIssuer\JsonEmisionTimbrado as JsonEmisionTimbrado;
use SWServices\Cancelation\CancelationService as CancelationService;
use SWServices\AccountBalance\AccountBalanceService as AccountBalanceService;
use SWServices\SatQuery\ServicioConsultaSAT as ConsultaCfdiSAT;
use SWServices\Csd\CsdService as CsdService;
use SWServices\Taxpayer\TaxpayerService as ValidarListaNegra;
header('Content-type: text/plain');
$params = array(
"url" => "http://services.test.sw.com.mx",
"user" => "jsalazar@wbox.mx",
"password" => "BIZBOX+SW+"
//"url"=>"http://services.sw.com.mx",
//"user"=>"jsalazar@waydata.cloud",
//"password"=> "temporal1021"
);
echo "\n\n------------Token---------------------\n\n";
try{
Authentication::auth($params);
$result = Authentication::Token();
if($result->status == "success") {
echo $result->data->token;
}
else {
echo $result->message;
}
}
catch(Exception $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
echo "\n\n------------Token---------------------\n\n";
$xml = file_get_contents($NomArchCFDI);
echo "\n\n--------------- Timbrado ------------------\n\n";
try {
StampService::Set($params);
$resultadoStamp = StampService::StampV4($xml);
var_dump($resultadoStamp);
}
catch(Exception $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
echo "\n\n-----------------Validación de XML ----------------\n\n";
die();
## FIN DEL PROCESO DE TIMBRADO #################################################
## 13. PROCESOS POSTERIORES AL TIMBRADO ########################################
#== 13.1 Se asigna la respuesta del servidor a una variable de tipo DOM ====
$VarXML = new DOMDocument();
$VarXML->loadXML($RespServ);
#== 13.2 Se graba la respuesta del servidor a un archivo .xml
// Descomentar si se desea crear el archivo XML con la respuesta del servidor.
// $VarXML->save($SendaCFDI."RespServ_Factura_".$NoFac.".xml");
// chmod($SendaCFDI."RespServ_Factura_".$NoFac.".xml", 0777);
echo "
";
#== 13.3 Se asigna el contenido del tag "xml" a una variable ===============
$RespServ = $VarXML->getElementsByTagName('xml');
#== 13.4 Se obtiene el valor del nodo ======================================
$valor_del_nodo = "";
foreach($RespServ as $Nodo){
$valor_del_nodo = $Nodo->nodeValue;
}
#== Si el nodo contiene datos se realizan los siguientes procesos ======
if($valor_del_nodo != ""){
// unlink($SendaCFDI."xlst_".$NoFac.".xml"); <-- Puede ser descomentado para eliminar el archivo .XML sin timbrar.
#== 13.5 Se muestra el .XML ya timbrado (CFDI V 3.2), opcional a mostrar =====
echo '';
echo 'FACTURA .XML (CFDI) YA TIMBRADA';
echo '
';
echo '';
echo htmlspecialchars($Nodo->nodeValue);
echo '
';
#=== 13.6 Guardando el CFDI en archivo .XML ============================
$NomArchXML = "CFDI-40_Factura_".$NoFac.".xml";
$NomArchPDF = "CFDI-40_Factura_".$NoFac.".pdf";
$xmlt = new DOMDocument();
$xmlt->loadXML($valor_del_nodo);
$xmlt->save($SendaCFDI.$NomArchXML);
chmod($SendaCFDI.$NomArchXML, 0777);
#== 13.7 Procesos para extraer datos del Timbre Fiscal del CFDI =========
$docXML = new DOMDocument();
$docXML->load($SendaCFDI."CFDI-40_Factura_".$NoFac.".xml");
$params = $docXML->getElementsByTagName("Comprobante");
foreach ($params as $param) {
$VersionCFDI = $param->getAttribute("Version");
$Total = $param->getAttribute('Total');
$Serie = $param->getAttribute('Serie');
$Folio = $param->getAttribute('Folio');
}
$SerieFolio = $Serie.$Folio;
$comprobante = $docXML->getElementsByTagName("TimbreFiscalDigital");
#== 13.8 Se obtienen contenidos de los atributos y se asignan a variables para ser mostrados =======
foreach($comprobante as $timFis){
$version_timbre = $timFis->getAttribute('Version');
$sello_SAT = $timFis->getAttribute('SelloSAT');
$cert_SAT = $timFis->getAttribute('NoCertificadoSAT');
$sello_CFD = $timFis->getAttribute('SelloCFD');
$tim_fecha = $timFis->getAttribute('FechaTimbrado');
$tim_uuid = $timFis->getAttribute('UUID');
echo '';
echo 'Serie y Folio: '.$SerieFolio.'
';
echo 'Versión de CFDI: '.$VersionCFDI.'
';
echo 'Versión de timbre: '.$version_timbre.'
';
echo 'Sello del SAT: '.$sello_SAT.'
';
echo 'Certificado del SAT: '.$cert_SAT.'
';
echo 'Sello del CFDI: '.$sello_CFD.'
';
echo 'Fecha de timbrado: '.$tim_fecha.'
';
echo 'Folio fiscal: '.$tim_uuid.'
';
echo 'Importe total: '.$Total.'
';
echo '
';
}
$params = $docXML->getElementsByTagName('Emisor');
foreach ($params as $param) {
$Emisor_RFC = $param->getAttribute('Rfc');
}
$params = $docXML->getElementsByTagName('Receptor');
foreach ($params as $param) {
$Receptor_RFC = $param->getAttribute('Rfc');
}
$params = $docXML->getElementsByTagName('Comprobante');
foreach ($params as $param) {
$total = $param->getAttribute('Total');
}
#== 13.9 Se crea el archivo .PNG con codigo bidimensional =================================
$filename = "archs_graf/Img_".$tim_uuid.".png";
$CadImpTot = ProcesImpTot($total);
$Cadena = "?re=".$Emisor_RFC."&rr=".$Receptor_RFC."&tt=".$CadImpTot."&id=".$tim_uuid;
QRcode::png($Cadena, $filename, 'H', 3, 2);
chmod($filename, 0777);
echo '';
echo 'GRÁFICO "QR" RESULTANTE.';
echo '
';
echo '
';
#== 13.10 Se crea código HTML para mostrar opciones al usuario.
?>
TODO supply a title
getElementsByTagName('CodigoError');
foreach($codigoError as $NodoStatus){
$valorNod = $NodoStatus->nodeValue;
}
echo '';
echo 'CÓDIGO DE ERROR.';
echo '
';
echo '';
echo $valorNod;
echo '
';
}
##### FIN DE PROCEDIMIENTOS ####################################################
### 14. FUNCIONES DEL MÓDULO ###################################################
# 14.1 Función que integra los nodos al archivo .XML y forma la "Cadena original".
function cargaAtt(&$nodo, $attr){
global $xml, $cadena_original;
$quitar = array('sello'=>1,'noCertificado'=>1,'certificado'=>1);
foreach ($attr as $key => $val){
$val = preg_replace('/\s\s+/', ' ', $val);
$val = trim($val);
if (strlen($val)>0){
$val = str_replace("|","/",$val);
$nodo->setAttribute($key,$val);
if (!isset($quitar[$key]))
if (substr($key,0,3) != "xml" &&
substr($key,0,4) != "xsi:")
$cadena_original .= $val . "|";
}
}
}
# 14.2 Función que integra los nodos al archivo .XML sin integrar a la "Cadena original".
function cargaAttSinIntACad(&$nodo, $attr){
global $xml;
$quitar = array('sello'=>1,'noCertificado'=>1,'certificado'=>1);
foreach ($attr as $key => $val){
$val = preg_replace('/\s\s+/', ' ', $val);
$val = trim($val);
if (strlen($val)>0){
$val = str_replace("|","/",$val);
$nodo->setAttribute($key,$val);
if (!isset($quitar[$key]))
if (substr($key,0,3) != "xml" &&
substr($key,0,4) != "xsi:");
}
}
}
# 14.3 Funciónes que da formato al "Importe total" como lo requiere el SAT para ser integrado al código QR.
function ProcesImpTot($ImpTot){
$ImpTot = number_format($ImpTot, 4); // <== Se agregó el 30 de abril de 2017.
$ArrayImpTot = explode(".", $ImpTot);
$NumEnt = $ArrayImpTot[0];
$NumDec = ProcesDecFac($ArrayImpTot[1]);
return $NumEnt.".".$NumDec;
}
function ProcesDecFac($Num){
$FolDec = "";
if ($Num < 10){$FolDec = "00000".$Num;}
if ($Num > 9 and $Num < 100){$FolDec = $Num."0000";}
if ($Num > 99 and $Num < 1000){$FolDec = $Num."000";}
if ($Num > 999 and $Num < 10000){$FolDec = $Num."00";}
if ($Num > 9999 and $Num < 100000){$FolDec = $Num."0";}
return $FolDec;
}