Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
</properties>
<artifactId>SW-JAVA</artifactId>
<version>1.0.23.1</version>
<version>1.0.24.1</version>
<packaging>jar</packaging>
<scm>
<url>https://github.com/lunasoft/sw-sdk-java</url>
Expand Down
11 changes: 6 additions & 5 deletions src/test/java/Tests/StampRetention/SWStampRetentionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,29 @@ public void testStampRetention_XML_STRING_USER_PASSWORD_AUTH_V3() throws Excepti
SWStampRetentionService api = new SWStampRetentionService(Utils.userSW, Utils.passwordSW, Utils.urlSW);
SuccessV3Response response = null;
Utils ut = new Utils();
String xml = ut.StringgenBasicoRetention(false);
String xml = ut.GetRetention();
response = (SuccessV3Response) api.StampRetention(xml, "v3");
Assert.assertNotNull(response.retencion);
Assert.assertTrue(response.Status.equals("success") || response.message.contains("307") || response.message.contains("401"));
System.out.println(response.Status);
System.out.println(response.HttpStatusCode);
System.out.println(response.retencion);
System.out.println(response.message);
Assert.assertNotNull(response.retencion);

}

@Test
public void testStampRetention_XML_STRING_TOKEN_AUTH_V3() throws Exception {
SWStampRetentionService api = new SWStampRetentionService(Utils.tokenSW, Utils.urlSW);
SuccessV3Response response = null;
Utils ut = new Utils();
String xml = ut.StringgenBasicoRetention(false);
String xml = ut.GetRetention();
response = (SuccessV3Response) api.StampRetention(xml, "v3");
System.out.println(response.Status);
System.out.println(response.HttpStatusCode);
System.out.println(response.retencion);
System.out.println(response.message);
String expect_status = "success";
Assert.assertTrue(expect_status.equalsIgnoreCase(response.Status));
Assert.assertTrue(response.Status.equals("success") || response.message.contains("307")|| response.message.contains("401"));
Assert.assertNotNull(response.retencion);
}
}
156 changes: 66 additions & 90 deletions src/test/java/Tests/Utils.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package Tests;

import java.io.*;
import java.util.*;
import java.nio.file.Files;
Expand All @@ -17,7 +18,6 @@
import org.apache.commons.codec.binary.Base64;
import org.junit.rules.TestName;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

Expand All @@ -43,44 +43,60 @@ public class Utils {
public static String passwordPfx = "swpass";
public static String rfc = "EKU9003173C9";
public static String cancelacionXml = loadResourceAsString("src/test/resources/Extras/CancelacionXML.xml");
public static String cancelacionXmlRet = loadResourceAsString("src/test/resources/Extras/CancelacionXMLRet.xml");
public static String aceptacionRechazoXml = loadResourceAsString("src/test/resources/Extras/AceptacionRechazo.xml");
public static String uuid = "d46316cf-416c-4777-848d-e3ef4ea5a47c";
public static String uuidRetencion = "42270add-4b74-401b-ad65-7db8ca6ca985";
public static String cancelacionXmlRet = loadResourceAsString("src/test/resources/Extras/CancelacionXMLRet.xml");
public static String uuid = "1f0110e0-6e11-49b9-b78c-5929cc3bfc01";
public static String foliosustitucion = "9509174a-f367-474e-bde7-4fb3347a9a22";
public static String uuidRetencion = "42270add-4b74-401b-ad65-7db8ca6ca985";
public static String folioSustitucionRet = "5c45cffb-63e3-48e1-9023-d9d0873ffd7a";

/**
* Genera un CFDI de retenciones especifico y lo sella en caso de indicarse.
* Genera un CFDI especifico y lo sella en caso de indicarse.
*
* @param fileName
* @param signed
* @param version
* @param isBase64
* @return String
*/
public String getRetentionCFDI(String fileName, boolean signed, boolean isBase64){
String xml = readFile(fileName);
//Sellado.
String cfdi = changeDateAndSignGeneric(xml, signed, null, true);
public String getCFDI(String fileName, boolean signed, String version, boolean isBase64) {

String xml = "";
try {
xml = new String(Files.readAllBytes(Paths.get(fileName)), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}

String cfdi = changeDateAndSign(xml, signed, version);

return isBase64 ? encodeSafe(cfdi) : cfdi;
if (isBase64) {
try {
return encodeBase64(cfdi);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

return cfdi;
}

/**
* Genera un CFDI especifico y lo sella en caso de indicarse.
* Obtiene un CFDI de retenciones.
*
* @param fileName
* @param signed
* @param version
* @param isBase64
* @return String
*/
public String getCFDI(String fileName, boolean signed, String version, boolean isBase64) {
String xml = readFile(fileName);
//Sellado.
String cfdi = changeDateAndSignGeneric(xml, signed, version, false);
public String getCFDIRetention(String fileName) {

String xml = "";
try {
xml = new String(Files.readAllBytes(Paths.get(fileName)), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}

return isBase64 ? encodeSafe(cfdi) : cfdi;
return xml;
}

/**
Expand Down Expand Up @@ -119,57 +135,51 @@ public String getJsonCFDI(String fileName, boolean isBase64) {
}

/**
* Genera un CFDI de retenciones o normal y lo sella en caso de indicarse.
* Genera un CFDI especifico y lo sella en caso de indicarse.
*
* @param xml
* @param signed
* @param version
* @param isRetention
* @return String
*/
private String changeDateAndSignGeneric(String xml, boolean signed, String version, boolean isRetention) {
private String changeDateAndSign(String xml, boolean signed, String version) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);

DocumentBuilder builder;
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
UUID uuid = UUID.randomUUID();
String randomUUIDString = uuid.toString().replace("-", "");
builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));

// UUID solo en CFDI normal
if (!isRetention) {
String folio = UUID.randomUUID().toString().replace("-", "") + "sdk-java";
doc.getDocumentElement().setAttribute("Folio", folio);
doc.getDocumentElement().setAttribute("Fecha", getDateCFDI());
} else {
doc.getDocumentElement().setAttribute("FechaExp", getDateCFDI());
}

// Atributos comunes
doc.getDocumentElement().setAttribute("Fecha", getDateCFDI());
doc.getDocumentElement().setAttribute("Folio", randomUUIDString + "sdk-java");
doc.getDocumentElement().setAttribute("Certificado", cerb64);
doc.getDocumentElement().setAttribute("NoCertificado", noCer);

// Firmado
if (signed) {
Sign sign = new Sign();
String cadena = isRetention
? GenerateCadenaRetention(doc,"src/test/resources/XSLT/Retention20/retencion20.xslt")
: GenerateCadena(doc, version);

String sello = sign.getSign(
cadena,
Files.readAllBytes(Paths.get("src/test/resources/CertificadosDePrueba/CSD_EKU9003173C9.key")),
"12345678a"
);
String cadena = GenerateCadena(doc, version);
String sello = sign.getSign(cadena,
Files.readAllBytes(Paths.get("src/test/resources/CertificadosDePrueba/CSD_EKU9003173C9.key")),
"12345678a");
doc.getDocumentElement().setAttribute("Sello", sello);
}

// Convertir a String
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer = tf.newTransformer();
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
return writer.toString();

} catch (Exception e) {
String output = writer.getBuffer().toString();
return output;
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
Expand All @@ -191,22 +201,6 @@ private String getDateCFDI() {
return realDate;
}

private String GenerateCadenaRetention(Document xml, String xsltPath)
throws TransformerConfigurationException, TransformerException, URISyntaxException {

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(new File(xsltPath)));
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(xml), new StreamResult(writer));
// Quitar saltos, tabs y espacios extra
String cadena = writer.toString();
cadena = cadena.replaceAll("\\r|\\n|\\t", "");
cadena = cadena.replaceAll(" +", " ");
cadena = cadena.trim();

return cadena;
}

private String GenerateCadena(Document xml, String version)
throws TransformerConfigurationException, TransformerException, URISyntaxException {

Expand Down Expand Up @@ -254,9 +248,6 @@ public String genNomina12TimbrePrevio(boolean isBase64) {
public String StringgenBasico(boolean isBase64) {
return getCFDI("src/test/resources/CFDI40/CFDI40/CFDI40_Ingreso.xml", true, "4.0", isBase64);
}
public String StringgenBasicoRetention(boolean isBase64) {
return getRetentionCFDI("src/test/resources/Retenciones20/retencion20.xml", true, isBase64);
}
public String StringgenLongXML(boolean isBase64) {
return getCFDI("src/test/resources/CFDI40/ZIP/155000conceptos.xml", true, "4.0", isBase64);
}
Expand All @@ -272,6 +263,9 @@ public String JsonGenBasico(boolean isBase64) {
public static boolean isValidB64(String value) {
return Base64.isBase64(value.getBytes());
}
public String GetRetention() {
return getCFDIRetention("src/test/resources/Retenciones20/retencion20.xml");
}

public static String getCertificadoB64() {
byte[] fileContent;
Expand Down Expand Up @@ -331,22 +325,4 @@ private static String loadResourceAsString(String path) {
return "";
}
}

private String readFile(String fileName) {
try {
return new String(Files.readAllBytes(Paths.get(fileName)), "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return "";
}
}

private String encodeSafe(String input) {
try {
return encodeBase64(input);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return input;
}
}
}
22 changes: 1 addition & 21 deletions src/test/resources/Retenciones20/retencion20.xml
Original file line number Diff line number Diff line change
@@ -1,21 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<retenciones:Retenciones xmlns:retenciones="http://www.sat.gob.mx/esquemas/retencionpago/2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sat.gob.mx/esquemas/retencionpago/2 http://www.sat.gob.mx/esquemas/retencionpago/2/retencionpagov2.xsd"
Version="2.0" FolioInt="7e6b73c1055bd042070b" FechaExp="2025-08-12T16:43:26"
LugarExpRetenc="45110" CveRetenc="01" NoCertificado="30001000000500003416"
Certificado="MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE="
Sello="e">
<retenciones:Emisor RfcE="EKU9003173C9" NomDenRazSocE="ESCUELA KEMPER URGATE"
RegimenFiscalE="601" />
<retenciones:Receptor NacionalidadR="Nacional">
<retenciones:Nacional RfcR="URE180429TM6" NomDenRazSocR="UNIVERSIDAD ROBOTICA ESPAÑOLA"
DomicilioFiscalR="86991" />
</retenciones:Receptor>
<retenciones:Periodo MesIni="01" MesFin="03" Ejercicio="2023" />
<retenciones:Totales MontoTotOperacion="2000.00" MontoTotGrav="2000.00" MontoTotExent="0"
MontoTotRet="580.00">
<retenciones:ImpRetenidos BaseRet="2000" ImpuestoRet="001" MontoRet="580.00"
TipoPagoRet="03" />
</retenciones:Totales>
</retenciones:Retenciones>
<?xml version="1.0" encoding="utf-8"?><retenciones:Retenciones xmlns:retenciones="http://www.sat.gob.mx/esquemas/retencionpago/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/esquemas/retencionpago/2 http://www.sat.gob.mx/esquemas/retencionpago/2/retencionpagov2.xsd" Version="2.0" FolioInt="fc0d7ac6013810499208" FechaExp="2025-09-04T16:13:28" LugarExpRetenc="45110" CveRetenc="01" NoCertificado="30001000000500003416" Certificado="MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE=" Sello="EvW+MZ9VQoDYTEzYmUIIifAivUq583eIeY6fu58w/7IrYzUt7qcpowLLyJ59GssBb+wVFJjT7R0UPMnXKXrGbJBun0Borri37xmTza9ZqqDf/u9HXXXI7Ge984NZuUrerfCz384xiRlsfSkwNffIJxtOy5yNBTiUDJNIN3IDrNS7h2nJauHVJJNGstnOntzzerM19Wa+Cv+IdTos5fKs+xDCqA8COu+/Yww8oUCTr0uGNNAJdZ57N8lnMMu2eyJbnaC0lsWwEV0ep8LmDpcxaxBV68d6cTNULMF2CADLjo/5fpv+uTI4qwaovr0Pmk4kkK/sVwnC1Ggf0cWio079IA=="><retenciones:Emisor RfcE="EKU9003173C9" NomDenRazSocE="ESCUELA KEMPER URGATE" RegimenFiscalE="601"/><retenciones:Receptor NacionalidadR="Nacional"><retenciones:Nacional RfcR="URE180429TM6" NomDenRazSocR="UNIVERSIDAD ROBOTICA ESPAÑOLA" DomicilioFiscalR="86991"/></retenciones:Receptor><retenciones:Periodo MesIni="01" MesFin="03" Ejercicio="2023"/><retenciones:Totales MontoTotOperacion="2000.00" MontoTotGrav="2000.00" MontoTotExent="0" MontoTotRet="580.00"><retenciones:ImpRetenidos BaseRet="2000" ImpuestoRet="001" MontoRet="580.00" TipoPagoRet="03"/></retenciones:Totales></retenciones:Retenciones>
Loading