Ver Mensaje Individual
  #1320  
Antiguo 17-02-2024
ermendalenda ermendalenda is offline
Miembro
 
Registrado: ago 2021
Posts: 865
Reputación: 3
ermendalenda Va por buen camino
codigo ejemplo php encapsulamiento y envio

Aquí te dejo un encapsulamiento y envio, totalmente funcional para face y faceb2b en entornos de prueba y producción, si aprendes como funciona lo puedes modificar para cualquier definición que hagan teniendo en cuenta que yo le paso el path donde tengo el fichero y los datos por curl de esta forma:
Código:
curl --connect-timeout 10 --insecure -A "FacturaePHP/1.7.1" -H "SOAPAction: https://webservice.face.gob.es#enviarFactura" --data "@C:\xml\Facturare_FICTICIO_fichero.xml" --cert-type P12 --cert c:\....\fichero_certificado.pfx:clave -H "Content-Type: text/xml" https://se-face-webservice.redsara.es/facturasspp2 -o C:\respuestas\Respuesta_face_o.html -D C:\respuestas\Respuesta_face_D.html
Código PHP:
 <?php 
//ASIGNA EL ENTORNO QUE VAMOS A USAR  $endpoint como variable de uso GLOBALS
//************************************
//*************  FACE   **************
//************************************
//  ENTORNO DE PRODUCCION
//$endpoint= "https://webservice.face.gob.es/facturasspp2" :
      
//  ENTORNO DE PRUEBAS
$endpoint"https://se-face-webservice.redsara.es/facturasspp2";      
//************************************


//************************************
//************  FACEB2B   ************
//************************************
//  ENTORNO DE PRODUCCION
//$endpoint= "https://ws.faceb2b.gob.es/sv1/invoice" :

//  ENTORNO DE PRUEBAS
//$endpoint= "https://se-ws-faceb2b.redsara.es/sv1/invoice";
//************************************





//**Asigna a $datos la variable de la llamada curl (fichero) que contiene 2 variables separadas por signo "="
$datos $_GET['fichero'];

//***Asigno $datos a un array ya que contiene 2 campos 
$varias=explode("=",$datos);
//***El primer campo del array contiene el nombre del fichero del certificado

// **EJEMPLO PFX $dir_cert = ($_SERVER['DOCUMENT_ROOT'].'/certs/Certificado.pfx' );
//variable de uso GLOBALS
$dir_cert = ($_SERVER['DOCUMENT_ROOT'].'/certs/'.$varias[1] );

//***El segundo campo del array contiene el password del certificado
//variable de uso GLOBALS
$clave=$varias[2];

//variable de uso GLOBALS
$filename=$varias[3];
$NombreFichero=$varias[3];

//variable de uso GLOBALS
$xml2=file_get_contents("php://input");


//variable de uso GLOBALS
$version "1.7.1";

// Cargamos la factura en una instancia de FacturaeFile

//$invoice2 = new InvoiceTest();

//$invoice2->EnviarFactura($xml2);
//*****************************
//****** ENVIAR POR FACE ******
//*****************************
    
$invoice = new FacturaeFile();
    
$invoice=$GLOBALS["xml2"];


    
    
$nulo=null;
    
$face = new FaceTrait();

    
$res =$face->sendInvoice("verifactu@gmail.com"$invoice);


//*****************************
//***** ENVIAR POR FACEB2B ****
//*****************************

//    $invoice = new FacturaeFile();
//    $invoice=$GLOBALS["xml2"];
//    $nulo=null;
//    $face = new FaceB2BTrait();

//    $res =$face->sendInvoice("verifactu@gmail.com", $invoice);




/**
 * Gets both public and private keys from a PKCS#12 certificate store or a PEM
 * file (X.509 certificate).
 */
class KeyPairReader {
  private 
$publicChain = [];
  private 
$privateKey null;


  
/**
   * Get public certificates chain from child to top CA
   * @return string[] Array of PEM strings
   */
  
public function getPublicChain() {
    return 
$this->publicChain;
  }


  
/**
   * Get public key
   * @return string|null Certificate for the Public Key in PEM format
   */
  
public function getPublicKey() {
    return empty(
$this->publicChain) ? null $this->publicChain[0];
  }


  
/**
   * Get private key
   * @return \OpenSSLAsymmetricKey|resource|null Decrypted Private Key
   */
  
public function getPrivateKey() {
    return 
$this->privateKey;
  }


  
/**
   * KeyPairReader constructor
   *
   * @param string      $publicPath  Path to public key in PEM or PKCS#12 file
   * @param string|null $privatePath Path to private key (null for PKCS#12)
   * @param string      $passphrase  Private key passphrase
   */
  
public function __construct($publicPath$privatePath=null$passphrase="") {
    if (
is_null($privatePath)) {
      
$this->readPkcs12($GLOBALS["dir_cert"], $passphrase);
    } else {
      
$this->readX509($GLOBALS["dir_cert"], $privatePath$passphrase);
    }
  }


  
/**
   * Read a X.509 certificate and PEM encoded private key
   *
   * @param string $publicPath  Path to public key PEM file
   * @param string $privatePath Path to private key PEM file
   * @param string $passphrase  Private key passphrase
   */
  
private function readX509($publicPath$privatePath$passphrase) {
    if (!
is_file($GLOBALS["dir_cert"]) || !is_file($privatePath)) return;

    
// Validate and normalize public key
    
$publicKey openssl_x509_read(file_get_contents($GLOBALS["dir_cert"]));
    if (empty(
$publicKey)) return;
    
openssl_x509_export($publicKey$publicKeyPem);
    
$this->publicChain = array($publicKeyPem);
    
    
// Decrypt private key
    
$this->privateKey openssl_pkey_get_private(file_get_contents($privatePath), $passphrase);
  }


  
/**
   * Read a PKCS#12 Certificate Store
   *
   * @param string $certPath   The certificate store file name
   * @param string $passphrase Password for unlocking the PKCS#12 file
   */
  
private function readPkcs12($certPath$passphrase) {
    if (!
is_file($certPath)) return;
    if (
openssl_pkcs12_read(file_get_contents($certPath), $store$passphrase)) {
      
$this->publicChain = array($store['cert']);
      if (!empty(
$store['extracerts'])) {
        
$this->publicChain array_merge($this->publicChain$store['extracerts']);
      }
      
$this->privateKey openssl_pkey_get_private($store['pkey']);
      unset(
$store);
    }
  }

}
class 
XmlTools {

  
/**
   * Escape XML value
   * @param  string $value Input value
   * @return string        Escaped input
   */
  
public function escape($value) {
    return 
htmlspecialchars($valueENT_XML1'UTF-8');
  }


  
/**
   * Generate random ID
   *
   * This method is used for generating random IDs required when signing the
   * document.
   *
   * @return int Random number
   */
  
public function randomId() {
    if (
function_exists('random_int')) return random_int(0x100000000x7FFFFFFF);
    return 
rand(100000999999);
  }


  
/**
   * Inject namespaces
   * @param  string          $xml   Input XML
   * @param  string|string[] $newNs Namespaces
   * @return string                 Canonicalized XML with new namespaces
   */
  
public function injectNamespaces($xml$newNs) {
    if (!
is_array($newNs)) $newNs = array($newNs);
    
$xml explode(">"$xml2);
    
$oldNs explode(" "$xml[0]);
    
$elementName array_shift($oldNs);

    
// Combine and sort namespaces
    
$xmlns = array();
    
$attributes = array();
    foreach (
array_merge($oldNs$newNs) as $name) {
      if (
strpos($name'xmlns:') === 0) {
        
$xmlns[] = $name;
      } else {
        
$attributes[] = $name;
      }
    }
    
sort($xmlns);
    
sort($attributes);
    
$ns array_merge($xmlns$attributes);

    
// Generate new XML element
    
$xml $elementName " " implode(' '$ns) . ">" $xml[1];
    return 
$xml;
  }


  
/**
   * To Base64
   * @param  string  $bytes  Input
   * @param  boolean $pretty Pretty Base64 response
   * @return string          Base64 response
   */
  
public function toBase64($bytes$pretty=false) {
    
$res base64_encode($bytes);
    return 
$pretty $this->prettify($res) : $res;
  }


  
/**
   * Prettify
   * @param  string $input Input string
   * @return string        Multi-line resposne
   */
  
private function prettify($input) {
    return 
chunk_split($input76"\n");
  }


  
/**
   * Get digest in SHA-512
   * @param  string  $input  Input string
   * @param  boolean $pretty Pretty Base64 response
   * @return string          Digest
   */
  
public function getDigest($input$pretty=false) {
    return 
$this->toBase64(hash("sha512"$inputtrue), $pretty);
  }


  
/**
   * Get certificate
   * @param  string  $pem    Certificate for the public key in PEM format
   * @param  boolean $pretty Pretty Base64 response
   * @return string          Base64 Certificate
   */
  
public function getCert($pem$pretty=true) {
    
$pem str_replace("-----BEGIN CERTIFICATE-----"""$pem);
    
$pem str_replace("-----END CERTIFICATE-----"""$pem);
    
$pem str_replace("\n"""str_replace("\r"""$pem));
    if (
$pretty$pem $this->prettify($pem);
    return 
$pem;
  }




  
/**
   * Get signature in SHA-1
   * @param  string  $payload    Data to sign
   * @param  string  $privateKey Private Key
   * @param  boolean $pretty     Pretty Base64 response
   * @return string              Base64 Signature
   */
  
public function getSignature($payload$privateKey$pretty=true) {
    
openssl_sign($payload$signature$privateKey);
    return 
$this->toBase64($signature$pretty);
  }


}

Class 
Faceb2bTrait {
  
/**
   * Get web namespace
   * @return string Web namespace
   */
  
protected function getWebNamespace() {
    return 
"https://webservice.faceb2b.gob.es";
  }


  
/**
   * Send invoice
   * @param  FacturaeFile      $invoice    Invoice
   * @param  FacturaeFile|null $attachment Optional attachment
   * @return SimpleXMLElement              Response
   */
  
public function sendInvoice($invoice$attachment=null) {
    
$tools = new XmlTools();
    
$req '<web:SendInvoice><request>';

    
$req .= '<invoiceFile>' .
        
'<content>' $tools->toBase64($GLOBALS["xml2"]) . '</content>' .
        
'<name>' $GLOBALS["NombreFichero"] . '</name>' .
        
'<mime>text/xml</mime>' // Mandatory MIME type
      
'</invoiceFile>';

    if (!
is_null($attachment)) {
      
$req .= '<attachmentFile>' .
          
'<content>' $tools->toBase64($attachment->getData()) . '</content>' .
          
'<name>' $attachment->getFilename() . '</name>' .
          
'<mime>' $attachment->getMimeType() . '</mime>' .
        
'</attachmentFile>';
    }

    
$req .= '</request></web:SendInvoice>';
    
//$soap=new SoapClient1();
$soap = new FacturaeFile();
      
    return 
$soap->request($req);
  }


  
/**
   * Get invoice details
   * @param  string           $regId Registry number
   * @return SimpleXMLElement        Response
   */
  
public function getInvoiceDetails($regId) {
    return 
$this->request('<web:GetInvoiceDetails><request>' .
      
'<registryNumber>' $regId '</registryNumber>' .
      
'</request></web:GetInvoiceDetails>');
  }


  
/**
   * Request invoice cancellation
   * @param  string           $regId   Registry number
   * @param  string           $reason  Reason code
   * @param  string|null      $comment Optional comments
   * @return SimpleXMLElement          Response
   */
  
public function requestInvoiceCancellation($regId$reason$comment=null) {
    
$req '<web:RequestInvoiceCancellation><request>';
    
$req .= '<registryNumber>' $regId '</registryNumber>';
    
$req .= '<reason>' $reason '</reason>';
    if (!
is_null($comment)) {
      
$req .= '<comment>' $comment '</comment>';
    }
    
$req .= '</request></web:RequestInvoiceCancellation>';

    return 
$this->request($req);
  }


  
/**
   * Get registered invoices
   * @param  string|null      $receivingUnit Receiving unit code
   * @return SimpleXMLElement                Response
   */
  
public function getRegisteredInvoices($receivingUnit=null) {
    
$req '<web:GetRegisteredInvoices><request>';
    if (
is_null($receivingUnit)) {
      
$req .= '<receivingUnit>' $receivingUnit '</receivingUnit>';
    }
    
$req .= '</request></web:GetRegisteredInvoices>';
    return 
$this->request($req);
  }


  
/**
   * Get invoice cancellations
   * @return SimpleXMLElement Response
   */
  
public function getInvoiceCancellations() {
    return 
$this->request('<web:GetInvoiceCancellations><request>' .
      
'</request></web:GetInvoiceCancellations>');
  }


  
/**
   * Download invoice
   * @param  string           $regId    Registry number
   * @param  boolean          $validate Validate invoice
   * @return SimpleXMLElement           Response
   */
  
public function downloadInvoice($regId$validate=true) {
    
$req '<web:DownloadInvoice><request>';
    
$req .= '<registryNumber>' $regId '</registryNumber>';
    if (
$validate) {
      
$req .= '<signatureValidationMode>validate</signatureValidationMode>';
    }
    
$req .= '</request></web:DownloadInvoice>';
    return 
$this->request($req);
  }


  
/**
   * Confirm invoice download
   * @param  string           $regId   Registry number
   * @return SimpleXMLElement          Response
   */
  
public function confirmInvoiceDownload($regId) {
    return 
$this->request('<web:ConfirmInvoiceDownload><request>' .
      
'<registryNumber>' $regId '</registryNumber>' .
      
'</request></web:ConfirmInvoiceDownload>');
  }


  
/**
   * Reject invoice
   * @param  string           $regId   Registry number
   * @param  string           $reason  Reason code
   * @param  string|null      $comment Optional comments
   * @return SimpleXMLElement          Response
   */
  
public function rejectInvoice($regId$reason$comment=null) {
    
$req '<web:RejectInvoice><request>';
    
$req .= '<registryNumber>' $regId '</registryNumber>';
    
$req .= '<reason>' $reason '</reason>';
    if (!
is_null($comment)) {
      
$req .= '<comment>' $comment '</comment>';
    }
    
$req .= '</request></web:RejectInvoice>';
    return 
$this->request($req);
  }


  
/**
   * Mark invoice as paid
   * @param  string           $regId   Registry number
   * @return SimpleXMLElement          Response
   */
  
public function markInvoiceAsPaid($regId) {
    return 
$this->request('<web:MarkInvoiceAsPaid><request>' .
      
'<registryNumber>' $regId '</registryNumber>' .
      
'</request></web:MarkInvoiceAsPaid>');
  }


  
/**
   * Accept invoice cancellation
   * @param  string           $regId   Registry number
   * @return SimpleXMLElement          Response
   */
  
public function acceptInvoiceCancellation($regId) {
    return 
$this->request('<web:AcceptInvoiceCancellation><request>' .
      
'<registryNumber>' $regId '</registryNumber>' .
      
'</request></web:AcceptInvoiceCancellation>');
  }


  
/**
   * Reject invoice cancellation
   * @param  string           $regId   Registry number
   * @param  string           $comment Comment
   * @return SimpleXMLElement          Response
   */
  
public function rejectInvoiceCancellation($regId$comment) {
    return 
$this->request('<web:RejectInvoiceCancellation><request>' .
      
'<registryNumber>' $regId '</registryNumber>' .
      
'<comment>' $comment '</comment>' .
      
'</request></web:RejectInvoiceCancellation>');
  }



  
/**
   * Get codes
   * @param  string           $type Code type
   * @return SimpleXMLElement       Response
   */
  
public function getCodes($type="") {
    return 
$this->request('<web:GetCodes><request>' .
      
'<codeType>' $type '</codeType>' .
      
'</request></web:GetCodes>');
  }
}
//trait FaceTrait {
class FaceTrait {
  
/**
   * Get web namespace
   * @return string Web namespace
   */
  
protected function getWebNamespace() {
    return 
"https://webservice.face.gob.es";
  }
  
/**
   * Send invoice
   * @param  string           $email       Email address
   * @param  FacturaeFile     $invoice     Invoice
   * @param  FacturaeFile[]   $attachments Attachments
   * @return SimpleXMLElement              Response
   */
  
public function sendInvoice($email$invoice$attachments=array()) {
    
$tools = new XmlTools();
    
$req '<web:enviarFactura><request>';
    
$req .= '<correo>' $email '</correo>';
    
$req .= '<factura>' .
        
'<factura>' $tools->toBase64($GLOBALS["xml2"]) . '</factura>' .
        
'<nombre>' $GLOBALS["NombreFichero"] . '</nombre>' .
        
'<mime>application/xml</mime>' // Mandatory MIME type
      
'</factura>';
    
$req .= '<anexos>';
    foreach (
$attachments as $file) {
      
$req .= '<anexo>' .
          
'<anexo>' $tools->toBase64($file->getData()) . '</anexo>' .
          
'<nombre>' $file->getFilename() . '</nombre>' .
          
'<mime>' $file->getMimeType() . '</mime>' .
        
'</anexo>';
    }
    
$req .= '</anexos>';
    
$req .= '</request></web:enviarFactura>';

//echo "*** Esta es la variable de envio req: ";
//echo $req;
//echo " *** FIN VARIABLE REQ *** ";


    //$soap=new SoapClient1();
    
$soap = new FacturaeFile();
      
    
$ok=$soap->request($req);
  }


  
/**
   * Cancel invoice 
   * @param  string           $regId  Invoice register ID
   * @param  string           $reason Cancelation reason
   * @return SimpleXMLElement         Response
   */
  
public function cancelInvoice($regId$reason) {
    return 
$this->request('<web:anularFactura>' .
      
'<numeroRegistro>' $regId '</numeroRegistro>' .
      
'<motivo>' $reason '</motivo>' .
      
'</web:anularFactura>');
  }

  
/**
   * Get invoice status codes
   * @return SimpleXMLElement Response
   */
  
public function getStatus() {
    return 
$this->request('<web:consultarEstados></web:consultarEstados>');
  }


  
/**
   * Get administrations
   * @param  boolean          $onlyTopLevel Get only top level administrations
   * @return SimpleXMLElement               Response
   */
  
public function getAdministrations($onlyTopLevel=true) {
    
$tag "consultarAdministraciones";
    if (!
$onlyTopLevel$tag .= "Repositorio";
    return 
$this->request("<web:$tag></web:$tag>");
  }


  
/**
   * Get units
   * @param  string|null      $code Administration code
   * @return SimpleXMLElement       Response
   */
  
public function getUnits($code=null) {
    if (
is_null($code)) return $this->request('<web:consultarUnidades></web:consultarUnidades>');
    return 
$this->request('<web:consultarUnidadesPorAdministracion>' .
      
'<codigoDir>' $code '</codigoDir>' .
      
'</web:consultarUnidadesPorAdministracion>');
  }


  
/**
   * Get NIFs
   * @param  string|null      $code Administration code
   * @return SimpleXMLElement       Response
   */
  
public function getNifs($code=null) {
    if (
is_null($code)) return $this->request('<web:consultarNIFs></web:consultarNIFs>');
    return 
$this->request('<web:consultarNIFsPorAdministracion>' .
      
'<codigoDir>' $code '</codigoDir>' .
      
'</web:consultarNIFsPorAdministracion>');
  }


  
/**
   * Get invoice
   * @param  string|string[]  $regId Invoice register ID(s)
   * @return SimpleXMLElement        Response
   */
  
public function getInvoices($regId) {
    if (
is_string($regId)) {
      return 
$this->request('<web:consultarFactura>' .
        
'<numeroRegistro>' $regId '</numeroRegistro>' .
        
'</web:consultarFactura>');
    }
    
$req '<web:consultarListadoFacturas><request>';
    foreach (
$regId as $id$req .= '<numeroRegistro>' $id '</numeroRegistro>';
    
$req .= '</request></web:consultarListadoFacturas>';
    return 
$this->request($req);
  }



}
trait 
StageableTrait {
  private 
$production true;

  
/**
   * Set production environment
   * @param boolean $production Is production
   */
  
public function setProduction($production) {
    
$this->production $production;
  }


  
/**
   * Is production
   * @return boolean Is production
   */
  
public function isProduction() {
    return 
$this->production;
  }
}
/**
 * Facturae File
 *
 * Represents a file that can be used as an attachment for an invoice or to
 * send information to a Web Service.
 */
class FacturaeFile {
  const 
REQUEST_EXPIRATION 60// In seconds

  
private $publicKey;
  private 
$privateKey;

  private 
$filename;
  private 
$data;
  private 
$mime;

/**
   * Get web namespace
   * @return string Web namespace
   */
  
protected function getWebNamespace() {
    return 
"https://webservice.face.gob.es";
  }


public function 
request($body) {

$tools = new XmlTools();
    

$nulo=null;


//DATOS SIGN

$policy= array(
    
"name" => "Politica de Firma FacturaE v3.1",
    
"url" => "http://www.facturae.es/politica_de_firma_formato_facturae/politica_de_firma_formato_facturae_v3_1.pdf",
    
"digest" => "Ohixl6upD6av8N7pEvDABhEL6hM=");
    
// Generate random IDs
    
    // Load public and private keys
    
$reader = new KeyPairReader($GLOBALS["dir_cert"], $nulo$GLOBALS["clave"]);
    
$publicChain2 $reader->getPublicChain();
    
$privateKey2 $reader->getPrivateKey();
    
$signPolicy2 $policy;
    unset(
$reader);


    
//No usado Comprueba si hay key publica y privada y devueleve 1=hay 0=no hay
    //return (!empty($publicChain2) && !empty($privateKey2));


    
$reader = new KeyPairReader($GLOBALS["dir_cert"], null$GLOBALS["clave"]);
    
//$publicChain1 = $reader->getPublicChain();
    
$publicKey1 $publicChain2;
     
$publicChain1 $publicChain2;

    
$privateKey1 $reader->getPrivateKey();
    
$signPolicy1 $signPolicy2;
    unset(
$reader);

    
$tools = new XmlTools();

    
// Generate random IDs for this request
    
$bodyId "BodyId-" $tools->randomId();
    
$certId "CertId-" $tools->randomId();
    
$keyId "KeyId-" $tools->randomId();
    
$strId "SecTokId-" $tools->randomId();
    
$timestampId "TimestampId-" $tools->randomId();
    
$sigId "SignatureId-" $tools->randomId();

    
// Define namespaces array
    
$ns = array(
      
"soapenv" => 'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"',
      
"web" => 'xmlns:web="' $this->getWebNamespace() . '"',
      
"ds" => 'xmlns:ds="http://www.w3.org/2000/09/xmldsig#"',
      
"wsu" => 'xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"',
      
"wsse" => 'xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"'
    
);

    
// Generate request body
    
$reqBody '<soapenv:Body wsu:Id="' $bodyId '">' $body '</soapenv:Body>';
    
$bodyDigest $tools->getDigest($tools->injectNamespaces($reqBody$ns));

    
// Generate timestamp
    
$timeCreated time();
    
$timeExpires $timeCreated self::REQUEST_EXPIRATION;
    
$reqTimestamp '<wsu:Timestamp wsu:Id="' $timestampId '">' .
        
'<wsu:Created>' date('c'$timeCreated) . '</wsu:Created>' .
        
'<wsu:Expires>' date('c'$timeExpires) . '</wsu:Expires>' .
      
'</wsu:Timestamp>';
    
$timestampDigest $tools->getDigest(
      
$tools->injectNamespaces($reqTimestamp$ns)
    );

    
// Generate request header
    
$reqHeader '<soapenv:Header>';
    
$reqHeader .= '<wsse:Security soapenv:mustUnderstand="1">' ;
    
$reqHeader .= '<wsse:BinarySecurityToken ' .
      
'EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ' .
      
'wsu:Id="' $certId '" ' .
      
'ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">' .
        
$tools->getCert($publicKey1[0], false) .
      
'</wsse:BinarySecurityToken>';

    
// Generate signed info
    
$signedInfo '<ds:SignedInfo>' .
        
'<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">' .
        
'</ds:CanonicalizationMethod>' .
        
'<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>' .
        
'<ds:Reference URI="#' $timestampId '">' .
          
'<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></ds:DigestMethod>' .
          
'<ds:DigestValue>' $timestampDigest '</ds:DigestValue>' .
        
'</ds:Reference>' .
        
'<ds:Reference URI="#' $bodyId '">' .
          
'<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512"></ds:DigestMethod>' .
          
'<ds:DigestValue>' $bodyDigest '</ds:DigestValue>' .
        
'</ds:Reference>' .
      
'</ds:SignedInfo>';
    
$signedInfoPayload $tools->injectNamespaces($signedInfo$ns);

    
// Add signature and KeyInfo to header
    
$reqHeader .= '<ds:Signature Id="' $sigId '">' .
      
$signedInfo .
      
'<ds:SignatureValue>' .
        
$tools->getSignature($signedInfoPayload$privateKey1false) .
      
'</ds:SignatureValue>';
    
$reqHeader .= '<ds:KeyInfo Id="' $keyId '">' .
      
'<wsse:SecurityTokenReference wsu:Id="' $strId '">' .
        
'<wsse:Reference URI="#' $certId '" ' .
        
'ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">' .
        
'</wsse:Reference>' .
      
'</wsse:SecurityTokenReference>' .
      
'</ds:KeyInfo>';
    
$reqHeader .= '</ds:Signature>';

    
// Add timestamp and close header
    
$reqHeader .= $reqTimestamp;
    
$reqHeader .= '</wsse:Security>';
    
$reqHeader .= '</soapenv:Header>';

    
// Generate final request
    
$req '<soapenv:Envelope>' $reqHeader $reqBody '</soapenv:Envelope>';
    
$req $tools->injectNamespaces($req$ns);
    
$req '<?xml version="1.0" encoding="UTF-8"?>' $req;

    
// Extract SOAP action from "<web:ACTION></web:ACTION>"
    
$soapAction substr($body5strpos($body'>')-5);
    
$soapAction $this->getWebNamespace() . "#$soapAction";

    
$ch curl_init();
    
curl_setopt_array($ch, array(
      
CURLOPT_URL => $GLOBALS['endpoint'],
      
CURLOPT_RETURNTRANSFER => 1,
      
CURLOPT_SSL_VERIFYPEER => 0,
      
CURLOPT_TIMEOUT => 30,
      
CURLOPT_POST => 1,
      
CURLOPT_POSTFIELDS => $req,
      
CURLOPT_HTTPHEADER => array(
        
"Content-Type: text/xml",
        
"SOAPAction: " $soapAction
      
),
      
CURLOPT_USERAGENT => "FacturaePHP/" $GLOBALS["version"]
    ));
    
$res curl_exec($ch);
    
curl_close($ch);
    unset(
$ch);


    
//// Parse response
    
    
$xml = new \DOMDocument();
    
$xml->loadXML($res);
    
$xml $xml->getElementsByTagName('Body')->item(0)->getElementsByTagName('*')->item(0);
$child $xml->getElementsByTagName('codigo');
 
foreach (
$child as $chi
{
    echo 
$chi->nodeName "=" $chi->nodeValue "\r\n" ;
 }
    
$child $xml->getElementsByTagName('descripcion');

foreach (
$child as $chi
{
    echo 
$chi->nodeName "=" $chi->nodeValue "\r\n" ;
 }
    
$child $xml->getElementsByTagName('codigo Seguimiento');

foreach (
$child as $chi
{
    echo 
$chi->nodeName "=" $chi->nodeValue "\r\n" ;
 }
    
$child $xml->getElementsByTagName('codigoSeguimiento');

foreach (
$child as $chi
{
    echo 
$chi->nodeName "=" $chi->nodeValue "\r\n" ;
 }


//echo  "---- FIN RESULTADO ----"  . "\r\n" . "---- RESPUESTA COMPLETA  ----"  . "\r\n" . $res . "\r\n" . "---- FIN RESPUESTA COMPLETA ----" .  $req;

//if ($res->resultado->codigo == 0) {
//  // La factura ha sido aceptada
//  echo "Número de registro => " . $res->factura->numeroRegistro;
//} else {
//  // FACe ha rechazado la factura
//}

//return $req;  
}



  
/**
   * Get data
   * @return string Data
   */
  
public function getData() {
    return 
$this->data;
  }


  
/**
   * Get filename
   * @return string Filename
   */
  
public function getFilename() {
    return 
$this->filename;
  }


  
/**
   * Get MIME type
   * @return string MIME type
   */
  
public function getMimeType() {
    return 
$this->mime;
  }
}




?>
[/php]
Responder Con Cita