# Liquidación de compra

## Introducción

La liquidación de compras electrónica es un comprobante digital que emite un contribuyente cuando realiza una adquisición a un proveedor no obligado a facturar electrónicamente, como personas naturales sin RUC o en el régimen popular. Este documento permite registrar contable y fiscalmente la operación, y debe incluir todos los datos necesarios para su validación tributaria. Se emite, firma y transmite al SRI de forma electrónica, como cualquier otro comprobante autorizado.

**Beneficios de la Facturación Electrónica**

* **Eficiencia Operativa:** La automatización del proceso de facturación reduce la carga administrativa, disminuyendo los errores humanos y acelerando las transacciones.
* **Reducción de Costos:** Menores gastos en papel, impresión, envío y almacenamiento de documentos físicos.
* **Acceso y Gestión Simplificados:** El almacenamiento digital facilita la búsqueda y gestión de documentos, lo que es especialmente útil para auditorías y cumplimiento fiscal.

## Autenticación

Para acceder al servicio de facturación electrónica a través de nuestra API SOAP deben de identificarse y autenticarse usando una credencial única denominada **Clave**.

La autenticación se realiza incluyendo la credencial en el cuerpo del mensaje SOAP, dentro del nodo `<Clave>`. A continuación, se describe la estructura de la solicitud.

Ejemplo:

```xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:com="https://ec.edocnube.com/api/emision/compretencion" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirFactura>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:Factura/>
      </emis:EmitirFactura>
   </soapenv:Body>
</soapenv:Envelope>
```

<table><thead><tr><th width="165">Elemento</th><th>Descripción</th></tr></thead><tbody><tr><td>Clave</td><td><strong>Requerido.</strong> Credencial única proporcionada a la empresa para autenticarse. Esta clave es específica y debe mantenerse confidencial.</td></tr></tbody></table>

{% tabs %}
{% tab title="JavaScript" %}

```javascript
 url = '/URL_SOAP_EMISION/EmitirDocumentoService.svc?wsdl';

// XML del mensaje SOAP
const soapRequest = `
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:com="https://ec.edocnube.com/api/emision/compretencion" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirFactura>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:Factura/>
      </emis:EmitirFactura>
   </soapenv:Body>
</soapenv:Envelope>
`;

// Configuración de la solicitud HTTP
const headers = {
  'Content-Type': 'text/xml; charset=utf-8', // Tipo de contenido para SOAP
  SOAPAction: 'http://tempuri.org/EmitirDocumentoService/EmitirFactura', // Acción SOAP específica
};

// Realizar la solicitud con fetch
fetch(url, {
  method: 'POST',
  headers: headers,
  body: soapRequest,
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.text();
  })
  .then((data) => {
    console.log('Respuesta SOAP:', data);
  })
  .catch((error) => {
    console.error('Error en la solicitud SOAP:', error.message);
  });

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
// URL del servicio WSDL
$wsdl = "/URL_SOAP_EMISION/EmitirDocumentoService.svc?wsdl";

try {
    // Crear un cliente SOAP
    $client = new SoapClient($wsdl, [
        'trace' => true,       // Habilitar trazas para depuración
        'cache_wsdl' => WSDL_CACHE_NONE, // No cachear el WSDL
        'exceptions' => true   // Lanzar excepciones en errores
    ]);

    // Parámetros para el método
    $params = [
        "Clave" => "{CLAVE_VALOR}", // Credencial única
        "Factura" => null
    ];

    // Llamar al método
    $response = $client->__soapCall("EmitirFactura", [$params]);

    // Mostrar la respuesta
    echo "Respuesta SOAP:\n";
    print_r($response);
} catch (SoapFault $fault) {
    // Manejo de errores
    echo "Error SOAP: " . $fault->getMessage() . "\n";
    echo "Código de error: " . $fault->faultcode . "\n";
    echo "Detalles:\n" . $fault->detail . "\n";
}
?>

```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        string url = "/URL_SOAP_EMISION/EmitirDocumentoService.svc";
        string soapAction = "http://tempuri.org/EmitirDocumentoService/EmitirFactura";
        
        string soapEnvelope = @"<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:com="https://ec.edocnube.com/api/emision/compretencion" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
           <soapenv:Header/>
           <soapenv:Body>
              <emis:EmitirFactura>
                 <emis:Clave>{CLAVE_VALOR}</Clave>
                 <emis:Factura/>
              </emis:EmitirFactura>
           </soapenv:Body>
        </soapenv:Envelope>";

        using (HttpClient client = new HttpClient())
        {
            var request = new HttpRequestMessage(HttpMethod.Post, url)
            {
                Content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml")
            };
            request.Headers.Add("SOAPAction", soapAction);

            HttpResponseMessage response = await client.SendAsync(request);
            string responseContent = await response.Content.ReadAsStringAsync();

            Console.WriteLine("Respuesta del servidor:");
            Console.WriteLine(responseContent);
        }
    }
}

```

{% endtab %}

{% tab title="Python" %}

```python
import requests

# URL del servicio SOAP
url = "/URL_SOAP_EMISION/EmitirDocumentoService.svc"

# Cabeceras HTTP
headers = {
    "Content-Type": "text/xml; charset=utf-8",
    "SOAPAction": "http://tempuri.org/EmitirDocumentoService/EmitirFactura"
}

# Cuerpo del mensaje SOAP
soap_body = """<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:com="https://ec.edocnube.com/api/emision/compretencion" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirFactura>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:Factura/>
      </emis:EmitirFactura>
   </soapenv:Body>
</soapenv:Envelope>"""

try:
    # Enviar la solicitud POST
    response = requests.post(url, data=soap_body, headers=headers)

    # Verificar el estado de la respuesta
    if response.status_code == 200:
        print("Respuesta del servidor:")
        print(response.text)
    else:
        print(f"Error en la solicitud: {response.status_code}")
        print(response.text)

except requests.exceptions.RequestException as e:
    print(f"Error al realizar la solicitud: {e}")

```

{% endtab %}

{% tab title="Curl" %}

```bash
curl -X POST "/URL_SOAP_EMISION/EmitirDocumentoService.svc" \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: http://tempuri.org/EmitirDocumentoService/EmitirFactura" \
-d '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:com="https://ec.edocnube.com/api/emision/compretencion" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirFactura>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:Factura/>
      </emis:EmitirFactura>
   </soapenv:Body>
</soapenv:Envelope>'

```

{% endtab %}
{% endtabs %}

## Emisión de Liquidación de Compra <a href="#emision-de-factura" id="emision-de-factura"></a>

En esta sección, abordaremos los detalles técnicos específicos del proceso de emisión de guía de remisión electrónicas utilizando la tecnología SOAP. Exploraremos cómo este enfoque facilita la integración eficiente y segura de los sistemas de facturación dentro de las infraestructuras empresariales existentes, asegurando la conformidad con los estándares legales y fiscales relevantes. Nos centraremos en la implementación de SOAP para describir las interacciones entre los sistemas y los métodos empleados para la transmisión de datos de facturación electrónica.

## Estados eDoc

La gestión adecuada de los estados eDoc es crucial en el sistema de facturación electrónica, ya que cada estado refleja una etapa específica en el proceso de validación y envío de documentos a la entidad tributaria. A continuación, se presenta una tabla que describe cada uno de los estados eDoc, proporcionando claridad sobre las acciones necesarias según el estado en que se encuentre el documento.

<table><thead><tr><th width="88" align="center">Valor</th><th>Descripción</th><th>Causa</th><th>Solución</th></tr></thead><tbody><tr><td align="center">2</td><td>Documento autorizado por el ente tributario</td><td>Documento autorizado por el SRI</td><td>Ninguna</td></tr><tr><td align="center">3</td><td>Documento no autorizado por el ente tributario</td><td>Documento no superó la validación debido al incumplimiento de las reglas de negocio establecidas por el SRI</td><td>Realizar la corrección de los datos del documento y emitirlo nuevamente</td></tr><tr><td align="center">4</td><td>Error al emitir o consultar el documento en eDoc</td><td>Ha ocurrido un error en eDoc, el cual ha sido identificado con un código para su seguimiento y solución</td><td>Levantar un ticket de atención en el portal de soporte técnico de GuruSoft</td></tr><tr><td align="center">5</td><td>Documento en espera de autorización por parte del ente tributario</td><td>eDoc no pudo establecer una conexión con el SRI para consultar la autorización del documento, se realizará una reconsulta automática posteriormente</td><td>Realizar la consulta del estado del documento mediante la API correspondiente, una vez transcurrido un intervalo de tiempo adecuado</td></tr><tr><td align="center">6</td><td>Documento rechazado por el ente tributario</td><td>Documento no cumplió con las validaciones de estructura y/o formato XML requeridas por el SRI</td><td>Realizar la corrección de los datos del documento y emitirlo nuevamente</td></tr><tr><td align="center">7</td><td>Documento en espera de recepción por parte del ente tributario</td><td>eDoc no pudo establecer una conexión con el SRI para transmitir el documento, se realizará un reenvío automático posteriormente</td><td>Realizar la consulta del estado del documento mediante la API correspondiente, una vez transcurrido un intervalo de tiempo adecuado</td></tr><tr><td align="center">11</td><td>Documento anulado en eDoc</td><td>Documento ha sido anulado por el emisor mediante el portal web del SRI</td><td>Una vez alcanzado este estado, el documento no puede ser modificado ni revertido</td></tr><tr><td align="center">15</td><td>Solicitud de emisión o consulta rechazada por eDoc</td><td>Solicitud de emisión o consulta no cumplió con las validaciones de estructura y/o formato XML requeridas por eDoc</td><td>Realizar la corrección de los datos del documento y emitirlo nuevamente</td></tr><tr><td align="center">18</td><td>Documento no encontrado en eDoc</td><td>Documento consultado no fue encontrando en eDoc</td><td>Realizar la corrección de los parámetros de la consulta y repetir el proceso</td></tr></tbody></table>

* **Estado Autorizado (2):** Este estado indica que el documento ha sido autorizado por la entidad tributaria. En este punto, no se requiere ninguna acción adicional como reenvío o consulta del estado, pues el documento ya ha completado su proceso satisfactoriamente.
* **Estado No autorizado (3):** Este estado indica que el documento no ha sido aprobado y requiere **corrección** para poder ser autorizado en un nuevo intento. Se permite un máximo de tres envíos por documento (incluyendo el primero). En caso de que el documento permanezca en estado No autorizado, deberá esperar al siguiente día para realizar un nuevo envío.
* **Estados Transitorios (5, 7):** Estos estados reflejan las fases intermedias en el proceso de envío y recepción de documentos con la entidad tributaria. En todos estos casos, no se deben reenviar los documentos, sino consultar su estado hasta que cambien a una situación definitiva.
* **Estados de Error y Corrección (4, 6, 15):** El estado 4 indica un error en el proceso de envío o procesamiento, y no debe reenviarse automáticamente; es necesario revisar el error específico y corregirlo si es posible. El estado 6 se asigna a documentos rechazados por la entidad tributaria y requiere corrección manual antes de un reenvío. El estado 15 sugiere que el documento fue devuelto por eDoc empresarial y debe ser analizado para determinar la causa y decidir las acciones correctivas apropiadas. En estos casos, la corrección de errores es fundamental antes de cualquier intento de reenvío.
* **Estado de Anulación (11):** Este estado indica que el documento ha sido anulado y, por lo tanto, ya no tiene validez legal o administrativa. No se requieren acciones adicionales para documentos en este estado, ya que han sido efectivamente retirados del proceso.

**Consideraciones Importantes**

* **Consultas de Estado:** Para los estados que sugieren consultar el estado del documento, es recomendable establecer un intervalo regular de consultas para evitar la saturación del sistema y asegurar la actualización oportuna del estado del documento.
* **Notificaciones a Soporte:** En casos de errores que no pueden ser resueltos directamente por el usuario, como el estado 4, es fundamental notificar al soporte técnico proporcionando todos los detalles necesarios para una rápida resolución del problema.

## Diccionario de datos

{% embed url="<https://wiki.edocnube.com/diccionario/Documentation/FromXml?classname=&p1=AJkuNFFcBIW7i1zn63Wd0zMug5qnw8YUIJVZZ4GV6wKJLsD/zqmX3g7ojWIfC7B6g7sCzj3eGRxTklfJ+lpnkcR7fXoHZszbiUl1yOPVS6JaBlwF/lISIm/ED8KEQVmI&p2=EoWbYb/FBQ7+HIWWn+AakB3g3J1gzmJ9kA8zwIvk7Vw=&p3=ASz1RE4QhWU=&p4=L5lbnPmTSNE=&p5=42yljgltFnM=&p6=0h6AVWZOsDA=>" %}

## Consumo

### Request

{% tabs %}
{% tab title="JavaScript" %}

```javascript
 url = '/URL_SOAP_EMISION/EmitirDocumentoService.svc?wsdl';

// XML del mensaje SOAP
const soapRequest = `
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:liq="https://ec.edocnube.com/api/emision/liquidacioncompra" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirLiquidacionCompra>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:LiquidacionCompra/>
      </emis:EmitirLiquidacionCompra>
   </soapenv:Body>
</soapenv:Envelope>
`;

// Configuración de la solicitud HTTP
const headers = {
  'Content-Type': 'text/xml; charset=utf-8', // Tipo de contenido para SOAP
  SOAPAction: 'http://tempuri.org/EmitirDocumentoService/EmitirLiquidacionCompra', // Acción SOAP específica
};

// Realizar la solicitud con fetch
fetch(url, {
  method: 'POST',
  headers: headers,
  body: soapRequest,
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.text();
  })
  .then((data) => {
    console.log('Respuesta SOAP:', data);
  })
  .catch((error) => {
    console.error('Error en la solicitud SOAP:', error.message);
  });

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
// URL del servicio WSDL
$wsdl = "/URL_SOAP_EMISION/EmitirDocumentoService.svc?wsdl";

try {
    // Crear un cliente SOAP
    $client = new SoapClient($wsdl, [
        'trace' => true,       // Habilitar trazas para depuración
        'cache_wsdl' => WSDL_CACHE_NONE, // No cachear el WSDL
        'exceptions' => true   // Lanzar excepciones en errores
    ]);

    // Parámetros para el método
    $params = [
        "Clave" => "{CLAVE_VALOR}", // Credencial única
        "LiquidacionCompra" => null
    ];

    // Llamar al método
    $response = $client->__soapCall("EmitirLiquidacionCompra", [$params]);

    // Mostrar la respuesta
    echo "Respuesta SOAP:\n";
    print_r($response);
} catch (SoapFault $fault) {
    // Manejo de errores
    echo "Error SOAP: " . $fault->getMessage() . "\n";
    echo "Código de error: " . $fault->faultcode . "\n";
    echo "Detalles:\n" . $fault->detail . "\n";
}
?>

```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        string url = "/URL_SOAP_EMISION/EmitirDocumentoService.svc";
        string soapAction = "http://tempuri.org/EmitirDocumentoService/EmitirLiquidacionCompra";
        
        string soapEnvelope = @"<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:liq="https://ec.edocnube.com/api/emision/liquidacioncompra" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
           <soapenv:Header/>
           <soapenv:Body>
              <emis:EmitirLiquidacionCompra>
                 <emis:Clave>{CLAVE_VALOR}</Clave>
                 <emis:LiquidacionCompra/>
              </emis:EmitirLiquidacionCompra>
           </soapenv:Body>
        </soapenv:Envelope>";

        using (HttpClient client = new HttpClient())
        {
            var request = new HttpRequestMessage(HttpMethod.Post, url)
            {
                Content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml")
            };
            request.Headers.Add("SOAPAction", soapAction);

            HttpResponseMessage response = await client.SendAsync(request);
            string responseContent = await response.Content.ReadAsStringAsync();

            Console.WriteLine("Respuesta del servidor:");
            Console.WriteLine(responseContent);
        }
    }
}

```

{% endtab %}

{% tab title="Python" %}

```python
import requests

# URL del servicio SOAP
url = "/URL_SOAP_EMISION/EmitirDocumentoService.svc"

# Cabeceras HTTP
headers = {
    "Content-Type": "text/xml; charset=utf-8",
    "SOAPAction": "http://tempuri.org/EmitirDocumentoService/EmitirLiquidacionCompra"
}

# Cuerpo del mensaje SOAP
soap_body = """<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:liq="https://ec.edocnube.com/api/emision/liquidacioncompra" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirLiquidacionCompra>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:LiquidacionCompra/>
      </emis:EmitirLiquidacionCompra>
   </soapenv:Body>
</soapenv:Envelope>"""

try:
    # Enviar la solicitud POST
    response = requests.post(url, data=soap_body, headers=headers)

    # Verificar el estado de la respuesta
    if response.status_code == 200:
        print("Respuesta del servidor:")
        print(response.text)
    else:
        print(f"Error en la solicitud: {response.status_code}")
        print(response.text)

except requests.exceptions.RequestException as e:
    print(f"Error al realizar la solicitud: {e}")
```

{% endtab %}

{% tab title="Curl" %}

```bash
curl -X POST "/URL_SOAP_EMISION/EmitirDocumentoService.svc" \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: http://tempuri.org/EmitirDocumentoService/EmitirLiquidacionCompra" \
-d '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:emis="https://ec.edocnube.com/api/emision" xmlns:liq="https://ec.edocnube.com/api/emision/liquidacioncompra" xmlns:ext="https://ec.edocnube.com/api/emision/extensiones">
   <soapenv:Header/>
   <soapenv:Body>
      <emis:EmitirLiquidacionCompra>
         <emis:Clave>{CLAVE_VALOR}</Clave>
         <emis:LiquidacionCompra/>
      </emis:EmitirLiquidacionCompra>
   </soapenv:Body>
</soapenv:Envelope>'
```

{% endtab %}
{% endtabs %}

### Response

En una comunicación SOAP, las respuestas HTTP pueden variar según el estado y el contenido de la comunicación:

* **200 (OK)**: La solicitud se procesó correctamente y devuelve un mensaje SOAP en XML con los detalles de la respuesta.

Estas respuestas permiten manejar adecuadamente los distintos escenarios de comunicación.

{% tabs %}
{% tab title="Estado HTTP 200" %}

```xml
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <EmitirLiquidacionCompraResponse xmlns="https://ec.edocnube.com/api/emision" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
         <Estado>2</Estado>
         <ClaveAcceso>2404202503099273796400110010150000000304618527311</ClaveAcceso>
         <NumAutorizacion>2404202503099273796400110010150000000304618527311</NumAutorizacion>
         <FechaAutorizacion>2025-06-12T09:29:05.000-05:00</FechaAutorizacion>
      </EmitirLiquidacionCompraResponse>
   </s:Body>
</s:Envelope>
```

{% endtab %}
{% endtabs %}
