Open ingtemix opened 9 years ago
Yo ya lo implementé, el problema es que tengo una versión a la que le he metido mucha mano y por eso no le hago un push,
Segun recuerdo pondré mas o menos los pasos para que alguien lo implemente en la versión original y lo suba.
1.- Conseguir los XSD y XSLT (podemos descargar las diferentes versiones directo del SAT).
2.- Agregarlo dentro de la carpeta main/resources (de preferencia en carpetas separadas, por ejemplo yo tengo la carpeta "VentaVehiculos/v10" y VentaVehiculos/v11" tanto en la carpeta de los XSLT como de los XSD
3.- Agregar al POM todos los XSD y XSLT (que quedarán algo así en el caso del complemento VentaVehiculov11)
*
*
Espero que te haya ayudado. Saludos.
Amigo podrías explicarme como tener un ambiente de trabajo con el codigo fuente???
En caso contrario apoyarme con estos cambios.
Saludos!!!
Explicar paso a paso como tener el ambiente funcional y óptimo es algo complejo pienso yo. Pero puedo darte un par de tips para facilitarte el aprendizaje. Primero que nada te recomiendo uses Netbeans pues al parecer se creó en ese ambiente y es el mas "amigable" para usar en este proyecto. He probado con eclipse y no es tan amigable, requiere de ciertas configuraciones. También te recomiendo aprender un poco de Git (lo básico) para aprendas a hacer los pull, commits, push etc... Ya que hayas aprendido un poco de Git (hay muchísima documentación en internet), tendrás que hacer un pull (como la palabra lo dice, "jalar" el código fuente a tu equipo) y realizar los cambios (los cambios en el código si podría ayudarte mas explicitamente). Después tendrías que hacer el commit y el push (puede que todo esto suene un poco raro, pero seguramente lo entenderás cuando veas Git). No estoy muy seguro como funcionen pues jamas he usado git para repositorios públicos, pero seguro no será muy dificil. Tamben asumo que ya debes tener conocimientos previos de Java. Espero haberte ayudado al menos un poco.
Hola amigo si uso Java pero en especial nunca he usado Git por eso la pregunta para obtener el codigo y de ahí empezarlo a modificar.
Uso Netbeans tratare de armar mi ambiente de pruebas cualquier cosa me puedo apoyar contigo??
Saludos!!!
De Git no ocupas saber la gran cosa, en internet veras muchos tutoriales de "primeros pasos con git" y cosas así. Claro, cualquier duda puedes consultarme, aunque te comento, no se mucho de Git, solo lo básico, pero te apoyo en lo que pueda. A la hora de realizar el push me imagino que alguien podra apoyarnos, ya que como te comento, solo he trabajado con repositorios locales. Saludos.
Listo Amigo ya pude clonar el codigo solo estoy revisando algunos problemas con algunas referencias.
Cualquier duda te pregunto.
Puedes darme tu correo electronico.
Saludos!!!
Amigo carga el código en Netbeans y me marca 2 errores con problemas de Referencia podrías apoyarme con dichos detalles???
Saludos!!!
Podrías colocar los errores mas especificamente? Te los lanza en consola? Saludos.
Me los lanza en esta clase en especifico
public class PrivateKeyLoader implements KeyLoader {
@Getter
PrivateKey key;
public PrivateKeyLoader(String privateKeyLocation, String keyPassword) {
this.setPrivateKey(privateKeyLocation, keyPassword);
}
public PrivateKeyLoader(InputStream privateKeyInputStream, String keyPassword) {
this.setPrivateKey(privateKeyInputStream, keyPassword);
}
Me pide implementar todos los metodos abstractos.
Saludos!!!
Según recuerdo eso es de la librería lombok, Tienes conocimeintos de Maven? Agrega la dependencia: org.projectlombok lombok 1.14.8 y Dale "Build with dependencies". Me avisas en que resultó.
Tengo poco conocimiento de Maven, pero por lo que pude ver es que esa referencia ya se encuentra en el archivo pom.xml
Lo hago pero me sigue mandando el mismo error.
Saludos!!!
Aun dándole "Build with Dependencies" ?
Si amigo lo que hice ahorita fue colocar esto:
@Override
public
Y funciona pero al realizar la validación del timbre de un xml me marca error.
Saludos!!!
El detalle es que la librería lombok genera ciertos valores de manera dinámica, y si haces esto lo que hará será que definirás el método como fijo (un método vacio) que no te serviría para nada. Te recomiendo eliminar del POM la librería lombok que te comenté, y posteriormente la agregues por medio del "Add Dependency" de netbeans (NO directamente en el POM) para que netbeans descargue de nuevo las librerías. Quedo en espera de tu respuesta,
Se me olvidaba! En su momento me topé con problemas con la versión de Java 8, te recomiendo te asegures que está usando la versión 7, y de no ser así, le asignes esa. Saludos.
Amigo lo tengo con Java 7, oyes una pregunta al verificar el tfd me marca un error cosa que no tenia en la versión 2.3
Saludos!!!
Que te marca de error? Intentaste lo del archivo POM que te comenté atras?
Si man y no funcion. Por otro lado realice una correccion a la clase TFD1c32.
package mx.bigdata.sat.cfdi;
import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.math.BigInteger; import java.security.PrivateKey; import java.security.Signature; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.UUID;
import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.util.JAXBSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator;
import mx.bigdata.sat.cfdi.schema.ObjectFactory; import mx.bigdata.sat.cfdi.schema.TimbreFiscalDigital; import mx.bigdata.sat.common.ComprobanteBase; import mx.bigdata.sat.common.NamespacePrefixMapperImpl;
import org.apache.commons.codec.binary.Base64; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.ErrorHandler;
public final class TFDv1c32 {
private static final String XSLT = "/xslt/cadenaoriginal_TFD_1_0.xslt";
private static final String XSD = "/xsd/v32/TimbreFiscalDigital.xsd";
private static final JAXBContext CONTEXT = createContext();
private static final JAXBContext createContext() {
try {
return JAXBContext.newInstance(new Class[] {mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital.class});
} catch (Exception e) {
throw new Error(e);
}
}
private final ComprobanteBase document;
private final mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital tfd;
private final X509Certificate cert;
private TransformerFactory tf;
public TFDv1c32(CFDI cfd, X509Certificate cert) throws Exception {
this(cfd, cert, UUID.randomUUID(), new Date());
}
TFDv1c32(CFDI cfd, X509Certificate cert, UUID uuid, Date date) throws Exception {
this.cert = cert;
this.document = cfd.getComprobante();
this.tfd = getTimbreFiscalDigital(document, uuid, date);
}
public void setTransformerFactory(TransformerFactory tf) {
this.tf = tf;
}
public int timbrar(PrivateKey key) throws Exception {
if (tfd.getSelloSAT() != null) {
return 304;
}
String signature = getSignature(key);
tfd.setSelloSAT(signature);
stamp();
return 300;
}
public void validar() throws Exception {
validar(null);
}
public void validar(ErrorHandler handler) throws Exception {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(getClass().getResource(XSD));
Validator validator = schema.newValidator();
if (handler != null) {
validator.setErrorHandler(handler);
}
validator.validate(new JAXBSource(CONTEXT, tfd));
}
public int verificar() throws Exception {
if (tfd == null) {
return 601; //No contiene timbrado
}
Base64 b64 = new Base64();
System.out.println("HOLA");
String sigStr = tfd.getSelloSAT();
System.out.println(tfd);
System.out.println("1.- " + tfd.getNoCertificadoSAT());
System.out.println("2.- " + tfd.getSelloCFD());
System.out.println("3.- " + tfd.getSelloSAT());
System.out.println("4.- " + tfd.getUUID());
System.out.println("5.- " + tfd.getVersion());
System.out.println("6.- " + tfd.getFechaTimbrado());
byte[] signature = b64.decode(sigStr);
byte[] bytes = getOriginalBytes();
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(cert);
sig.update(bytes);
boolean verified = sig.verify(signature);
return verified ? 600 : 602; //Sello del timbrado no valido
}
public String getCadenaOriginal() throws Exception {
byte[] bytes = getOriginalBytes();
return new String(bytes);
}
public void guardar(OutputStream out) throws Exception {
Marshaller m = CONTEXT.createMarshaller();
m.setProperty("com.sun.xml.bind.namespacePrefixMapper",
new NamespacePrefixMapperImpl(CFDv32.PREFIXES));
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
"http://www.sat.gob.mx/cfd/3 "
+ "http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd");
m.marshal(document.getComprobante(), out);
}
mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital getTimbre() {
return tfd;
}
byte[] getOriginalBytes() throws Exception {
JAXBSource in = new JAXBSource(CONTEXT, tfd);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result out = new StreamResult(baos);
TransformerFactory factory = tf;
if (factory == null) {
factory = TransformerFactory.newInstance();
}
Transformer transformer = factory
.newTransformer(new StreamSource(getClass().getResourceAsStream(XSLT)));
transformer.transform(in, out);
return baos.toByteArray();
}
String getSignature(PrivateKey key) throws Exception {
byte[] bytes = getOriginalBytes();
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(key);
sig.update(bytes);
byte[] signed = sig.sign();
Base64 b64 = new Base64(-1);
return b64.encodeToString(signed);
}
private void stamp() throws Exception {
Element element = marshalTFD();
document.setComplemento(element);
}
private Element marshalTFD() throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Marshaller m = CONTEXT.createMarshaller();
m.setProperty("com.sun.xml.bind.namespacePrefixMapper",
new NamespacePrefixMapperImpl(CFDv3.PREFIXES));
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
"http://www.sat.gob.mx/TimbreFiscalDigital TimbreFiscalDigital.xsd");
m.marshal(tfd, doc);
return doc.getDocumentElement();
}
private TimbreFiscalDigital createStamp(UUID uuid, Date date) {
ObjectFactory of = new ObjectFactory();
TimbreFiscalDigital tfd = of.createTimbreFiscalDigital();
tfd.setVersion("1.0");
tfd.setFechaTimbrado(date);
tfd.setSelloCFD(document.getSello());
tfd.setUUID(uuid.toString());
BigInteger bi = cert.getSerialNumber();
tfd.setNoCertificadoSAT(new String(bi.toByteArray()));
return tfd;
}
private mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital getTimbreFiscalDigital(ComprobanteBase document, UUID uuid, Date date) throws Exception {
Iterator i$;
if (document.hasComplemento()) {
List list = document.getComplementoGetAny();
for (i$ = list.iterator(); i$.hasNext();) {
Object o = i$.next();
System.out.println(o.getClass());
if ((o instanceof mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital)) {
System.out.println("HOLA");
return (mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital) o;
}
}
}
return null;
/*if (document.hasComplemento()) {
List<Object> list = document.getComplementoGetAny();
for (Object o : list) {
if (o instanceof TimbreFiscalDigital) {
System.out.println("TIMBRE");
return (TimbreFiscalDigital) o;
}
}
}
System.out.println("NO ENOCNTRE");
return;*/
}
}
En el metodo private mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital getTimbreFiscalDigital(ComprobanteBase document, UUID uuid, Date date)
El timbre fiscal no coincide y nunca entra al if if ((o instanceof mx.bigdata.sat.cfdi.v32.schema.TimbreFiscalDigital)) siempre lo manda a timbrar y eso me regresa un null en el selloSAT.
Con eso ya funciono.
Saludos!!!
Podrías preguntar a los dueños del repositorio como realizar el push y así actualizar la libreria.
Amigo efectivamente el día de ayer estuve realizando pruebas del metodo verificar y si funciono así tambien ya agregue los nuevos complementos con las indicaciones que me diste y funciono a la perfección amigo.
Muchas gracias. Saludos!!!
Hola Amigo buen dia,
Fijate que estoy realizando una validación de sello y veo que al generar la cadena original si tengo un dato como .91 me lo convierte a 0.91 lo que me hace tener inválido el sello.
Tendrás algún comentario al respecto.
Claro que si, ya que yo tambien utilicé esta libreria para hacer un validador, tengo bastantes cambios que le hice pero ya que tiene mucha mano mía, no quise darles el push pero dejame busco esa parte del código.
Tienes que modificar tu método de GetOriginalBytes, y enviarle un inputstream para que lea el archivo exactamente como es y no lo convierta como me comentas, el método que debes colocar es este.
byte[] getOriginalBytes(InputStream in) throws Exception{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
Source source = new StreamSource(in);
Source xsl = new StreamSource(getClass().getResourceAsStream(XSLT));
Result out = new StreamResult(baos);
TransformerFactory factory = tf;
if (factory == null) {
factory = TransformerFactory.newInstance();
factory.setURIResolver(new URIResolverImpl());
}
Transformer transformer = factory
.newTransformer(new StreamSource(getClass().getResourceAsStream(XSLT)));
transformer.transform(source, out);
} finally {
in.close();
}
return baos.toByteArray();
}
Ya el inputstream puedes enviarselo como gustes, si ocupas más ayuda hazmelo saber. Saludos.
Hola Amigo buen día,
Ya detecte el problema y veía que radicaba que en source mandaban la clase comprobante y por ende el .91 lo convertía a BigDecimal. Eres muy acertado en tus comentarios ya pude resolver el detalle.
Saludos!!!
Lo que se te ofrezca, saludos
Hola Amigo,
Una pregunta esta librería puede ayudarme a realizar la firma para la cancelación de documentos.
Quedo a espera de tus comentarios. Saludos!!!
Pues cancelación de que manera? No creo que esta librería tenga de manera nativa la cancelación pues los PAC's manejan diferentes métodos y servicio, hasta donde tengo entendido no hay uno "genérico" para cancelar en el SAT por medio de un WebService.
Hola amigo lo que tengo que hacer es firmar la cancelación a traves del .key y .cer.
Ya lo pude realizar pero obtengo espacios entre el sello esto es correcto.
Probablemente esto se deba a un error en la codificación, quizá podría apoyarte un poco más si me indicaras el método o librería que utilizas y exactamente que es lo que estas enviando. Saludos.
Hola compañeros me acabo de dar cuenta que la aplicación no valida ciertos complementos por la cadena original.
Pueden indicarme como descargar el codigo para poder colaborar con ustedes.
Saludos!!!