Skip to content

Commit d40e86a

Browse files
Release/0.0.19.1 (#62)
* Feature/ss730 (#55) * update version * update readme * add auth v2 * add users v2 * add balance v2 * add request put and delete with body * add encoding utf-8 * fix methods * add constant user * Feature(SS-839): Add stamp retention V3 * Feature SS-850: Se agrega clases y metodo para cancelación retenciones por xml * Feature SS-850: Fix comments * Feature(SS-862): Add cancelacion retencion * Feature(SS-862): Update cancelation retention class * modify UT to receive error codes (#61) * modify UT to recive error codes * delete reference disabled * fix readme --------- Co-authored-by: martinf12 <martin.flores@sw.com.mx> Co-authored-by: martinfnsw <88680430+martinfnsw@users.noreply.github.com>
1 parent 8fdd58a commit d40e86a

File tree

18 files changed

+988
-11
lines changed

18 files changed

+988
-11
lines changed

README.md

Lines changed: 312 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,318 @@ public class App {
705705
```
706706
</details>
707707

708+
### **Timbrado CFDI de Retenciones** ###
709+
<details>
710+
<summary>
711+
Timbrado
712+
</summary>
713+
714+
## Timbrado de Retenciones ##
715+
**Timbrado de Retenciones** Recibe el contenido de un **XML de retención** ya emitido (sellado) en formato **String**, posteriormente si la retención y el token son correctos devuelve la retención timbrada, en caso contrario lanza una excepción.
716+
717+
**Timbrar Retención XML en formato string utilizando usuario y contraseña**
718+
```java
719+
import java.nio.file.Files;
720+
import java.nio.file.Paths;
721+
import mx.com.sw.services.stampretention.StampRetention;
722+
import mx.com.sw.services.stampretention.responses.StampRetentionResponseV3;
723+
724+
public class App {
725+
726+
public static void main(String[] args)
727+
{
728+
try
729+
{
730+
//Creamos una instancia de tipo StampRetention
731+
//A esta le pasamos la Url, Usuario y Contraseña para obtener el token
732+
//Automaticamente despues de obtenerlo se procedera a timbrar la retención
733+
StampRetention stampRetention = new StampRetention("https://services.test.sw.com.mx", "user", "password", null, 0);
734+
String xml = new String(Files.readAllBytes(Paths.get("retencion.xml")), "UTF-8");
735+
StampRetentionResponseV3 response = stampRetention.timbrarV3(xml);
736+
737+
if (response.getStatus().equalsIgnoreCase("success"))
738+
{
739+
//Retención timbrada
740+
System.out.println(response.getData().getRetention());
741+
}
742+
else
743+
{
744+
//Obtenemos el detalle del Error
745+
System.out.println("Error al timbrar retención");
746+
System.out.println(response.getMessage());
747+
System.out.println(response.getMessageDetail());
748+
}
749+
}
750+
catch (Exception e)
751+
{
752+
System.out.println(e);
753+
}
754+
}
755+
}
756+
```
757+
758+
**Timbrar Retención XML en formato string utilizando token** [¿Como obtener token?](http://developers.sw.com.mx/knowledge-base/generar-un-token-infinito/)
759+
```java
760+
import java.nio.file.Files;
761+
import java.nio.file.Paths;
762+
import mx.com.sw.services.stampretention.StampRetention;
763+
import mx.com.sw.services.stampretention.responses.StampRetentionResponseV3;
764+
765+
public class App {
766+
767+
public static void main(String[] args)
768+
{
769+
try
770+
{
771+
//Creamos una instancia de tipo StampRetention
772+
//A esta le pasamos la Url y su Token infinito
773+
//Este lo puede obtener ingresando al administrador de timbres con su usuario y contraseña
774+
StampRetention stampRetention = new StampRetention("https://services.test.sw.com.mx", "T2lYQ0t4L0R...", null, 0);
775+
String xml = new String(Files.readAllBytes(Paths.get("retencion.xml")), "UTF-8");
776+
StampRetentionResponseV3 response = stampRetention.timbrarV3(xml);
777+
778+
if (response.getStatus().equalsIgnoreCase("success"))
779+
{
780+
//Retención timbrada
781+
System.out.println(response.getData().getRetention());
782+
}
783+
else
784+
{
785+
//Obtenemos el detalle del Error
786+
System.out.println("Error al timbrar retención");
787+
System.out.println(response.getMessage());
788+
System.out.println(response.getMessageDetail());
789+
}
790+
}
791+
catch (Exception e)
792+
{
793+
System.out.println(e);
794+
}
795+
}
796+
}
797+
```
798+
799+
</details>
800+
801+
---
802+
### **Cancelación Retenciones** ###
803+
Servicio que permite cancelar facturas de retenciones e información de pagos con sus complementos a través de un Web Service.
804+
<details>
805+
<summary>Cancelación por XML</summary>
806+
807+
<br>
808+
809+
## Cancelación retenciones por XML ##
810+
Este método recibe únicamente el XML sellado con el UUID a cancelar de retenciones e información de pagos.
811+
812+
813+
**Ejemplo de consumo de la librería para cancelar retenciones con XML**
814+
```java
815+
import java.nio.file.Files;
816+
import java.nio.file.Paths;
817+
import mx.com.sw.services.cancelationretention.CancelationRetention;
818+
import mx.com.sw.services.cancelationretention.responses.CancelationRetentionResponse;
819+
820+
public class App {
821+
822+
public static void main(String[] args)
823+
{
824+
try
825+
{
826+
//Creamos una instancia de tipo CancelationRetention
827+
//A esta le pasamos la Url, Usuario y Contraseña para obtener el token
828+
//Automaticamente despues de obtenerlo se procedera a Cancelar la retención
829+
CancelationRetention cancelation = new CancelationRetention("https://services.test.sw.com.mx", "user",
830+
"password", null, 0);
831+
//Obtenemos el XML de cancelacion
832+
String xmlCancelation = new String(Files.readAllBytes(Paths.get("cancelacion_retencion.xml")), "UTF-8");
833+
CancelationRetentionResponse response = cancelation.cancelar(xmlCancelation);
834+
835+
if (response.getStatus().equalsIgnoreCase("success"))
836+
{
837+
//Acuse de cancelación
838+
System.out.println(response.getData().getAcuse());
839+
//Estatus del UUID
840+
System.out.println(response.getData().getUUID());
841+
}
842+
else
843+
{
844+
//Obtenemos el detalle del Error
845+
System.out.println("Error al cancelar");
846+
System.out.println(response.getMessage());
847+
System.out.println(response.getMessageDetail());
848+
}
849+
}
850+
catch (Exception e)
851+
{
852+
System.out.println(e);
853+
}
854+
}
855+
}
856+
```
857+
858+
**Ejemplo de consumo de la librería para cancelar retenciones con XML utilizando token**
859+
```java
860+
import java.nio.file.Files;
861+
import java.nio.file.Paths;
862+
import mx.com.sw.services.cancelationretention.CancelationRetention;
863+
import mx.com.sw.services.cancelationretention.responses.CancelationRetentionResponse;
864+
865+
public class App {
866+
867+
public static void main(String[] args)
868+
{
869+
try
870+
{
871+
//Creamos una instancia de tipo CancelationRetention
872+
//A esta le pasamos la Url y el token infinito
873+
//Este lo puede obtener ingresando al administrador de timbres con su usuario y contraseña
874+
CancelationRetention cancelation = new CancelationRetention("https://services.test.sw.com.mx", "T2lYQ0t4L0R...", null, 0);
875+
//Obtenemos el XML de cancelacion
876+
String xmlCancelation = new String(Files.readAllBytes(Paths.get("cancelacion_retencion.xml")), "UTF-8");
877+
CancelationRetResponse response = cancelation.cancelar(xmlCancelation);
878+
879+
if (response.getStatus().equalsIgnoreCase("success"))
880+
{
881+
//Acuse de cancelación
882+
System.out.println(response.getData().getAcuse());
883+
//Estatus del UUID
884+
System.out.println(response.getData().getUUID());
885+
}
886+
else
887+
{
888+
//Obtenemos el detalle del Error
889+
System.out.println("Error al cancelar");
890+
System.out.println(response.getMessage());
891+
System.out.println(response.getMessageDetail());
892+
}
893+
}
894+
catch (Exception e)
895+
{
896+
System.out.println(e);
897+
}
898+
}
899+
}
900+
```
901+
</details>
902+
<details>
903+
<summary>
904+
Cancelación por CSD
905+
</summary>
906+
907+
## Cancelación por CSD ##
908+
909+
Como su nombre lo indica, este metodo recibe todos los elementos que componen el CSD los cuales son los siguientes:
910+
911+
* Certificado (.cer) en **Base64**
912+
* Key (.key) en **Base64**
913+
* RFC emisor
914+
* Password del archivo key
915+
* UUID
916+
* Motivo
917+
* Folio Sustitución
918+
919+
**Ejemplo de consumo de la libreria para cancelar con CSD con motivo de cancelación 01 con relación a documento**
920+
921+
```java
922+
import mx.com.sw.services.cancelationretention.CancelationRetention;
923+
import mx.com.sw.services.cancelationretention.responses.CancelationRetResponse;
924+
import org.junit.jupiter.api.Assertions;
925+
import org.junit.jupiter.api.Test;
926+
927+
public class App {
928+
929+
@Test
930+
public void testCancellationCSD() {
931+
try {
932+
// Creamos una instancia de tipo CancelationRetention, pasándole la URL y el token
933+
CancelationRetention cancelation = new CancelationRetention(settings.getUrlSW(), settings.getTokenSW(), null, 0);
934+
935+
// Obtenemos los datos del CSD desde la configuración
936+
String csdBase64 = settings.getCSD();
937+
String keyBase64 = settings.getKey();
938+
String password = settings.getPasswordCSD();
939+
String rfc = settings.getRFC();
940+
941+
// Definimos el UUID a cancelar
942+
String uuid = "8D93A20F-E9EF-42CA-A2B9-2986A352DCEC";
943+
944+
// Realizamos la petición de cancelación al servicio
945+
CancelationRetResponse response = cancelation.cancelar(csdBase64, keyBase64, rfc, password, uuid, "02", null);
946+
947+
// Verificamos que la respuesta no sea nula y contenga un estado
948+
Assertions.assertNotNull(response);
949+
Assertions.assertNotNull(response.getStatus());
950+
951+
// Validamos que el estatus sea "success" o que indique intermitencia del SAT
952+
Assertions.assertTrue("success".equalsIgnoreCase(response.getStatus()) || response.getMessage().contains("Intermitencia del SAT"));
953+
} catch (ServicesException ex) {
954+
// Manejamos una posible excepción
955+
Assertions.assertNotNull(ex);
956+
}
957+
}
958+
}
959+
960+
```
961+
962+
</details>
963+
<details>
964+
<summary>
965+
Cancelación por PFX
966+
</summary>
967+
968+
## Cancelación por PFX ##
969+
970+
Este método recibe los siguientes parametros:
971+
* Archivo PFX en **Base64**
972+
* RFC emisor
973+
* Password (CSD)
974+
* UUID
975+
* Motivo
976+
* Folio Sustitución
977+
978+
**Ejemplo de consumo de la libreria para cancelar con PFX con motivo 01 con documento relacionado**
979+
980+
```java
981+
import mx.com.sw.services.cancelationretention.responses.CancelationRetResponse;
982+
import org.junit.jupiter.api.Assertions;
983+
import org.junit.jupiter.api.Test;
984+
985+
public class App {
986+
987+
@Test
988+
public void testCancellationPFX() {
989+
try {
990+
// Creamos una instancia de tipo CancelationRetention, pasando la URL, usuario y contraseña para obtener el token
991+
CancelationRetention cancelation = new CancelationRetention(settings.getUrlSW(), settings.getUserSW(), settings.getPasswordSW(), null, 0);
992+
993+
// Obtenemos los datos del PFX desde la configuración
994+
String pfxBase64 = settings.getPFX();
995+
String password = settings.getPasswordPFX();
996+
String rfc = settings.getRFC();
997+
998+
// Definimos el UUID a cancelar
999+
String uuid = "8D93A20F-E9EF-42CA-A2B9-2986A352DCEC";
1000+
1001+
// Realizamos la petición de cancelación al servicio
1002+
CancelationRetResponse response = cancelation.cancelar(pfxBase64, rfc, password, uuid, "02", null);
1003+
1004+
// Verificamos que la respuesta no sea nula y contenga un estado
1005+
Assertions.assertNotNull(response);
1006+
Assertions.assertNotNull(response.getStatus());
1007+
1008+
// Validamos que el estatus sea "success" o que indique intermitencia del SAT
1009+
Assertions.assertTrue("success".equalsIgnoreCase(response.getStatus()) || response.getMessage().contains("Intermitencia del SAT"));
1010+
} catch (ServicesException ex) {
1011+
// Manejamos una posible excepción
1012+
Assertions.assertNotNull(ex);
1013+
}
1014+
}
1015+
}
1016+
1017+
```
1018+
</details>
1019+
7081020
## Validación ##
7091021

7101022
<details>
@@ -2985,7 +3297,6 @@ public class App {
29853297
}
29863298
```
29873299
</details>
2988-
29893300
---
29903301

29913302
Para mayor referencia de un listado completo de los servicios favor de visitar el siguiente [link](http://developers.sw.com.mx/).

pom.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>mx.com.sw</groupId>
55
<artifactId>sdk-java18</artifactId>
6-
<version>0.0.15.1</version>
6+
<version>0.0.19.1</version>
77
<packaging>jar</packaging>
88
<properties>
99
<maven.compiler.source>1.8</maven.compiler.source>
@@ -300,6 +300,16 @@
300300
</execution>
301301
</executions>
302302
</plugin>
303+
<plugin>
304+
<groupId>com.diffplug.spotless</groupId>
305+
<artifactId>spotless-maven-plugin</artifactId>
306+
<version>2.37.0</version>
307+
<configuration>
308+
<java>
309+
<googleJavaFormat/>
310+
</java>
311+
</configuration>
312+
</plugin>
303313
<plugin>
304314
<groupId>org.apache.maven.plugins</groupId>
305315
<artifactId>maven-surefire-plugin</artifactId>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version="1.0" encoding="utf-8" ?><Cancelacion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Fecha="2025-08-13T10:37:18" RfcEmisor="EKU9003173C9" xmlns="http://www.sat.gob.mx/esquemas/retencionpago/1"><Folios><Folio UUID="3044cc3f-572f-4535-85e2-374c205f5b11" Motivo="02" FolioSustitucion=""/></Folios><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>9BJNvxbmxoUZZZInri6L3HhxeN8=</DigestValue></Reference></SignedInfo><SignatureValue>LbAI6rBtmmgH7KeJ2f0EnH19iN+Z+dubN4YjoRf7SLBZiI+wUEIEjBhQAhVU8USDRSbwxJ66/E13MiQlmeBNuwOzsFaF1l7Haf2Cn4tmrLrKKKPS36HZ4sBgc+wkInLtfMEHWuzPwEhs3oQ6z1TFpNTvFPSS0buqsVX6hHWmnbrSARtxWK/FPzC7tsSqx9WQw0WYDvL6TIauPwNdNgpOx73xensQOfX3CO8LiW8NFLt2F3O07Xde3uIeciJNUK0+/uKjbj6X0O2QFS/71tJLyBaDo984FvesKD31yZOKx0QYLS05oPb1N1CH01DTXPeP/4t9qJf7L4P9qAsVTARlow==</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIFsDCCA5igAwIBAgIUMzAwMDEwMDAwMDA1MDAwMDM0MTYwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWxpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMjMwNTE4MTE0MzUxWhcNMjcwNTE4MTE0MzUxWjCB1zEnMCUGA1UEAxMeRVNDVUVMQSBLRU1QRVIgVVJHQVRFIFNBIERFIENWMScwJQYDVQQpEx5FU0NVRUxBIEtFTVBFUiBVUkdBVEUgU0EgREUgQ1YxJzAlBgNVBAoTHkVTQ1VFTEEgS0VNUEVSIFVSR0FURSBTQSBERSBDVjElMCMGA1UELRMcRUtVOTAwMzE3M0M5IC8gVkFEQTgwMDkyN0RKMzEeMBwGA1UEBRMVIC8gVkFEQTgwMDkyN0hTUlNSTDA1MRMwEQYDVQQLEwpTdWN1cnNhbCAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmecO6n2GS0zL025gbHGQVxznPDICoXzR2uUngz4DqxVUC/w9cE6FxSiXm2ap8Gcjg7wmcZfm85EBaxCx/0J2u5CqnhzIoGCdhBPuhWQnIh5TLgj/X6uNquwZkKChbNe9aeFirU/JbyN7Egia9oKH9KZUsodiM/pWAH00PCtoKJ9OBcSHMq8Rqa3KKoBcfkg1ZrgueffwRLws9yOcRWLb02sDOPzGIm/jEFicVYt2Hw1qdRE5xmTZ7AGG0UHs+unkGjpCVeJ+BEBn0JPLWVvDKHZAQMj6s5Bku35+d/MyATkpOPsGT/VTnsouxekDfikJD1f7A1ZpJbqDpkJnss3vQIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG9w0BAQsFAAOCAgEAFaUgj5PqgvJigNMgtrdXZnbPfVBbukAbW4OGnUhNrA7SRAAfv2BSGk16PI0nBOr7qF2mItmBnjgEwk+DTv8Zr7w5qp7vleC6dIsZFNJoa6ZndrE/f7KO1CYruLXr5gwEkIyGfJ9NwyIagvHHMszzyHiSZIA850fWtbqtythpAliJ2jF35M5pNS+YTkRB+T6L/c6m00ymN3q9lT1rB03YywxrLreRSFZOSrbwWfg34EJbHfbFXpCSVYdJRfiVdvHnewN0r5fUlPtR9stQHyuqewzdkyb5jTTw02D2cUfL57vlPStBj7SEi3uOWvLrsiDnnCIxRMYJ2UA2ktDKHk+zWnsDmaeleSzonv2CHW42yXYPCvWi88oE1DJNYLNkIjua7MxAnkNZbScNw01A6zbLsZ3y8G6eEYnxSTRfwjd8EP4kdiHNJftm7Z4iRU7HOVh79/lRWB+gd171s3d/mI9kte3MRy6V8MMEMCAnMboGpaooYwgAmwclI2XZCczNWXfhaWe0ZS5PmytD/GDpXzkX0oEgY9K/uYo5V77NdZbGAjmyi8cE2B2ogvyaN2XfIInrZPgEffJ4AB7kFA2mwesdLOCh0BLD9itmCve3A1FGR4+stO2ANUoiI3w3Tv2yQSg4bjeDlJ08lXaaFCLW2peEXMXjQUk7fmpb5MNuOUTW6BE=</X509Certificate><X509IssuerSerial><X509IssuerName>CN=AC UAT, O=SERVICIO DE ADMINISTRACION TRIBUTARIA, OU=SAT-IES Authority, E=oscar.martinez@sat.gob.mx, STREET=3ra cerrada de caliz, PostalCode=06370, C=MX, ST=CIUDAD DE MEXICO, L=COYOACAN, OID.2.5.4.45=2.5.4.45, OID.1.2.840.113549.1.9.2=responsable: ACDMA-SAT</X509IssuerName><X509SerialNumber>3330303031303030303030353030303033343136</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></Cancelacion>

resources/pdfresult.pdf

10 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)