¿ Que sabemos de la factura de crédito en Aegentina ?
Factura de credito - solicitud del tiket de acceso
Mar Abr 21, 2020 11:13 am
Hola. Mi nombre es Alejandro y después de haber pasado años estudiando y programando utilidades para la confección de facturas electrónicas en la argentina, quiero compartir mi conocimiento y charlar de este tema con colegas programadores. Por supuesto que ya les pedire ayuda en algo, pero por ahora voy a empezar por la solicitud de un tiket de acceso para interactuar con el web service para gestión de factura electrónica de crédito. Por otro lado les cuento que el lenguaje de programación que voy a utilizar es Harbour en su versión oficial ( HMG Harbour ) .
Por cierto, este programa no es funcional, pero espero que de luz respecto de como iniciar el camino. (No se olviden que es mi primer POST)
Gracias
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <hmg.ch>
#define CRLF chr(13)+chr(10)
PUBLIC cToken := ''
PUBLIC cSign := ''
PUBLIC cSOURCE := 'SERIALNUMBER=CUIT 20174237361, CN=certale1'
PUBLIC cDESTINATIONDN := 'cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239'
PUBLIC cUNIQUEID := '123456789'
PUBLIC cSERVICE := 'wsfecred'
PUBLIC cSOAPACTION := '"http://ar.gob.afip.wsfecred/FECredService/"'
PUBLIC cPathOpenSsl := 'C:\OpenSSL\Bin'
/* SERVER DE AUTENTICACION */
/* HOMOLOGACION */
*PUBLIC cWSAA_URL := 'https://wsaa.afip.gov.ar/ws/services/LoginCms'
/* PRUEBA */
PUBLIC cWSAA_URL := 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms'
/* SERVER DE FACTURA DE CRÉDITO */
/* HOMOLOGACION */
*PUBLIC cWSFC_URL := 'https://serviciosjava.afip.gob.ar/wsfecred/FECredService?wsdl'
/* PRUEBA */
PUBLIC cWSFC_URL := 'https://fwshomo.afip.gov.ar/wsfecred/FECredService?wsdl'
/*-----------------------------------------------------------------------------*/
FUNCTION WSAA_LlamoAlWS( c_CMS_Base64 )
/*-----------------------------------------------------------------------------*/
local oWSAA := ''
local cRespuesta := ''
local cXml := ''
* Armo el XML con el TRA
cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
cXml += '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + CRLF
cXml += '<soap:Body>' + CRLF
cXml += ' <loginCms xmlns="http://wsaa.view.sua.dvadac.desein.afip.gov">' + CRLF
cXml += ' <in0>' + c_CMS_Base64 + '</in0>' + CRLF
cXml += ' </loginCms>' + CRLF
cXml += '</soap:Body>' + CRLF
cXml += '</soap:Envelope>' + CRLF
* Creo y Valido el Objeto oWSAA
oWSAA := Win_OleCreateObject( 'MSXML2.XMLHTTP' )
if empty( oWSAA )
alert( 'NO se Pudo Crear el Objeto oWSAA;se Cancela el Programa' )
RETURN( .F. )
endif
* Llamo al Webservice
* Defino Opciones
oWSAA:OPEN( 'POST', cWSAA_URL, .F. )
oWSAA:setRequestHeader( "SOAPAction:", "None" )
oWSAA:setRequestHeader( "Content-Type", "text/xml;charset=UTF-8" )
* Envio el Archivo y Recibo la Respuesta del WS
oWSAA:SEND( cXml )
* Si el status es diferente a 200, ocurrió algún error de conectividad con el WS
*if oWSAA:STATUS == 200
cRespuesta := oWSAA:ResponseText
*endif
* Hago MAS Legible la Respuesta del Webservice
if !empty( cRespuesta )
cRespuesta := DoyFormaAlXml( cRespuesta )
endif
* Dicen que si no se borra el Objeto, despues de un tiempo se incrementa mucho
* el uso de memoria por parte del programa. No lo constate, pero por las dudas
oWSAA := NIL
release oWSAA
* Si estoy en Modo Debug, Grabo los Archivos XML para Control
if l_Debug == .T.
memowrit( 'FETA_Req.xml', cXml )
memowrit( 'FETA_Res.xml', cRespuesta )
endif
RETURN( cRespuesta )
/*-----------------------------------------------------------------------------*/
STATIC FUNCTION DoyFormaAlXml( c_Xml )
/*-----------------------------------------------------------------------------*/
* Por las Dudas de que la Respuesta venga en Formato RAW
if '<' $ c_Xml // <
c_Xml := strtran( c_Xml, '<', '<' )
endif
if '>' $ c_Xml // >
c_Xml := strtran( c_Xml, '>', '>' )
endif
if '"' $ c_Xml // "
c_Xml := strtran( c_Xml, '"', '"' )
endif
if ''' $ c_Xml // \
c_Xml := strtran( c_Xml, ''', '\' )
endif
if '&' $ c_Xml // &
c_Xml := strtran( c_Xml, '&', '&' )
endif
/*-----------------------------------------------------------------------------*/
FUNCTION WSAA_PidoElTicketDeAcceso( l_Prueba, l_Debug )
/*-----------------------------------------------------------------------------*/
local cGENERATIONTIME := TimeFMT( HB_DateTime(), -1 ) // - 1Hs
local cEXPIRATIONTIME := TimeFMT( HB_DateTime(), 1 ) // + 1Hs
local cXML := '' // Variable donde Armo el XML
local cCMS := '' // Variable donde esta el XML y su Firma Electronica
local cTRA := '' // Ticket de requerimiento de Acceso
local cCMS_Base64 := '' // Variable donde esta el CMS Codificado en Base64
local cCmdSign := '' // Comando para llamar a OpenSsl y Generar la Firma del Archivo XML
local cRespuesta := ''
* ARMO EL ARCHIVO XML con el mensaje del TRA (LoginTicketRequest.xml) ============
cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
cXml += '<loginTicketRequest version="1.0">' + CRLF
cXml += ' <header>' + CRLF
*cXml += ' <source>' + cSOURCE + '</source>' + CRLF
*cXml += ' <destination>' + cDESTINATIONDN + '</destination>' + CRLF
cXml += ' <uniqueId>' + cUNIQUEID + '</uniqueId>' + CRLF
cXml += ' <generationTime>' + cGENERATIONTIME + '</generationTime>' + CRLF
cXml += ' <expirationTime>' + cEXPIRATIONTIME + '</expirationTime>' + CRLF
cXml += ' </header>' + CRLF
cXml += ' <service>' + cSERVICE + '</service>' + CRLF
cXml += '</loginTicketRequest>' + CRLF
*---------------------------------------------------------------------------------
* Grabo el Archivo XML con el Nombre TRA.xml
if ( nHandle := fcreate( 'TRA.xml', 0 ) ) == -1
alert( 'NO se pudo crear TRA.xml' )
RETURN( .F. )
else
fwrite( nHandle, cXml )
fclose( nHandle )
endif
cCmdSign := 'openssl smime' + ;
' -sign' + ;
' -in ' + 'TRA.xml' + ; // Archivo XML a Firmar
' -out ' + 'TRA.tmp' + ; // Archivo con la Firma
' -signer ' + cCERT + ; //
' -inkey ' + cPRIVATEKEY + ; //
' -outform ' + 'DER' + ; // Lo Graba en Binario ('PEM' lo graba como numeros con 4 lineas de titulos)
' -nodetach' // NO se Incluye el Archivo Original en la Salida
cBat := ''
cBat += 'path ' + cPathOpenSsl + CRLF
cBat += cCmdSign + CRLF
memowrit( 'FirmoXML.bat', cBat )
*----------------------------------------------------------------------------
* Ejecuto el BAT para Generar TRA.tmp con la Firma
HB_run( 'FirmoXML.bat' ) // HB_run() -> Funci¢n de Harbour para llamar progrmas externos
cCMS := memoread( 'TRA.tmp' ) // Leo el Archivo Firmado
* Codifico en base64
cCMS_Base64 := hb_base64Encode( cCMS ) // Función de Harbour
* Llamo al WS de Autenticaci¢n (WSAA)
cRespuesta := WSAA_LlamoAlWS( cCMS_Base64, l_Prueba, l_Debug )
aRespuesta := LeeRespuesta( cRespuesta, 'FETA' )
RETURN( aRespuesta )
Por cierto, este programa no es funcional, pero espero que de luz respecto de como iniciar el camino. (No se olviden que es mi primer POST)
Gracias
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <hmg.ch>
#define CRLF chr(13)+chr(10)
PUBLIC cToken := ''
PUBLIC cSign := ''
PUBLIC cSOURCE := 'SERIALNUMBER=CUIT 20174237361, CN=certale1'
PUBLIC cDESTINATIONDN := 'cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239'
PUBLIC cUNIQUEID := '123456789'
PUBLIC cSERVICE := 'wsfecred'
PUBLIC cSOAPACTION := '"http://ar.gob.afip.wsfecred/FECredService/"'
PUBLIC cPathOpenSsl := 'C:\OpenSSL\Bin'
/* SERVER DE AUTENTICACION */
/* HOMOLOGACION */
*PUBLIC cWSAA_URL := 'https://wsaa.afip.gov.ar/ws/services/LoginCms'
/* PRUEBA */
PUBLIC cWSAA_URL := 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms'
/* SERVER DE FACTURA DE CRÉDITO */
/* HOMOLOGACION */
*PUBLIC cWSFC_URL := 'https://serviciosjava.afip.gob.ar/wsfecred/FECredService?wsdl'
/* PRUEBA */
PUBLIC cWSFC_URL := 'https://fwshomo.afip.gov.ar/wsfecred/FECredService?wsdl'
/*-----------------------------------------------------------------------------*/
FUNCTION WSAA_LlamoAlWS( c_CMS_Base64 )
/*-----------------------------------------------------------------------------*/
local oWSAA := ''
local cRespuesta := ''
local cXml := ''
* Armo el XML con el TRA
cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
cXml += '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + CRLF
cXml += '<soap:Body>' + CRLF
cXml += ' <loginCms xmlns="http://wsaa.view.sua.dvadac.desein.afip.gov">' + CRLF
cXml += ' <in0>' + c_CMS_Base64 + '</in0>' + CRLF
cXml += ' </loginCms>' + CRLF
cXml += '</soap:Body>' + CRLF
cXml += '</soap:Envelope>' + CRLF
* Creo y Valido el Objeto oWSAA
oWSAA := Win_OleCreateObject( 'MSXML2.XMLHTTP' )
if empty( oWSAA )
alert( 'NO se Pudo Crear el Objeto oWSAA;se Cancela el Programa' )
RETURN( .F. )
endif
* Llamo al Webservice
* Defino Opciones
oWSAA:OPEN( 'POST', cWSAA_URL, .F. )
oWSAA:setRequestHeader( "SOAPAction:", "None" )
oWSAA:setRequestHeader( "Content-Type", "text/xml;charset=UTF-8" )
* Envio el Archivo y Recibo la Respuesta del WS
oWSAA:SEND( cXml )
* Si el status es diferente a 200, ocurrió algún error de conectividad con el WS
*if oWSAA:STATUS == 200
cRespuesta := oWSAA:ResponseText
*endif
* Hago MAS Legible la Respuesta del Webservice
if !empty( cRespuesta )
cRespuesta := DoyFormaAlXml( cRespuesta )
endif
* Dicen que si no se borra el Objeto, despues de un tiempo se incrementa mucho
* el uso de memoria por parte del programa. No lo constate, pero por las dudas
oWSAA := NIL
release oWSAA
* Si estoy en Modo Debug, Grabo los Archivos XML para Control
if l_Debug == .T.
memowrit( 'FETA_Req.xml', cXml )
memowrit( 'FETA_Res.xml', cRespuesta )
endif
RETURN( cRespuesta )
/*-----------------------------------------------------------------------------*/
STATIC FUNCTION DoyFormaAlXml( c_Xml )
/*-----------------------------------------------------------------------------*/
* Por las Dudas de que la Respuesta venga en Formato RAW
if '<' $ c_Xml // <
c_Xml := strtran( c_Xml, '<', '<' )
endif
if '>' $ c_Xml // >
c_Xml := strtran( c_Xml, '>', '>' )
endif
if '"' $ c_Xml // "
c_Xml := strtran( c_Xml, '"', '"' )
endif
if ''' $ c_Xml // \
c_Xml := strtran( c_Xml, ''', '\' )
endif
if '&' $ c_Xml // &
c_Xml := strtran( c_Xml, '&', '&' )
endif
/*-----------------------------------------------------------------------------*/
FUNCTION WSAA_PidoElTicketDeAcceso( l_Prueba, l_Debug )
/*-----------------------------------------------------------------------------*/
local cGENERATIONTIME := TimeFMT( HB_DateTime(), -1 ) // - 1Hs
local cEXPIRATIONTIME := TimeFMT( HB_DateTime(), 1 ) // + 1Hs
local cXML := '' // Variable donde Armo el XML
local cCMS := '' // Variable donde esta el XML y su Firma Electronica
local cTRA := '' // Ticket de requerimiento de Acceso
local cCMS_Base64 := '' // Variable donde esta el CMS Codificado en Base64
local cCmdSign := '' // Comando para llamar a OpenSsl y Generar la Firma del Archivo XML
local cRespuesta := ''
* ARMO EL ARCHIVO XML con el mensaje del TRA (LoginTicketRequest.xml) ============
cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
cXml += '<loginTicketRequest version="1.0">' + CRLF
cXml += ' <header>' + CRLF
*cXml += ' <source>' + cSOURCE + '</source>' + CRLF
*cXml += ' <destination>' + cDESTINATIONDN + '</destination>' + CRLF
cXml += ' <uniqueId>' + cUNIQUEID + '</uniqueId>' + CRLF
cXml += ' <generationTime>' + cGENERATIONTIME + '</generationTime>' + CRLF
cXml += ' <expirationTime>' + cEXPIRATIONTIME + '</expirationTime>' + CRLF
cXml += ' </header>' + CRLF
cXml += ' <service>' + cSERVICE + '</service>' + CRLF
cXml += '</loginTicketRequest>' + CRLF
*---------------------------------------------------------------------------------
* Grabo el Archivo XML con el Nombre TRA.xml
if ( nHandle := fcreate( 'TRA.xml', 0 ) ) == -1
alert( 'NO se pudo crear TRA.xml' )
RETURN( .F. )
else
fwrite( nHandle, cXml )
fclose( nHandle )
endif
cCmdSign := 'openssl smime' + ;
' -sign' + ;
' -in ' + 'TRA.xml' + ; // Archivo XML a Firmar
' -out ' + 'TRA.tmp' + ; // Archivo con la Firma
' -signer ' + cCERT + ; //
' -inkey ' + cPRIVATEKEY + ; //
' -outform ' + 'DER' + ; // Lo Graba en Binario ('PEM' lo graba como numeros con 4 lineas de titulos)
' -nodetach' // NO se Incluye el Archivo Original en la Salida
cBat := ''
cBat += 'path ' + cPathOpenSsl + CRLF
cBat += cCmdSign + CRLF
memowrit( 'FirmoXML.bat', cBat )
*----------------------------------------------------------------------------
* Ejecuto el BAT para Generar TRA.tmp con la Firma
HB_run( 'FirmoXML.bat' ) // HB_run() -> Funci¢n de Harbour para llamar progrmas externos
cCMS := memoread( 'TRA.tmp' ) // Leo el Archivo Firmado
* Codifico en base64
cCMS_Base64 := hb_base64Encode( cCMS ) // Función de Harbour
* Llamo al WS de Autenticaci¢n (WSAA)
cRespuesta := WSAA_LlamoAlWS( cCMS_Base64, l_Prueba, l_Debug )
aRespuesta := LeeRespuesta( cRespuesta, 'FETA' )
RETURN( aRespuesta )
Permisos de este foro:
No puedes responder a temas en este foro.