Crear factura electrónica de ARCA en Visual Basic 6
Con pocas líneas de código

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

Conectar tu sistema con la facturación electrónica de ARCA
Guía paso a paso
El primer paso para crear una factura electrónica de ARCA en Visual Basic 6 es obtener el Código de Autorización Electrónico o CAE.
Esto lo vamos a hacer utilizando Afip SDK que nos permite conectarnos a los web services de ARCA sin complicarnos con el uso de SOAP y la autenticación.
Ademas, vamos a usar https://github.com/VBA-tools/VBA-JSON/blob/master/JsonConverter.bas para trabajar con JSON.
Para esto debemos descargar descargar JsonConverter.bas, y agregarlo a nuestro proyecto.

Elegimos “JsonConverter.bas”

Y agregar la referencia “Microsoft Scripting Runtime”

Elegimos “Microsoft Scripting Runtime”

Obtener la autorización
Lo primero que tenemos hacer es obtener el “Token authorization”, que seria la autorización en ARCA.
Para usar los web services de ARCA, se requiere un certificado digital, con Afip SDK puedes integrarte en modo desarrollo usando el CUIT 20409378472
sin necesidad de obtener un certificado, para poder integrarte lo más rápido posible.
Te dejo este enlace por si luego quieres usar tu propio certificado para desarrollo.
Debemos ejecutar una solicitud POST al endpoint
https://app.afipsdk.com/api/v1/afip/auth
Private Sub GetAuthorization()
Dim objHttp As Object
Dim strResponse As String
Dim strAuthUrl As String
Dim strAuthData As String
Dim dictAuthData As Dictionary
' Crear objeto XMLHTTP
Set objHttp = CreateObject("MSXML2.XMLHTTP")
strAuthUrl = "https://app.afipsdk.com/api/v1/afip/auth"
' Preparamos la data para pedir el TA
Set dictAuthData = New Dictionary
dictAuthData.Add "environment", "dev"
dictAuthData.Add "tax_id", "20409378472"
dictAuthData.Add "wsid", "wsfe"
strAuthData = JsonConverter.ConvertToJson(dictAuthData)
With objHttp
.Open "POST", strAuthUrl, False
.setRequestHeader "Content-Type", "application/json"
.Send strAuthData
If .Status <> 200 Then
MsgBox "Error en la autorización: " & .Status
MsgBox "Respuesta: " & .responseText
Exit Sub
End If
strResponse = .responseText
End With
' Parsear respuesta JSON (requiere función auxiliar ParseJson)
Dim objJson As Object
Set objJson = JsonConverter.ParseJson(strResponse)
' Guardar token y sign
gstrToken = objJson("token")
gstrSign = objJson("sign")
Debug.Print "Token: " & gstrToken
Debug.Print "Sign: " & gstrSign
End Sub
Ahora tenemos token y sign que nos dio ARCA para usar el web service. No es necesario que lo guardemos, Afip SDK se encarga de esto por nosotros, debemos solicitarlo antes de cada llamada a los métodos del web service.
Obtener el número del último comprobante
Antes de crear la factura, necesitamos saber cuál es el último número de comprobante autorizado. Esto es fundamental para evitar el error (10016) El número o fecha del comprobante no se corresponde con el próximo a autorizar.
Para esto, vamos a usar el método FECompUltimoAutorizado
haciendo una solicitud POST al endpoint:
https://app.afipsdk.com/api/v1/afip/requests
Ahora sí, con el número correcto, podemos crear la factura:
Crear la factura
Vamos a crear una Factura B por un importe de $121. En nuestro código, añadimos la siguiente función autocontenida:
Debemos ejecutar una solicitud POST al endpoint
https://app.afipsdk.com/api/v1/afip/requests
Private Sub CreateInvoice()
Dim objHttp As Object
Dim strResponse As String
Dim strAuthUrl As String
Dim strAuthData As String
Dim dictAuthData As Dictionary
' Crear objeto XMLHTTP para autorización
Set objHttp = CreateObject("MSXML2.XMLHTTP")
strAuthUrl = "https://app.afipsdk.com/api/v1/afip/auth"
' Preparamos la data para pedir el TA
Set dictAuthData = New Dictionary
dictAuthData.Add "environment", "dev"
dictAuthData.Add "tax_id", "20409378472"
dictAuthData.Add "wsid", "wsfe"
strAuthData = JsonConverter.ConvertToJson(dictAuthData)
With objHttp
.Open "POST", strAuthUrl, False
.setRequestHeader "Content-Type", "application/json"
.Send strAuthData
If .Status <> 200 Then
MsgBox "Error en la autorización: " & .Status
MsgBox "Respuesta: " & .responseText
Exit Sub
End If
strResponse = .responseText
End With
' Parsear respuesta JSON (requiere función auxiliar ParseJson)
Dim objJson As Object
Set objJson = JsonConverter.ParseJson(strResponse)
' Guardar token y sign
Dim gstrToken As String, gstrSign As String
gstrToken = objJson("token")
gstrSign = objJson("sign")
Debug.Print "Token: " & gstrToken
Debug.Print "Sign: " & gstrSign
' --- Obtener el número del próximo comprobante ---
Dim objHttpComp As Object
Set objHttpComp = CreateObject("MSXML2.XMLHTTP")
Dim strCompUrl As String
strCompUrl = "https://app.afipsdk.com/api/v1/afip/requests"
Dim dictRequest As Dictionary
Set dictRequest = New Dictionary
dictRequest.Add "environment", "dev"
dictRequest.Add "method", "FECompUltimoAutorizado"
dictRequest.Add "wsid", "wsfe"
Dim dictParams As Dictionary
Set dictParams = New Dictionary
Dim dictAuth As Dictionary
Set dictAuth = New Dictionary
dictAuth.Add "Token", gstrToken
dictAuth.Add "Sign", gstrSign
dictAuth.Add "Cuit", "20409378472"
dictParams.Add "Auth", dictAuth
dictParams.Add "PtoVta", 1
dictParams.Add "CbteTipo", 6
dictRequest.Add "params", dictParams
Dim strData As String
strData = JsonConverter.ConvertToJson(dictRequest)
With objHttpComp
.Open "POST", strCompUrl, False
.setRequestHeader "Content-Type", "application/json"
.Send strData
If .Status <> 200 Then
MsgBox "Error al obtener el último comprobante: " & .Status
Exit Sub
End If
strResponse = .responseText
End With
Dim objJsonComp As Object
Set objJsonComp = JsonConverter.ParseJson(strResponse)
' El número siguiente es el último autorizado + 1
Dim nextVoucher As Long
nextVoucher = objJsonComp("FECompUltimoAutorizadoResult")("CbteNro") + 1
' --- Crear la factura ---
Dim strInvoiceUrl As String
Dim strInvoiceData As String
Set objHttp = CreateObject("MSXML2.XMLHTTP")
strInvoiceUrl = "https://app.afipsdk.com/api/v1/afip/requests"
Dim dictInvoiceData As Dictionary
Set dictInvoiceData = New Dictionary
With dictInvoiceData
.Add "environment", "dev"
.Add "method", "FECAESolicitar"
.Add "wsid", "wsfe"
End With
Dim dictParamsInv As Dictionary
Set dictParamsInv = New Dictionary
' Auth
Dim dictAuthInv As Dictionary
Set dictAuthInv = New Dictionary
With dictAuthInv
.Add "Token", gstrToken
.Add "Sign", gstrSign
.Add "Cuit", "20409378472"
End With
dictParamsInv.Add "Auth", dictAuthInv
' FeCAEReq
Dim dictFeCAEReq As Dictionary
Set dictFeCAEReq = New Dictionary
' FeCabReq
Dim dictFeCabReq As Dictionary
Set dictFeCabReq = New Dictionary
With dictFeCabReq
.Add "CantReg", 1
.Add "PtoVta", 1
.Add "CbteTipo", 6
End With
dictFeCAEReq.Add "FeCabReq", dictFeCabReq
' FeDetReq
Dim dictFeDetReq As Dictionary
Set dictFeDetReq = New Dictionary
' FECAEDetRequest
Dim dictDetReq As Dictionary
Set dictDetReq = New Dictionary
With dictDetReq
.Add "Concepto", 1
.Add "DocTipo", 99
.Add "DocNro", 0
.Add "CbteDesde", nextVoucher
.Add "CbteHasta", nextVoucher
.Add "CbteFch", Format$(Date, "yyyymmdd")
.Add "ImpTotal", 121
.Add "ImpTotConc", 0
.Add "ImpNeto", 100
.Add "ImpOpEx", 0
.Add "ImpIVA", 21
.Add "ImpTrib", 0
.Add "MonId", "PES"
.Add "MonCotiz", 1
.Add "CondicionIVAReceptorId", 5
End With
' Iva
Dim dictIva As Dictionary
Set dictIva = New Dictionary
' Array Alic Iva
Dim colAlicIva As Collection
Set colAlicIva = New Collection
Dim dictIvaItem As Dictionary
Set dictIvaItem = New Dictionary
With dictIvaItem
.Add "Id", 5
.Add "BaseImp", 100
.Add "Importe", 21
End With
colAlicIva.Add dictIvaItem
dictIva.Add "AlicIva", colAlicIva
dictDetReq.Add "Iva", dictIva
dictFeDetReq.Add "FECAEDetRequest", dictDetReq
dictFeCAEReq.Add "FeDetReq", dictFeDetReq
dictParamsInv.Add "FeCAEReq", dictFeCAEReq
dictInvoiceData.Add "params", dictParamsInv
strInvoiceData = JsonConverter.ConvertToJson(dictInvoiceData, Whitespace:=2)
With objHttp
.Open "POST", strInvoiceUrl, False
.setRequestHeader "Content-Type", "application/json"
.Send strInvoiceData
If .Status <> 200 Then
MsgBox "Error al crear la factura: " & .Status
Exit Sub
End If
strResponse = .responseText
End With
Debug.Print "Respuesta: " & strResponse
Set objJson = ParseJson(strResponse)
End Sub
En la respuesta tenemos el CAE y vencimiento correspondientes a la factura que acabamos de crear.
{
...
"CAE": "12345678987654",
"CAEFchVto": "20240327"
...
}
Ejemplos de otros tipos de comprobantes
Problemas comunes
Si estás teniendo el error (10016) El número o fecha del comprobante no se corresponde con el próximo a autorizar te recomiendo leer este artículo.

Error (10016) El numero o fecha del comprobante no se corresponde con el proximo a autorizar
Pasos para resolver este error
Si estás teniendo el error (10242) El campo Condición IVA receptor es obligatorio. Consultar método FEParamGetCondicionIvaReceptor te recomiendo leer este artículo.

Error (10242) El campo Condicion IVA receptor no es un valor valido/es obligatorio
Pasos para resolver este error
Con la autorización creada ya podemos proceder a crear el PDF para presentarle a nuestro cliente. Puedes usar como base esta factura o ticket de ejemplo.
Luego, lo único que nos queda es pasar a modo producción, para más información de cómo hacerlo pueden dirigirse a la documentación de la librería https://docs.afipsdk.com/
Ante cualquier duda o pregunta al respecto, pueden resolverla rápidamente dentro de la Comunidad Afip SDK. Además, puedes unirte para estar al tanto de las novedades y problemas técnicos al usar los servicios de ARCA.