Ruby.

 

La siguiente guía comprende la conexión con el servicio de timbrado utilizando Ruby 1.9.3 o superior.

El código de esta guía se encuentra disponible para su descarga en el repositorio de ejemplos para Timbre Fiscal.


Generar Timbre

Para generar un timbre utilizando el servidor de pruebas es necesario tener los siguientes datos del servidor a la mano:

 Servidor de prueba: https://staging.diverza.com/stamp
 Token de prueba: ABCD1234
 Metodo HTTP: POST
 Header HTTP: x-auth-token

Así como también el CFDI de prueba que usaremos en este ejercicio:

<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante 
    xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" 
    xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    LugarExpedicion="D.F.,MEXICO" 
    NumCtaPago="DESCONOCIDO" 
    formaDePago="PAGO EN UNA SOLA EXHIBICION" 
    metodoDePago="TRANSFERENCIA ELECTRONICA"
    subTotal="1000.00" 
    total="1160.00" 
    fecha="2013-12-02T22:18:24" 
    certificado="MIIEdDCCA1ygAwIBAgIUMjAwMDEwMDAwMDAxMDAwMDU4NjcwDQYJKoZIhvcNAQEFBQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAoMJlNlcnZpY2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1pbmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRlIGxhIEluZm9ybWFjacOzbjEpMCcGCSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkMHUF2LiBIaWRhbGdvIDc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDELMAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBAcMCUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkCDCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEFyY2lnYTAeFw0xMjA3MjcxNzAyMDBaFw0xNjA3MjcxNzAyMDBaMIHbMSkwJwYDVQQDEyBBQ0NFTSBTRVJWSUNJT1MgRU1QUkVTQVJJQUxFUyBTQzEpMCcGA1UEKRMgQUNDRU0gU0VSVklDSU9TIEVNUFJFU0FSSUFMRVMgU0MxKTAnBgNVBAoTIEFDQ0VNIFNFUlZJQ0lPUyBFTVBSRVNBUklBTEVTIFNDMSUwIwYDVQQtExxBQUEwMTAxMDFBQUEgLyBIRUdUNzYxMDAzNFMyMR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFVuaWRhZCAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2TTQSPONBOVxpXv9wLYo8jezBrb34i/tLx8jGdtyy27BcesOav2c1NS/Gdv10u9SkWtwdy34uRAVe7H0a3VMRLHAkvp2qMCHaZc4T8k47Jtb9wrOEh/XFS8LgT4y5OQYo6civfXXdlvxWU/gdM/e6I2lg6FGorP8H4GPAJ/qCNwIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQUFAAOCAQEATxMecTpMbdhSHo6KVUg4QVF4Op2IBhiMaOrtrXBdJgzGotUFcJgdBCMjtTZXSlq1S4DG1jr8p4NzQlzxsdTxaB8nSKJ4KEMgIT7E62xRUj15jI49qFz7f2uMttZLNThipunsN/NF1XtvESMTDwQFvas/Ugig6qwEfSZc0MDxMpKLEkEePmQwtZD+zXFSMVa6hmOu4M+FzGiRXbj4YJXn9Myjd8xbL/c+9UIcrYoZskxDvMxc6/6M3rNNDY3OFhBK+V/sPMzWWGt8S1yjmtPfXgFs1t65AZ2hcTwTAuHrKwDatJ1ZPfa482ZBROAAX1waz7WwXp0gso7sDCm2/yUVww==" 
    noCertificado="20001000000100005867" 
    sello="qTzEwNUDvk/WpeFstpf/FLNmiHMxiL8pDTXGNb+DCFO0Z7SXMZJCim3JAlBw8Astvr0/jiVfo3WdWbaX88cC1l1+iipOLdedbFNHZUmsW86nC1YQHWw0S6mEiGH0ZxGa5KOl/1mrvPlDweeCiyYavNQeEuO1r0/ELobMi07w6ps=" 
    tipoDeComprobante="ingreso"
    version="3.2" >
    <cfdi:Emisor nombre="EMPRESA DEMO" rfc="AAA010101AAA">
        <cfdi:DomicilioFiscal codigoPostal="34343" pais="MEXICO" estado="DISTRITO FEDERAL" municipio="BENITO JUAREZ" calle="REFORMA"/>
        <cfdi:RegimenFiscal Regimen="PERSONA FISCA"/>
    </cfdi:Emisor>
    <cfdi:Receptor nombre="PUBLICO EN GENERAL" rfc="XAXX010101000">
        <cfdi:Domicilio pais="MEXICO" calle="INSURGENTES"/>
    </cfdi:Receptor>
    <cfdi:Conceptos>
        <cfdi:Concepto importe="1000.00" valorUnitario="1000.00" descripcion="PZA" unidad="CANT" cantidad="1"/>
    </cfdi:Conceptos>
    <cfdi:Impuestos>
        <cfdi:Traslados>
            <cfdi:Traslado importe="160.00" tasa="160.00" impuesto="IVA"/>
        </cfdi:Traslados>
    </cfdi:Impuestos>
    <cfdi:Addenda/>
</cfdi:Comprobante>

Nota: Para conocer más acerca de como construir un CFDI, te recomendamos visitar la siguiente guía: Como generar un CFDI.


Inicio

Primeramente necesitamos crear un nuevo archivo con el nombre timbrar.rb y una vez que lo hayamos creado, por motivos de facilidad para esta guía es almacenar el CFDI a timbrar en una variable:

cfd = <<-EOF
<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante 
    xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" 
    xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    LugarExpedicion="D.F.,MEXICO" 
    NumCtaPago="DESCONOCIDO" 
    formaDePago="PAGO EN UNA SOLA EXHIBICION" 
    metodoDePago="TRANSFERENCIA ELECTRONICA"
    subTotal="1000.00" 
    total="1160.00" 
    fecha="2013-12-02T22:18:24" 
    certificado="MIIEdDCCA1ygAwIBAgIUMjAwMDEwMDAwMDAxMDAwMDU4NjcwDQYJKoZIhvcNAQEFBQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAoMJlNlcnZpY2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1pbmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRlIGxhIEluZm9ybWFjacOzbjEpMCcGCSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkMHUF2LiBIaWRhbGdvIDc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDELMAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBAcMCUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkCDCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEFyY2lnYTAeFw0xMjA3MjcxNzAyMDBaFw0xNjA3MjcxNzAyMDBaMIHbMSkwJwYDVQQDEyBBQ0NFTSBTRVJWSUNJT1MgRU1QUkVTQVJJQUxFUyBTQzEpMCcGA1UEKRMgQUNDRU0gU0VSVklDSU9TIEVNUFJFU0FSSUFMRVMgU0MxKTAnBgNVBAoTIEFDQ0VNIFNFUlZJQ0lPUyBFTVBSRVNBUklBTEVTIFNDMSUwIwYDVQQtExxBQUEwMTAxMDFBQUEgLyBIRUdUNzYxMDAzNFMyMR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFVuaWRhZCAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2TTQSPONBOVxpXv9wLYo8jezBrb34i/tLx8jGdtyy27BcesOav2c1NS/Gdv10u9SkWtwdy34uRAVe7H0a3VMRLHAkvp2qMCHaZc4T8k47Jtb9wrOEh/XFS8LgT4y5OQYo6civfXXdlvxWU/gdM/e6I2lg6FGorP8H4GPAJ/qCNwIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQUFAAOCAQEATxMecTpMbdhSHo6KVUg4QVF4Op2IBhiMaOrtrXBdJgzGotUFcJgdBCMjtTZXSlq1S4DG1jr8p4NzQlzxsdTxaB8nSKJ4KEMgIT7E62xRUj15jI49qFz7f2uMttZLNThipunsN/NF1XtvESMTDwQFvas/Ugig6qwEfSZc0MDxMpKLEkEePmQwtZD+zXFSMVa6hmOu4M+FzGiRXbj4YJXn9Myjd8xbL/c+9UIcrYoZskxDvMxc6/6M3rNNDY3OFhBK+V/sPMzWWGt8S1yjmtPfXgFs1t65AZ2hcTwTAuHrKwDatJ1ZPfa482ZBROAAX1waz7WwXp0gso7sDCm2/yUVww==" 
    noCertificado="20001000000100005867" 
    sello="qTzEwNUDvk/WpeFstpf/FLNmiHMxiL8pDTXGNb+DCFO0Z7SXMZJCim3JAlBw8Astvr0/jiVfo3WdWbaX88cC1l1+iipOLdedbFNHZUmsW86nC1YQHWw0S6mEiGH0ZxGa5KOl/1mrvPlDweeCiyYavNQeEuO1r0/ELobMi07w6ps=" 
    tipoDeComprobante="ingreso"
    version="3.2" >
    <cfdi:Emisor nombre="EMPRESA DEMO" rfc="AAA010101AAA">
        <cfdi:DomicilioFiscal codigoPostal="34343" pais="MEXICO" estado="DISTRITO FEDERAL" municipio="BENITO JUAREZ" calle="REFORMA"/>
        <cfdi:RegimenFiscal Regimen="PERSONA FISCA"/>
    </cfdi:Emisor>
    <cfdi:Receptor nombre="PUBLICO EN GENERAL" rfc="XAXX010101000">
        <cfdi:Domicilio pais="MEXICO" calle="INSURGENTES"/>
    </cfdi:Receptor>
    <cfdi:Conceptos>
        <cfdi:Concepto importe="1000.00" valorUnitario="1000.00" descripcion="PZA" unidad="CANT" cantidad="1"/>
    </cfdi:Conceptos>
    <cfdi:Impuestos>
        <cfdi:Traslados>
            <cfdi:Traslado importe="160.00" tasa="160.00" impuesto="IVA"/>
        </cfdi:Traslados>
    </cfdi:Impuestos>
    <cfdi:Addenda/>
</cfdi:Comprobante>
EOF

Petición HTTP

Para realizar peticiones HTTP desde Ruby es necesario importar net/http, lo cual se realiza de la siguiente manera:

require "net/http"

El siguiente paso es crear un nuevo objeto HTTP, para realizar la petición al servicio web indicando la URL del servidor de timbrado y el puerto en el cual esta publicado:

http = Net::HTTP.new("staging.diverza.com", 80)

Nota: Se agrego la URL sin extension alguna.

Lo siguiente seria indicar que tipo de metido queremos ejecutar en el servicio, en este caso es un POST a la extension stamp:

request = Net::HTTP::Post.new("/stamp")

Por motivos de seguridad es necesario que agreguemos un token de seguridad a la petición, en esta guía utilizaremos el de prueba ABCD1234 y este deberá ser cambiado cuando deseemos pasar el código a producción:

request.add_field('x-auth-token', 'ABCD1234')

El CFDI a timbrar se debe agregar como cuerpo de la petición HTTP de la siguiente manera:

request.body = cfd

Finalmente ejecutamos la petición de timbrado:

response = http.request(request)

Obtener el timbre

Para obtener los datos de respuesta del servidor simplemente se necesita lo siguiente:

response_code = response.code
stamp = response.body

puts "Codigo HTTP: #{response_code}"
puts "Timbre: #{stamp}"

Si ejecutamos el código utilizando:

$ ruby timbrar.rb

Nota: La dirección del ejecutable ruby puede variar entre sistemas operativos y procesos de instalación.

Podremos observar que el timbre es devuelto por el servicio en el cuerpo de la respuesta, y al imprimir la variable stamp debe observarse algo similar a lo siguiente:

<tfd:TimbreFiscalDigital 
  xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" 
  xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigital.xsd" 

  selloSAT="Ae0K1DyTpecq8xZAB8SSCccx5Gzrqr+HaD1tEQ/dFNqobiZDfJ2U9eJ9BRxYn1K6Zw4A0W2PbBs3VUFFasuJHkfw5nLxb+M/hu55Gomhw9OjhKsH0ABnOGa3vQHWPHHDFB9zb4/sMxdUTqEubent8Zvb3nfKaxdgX9BkVFYgd+c=" 
  noCertificadoSAT="20001000000100005761" 
  selloCFD="qTzEwNUDvk/WpeFstpf/FLNmiHMxiL8pDTXGNb+DCFO0Z7SXMZJCim3JAlBw8Astvr0/jiVfo3WdWbaX88cC1l1+iipOLdedbFNHZUmsW86nC1YQHWw0S6mEiGH0ZxGa5KOl/1mrvPlDweeCiyYavNQeEuO1r0/ELobMi07w6ps=" 
  FechaTimbrado="2014-08-27T19:33:42" 
  UUID="e52d9982-1cd1-4b99-aa3c-0f6172d07412" 

  version="1.0"/>

El código de respuesta del servidor que se encuentra en la variable response_code deberá ser 200 OK cuando la petición sea exitosa, en caso contrario te invitamos a revisar la Lista de Códigos de Respuesta, que contiene todos los posibles códigos de respuesta del servicio de timbrado y sus posibles soluciones.