/** * Copyright [2009] [NIC Labs] * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or * agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * **/ package cl.nic.dte.net; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.security.InvalidAlgorithmParameterException; import java.security.KeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Iterator; import javax.xml.crypto.MarshalException; import javax.xml.crypto.dsig.XMLSignatureException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.soap.MessageFactory; import javax.xml.soap.Name; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPBodyElement; import javax.xml.soap.SOAPConnection; import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; import org.apache.http.client.protocol.ClientContext; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlOptions; import org.xml.sax.SAXException; import cl.nic.dte.util.Utilities; import cl.sii.siiDte.GetTokenDocument; import cl.sii.siiDte.RECEPCIONDTEDocument; import cl.sii.siiDte.DTEDefType.Documento; import cl.sii.xmlSchema.RESPUESTADocument; public class ConexionSii { public boolean autentifica(PrivateKey pKey) { return false; } @SuppressWarnings("unchecked") public String getToken(PrivateKey pKey, X509Certificate cert) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyException, MarshalException, XMLSignatureException, SAXException, IOException, ParserConfigurationException, XmlException, UnsupportedOperationException, SOAPException, ConexionSiiException { String urlSolicitud = Utilities.netLabels .getString("URL_SOLICITUD_TOKEN"); String semilla = getSemilla(); GetTokenDocument req = GetTokenDocument.Factory.newInstance(); req.addNewGetToken().addNewItem().setSemilla(semilla); HashMap<String, String> namespaces = new HashMap<String, String>(); namespaces.put("", "http://www.sii.cl/SiiDte"); XmlOptions opts = new XmlOptions(); opts = new XmlOptions(); opts.setSaveImplicitNamespaces(namespaces); opts.setLoadSubstituteNamespaces(namespaces); opts.setSavePrettyPrint(); opts.setSavePrettyPrintIndent(0); req = GetTokenDocument.Factory.parse(req.newInputStream(opts), opts); // firmo req.sign(pKey, cert); SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance(); SOAPConnection con = scFactory.createConnection(); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); header.detachNode(); Name bodyName = envelope.createName("getToken", "m", urlSolicitud); SOAPBodyElement gltp = body.addBodyElement(bodyName); Name toKname = envelope.createName("pszXml"); SOAPElement toKsymbol = gltp.addChildElement(toKname); opts = new XmlOptions(); opts.setCharacterEncoding("ISO-8859-1"); opts.setSaveImplicitNamespaces(namespaces); toKsymbol.addTextNode(req.xmlText(opts)); message.getMimeHeaders().addHeader("SOAPAction", ""); URL endpoint = new URL(urlSolicitud); message.writeTo(System.out); SOAPMessage responseSII = con.call(message, endpoint); SOAPPart sp = responseSII.getSOAPPart(); SOAPBody b = sp.getEnvelope().getBody(); cl.sii.xmlSchema.RESPUESTADocument resp = null; for (Iterator<SOAPBodyElement> res = b.getChildElements(sp .getEnvelope().createName("getTokenResponse", "ns1", urlSolicitud)); res.hasNext();) { for (Iterator<SOAPBodyElement> ret = res.next().getChildElements( sp.getEnvelope().createName("getTokenReturn", "ns1", urlSolicitud)); ret.hasNext();) { namespaces = new HashMap<String, String>(); namespaces.put("", "http://www.sii.cl/XMLSchema"); opts.setLoadSubstituteNamespaces(namespaces); resp = RESPUESTADocument.Factory.parse(ret.next().getValue(), opts); } } if (resp != null && resp.getRESPUESTA().getRESPHDR().getESTADO() == 0) { return resp.getRESPUESTA().getRESPBODY().getTOKEN(); } else { throw new ConexionSiiException("No obtuvo Semilla: Codigo: " + resp.getRESPUESTA().getRESPHDR().getESTADO() + "; Glosa: " + resp.getRESPUESTA().getRESPHDR().getGLOSA()); } } @SuppressWarnings("unchecked") private String getSemilla() throws UnsupportedOperationException, SOAPException, IOException, XmlException, ConexionSiiException { SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance(); SOAPConnection con = scFactory.createConnection(); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); header.detachNode(); String urlSolicitud = Utilities.netLabels .getString("URL_SOLICITUD_SEMILLA"); Name bodyName = envelope.createName("getSeed", "m", urlSolicitud); message.getMimeHeaders().addHeader("SOAPAction", ""); body.addBodyElement(bodyName); URL endpoint = new URL(urlSolicitud); SOAPMessage responseSII = con.call(message, endpoint); SOAPPart sp = responseSII.getSOAPPart(); SOAPBody b = sp.getEnvelope().getBody(); cl.sii.xmlSchema.RESPUESTADocument resp = null; for (Iterator<SOAPBodyElement> res = b.getChildElements(sp .getEnvelope().createName("getSeedResponse", "ns1", urlSolicitud)); res.hasNext();) { for (Iterator<SOAPBodyElement> ret = res.next().getChildElements( sp.getEnvelope().createName("getSeedReturn", "ns1", urlSolicitud)); ret.hasNext();) { HashMap<String, String> namespaces = new HashMap<String, String>(); namespaces.put("", "http://www.sii.cl/XMLSchema"); XmlOptions opts = new XmlOptions(); opts.setLoadSubstituteNamespaces(namespaces); resp = RESPUESTADocument.Factory.parse(ret.next().getValue(), opts); } } if (resp != null && resp.getRESPUESTA().getRESPHDR().getESTADO() == 0) { return resp.getRESPUESTA().getRESPBODY().getSEMILLA(); } else { throw new ConexionSiiException("No obtuvo Semilla: Codigo: " + resp.getRESPUESTA().getRESPHDR().getESTADO() + "; Glosa: " + resp.getRESPUESTA().getRESPHDR().getGLOSA()); } } /** * Consulta el estado de un DTE en el ambiente de produccion del SII * * @param rutConsultante * @param dte * @param token * @return * @throws UnsupportedOperationException * @throws SOAPException * @throws MalformedURLException * @throws XmlException */ public RESPUESTADocument getEstadoDTEProduccion(String rutConsultante, Documento dte, String token) throws UnsupportedOperationException, SOAPException, MalformedURLException, XmlException { String urlSolicitud = Utilities.netLabels .getString("URL_CONSULTA_ESTADO_DTE_PRODUCCION"); return getEstadoDTE(rutConsultante, dte, token, urlSolicitud); } /** * Consulta el estado de un DTE en el ambiente de del SII * * @param rutConsultante * @param dte * @param token * @return * @throws UnsupportedOperationException * @throws SOAPException * @throws MalformedURLException * @throws XmlException */ public RESPUESTADocument getEstadoDTECertificacion(String rutConsultante, Documento dte, String token) throws UnsupportedOperationException, SOAPException, MalformedURLException, XmlException { String urlSolicitud = Utilities.netLabels .getString("URL_CONSULTA_ESTADO_DTE_CERTIFICACION"); return getEstadoDTE(rutConsultante, dte, token, urlSolicitud); } @SuppressWarnings("unchecked") private RESPUESTADocument getEstadoDTE(String rutConsultante, Documento dte, String token, String urlSolicitud) throws UnsupportedOperationException, SOAPException, MalformedURLException, XmlException { String rutEmisor = dte.getEncabezado().getEmisor().getRUTEmisor(); String rutReceptor = dte.getEncabezado().getReceptor().getRUTRecep(); Integer tipoDTE = dte.getEncabezado().getIdDoc().getTipoDTE() .intValue(); long folioDTE = dte.getEncabezado().getIdDoc().getFolio(); String fechaEmision = Utilities.fechaEstadoDte.format(dte .getEncabezado().getIdDoc().getFchEmis().getTime()); long montoTotal = dte.getEncabezado().getTotales().getMntTotal(); SOAPConnectionFactory scFactory = SOAPConnectionFactory.newInstance(); SOAPConnection con = scFactory.createConnection(); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); header.detachNode(); Name bodyName = envelope.createName("getEstDte", "m", urlSolicitud); SOAPBodyElement gltp = body.addBodyElement(bodyName); Name toKname = envelope.createName("RutConsultante"); SOAPElement toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutConsultante.substring(0, rutConsultante .length() - 2)); toKname = envelope.createName("DvConsultante"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutConsultante.substring( rutConsultante.length() - 1, rutConsultante.length())); toKname = envelope.createName("RutCompania"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutEmisor.substring(0, rutEmisor.length() - 2)); toKname = envelope.createName("DvCompania"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutEmisor.substring(rutEmisor.length() - 1, rutEmisor.length())); toKname = envelope.createName("RutReceptor"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutReceptor .substring(0, rutReceptor.length() - 2)); toKname = envelope.createName("DvReceptor"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(rutReceptor.substring(rutReceptor.length() - 1, rutReceptor.length())); toKname = envelope.createName("TipoDte"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(Integer.toString(tipoDTE)); toKname = envelope.createName("FolioDte"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(Long.toString(folioDTE)); toKname = envelope.createName("FechaEmisionDte"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(fechaEmision); toKname = envelope.createName("MontoDte"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(Long.toString(montoTotal)); toKname = envelope.createName("Token"); toKsymbol = gltp.addChildElement(toKname); toKsymbol.addTextNode(token); message.getMimeHeaders().addHeader("SOAPAction", ""); URL endpoint = new URL(urlSolicitud); SOAPMessage responseSII = con.call(message, endpoint); SOAPPart sp = responseSII.getSOAPPart(); SOAPBody b = sp.getEnvelope().getBody(); for (Iterator<SOAPBodyElement> res = b.getChildElements(sp .getEnvelope().createName("getEstDteResponse", "ns1", urlSolicitud)); res.hasNext();) { for (Iterator<SOAPBodyElement> ret = res.next().getChildElements( sp.getEnvelope().createName("getEstDteReturn", "ns1", urlSolicitud)); ret.hasNext();) { HashMap<String, String> namespaces = new HashMap<String, String>(); namespaces.put("", "http://www.sii.cl/XMLSchema"); XmlOptions opts = new XmlOptions(); opts.setLoadSubstituteNamespaces(namespaces); return RESPUESTADocument.Factory.parse(ret.next().getValue(), opts); } } return null; } /** * Envia el archivo XML indicado al ambiente de produccion del SII. * * @param rutEnvia * @param rutCompania * @param archivoEnviarSII * @param token * @return * @throws ClientProtocolException * @throws ParseException * @throws IOException * @throws XmlException */ public RECEPCIONDTEDocument uploadEnvioProduccion(String rutEnvia, String rutCompania, File archivoEnviarSII, String token) throws ClientProtocolException, ParseException, IOException, XmlException { String urlEnvio = Utilities.netLabels .getString("URL_UPLOAD_PRODUCCION"); String hostEnvio = Utilities.netLabels .getString("HOST_UPLOAD_PRODUCCION"); return uploadEnvio(rutEnvia, rutCompania, archivoEnviarSII, token, urlEnvio, hostEnvio); } /** * Envia el archivo XML indicado al ambiente de certificacion del SII. * * @param rutEnvia * @param rutCompania * @param archivoEnviarSII * @param token * @return * @throws ClientProtocolException * @throws ParseException * @throws IOException * @throws XmlException */ public RECEPCIONDTEDocument uploadEnvioCertificacion(String rutEnvia, String rutCompania, File archivoEnviarSII, String token) throws ClientProtocolException, ParseException, IOException, XmlException { String urlEnvio = Utilities.netLabels .getString("URL_UPLOAD_CERTIFICACION"); String hostEnvio = Utilities.netLabels .getString("HOST_UPLOAD_CERTIFICACION"); return uploadEnvio(rutEnvia, rutCompania, archivoEnviarSII, token, urlEnvio, hostEnvio); } private RECEPCIONDTEDocument uploadEnvio(String rutEnvia, String rutCompania, File archivoEnviarSII, String token, String urlEnvio, String hostEnvio) throws ClientProtocolException, IOException, org.apache.http.ParseException, XmlException { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(urlEnvio); MultipartEntity reqEntity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE); reqEntity.addPart("rutSender", new StringBody(rutEnvia.substring(0, rutEnvia.length() - 2))); reqEntity.addPart("dvSender", new StringBody(rutEnvia.substring( rutEnvia.length() - 1, rutEnvia.length()))); reqEntity.addPart("rutCompany", new StringBody(rutCompania.substring(0, (rutCompania).length() - 2))); reqEntity.addPart("dvCompany", new StringBody(rutCompania.substring( rutCompania.length() - 1, rutCompania.length()))); FileBody bin = new FileBody(archivoEnviarSII); reqEntity.addPart("archivo", bin); httppost.setEntity(reqEntity); BasicClientCookie cookie = new BasicClientCookie("TOKEN", token); cookie.setPath("/"); cookie.setDomain(hostEnvio); cookie.setSecure(true); cookie.setVersion(1); CookieStore cookieStore = new BasicCookieStore(); cookieStore.addCookie(cookie); httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); httppost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); httppost.addHeader(new BasicHeader("User-Agent", Utilities.netLabels .getString("UPLOAD_SII_HEADER_VALUE"))); HttpResponse response = httpclient.execute(httppost, localContext); HttpEntity resEntity = response.getEntity(); RECEPCIONDTEDocument resp = null; HashMap<String, String> namespaces = new HashMap<String, String>(); namespaces.put("", "http://www.sii.cl/SiiDte"); XmlOptions opts = new XmlOptions(); opts.setLoadSubstituteNamespaces(namespaces); resp = RECEPCIONDTEDocument.Factory.parse(EntityUtils .toString(resEntity), opts); return resp; } }