# Factura electrónica

### Requisitos previos

Para poder usar esta guía, primero necesitarás:

* [Integrar Afip SDK en tu proyecto](/readme.md#integracion)

***

La especificación de este Web Service se encuentra disponible en <https://www.afip.gob.ar/ws/documentacion/manuales/manual-desarrollador-ARCA-COMPG-v4-0.pdf>

<details>

<summary>Identificador <kbd>wsfe</kbd></summary>

Producción <img src="/files/N4QM8iTXaXtQ66Xj8Gs5" alt="Produccion" data-size="line">

Desarrollo <img src="/files/SkkUxkZmP1C06dac8VG5" alt="Desarrollo" data-size="original">

</details>

{% hint style="info" %}
Aquí hablaremos de comprobante indistintamente si es una factura, nota de crédito, etc.
{% endhint %}

*Si es tu primera vez conectándote con la facturación electrónica de AFIP/ARCA, te recomiendo leer esta guía básica sobre su funcionamiento general:*

{% embed url="<https://afipsdk.com/blog/conectar-tu-sistema-con-la-facturacion-electronica-de-afip/>" fullWidth="false" %}

***

### Crear PDF

{% content-ref url="/pages/ffTzRIgExZ712TAX7yJx" %}
[Crear PDF](/siguientes-pasos/web-services/factura-electronica/crear-pdf.md)
{% endcontent-ref %}

### **Obtener número del último comprobante creado**

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

<pre class="language-javascript"><code class="lang-javascript"><strong>// Numero de punto de venta
</strong>const puntoDeVenta = 1;

// Tipo de comprobante
const tipoDeComprobante = 6; // 6 = Factura B

const lastVoucher = await afip.ElectronicBilling.getLastVoucher(puntoDeVenta, tipoDeComprobante);
</code></pre>

{% endtab %}

{% tab title="PHP" %}

```php
// Numero de punto de venta
$punto_de_venta = 1;

// Tipo de comprobante
$tipo_de_comprobante = 6; // 6 = Factura B

$last_voucher = $afip->ElectronicBilling->GetLastVoucher($punto_de_venta, $tipo_de_comprobante);
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# Numero de punto de venta
punto_de_venta = 1

# Tipo de comprobante
tipo_de_comprobante = 6 # 6 = Factura B

last_voucher = afip.ElectronicBilling.getLastVoucher(punto_de_venta, tipo_de_comprobante)
```

{% endtab %}

{% tab title="Python" %}

```python
# Numero de punto de venta
punto_de_venta = 1

# Tipo de comprobante
tipo_de_comprobante = 6 # 6 = Factura B

last_voucher = afip.ElectronicBilling.getLastVoucher(punto_de_venta, tipo_de_comprobante)
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// Punto de venta
int puntoDeVenta = 1;

// Tipo de comprobante
int tipoDeFactura = 6; // 6 = Factura B

var lastVoucher = await afip.ElectronicBilling.GetLastVoucherAsync(puntoDeVenta, tipoDeFactura);
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FECompUltimoAutorizado",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "PtoVta" : 1,
        "CbteTipo" : 6
    }
}
```

{% endtab %}
{% endtabs %}

### **Crear y asignar CAE a un comprobante**

{% tabs %}
{% tab title="Node" %}
Debemos utilizar el método `createVoucher` pasándole como parámetro un Objeto con los detalles del comprobante y si queremos tener la respuesta completa enviada por el WS debemos pasarle como segundo parámetro `true`, en caso de no enviarle el segundo parámetro nos devolverá como respuesta `{ CAE : CAE asignado el comprobante, CAEFchVto : Fecha de vencimiento del CAE (yyyy-mm-dd) }`.

```js
// Devolver respuesta completa del web service
const returnFullResponse = false;

const date = new Date(Date.now() - ((new Date()).getTimezoneOffset() * 60000)).toISOString().split('T')[0];

// Info del comprobante
let data = {
	'CantReg' 	: 1,  // Cantidad de comprobantes a registrar
	'PtoVta' 	: 1,  // Punto de venta
	'CbteTipo' 	: 6,  // Tipo de comprobante (ver tipos disponibles) 
	'Concepto' 	: 1,  // Concepto del Comprobante: (1)Productos, (2)Servicios, (3)Productos y Servicios
	'DocTipo' 	: 99, // Tipo de documento del comprador (99 consumidor final, ver tipos disponibles)
	'DocNro' 	: 0,  // Número de documento del comprador (0 consumidor final)
	'CbteDesde' 	: 1,  // Número de comprobante o numero del primer comprobante en caso de ser mas de uno
	'CbteHasta' 	: 1,  // Número de comprobante o numero del último comprobante en caso de ser mas de uno
	'CbteFch' 	: parseInt(date.replace(/-/g, '')), // (Opcional) Fecha del comprobante (yyyymmdd) o fecha actual si es nulo
	'ImpTotal' 	: 121, // Importe total del comprobante
	'ImpTotConc' 	: 0,   // Importe neto no gravado
	'ImpNeto' 	: 100, // Importe neto gravado
	'ImpOpEx' 	: 0,   // Importe exento de IVA
	'ImpIVA' 	: 21,  //Importe total de IVA
	'ImpTrib' 	: 0,   //Importe total de tributos
	'MonId' 	: 'PES', //Tipo de moneda usada en el comprobante (ver tipos disponibles)('PES' para pesos argentinos)
	'CondicionIVAReceptorId' : 5, // Condición frente al IVA del receptor  
	'MonCotiz' 	: 1,     // Cotización de la moneda usada (1 para pesos argentinos)  
	'Iva' 		: [ // (Opcional) Alícuotas asociadas al comprobante
		{
			'Id' 		: 5, // Id del tipo de IVA (5 para 21%)(ver tipos disponibles) 
			'BaseImp' 	: 100, // Base imponible
			'Importe' 	: 21 // Importe 
		}
	],
};

const res = await afip.ElectronicBilling.createVoucher(data, returnFullResponse);

res['CAE']; //CAE asignado el comprobante
res['CAEFchVto']; //Fecha de vencimiento del CAE (yyyy-mm-dd)
```

{% hint style="info" %}
Este método acepta mas parámetros, podes encontrar todos los parámetros disponibles [En este ejemplo](https://github.com/AfipSDK/afip.js/blob/master/examples/createVoucher.js)
{% endhint %}
{% endtab %}

{% tab title="PHP" %}
Debemos utilizar el método `CreateVoucher` pasándole como parámetro un Array con los detalles del comprobante y si queremos tener la respuesta completa devuelta por el WS debemos pasarle como segundo parámetro TRUE, en caso de no enviarle el segundo parámetro nos devolverá como respuesta `array(CAE => CAE asignado el comprobante, CAEFchVto => Fecha de vencimiento del CAE (yyyy-mm-dd))`.

```php
// Devolver respuesta completa del web service
$return_full_response = FALSE;

// Info del comprobante
$data = array(
	'CantReg' 	=> 1,  // Cantidad de comprobantes a registrar
	'PtoVta' 	=> 1,  // Punto de venta
	'CbteTipo' 	=> 6,  // Tipo de comprobante (ver tipos disponibles) 
	'Concepto' 	=> 1,  // Concepto del Comprobante: (1)Productos, (2)Servicios, (3)Productos y Servicios
	'DocTipo' 	=> 99, // Tipo de documento del comprador (99 consumidor final, ver tipos disponibles)
	'DocNro' 	=> 0,  // Número de documento del comprador (0 consumidor final)
	'CbteDesde' 	=> 1,  // Número de comprobante o numero del primer comprobante en caso de ser mas de uno
	'CbteHasta' 	=> 1,  // Número de comprobante o numero del último comprobante en caso de ser mas de uno
	'CbteFch' 	=> intval(date('Ymd')), // (Opcional) Fecha del comprobante (yyyymmdd) o fecha actual si es nulo
	'ImpTotal' 	=> 121, // Importe total del comprobante
	'ImpTotConc' 	=> 0,   // Importe neto no gravado
	'ImpNeto' 	=> 100, // Importe neto gravado
	'ImpOpEx' 	=> 0,   // Importe exento de IVA
	'ImpIVA' 	=> 21,  //Importe total de IVA
	'ImpTrib' 	=> 0,   //Importe total de tributos
	'MonId' 	=> 'PES', //Tipo de moneda usada en el comprobante (ver tipos disponibles)('PES' para pesos argentinos) 
	'MonCotiz' 	=> 1,     // Cotización de la moneda usada (1 para pesos argentinos)  
	'CondicionIVAReceptorId' => 5, // Condición frente al IVA del receptor  
	'Iva' 		=> array( // (Opcional) Alícuotas asociadas al comprobante
		array(
			'Id' 		=> 5, // Id del tipo de IVA (5 para 21%)(ver tipos disponibles) 
			'BaseImp' 	=> 100, // Base imponible
			'Importe' 	=> 21 // Importe 
		)
	), 
);

$res = $afip->ElectronicBilling->CreateVoucher($data, $return_full_response);

$res['CAE']; //CAE asignado el comprobante
$res['CAEFchVto']; //Fecha de vencimiento del CAE (yyyy-mm-dd)
```

{% hint style="info" %}
Este método acepta mas parámetros, podes encontrar todos los parámetros disponibles [En este ejemplo](https://github.com/AfipSDK/afip.php/blob/master/examples/CreateVoucher.php)
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}
Debemos utilizar el método `createVoucher` pasándole como parámetro un Hash con los detalles del comprobante y si queremos tener la respuesta completa devuelta por el WS debemos pasarle como segundo parámetro true, en caso de no enviarle el segundo parámetro nos devolverá como respuesta `{ "CAE": CAE asignado el comprobante, "CAEFchVto" : Fecha de vencimiento del CAE (yyyy-mm-dd) }`.

```ruby
# Devolver respuesta completa del web service
return_full_response = FALSE

# Info del comprobante
data = {
  "CantReg": 1,  # Cantidad de comprobantes a registrar
  "PtoVta": 1,  # Punto de venta
  "CbteTipo": 6,  # Tipo de comprobante (ver tipos disponibles) 
  "Concepto": 1,  # Concepto del Comprobante: (1)Productos, (2)Servicios, (3)Productos y Servicios
  "DocTipo": 99, # Tipo de documento del comprador (99 consumidor final, ver tipos disponibles)
  "DocNro": 0,  # Número de documento del comprador (0 consumidor final)
  "CbteDesde": 1,  # Número de comprobante o numero del primer comprobante en caso de ser mas de uno
  "CbteHasta": 1,  # Número de comprobante o numero del último comprobante en caso de ser mas de uno
  "CbteFch": 20231220, # (Opcional) Fecha del comprobante (yyyymmdd) o fecha actual si es nulo
  "ImpTotal": 121, # Importe total del comprobante
  "ImpTotConc": 0,   # Importe neto no gravado
  "ImpNeto": 100, # Importe neto gravado
  "ImpOpEx": 0,   # Importe exento de IVA
  "ImpIVA": 21,  # Importe total de IVA
  "ImpTrib": 0,   # Importe total de tributos
  "MonId": "PES", # Tipo de moneda usada en el comprobante (ver tipos disponibles)("PES" para pesos argentinos) 
  "MonCotiz": 1,     # Cotización de la moneda usada (1 para pesos argentinos)  
  "CondicionIVAReceptorId" : 5, # Condición frente al IVA del receptor  
  "Iva": [ # (Opcional) Alícuotas asociadas al comprobante
    {
      "Id": 5, # Id del tipo de IVA (5 para 21%)(ver tipos disponibles) 
      "BaseImp": 100, # Base imponible
      "Importe": 21 # Importe 
    }
  ]
}

res = afip.ElectronicBilling.createVoucher(data, return_full_response)

res["CAE"] # CAE asignado el comprobante
res["CAEFchVto"] # Fecha de vencimiento del CAE (yyyy-mm-dd)
```

{% endtab %}

{% tab title="Python" %}
Debemos utilizar el método `createVoucher` pasándole como parámetro un Hash con los detalles del comprobante y si queremos tener la respuesta completa devuelta por el WS debemos pasarle como segundo parámetro true, en caso de no enviarle el segundo parámetro nos devolverá como respuesta `{ "CAE": CAE asignado el comprobante, "CAEFchVto" : Fecha de vencimiento del CAE (yyyy-mm-dd) }`.

```python
# Devolver respuesta completa del web service
return_full_response = False

# Info del comprobante
data = {
  "CantReg": 1,  # Cantidad de comprobantes a registrar
  "PtoVta": 1,  # Punto de venta
  "CbteTipo": 6,  # Tipo de comprobante (ver tipos disponibles) 
  "Concepto": 1,  # Concepto del Comprobante: (1)Productos, (2)Servicios, (3)Productos y Servicios
  "DocTipo": 99, # Tipo de documento del comprador (99 consumidor final, ver tipos disponibles)
  "DocNro": 0,  # Número de documento del comprador (0 consumidor final)
  "CbteDesde": 1,  # Número de comprobante o numero del primer comprobante en caso de ser mas de uno
  "CbteHasta": 1,  # Número de comprobante o numero del último comprobante en caso de ser mas de uno
  "CbteFch": 20231220, # (Opcional) Fecha del comprobante (yyyymmdd) o fecha actual si es nulo
  "ImpTotal": 121, # Importe total del comprobante
  "ImpTotConc": 0,   # Importe neto no gravado
  "ImpNeto": 100, # Importe neto gravado
  "ImpOpEx": 0,   # Importe exento de IVA
  "ImpIVA": 21,  # Importe total de IVA
  "ImpTrib": 0,   # Importe total de tributos
  "MonId": "PES", # Tipo de moneda usada en el comprobante (ver tipos disponibles)("PES" para pesos argentinos) 
  "MonCotiz": 1,     # Cotización de la moneda usada (1 para pesos argentinos)  
  "CondicionIVAReceptorId" : 5, # Condición frente al IVA del receptor  
  "Iva": [ # (Opcional) Alícuotas asociadas al comprobante
    {
      "Id": 5, # Id del tipo de IVA (5 para 21%)(ver tipos disponibles) 
      "BaseImp": 100, # Base imponible
      "Importe": 21 # Importe 
    }
  ]
}

res = afip.ElectronicBilling.createVoucher(data, return_full_response)

res["CAE"] # CAE asignado el comprobante
res["CAEFchVto"] # Fecha de vencimiento del CAE (yyyy-mm-dd)
```

{% endtab %}

{% tab title=".NET" %}
Debemos utilizar el método `CreateVoucherAsync` pasándole como parámetro un Objeto con los detalles del comprobante y si queremos tener la respuesta completa enviada por el WS debemos pasarle como segundo parámetro `true`, en caso de no enviarle el segundo parámetro nos devolverá como respuesta `new Dictionary<string, object?> { ["CAE"] : CAE asignado el comprobante, ["CAEFchVto"] : Fecha de vencimiento del CAE (yyyy-mm-dd) }`.

```csharp
// Devolver respuesta completa del web service
bool returnFullResponse = false;

// Info del comprobante
var data = new Dictionary<string, object?>
{
    ["CantReg"] = 1, // Cantidad de comprobantes a registrar
    ["PtoVta"] = 1, // Punto de venta
    ["CbteTipo"] = 6, // Tipo de comprobante (ver tipos disponibles)
    ["Concepto"] = 1, // Concepto del Comprobante: (1)Productos, (2)Servicios, (3)Productos y Servicios
    ["DocTipo"] = 99, // Tipo de documento del comprador (99 consumidor final, ver tipos disponibles)
    ["DocNro"] = 0, // Número de documento del comprador (0 consumidor final)
    ["CbteDesde"] = 1, // Número de comprobante o numero del primer comprobante en caso de ser mas de uno
    ["CbteHasta"] = 1, // Número de comprobante o numero del último comprobante en caso de ser mas de uno
    ["CbteFch"] = int.Parse(DateTime.UtcNow.ToString("yyyyMMdd")), // (Opcional) Fecha del comprobante (yyyymmdd) o fecha actual si es nulo
    ["ImpTotal"] = 121, // Importe total del comprobante
    ["ImpTotConc"] = 0, // Importe neto no gravado
    ["ImpNeto"] = 100, // Importe neto gravado
    ["ImpOpEx"] = 0, // Importe exento de IVA
    ["ImpIVA"] = 21, // Importe total de IVA
    ["ImpTrib"] = 0, // Importe total de tributos
    ["MonId"] = "PES", // Tipo de moneda usada en el comprobante (ver tipos disponibles)('PES' para pesos argentinos)
    ["MonCotiz"] = 1, // Cotización de la moneda usada (1 para pesos argentinos)
    ["CondicionIVAReceptorId"] = 5, // Condición frente al IVA del receptor
    ["Iva"] = new[] // (Opcional) Alícuotas asociadas al comprobante
    {
        new Dictionary<string, object?>
        {
            ["Id"] = 5, // Id del tipo de IVA (5 para 21%)(ver tipos disponibles)
            ["BaseImp"] = 100, // Base imponible
            ["Importe"] = 21 // Importe
        }
    }
};

var res = await afip.ElectronicBilling.CreateVoucherAsync(data, returnFullResponse);

res["CAE"]; //CAE asignado el comprobante
res["CAEFchVto"]; //Fecha de vencimiento del CAE (yyyy-mm-dd)
```

{% hint style="info" %}
Este método acepta mas parámetros, podes encontrar todos los parámetros disponibles [En este ejemplo](https://github.com/AfipSDK/afip.net/blob/main/examples/CreateVoucher/Program.cs)
{% endhint %}
{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FECAESolicitar",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "FeCAEReq" : {
            "FeCabReq" : {
                "CantReg" 	: 1,
                "PtoVta" 	: 1,
                "CbteTipo" 	: 6
            },
            "FeDetReq" : { 
                "FECAEDetRequest" : {
                    "Concepto" : 1,
                    "DocTipo" : 99,
                    "DocNro" : 0,
                    "CbteDesde" : 1,
                    "CbteHasta" : 1,
                    "CbteFch" : 20240313,
                    "ImpTotal" : 121,
                    "ImpTotConc" : 0,
                    "ImpNeto" : 100,
                    "ImpOpEx" : 0,
                    "ImpIVA" : 21,
                    "ImpTrib" : 0,
                    "MonId" : "PES",
                    "MonCotiz" : 1,
                    "CondicionIVAReceptorId" : 5,
                    "Iva" : { 
                        "AlicIva": [{
                                "Id" : 5,
                                "BaseImp" : 100,
                                "Importe" : 21
                        }]
                    }
                }
            }
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Crear y asignar CAE a siguiente comprobante**

{% tabs %}
{% tab title="Node" %}
Debemos utilizar el método `createNextVoucher` pasándole como parámetro un Objeto con los detalles del comprobante al igual que el método `createVoucher`, nos devolverá como respuesta `{ CAE : CAE asignado al comprobante, CAEFchVto : Fecha de vencimiento del CAE (yyyy-mm-dd), voucher_number : Número asignado al comprobante }`.

```js
const res = await afip.ElectronicBilling.createNextVoucher(data);

res['CAE']; //CAE asignado el comprobante
res['CAEFchVto']; //Fecha de vencimiento del CAE (yyyy-mm-dd)
res['voucher_number']; //Número asignado al comprobante
```

{% endtab %}

{% tab title="PHP" %}
Debemos utilizar el método `CreateNextVoucher` pasándole como parámetro un Array con los detalles del comprobante al igual que el método `CreateVoucher`, nos devolverá como respuesta `array(CAE => CAE asignado al comprobante, CAEFchVto => Fecha de vencimiento del CAE (yyyy-mm-dd), voucher_number => Número asignado al comprobante)`.

```php
$res = $afip->ElectronicBilling->CreateNextVoucher($data);

$res['CAE']; //CAE asignado el comprobante
$res['CAEFchVto']; //Fecha de vencimiento del CAE (yyyy-mm-dd)
$res['voucher_number']; //Número asignado al comprobante
```

{% endtab %}

{% tab title="Ruby" %}
Debemos utilizar el método `createNextVoucher` pasándole como parámetro un Hash con los detalles del comprobante al igual que el método `createVoucher`, nos devolverá como respuesta `{ "CAE" : CAE asignado al comprobante, "CAEFchVto" : Fecha de vencimiento del CAE (yyyy-mm-dd), "voucher_number" : Número asignado al comprobante }`.

```ruby
res = afip.ElectronicBilling.createNextVoucher(data)

res["CAE"] # CAE asignado el comprobante
res["CAEFchVto"] # Fecha de vencimiento del CAE (yyyy-mm-dd)
res["voucher_number"] # Número asignado al comprobante
```

{% endtab %}

{% tab title="Python" %}
Debemos utilizar el método `createNextVoucher` pasándole como parámetro un Hash con los detalles del comprobante al igual que el método `createVoucher`, nos devolverá como respuesta `{ "CAE" : CAE asignado al comprobante, "CAEFchVto" : Fecha de vencimiento del CAE (yyyy-mm-dd), "voucher_number" : Número asignado al comprobante }`.

```python
res = afip.ElectronicBilling.createNextVoucher(data)

res["CAE"] # CAE asignado el comprobante
res["CAEFchVto"] # Fecha de vencimiento del CAE (yyyy-mm-dd)
res["voucher_number"] # Número asignado al comprobante
```

{% endtab %}

{% tab title=".NET" %}
Debemos utilizar el método `CreateNextVoucherAsync` pasándole como parámetro un Objeto con los detalles del comprobante al igual que el método `CreateVoucherAsync`, nos devolverá como respuesta `new Dictionary<string, object?> { ["CAE"] : CAE asignado el comprobante, ["CAEFchVto"] : Fecha de vencimiento del CAE (yyyy-mm-dd) }`.

```csharp
var res = await afip.ElectronicBilling.CreateNextVoucherAsync(data);

res["CAE"]; //CAE asignado el comprobante
res["CAEFchVto"]; //Fecha de vencimiento del CAE (yyyy-mm-dd)
res["voucher_number"]; //Número asignado al comprobante
```

{% endtab %}

{% tab title="API" %}
Se debe llamar al endpoint [Obtener número del último comprobante creado](#obtener-numero-del-ultimo-comprobante-creado), al numero de comprobante que nos devuelve sumarle `1`, y llamar al endpoint [Crear y asignar CAE a un comprobante](#crear-y-asignar-cae-a-un-comprobante)
{% endtab %}
{% endtabs %}

### **Obtener información de un comprobante ya emitido**

Con este método podemos obtener toda la información relacionada a un comprobante o simplemente saber si el comprobante existe.

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

```js
// Numero de comprobante
const numeroDeComprobante = 1;

// Numero de punto de venta
const puntoDeVenta = 1;

// Tipo de comprobante
const tipoDeComprobante = 6; // 6 = Factura B

const voucherInfo = await afip.ElectronicBilling.getVoucherInfo(numeroDeComprobante, puntoDeVenta, tipoDeComprobante);

if(voucherInfo === null){
    console.log('El comprobante no existe');
}
else{
    console.log('Esta es la información del comprobante:');
    console.log(voucherInfo);
}
```

{% endtab %}

{% tab title="PHP" %}

```php
// Numero de comprobante
$numero_de_comprobante = 1;

// Numero de punto de venta
$punto_de_venta = 1;

// Tipo de comprobante
$tipo_de_comprobante = 6; // 6 = Factura B

$voucher_info = $afip->ElectronicBilling->GetVoucherInfo($numero_de_comprobante, $punto_de_venta, $tipo_de_comprobante);

if($voucher_info === NULL){
    echo 'El comprobante no existe';
}
else{
    echo 'Esta es la información del comprobante:';
    echo '<pre>';
    print_r($voucher_info);
    echo '</pre>';
}
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# Numero de comprobante
numero_de_comprobante = 1

# Numero de punto de venta
punto_de_venta = 1

# Tipo de comprobante
tipo_de_comprobante = 6 # 6 = Factura B

voucher_info = afip.ElectronicBilling.getVoucherInfo(numero_de_comprobante, punto_de_venta, tipo_de_comprobante)

puts  "Esta es la información del comprobante:"
puts voucher_info
```

{% endtab %}

{% tab title="Python" %}

```python
# Numero de comprobante
numero_de_comprobante = 1

# Numero de punto de venta
punto_de_venta = 1

# Tipo de comprobante
tipo_de_comprobante = 6 # 6 = Factura B

voucher_info = afip.ElectronicBilling.getVoucherInfo(numero_de_comprobante, punto_de_venta, tipo_de_comprobante)

print("Esta es la información del comprobante:")
print(voucher_info)
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// Numero de comprobante
int numeroDeComprobante = 1;

// Numero de punto de venta
int puntoDeVenta = 1;

// Tipo de comprobante
int tipoDeComprobante = 6; // 6 = Factura B

var voucherInfo = await afip.ElectronicBilling.GetVoucherInfoAsync(numeroDeComprobante, puntoDeVenta, tipoDeComprobante);

if (voucherInfo == null) {
    Console.WriteLine("El comprobante no existe");
} else {
    Console.WriteLine("Esta es la información del comprobante:");
    Console.WriteLine(JsonSerializer.Serialize(voucherInfo));
}
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FECompConsultar",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "FeCompConsReq" : {
            "CbteNro" : 10,
            "PtoVta" : 1,
            "CbteTipo" : 6
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Crear CAEA**

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

```javascript
// Periodo del CAEA. (yyyymm) 
const periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
const orden = 1;

const caeaInfo = await afip.ElectronicBilling.createCAEA(periodo, orden);

```

{% endtab %}

{% tab title="PHP" %}

```php
// Periodo del CAEA. (yyyymm) 
$periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
$orden = 1;

$caea_info = $afip->ElectronicBilling->CreateCAEA($periodo, $orden);
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# Periodo del CAEA. (yyyymm) 
periodo = 202307

# Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
orden = 1

caea_info = afip.ElectronicBilling.createCAEA(periodo, orden)
```

{% endtab %}

{% tab title="Python" %}

```python
# Periodo del CAEA. (yyyymm) 
periodo = 202307

# Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
orden = 1

caea_info = afip.ElectronicBilling.createCAEA(periodo, orden)
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// Periodo del CAEA. (yyyymm) 
int periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
int orden = 1;

var caeaInfo = await afip.ElectronicBilling.CreateCAEAAsync(periodo, orden);

```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FECAEASolicitar",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "Periodo": 202403,
        "Orden": 1
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener información de CAEA ya emitido**

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

```javascript
// Periodo del CAEA. (yyyymm) 
const periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
const orden = 1;

const caeaInfo = await afip.ElectronicBilling.getCAEA(periodo, orden);
```

{% endtab %}

{% tab title="PHP" %}

```php
// Periodo del CAEA. (yyyymm) 
$periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
$orden = 1;

$caea_info = $afip->ElectronicBilling->GetCAEA($periodo, $orden);
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# Periodo del CAEA. (yyyymm) 
periodo = 202307

# Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
orden = 1

caea_info = afip.ElectronicBilling.getCAEA(periodo, orden)
```

{% endtab %}

{% tab title="Python" %}

```python
# Periodo del CAEA. (yyyymm) 
periodo = 202307

# Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
orden = 1

caea_info = afip.ElectronicBilling.getCAEA(periodo, orden)
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// Periodo del CAEA. (yyyymm) 
int periodo = 202307;

// Orden del CAEA dentro del periodo. Quincena 1, Quincena 2 
int orden = 1;

var caeaInfo = await afip.ElectronicBilling.GetCAEAAsync(periodo, orden);
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FECAEAConsultar",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "Periodo": 202403,
        "Orden": 1
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener puntos de venta disponibles**

{% hint style="warning" %}
Es normal recibir un error en testing ya que no existen puntos de venta para testing (siempre se usa `1`)
{% endhint %}

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

```js
const salesPoints = await afip.ElectronicBilling.getSalesPoints()
```

{% endtab %}

{% tab title="PHP" %}

```php
$sales_points = $afip->ElectronicBilling->GetSalesPoints();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
sales_points = afip.ElectronicBilling.getSalesPoints
```

{% endtab %}

{% tab title="Python" %}

```python
sales_points = afip.ElectronicBilling.getSalesPoints()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var salesPoints = await afip.ElectronicBilling.GetSalesPointsAsync()
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetPtosVenta",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de comprobantes disponibles**

```js
const voucherTypes = await afip.ElectronicBilling.getVoucherTypes();
```

```php
$voucher_types = $afip->ElectronicBilling->GetVoucherTypes();
```

```ruby
voucher_types = afip.ElectronicBilling.getVoucherTypes
```

```python
voucher_types = afip.ElectronicBilling.getVoucherTypes()
```

{% tabs %}
{% tab title=".NET" %}

```csharp
var voucherTypes = await afip.ElectronicBilling.GetVoucherTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposCbte",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de conceptos disponibles**

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

```js
const conceptTypes = await afip.ElectronicBilling.getConceptTypes();
```

{% endtab %}

{% tab title="PHP" %}

```php
$concept_types = $afip->ElectronicBilling->GetConceptTypes();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
concept_types = afip.ElectronicBilling.getConceptTypes
```

{% endtab %}

{% tab title="Python" %}

```python
concept_types = afip.ElectronicBilling.getConceptTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
const conceptTypes = await afip.ElectronicBilling.GetConceptTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposConcepto",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de documentos disponibles**

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

```js
const documentTypes = await afip.ElectronicBilling.getDocumentTypes();
```

{% endtab %}

{% tab title="PHP" %}

```php
$document_types = $afip->ElectronicBilling->GetDocumentTypes();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
document_types = afip.ElectronicBilling.getDocumentTypes
```

{% endtab %}

{% tab title="Python" %}

```python
document_types = afip.ElectronicBilling.getDocumentTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var documentTypes = await afip.ElectronicBilling.GetDocumentTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposDoc",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de alícuotas disponibles**

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

```js
const aloquotTypes = await afip.ElectronicBilling.getAliquotTypes();
```

{% endtab %}

{% tab title="PHP" %}

```php
$aloquot_types = $afip->ElectronicBilling->GetAliquotTypes();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
aloquot_types = afip.ElectronicBilling.getAliquotTypes
```

{% endtab %}

{% tab title="Python" %}

```python
aloquot_types = afip.ElectronicBilling.getAliquotTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var aloquotTypes = await afip.ElectronicBilling.GetAliquotTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposIva",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de monedas disponibles**

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

```js
const currenciesTypes = await afip.ElectronicBilling.getCurrenciesTypes();
```

{% endtab %}

{% tab title="PHP" %}

```php
$currencies_types = $afip->ElectronicBilling->GetCurrenciesTypes();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
currencies_types = afip.ElectronicBilling.getCurrenciesTypes
```

{% endtab %}

{% tab title="Python" %}

```python
currencies_types = afip.ElectronicBilling.getCurrenciesTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var currenciesTypes = await afip.ElectronicBilling.GetCurrenciesTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposMonedas",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        
    }
}
```

{% endtab %}
{% endtabs %}

### Obtener cotización de moneda

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

```js
// ID de la moneda a consultar (El ID se obtiene del método para obtener los tipos de monedas)
const currencyID = 'DOL'

// Fecha de la cotización en formato aaaammdd | Por ej. 20250221 = 21 de febrero de 2025
const rateDate = '20250221';

const exchangeRate =  await afip.ElectronicBilling.executeRequest('FEParamGetCotizacion', {
    MonId: currencyID,
    FchCotiz: rateDate
})
```

{% endtab %}

{% tab title="PHP" %}

```php
// ID de la moneda a consultar (El ID se obtiene del método para obtener los tipos de monedas)
$currency_id = 'DOL'

// Fecha de la cotización en formato aaaammdd | Por ej. 20250221 = 21 de febrero de 2025
$rate_date = '20250221';

$exchange_rate =  $afip->ElectronicBilling->ExecuteRequest('FEParamGetCotizacion', array(
    "MonId" => $currency_id,
    "FchCotiz" => $rate_date
));
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# ID de la moneda a consultar (El ID se obtiene del método para obtener los tipos de monedas)
currency_id = 'DOL'

# Fecha de la cotización en formato aaaammdd | Por ej. 20250221 = 21 de febrero de 2025
rate_date = '20250221';

exchange_rate =  afip.ElectronicBilling.executeRequest('FEParamGetCotizacion', {
    "MonId": currency_id,
    "FchCotiz": rate_date
});
```

{% endtab %}

{% tab title="Python" %}

```python
# ID de la moneda a consultar (El ID se obtiene del método para obtener los tipos de monedas)
currency_id = 'DOL'

# Fecha de la cotización en formato aaaammdd | Por ej. 20250221 = 21 de febrero de 2025
rate_date = '20250221';

exchange_rate =  afip.ElectronicBilling.executeRequest('FEParamGetCotizacion', {
    "MonId": currency_id,
    "FchCotiz": rate_date
});
```

{% endtab %}

{% tab title=".NET" %}

```csharp
// ID de la moneda a consultar (El ID se obtiene del método para obtener los tipos de monedas)
string currencyID = 'DOL'

// Fecha de la cotización en formato aaaammdd | Por ej. 20250221 = 21 de febrero de 2025
string rateDate = '20250221';

var exchangeRate =  await afip.ElectronicBilling.ExecuteRequestAsync<Dictionary<string, object?>>(
    "FEParamGetCotizacion", 
    new Dictionary<string, object?> {
        ["MonId"] = currencyID,
        ["FchCotiz"] = rateDate
    });
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetCotizacion",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        },
        "MonId": "DOL",
        "FchCotiz": "20250221"
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de opciones disponibles para el comprobante**

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

```js
const optionTypes = await afip.ElectronicBilling.getOptionsTypes();
```

{% endtab %}

{% tab title="PHP" %}

```php
$option_types = $afip->ElectronicBilling->GetOptionsTypes();
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
option_types = afip.ElectronicBilling.getOptionsTypes
```

{% endtab %}

{% tab title="Python" %}

```python
option_types = afip.ElectronicBilling.getOptionsTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var optionTypes = await afip.ElectronicBilling.GetOptionsTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposOpcional",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de tributos disponibles**

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

```js
const taxTypes = await afip.ElectronicBilling.getTaxTypes();
```

{% endtab %}

{% tab title="PHP" %}

<pre class="language-php"><code class="lang-php"><strong>$tax_types = $afip->ElectronicBilling->GetTaxTypes();
</strong></code></pre>

{% endtab %}

{% tab title="Ruby" %}

```ruby
tax_types = afip.ElectronicBilling.getTaxTypes
```

{% endtab %}

{% tab title="Python" %}

```python
tax_types = afip.ElectronicBilling.getTaxTypes()
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var taxTypes = await afip.ElectronicBilling.GetTaxTypesAsync();
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetTiposTributos",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Obtener tipos de** condiciones frente al IVA **disponibles**

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

```js
const taxConditionTypes =  await afip.ElectronicBilling.executeRequest('FEParamGetCondicionIvaReceptor')
```

{% endtab %}

{% tab title="PHP" %}

```php
$tax_condition_types = $afip->ElectronicBilling->ExecuteRequest('FEParamGetCondicionIvaReceptor');
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
tax_condition_types = afip.ElectronicBilling.executeRequest('FEParamGetCondicionIvaReceptor')
```

{% endtab %}

{% tab title="Python" %}

```python
tax_condition_types = afip.ElectronicBilling.executeRequest('FEParamGetCondicionIvaReceptor')
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var taxConditionTypes =  await afip.ElectronicBilling.ExecuteRequestAsync<Dictionary<string, object?>>('FEParamGetCondicionIvaReceptor');
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEParamGetCondicionIvaReceptor",
    "wsid": "wsfe",
    "params": {
        "Auth" : { 
            "Token": "{{token}}",
            "Sign": "{{sign}}",
            "Cuit": "20409378472"
        }
    }
}
```

{% endtab %}
{% endtabs %}

### **Transformar formato de fecha que utiliza AFIP**

De `yyyymmdd` a `yyyy-mm-dd`

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

```js
const date = afip.ElectronicBilling.formatDate('19970508'); //Nos devuelve 1997-05-08
```

{% endtab %}

{% tab title="PHP" %}

```php
$date = $afip->ElectronicBilling->FormatDate('19970508'); //Nos devuelve 1997-05-08
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
date = afip.ElectronicBilling.formatDate('19970508') # Nos devuelve 1997-05-08
```

{% endtab %}

{% tab title="Python" %}

```python
date = afip.ElectronicBilling.formatDate('19970508') # Nos devuelve 1997-05-08
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var date = afip.ElectronicBilling.FormatDate('19970508'); //Nos devuelve 1997-05-08
```

{% endtab %}

{% tab title="API" %}
Si lo necesitas, a esto podes implementarlo con el lenguaje que utilices.
{% endtab %}
{% endtabs %}

### **Obtener estado del servidor**

{% hint style="warning" %}
No te confíes mucho de este método, ARCA siempre devuelve que esta todo bien incluso cuando hay algo fallando.
{% endhint %}

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

```js
const serverStatus = await afip.ElectronicBilling.getServerStatus();

console.log('Este es el estado del servidor:');
console.log(serverStatus);
```

{% endtab %}

{% tab title="PHP" %}

```php
$server_status = $afip->ElectronicBilling->GetServerStatus();

echo 'Este es el estado del servidor:';
echo '<pre>';
print_r($server_status);
echo '</pre>';
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
server_status = afip.ElectronicBilling.getServerStatus

puts "Este es el estado del servidor:"
puts server_status
```

{% endtab %}

{% tab title="Python" %}

```python
server_status = afip.ElectronicBilling.getServerStatus()

print("Este es el estado del servidor:")
print(server_status)
```

{% endtab %}

{% tab title=".NET" %}

```csharp
var serverStatus = await afip.ElectronicBilling.GetServerStatusAsync();

Console.WriteLine('Este es el estado del servidor:');
Console.WriteLine(JsonSerializer.Serialize(serverStatus));
```

{% endtab %}

{% tab title="API" %}
**Endpoint**

<mark style="color:blue;">`POST`</mark> `https://app.afipsdk.com/api/v1/afip/requests`

**Ejemplo**

```json
{
    "environment": "dev",
    "method": "FEDummy",
    "wsid": "wsfe",
    "params": {}
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.afipsdk.com/siguientes-pasos/web-services/factura-electronica.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
