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
199 changes: 199 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,205 @@ public class ExampleReadme {
```
</details>

# Cancelación de Retenciones #

Este servicio se utiliza para cancelar retenciones, aquí los métodos que se ofrecen:

<details>
<summary>
Cancelación de Retenciones por CSD
</summary>
Como su nombre lo indica, este método recibe todos los elementos que componen el CSD los cuales son los siguientes:

- Certificado (.cer) en Base64
- Key (.key) en Base64
- RFC emisor
- Password del archivo key
- UUID
- Motivo
- Folio Sustitución (requerido sólo cuando Motivo es 01)

**Ejemplo de consumo de la librería para cancelar retenciones con CSD**

```java
package com.mycompany.examplereadme;

import Exceptions.AuthException;
import Exceptions.GeneralException;
import Services.CancelationRetention.SWCancelationRetentionService;
import Utils.Responses.Cancelation.CancelationResponse;
import java.io.IOException;

public class ExampleReadme {

public static void main(String[] args) {
try {
//Instancia del servicio y autenticación
SWCancelationRetentionService sdk = new SWCancelationRetentionService("user", "password", "https://services.test.sw.com.mx");
CancelationResponse response = null;
//Paso de datos de cancelación
response = (CancelationResponse) sdk.Cancelation("uuid", "password_csd", "rfc", "b64Cer", "b64Key", "motivo", "folio_sustitucion");
//Muestra los resultados
System.out.println(response.Status);
System.out.println(response.HttpStatusCode);
System.out.println(response.acuse);
System.out.println(response.uuid);
System.out.println(response.uuidStatusCode);
//En caso de obtener un error, este puede obtenerse de los campos
System.out.println(response.message);
System.out.println(response.messageDetail);
} catch (AuthException | GeneralException | IOException e) {
System.out.println(e);
}

}
}
```

**Cancelar retenciones con CSD utilizando token**

```java
//Basta con sustituir esta linea en el ejemplo anterior, colocarás el token de tu cuenta y la URL base del ambiente que requieres acceder
SWCancelationRetentionService sdk = new SWCancelationRetentionService("tokenUser", "https://services.test.sw.com.mx");
```
</details>

<details>
<summary>
Cancelación de Retenciones por PFX
</summary>

Este método recibe los siguientes parámetros:

- Archivo PFX en Base64
- RFC emisor
- Password de PFX
- UUID
- Motivo
- Folio Sustitución (requerido sólo cuando Motivo es 01)

**Ejemplo de consumo de la librería para cancelar retenciones con PFX**

```java
package com.mycompany.examplereadme;

import Exceptions.AuthException;
import Exceptions.GeneralException;
import Services.CancelationRetention.SWCancelationRetentionService;
import Utils.Responses.Cancelation.CancelationResponse;
import java.io.IOException;

public class ExampleReadme {

public static void main(String[] args) {
try {
//Instancia del servicio y autenticación
SWCancelationRetentionService sdk = new SWCancelationRetentionService("user", "password", "https://services.test.sw.com.mx");
CancelationResponse response = null;
//Paso de datos de cancelación
response = (CancelationResponse) sdk.Cancelation("uuid", "password_pfx", "rfc", "pfxb64", "motivo", "folio_sustitucion");
//Muestra los resultados
System.out.println(response.Status);
System.out.println(response.HttpStatusCode);
System.out.println(response.acuse);
System.out.println(response.uuid);
System.out.println(response.uuidStatusCode);
//En caso de obtener un error, este puede obtenerse de los campos
System.out.println(response.message);
System.out.println(response.messageDetail);
} catch (AuthException | GeneralException | IOException e) {
System.out.println(e);
}

}
}
```

**Cancelar retenciones con PFX utilizando token**

```java
//Basta con sustituir esta linea en el ejemplo anterior, colocarás el token de tu cuenta y la URL base del ambiente que requieres acceder
SWCancelationRetentionService sdk = new SWCancelationRetentionService("tokenUser", "https://services.test.sw.com.mx");
```
</details>

<details>
<summary>
Cancelación de Retenciones por XML
</summary>

Este método recibe únicamente el XML sellado con los UUID a cancelar.

**Ejemplo de XML para cancelar retenciones**
```xml
<?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-31T01:57:44"
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#">
<!-- ... contenido de la firma ... -->
</Signature>
</Cancelacion>
```

Para caso de motivo 01 deberá añadir el atributo "FolioSustitucion" dentro del Nodo
**Ejemplo nodo Folio motivo 01**
```xml
<Folios>
<Folio UUID="3044cc3f-572f-4535-85e2-374c205f5b11" Motivo="01" FolioSustitucion="b3641a4b-7177-4323-aaa0-29bd34bf1ff8" />
</Folios>
```

**Ejemplo de consumo de la librería para cancelar retenciones por XML**

```java
package com.mycompany.examplereadme;

import Exceptions.AuthException;
import Exceptions.GeneralException;
import Services.CancelationRetention.SWCancelationRetentionService;
import Utils.Responses.Cancelation.CancelationResponse;
import java.io.IOException;

public class ExampleReadme {

public static void main(String[] args) {
try {
//Instancia del servicio y autenticación
SWCancelationRetentionService sdk = new SWCancelationRetentionService("user", "password", "https://services.test.sw.com.mx");
CancelationResponse response = null;
//Paso de XML de cancelación
response = (CancelationResponse) sdk.Cancelation("xmlCancelacion");
//Muestra los resultados
System.out.println(response.Status);
System.out.println(response.HttpStatusCode);
System.out.println(response.acuse);
System.out.println(response.uuid);
System.out.println(response.uuidStatusCode);
//En caso de obtener un error, este puede obtenerse de los campos
System.out.println(response.message);
System.out.println(response.messageDetail);
} catch (AuthException | GeneralException | IOException e) {
System.out.println(e);
}

}
}
```

**Cancelar retenciones por XML utilizando token**

```java
//Basta con sustituir esta linea en el ejemplo anterior, colocarás el token de tu cuenta y la URL base del ambiente que requieres acceder
SWCancelationRetentionService sdk = new SWCancelationRetentionService("tokenUser", "https://services.test.sw.com.mx");
```
</details>


# Validación #

Expand Down
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.22.1</version>
<version>1.0.23.1</version>
<packaging>jar</packaging>
<scm>
<url>https://github.com/lunasoft/sw-sdk-java</url>
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/Services/Cancelation/SWCancelationService.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@ public SWCancelationService(String token, String URI, String proxyHost, int prox
}

public IResponse Cancelation(String uuid, String password, String rfc, String b64Cer, String b64Key, String motivo, String folioSustitucion) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc, b64Cer, b64Key, motivo, folioSustitucion, getProxyHost(), getProxyPort());
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc, b64Cer, b64Key, motivo, folioSustitucion, false, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequest(settings);
}

public IResponse Cancelation(String xml) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), xml, getProxyHost(), getProxyPort());
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), xml, false, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequestXml(settings, true);
}

public IResponse Cancelation(String uuid, String password, String rfc, String b64Pfx, String motivo, String folioSustitucion) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc, b64Pfx, motivo, folioSustitucion, getProxyHost(), getProxyPort());
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc, b64Pfx, motivo, folioSustitucion, false, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequestPfx(settings);
}

public IResponse Cancelation(String uuid, String rfc, String motivo, String folioSustitucion) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, rfc, motivo, folioSustitucion, getProxyHost(), getProxyPort());
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, rfc, motivo, folioSustitucion, false, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequestUuid(settings);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package Services.CancelationRetention;

import java.io.IOException;
import Exceptions.AuthException;
import Exceptions.GeneralException;
import Services.SWService;
import Utils.Requests.Cancelation.CancelationOptionsRequest;
import Utils.Requests.Cancelation.CancelationRequest;
import Utils.Responses.IResponse;

/**
* Servicio para implementaci�n de cancelaci�n de retenciones.
*/
public class SWCancelationRetentionService extends SWService {

public SWCancelationRetentionService(String user, String password, String URI) throws AuthException {
super(user, password, URI);
}

public SWCancelationRetentionService(String token, String URI) {
super(token, URI);
}

public SWCancelationRetentionService(String user, String password, String URI, String proxyHost, int proxyPort)
throws AuthException {
super(user, password, URI, proxyHost, proxyPort);
}

public SWCancelationRetentionService(String token, String URI, String proxyHost, int proxyPort) {
super(token, URI, proxyHost, proxyPort);
}

/**
* Realiza la cancelaci�n de retenciones utilizando el certificado CSD.
*
* @param uuid uuid factura.
* @param password password de llave privada.
* @param rfc rfc emisor.
* @param csd String base64 del certificado.
* @param key String base64 de llave privada.
* @param motivo motivo de cancelacion.
* @param folioSustitucion uuid factura que sustituye.
* @throws AuthException Si ocurre un error de autenticaci�n.
* @throws GeneralException Si ocurre un error general en el proceso.
* @throws IOException Si ocurre un error de entrada/salida.
* @return {@link IResponse} La respuesta del servicio de cancelaci�n.
*/
public IResponse Cancelation(String uuid, String password, String rfc, String b64Cer, String b64Key, String motivo,
String folioSustitucion) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc,
b64Cer, b64Key, motivo, folioSustitucion, true, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequest(settings);
}

/**
* Realiza la cancelaci�n de retenciones mediante PFX.
*
* @param uuid uuid factura.
* @param password password de llave privada.
* @param rfc rfc emisor.
* @param b64Pfx El archivo PFX del contribuyente codificado en
* Base64.
* @param motivo motivo de cancelacion.
* @param folioSustitucion uuid factura que sustituye.
* @throws AuthException Si ocurre un error de autenticaci�n.
* @throws GeneralException Si ocurre un error general en el proceso.
* @throws IOException Si ocurre un error de entrada/salida.
* @return {@link IResponse} La respuesta del servicio de cancelaci�n.
*/
public IResponse Cancelation(String uuid, String password, String rfc, String b64Pfx, String motivo,
String folioSustitucion) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), uuid, password, rfc,
b64Pfx, motivo, folioSustitucion, true, getProxyHost(), getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequestPfx(settings);
}

/**
* Realiza la cancelaci�n de retenciones mediante XML.
*
* @param xml String XML de cancelaci�n de retenciones.
* @throws AuthException Si ocurre un error de autenticaci�n.
* @throws GeneralException Si ocurre un error general en el proceso.
* @throws IOException Si ocurre un error de entrada/salida.
* @return {@link IResponse} respuesta del servicio de cancelaci�n.
*/
public IResponse Cancelation(String xml) throws AuthException, GeneralException, IOException {
CancelationOptionsRequest settings = new CancelationOptionsRequest(getToken(), getURI(), xml, true, getProxyHost(),
getProxyPort());
CancelationRequest req = new CancelationRequest();
return req.sendRequestXml(settings, true);
}
}
3 changes: 3 additions & 0 deletions src/main/java/Utils/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public class Constants {
public static String CANCELATION_CSD_PATH = "/cfdi33/cancel/csd";
public static String CANCELATION_XML_PATH = "/cfdi33/cancel/xml";
public static String CANCELATION_PFX_PATH = "/cfdi33/cancel/pfx";
public static String CANCELATION_RET_CSD_PATH = "/retencion/cancel/csd";
public static String CANCELATION_RET_XML_PATH = "/retencion/cancel/xml";
public static String CANCELATION_RET_PFX_PATH = "/retencion/cancel/pfx";
public static String CANCELATION_UUID_PATH = "/cfdi33/cancel/";
public static String BALANCE_ACCOUNT_PATH = "/account/balance/";
public static String BALANCE_ACCOUNT_MANAGEMENT_PATH = "/management/api/balance/";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ public class CancelationOptionsRequest extends IRequest{
private String xml;
private String motivo;
private String folioSustitucion;
private boolean isRetention;


public CancelationOptionsRequest(String token, String URI, String uuid, String password, String rfc, String b64Cer, String b64Key, String motivo, String folioSustitucion, String proxyHost, int proxyPort) {
super(token, URI+ Constants.CANCELATION_CSD_PATH, proxyHost, proxyPort);
public CancelationOptionsRequest(String token, String URI, String uuid, String password, String rfc, String b64Cer, String b64Key, String motivo, String folioSustitucion, boolean isRetention, String proxyHost, int proxyPort) {
super(token, URI+ (isRetention ? Constants.CANCELATION_RET_CSD_PATH : Constants.CANCELATION_CSD_PATH), proxyHost, proxyPort);
this.uuid = uuid;
this.password = password;
this.rfc = rfc;
Expand All @@ -26,8 +27,8 @@ public CancelationOptionsRequest(String token, String URI, String uuid, String p
this.folioSustitucion = folioSustitucion;
}

public CancelationOptionsRequest(String token, String URI, String uuid, String password, String rfc, String b64Pfx, String motivo, String folioSustitucion, String proxyHost, int proxyPort) {
super(token, URI+ Constants.CANCELATION_PFX_PATH, proxyHost, proxyPort);
public CancelationOptionsRequest(String token, String URI, String uuid, String password, String rfc, String b64Pfx, String motivo, String folioSustitucion, boolean isRetention, String proxyHost, int proxyPort) {
super(token, URI+ (isRetention ? Constants.CANCELATION_RET_PFX_PATH : Constants.CANCELATION_PFX_PATH), proxyHost, proxyPort);
this.uuid = uuid;
this.password = password;
this.rfc = rfc;
Expand All @@ -36,11 +37,11 @@ public CancelationOptionsRequest(String token, String URI, String uuid, String p
this.folioSustitucion = folioSustitucion;
}

public CancelationOptionsRequest(String token, String URI, String xml, String proxyHost, int proxyPort) {
super(token, URI+ Constants.CANCELATION_XML_PATH, proxyHost, proxyPort);
public CancelationOptionsRequest(String token, String URI, String xml, boolean isRetention, String proxyHost, int proxyPort) {
super(token, URI+ (isRetention ? Constants.CANCELATION_RET_XML_PATH : Constants.CANCELATION_XML_PATH), proxyHost, proxyPort);
this.xml = xml;
}
public CancelationOptionsRequest(String token, String URI, String uuid, String rfc, String motivo, String folioSustitucion, String proxyHost, int proxyPort) {
public CancelationOptionsRequest(String token, String URI, String uuid, String rfc, String motivo, String folioSustitucion, boolean isRetention, String proxyHost, int proxyPort) {
//super(token, URI + Constants.CANCELATION_UUID_PATH + rfc + "/" + uuid + "/" + motivo + "/" + foliosustitucion, proxyHost, proxyPort);
super(token, URI + Constants.CANCELATION_UUID_PATH + String.format("%s/%s/%s/%s", rfc, uuid, motivo, folioSustitucion ), proxyHost, proxyPort);
this.uuid = uuid;
Expand Down Expand Up @@ -81,4 +82,7 @@ public String getMotivo() {
public String getFolioSustitucion() {
return folioSustitucion;
}
public boolean getRetention() {
return isRetention;
}
}
Loading