Muchas veces se me ocurrio intentar conectar mi aplicacion de gestion de empresa con el servicio electronico de AFIP (Ente regulador de la argentino) para por ejemplo realizar la facturacion electronica.
Resumen, es una mala idea. Este es mi segundo intento de realizar la conexion. En el primer intento fracase abruptamente por falta de documentacion, ejemplos que no funcionaban y otras cosas que no ayudaron a completar el proyecto con exito.
Esta vez en cambio, encontre un poco mas de ayuda en linea, estudie un poco mejor la legislacion y la documentacion del sistema, con lo que pude completar con exito.
Entonces ahora te cuento como hacerlo sin morir en el intento
PD: hay un glosario al fondo.
Pre-requisitos
Tener un certificado de seguridad de autorizado por afip
Procedimiento General
1. Nos logeamos con el servidor de AFIP mediante el WSAA
2. Obtenemos el TA para poder realizar transacciones con el resto de los servicios
3. Preguntamos el ultimo Codigo usado
4. Mandamos a crear una nueva factura
5. Pedimos el PDF
Primero veremos como conseguir el certificado digital necesario para comunicarnos con los servidores de AFIP. Esto lo veremos en el siguiente post dedicado a eso:
Obtener Certificado de AFIP para Facturacion Electronica
https://exgetmessageaux.blogspot.com.ar/2018/02/obtener-certificado-de-afip-para.html
Ahora veremos como logearnos con el servidor de AFIP para conseguir un TA que nos permita realizar operaciones en los servidores de AFIP.
Los servidores de AFIP para las fechas utilizan el formato yyyyMMdd, es decir para la fecha 21 de enero del 2017, utilizaremos el string "20170121" (2017-01-21)
Estos, utilizan un web service SOAP, que se maneja a travez de XML para la comunicacion, es decir, armamos un XML que explique que queremos hacer, y todos los datos necesarios, y el WS hace lo que puede y nos devuelve otro XML con un resumen de lo que pudo hacer y lo que no.
Con esto veremos ahora en contexto como seria el XML que le vamos a enviar al WSAA para logearnos:
<loginTicketRequest> <header> <uniqueId>1</uniqueId> <generationTime>2017-09-08T08:25:56</generationTime> <expirationTime>2017-09-08T08:45:56</expirationTime> </header> <service>wsfe</service> </loginTicketRequest>
Ahora, el WSAA es el unico que te pide que le envies el XML, el WSFE lo hace a travez de su WSDL, lo que es parecido pero en codigo nativo, sin tocar XML.
Para esto puedo recomendar hacer un template del XML basico y despues modificarlo con cada llamada.
Con motivo de simplificar el tutorial, vamos a hacerlo directamente en un string, que pueda convertir en un objeto XMLDocument y manipularlo con eso.
Si todo sale bien, deberíamos recibir algo de este estilo
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <loginTicketResponse version="1"> <header> <source>CN=wsaahomo, O=AFIP, C=AR, SERIALNUMBER=CUIT 33693450239</source> <destination>SERIALNUMBER=CUIT 20375124685, CN=gestionpersonal</destination> <uniqueId>3594694368</uniqueId> <generationTime>2017-09-08T08:35:53.544-03:00</generationTime> <expirationTime>2017-09-08T20:35:53.544-03:00</expirationTime> </header> <credentials> <token> A very long string </token> <sign> A no so long string </sign> </credentials> </loginTicketResponse>
Donde lo que nos importa es lo que viene en token y en sign, en estos deberían venir dos cadenas de caracteres que nos van a dar el permiso para la sesion.
Bueno, veamos algo de codigo.
Primero creamos un proyecto .NET (en mi caso VB .NET y WinForm) y le agregamos algo para agregar el certificado que vamos a usar, la clave del certificado, el servicio que vamos a usar (todo esto, en nuestro producto final, junto con el CUIT del responsable, deberían estar en una ventana de configuraciones), Un boton de login, y otro de WSFE (para hacer la factura). Podemos agregarle otras cosas como ver lo que estamos enviando y reciviendo (crudo) y un selector de testing y homologacion. La idea de esto es hacer un prototipo de conexion, y que ustedes rescaten lo que les sirve y lo apliquen a su programa.
El proyecto del prototipo esta aca:
GitHub AFIP WSFE WSAA Prototype
La primera ventana nos quedara algo así:
y el código que importa es el que esta atrás del Login:
Private l As LoginClass Private url As String = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms" Private Sub LoginBtn_Click(sender As Object, e As EventArgs) Handles LoginBtn.Click l = New LoginClass(ServicioTX.Text, url, CertificadoTX.Text, ClaveTX.Text) l.hacerLogin() End Sub
Donde LoginClass es la que hace la magia de la conexion. Esta la podemos encontrar aca:
GitHub LoginClass
Pero antes de meternos de lleno en esto, vamos a agregar los WS a travez de sus WSDL (El WSDL describe lo mejor que puede el WS para que directamente Visual Studio u otro, sepa como comunicarse con este)
Para esto seguiremos este post separado
Agregar referencia a WS SOAP AFIP a Visual Studio
https://exgetmessageaux.blogspot.com.ar/2018/02/agregar-referencia-ws-soap-afip-visual.html
Ahora si podemos ver/agregar la clase LoginClass
En el contructor no hay nada en particular, solo toma los datos de Servicio, la URL del servidor que vamos a usar (Homo o Produccion), la ubicacion del Certificado y la clave.Lo importante esta en metodo hacerLogin()
En la primera parte:
'Preparo el XML Request XmlLoginTicketRequest = New XmlDocument XMLLoader.loadTemplate(XmlLoginTicketRequest, "LoginTemplate") uniqueIdNode = XmlLoginTicketRequest.SelectSingleNode("//uniqueId") generationTimeNode = XmlLoginTicketRequest.SelectSingleNode("//generationTime") ExpirationTimeNode = XmlLoginTicketRequest.SelectSingleNode("//expirationTime") ServiceNode = XmlLoginTicketRequest.SelectSingleNode("//service") generationTimeNode.InnerText = DateTime.Now.AddMinutes(-10).ToString("s") ExpirationTimeNode.InnerText = DateTime.Now.AddMinutes(+10).ToString("s") uniqueIdNode.InnerText = CStr(_globalId) ServiceNode.InnerText = serv
Simplemente traemos el template del XML (el que hablamos antes) que vamos a enviar y le seteamos todos los campos (UniqueId, GenerationTime, ExpirationTime y Service)
PD: Para traer el Template use una pequeña clase que use en otros proyectos, que esta en el fondo de la misma clase, la misma se llama XMLLoader.
Acá se vuelve un poco mas complicado:
'Obtenemos el Cert certificado = New X509Certificate2 If clave.IsReadOnly Then certificado.Import(File.ReadAllBytes(cert_path), clave, X509KeyStorageFlags.PersistKeySet) Else certificado.Import(File.ReadAllBytes(cert_path)) End If Dim msgBytes As Byte() = Encoding.UTF8.GetBytes(XmlLoginTicketRequest.OuterXml)
Ahora puede ocurrir un problema, si el sistema no nos deja crear el Certificado, osea que no nos reconoce la clase X509Certificate2 vamos a tener que agregar la referencia a Seguridad de .NET de la siguiente forma:
Vamos a My Project en el Explorador de Soluciones
Ahora, en las pestañas izquierdas vamos a donde dice Referencias
De ahí vamos a abajo donde dice Agregar
Ahora buscamos en el panel lateral, en la sección donde dice Ensablados, y dentro de este buscamos el que dice Framework, cuando lo seleccionemos nos actualizara la lista de librerías, ahora buscaremos en el panel central la librería de System.Security , chequeamos el checkbox que nos aparece en el nombre y le damos a Aceptar.
Y luego nos aseguramos de tener el siguiente import en nuestra clase:
Imports System.Security.Cryptography.X509Certificates
Ahora si, volviendo al LoginClass, la siguiente parte es firmar el mensaje:
'Firmamos Dim infoContenido As New ContentInfo(msgBytes) Dim cmsFirmado As New SignedCms(infoContenido) Dim cmsFirmante As New CmsSigner(certificado) cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly cmsFirmado.ComputeSignature(cmsFirmante) cmsFirmadoBase64 = Convert.ToBase64String(cmsFirmado.Encode())
Ahora tenemos el XML Firmado y codificado en la variable cmsFirmadoBase64 que es la que vamos a enviar a la AFIP para que nos autorice.
Ya ahora enviamos la info:
'Hago el login Dim servicio As New WSAA.LoginCMSService servicio.Url = url loginTicketResponse = servicio.loginCms(cmsFirmadoBase64)
Si todo salio bien en la variable loginTicketResponse vamos a tener el XML con la respuesta en forma de String, El siguiente paso, es convertirlo a XML Document (Object) y analizarlo, a ver que nos responde el servidor:
Analizamos la respuesta XmlLoginTicketResponse = New XmlDocument XmlLoginTicketResponse.LoadXml(loginTicketResponse) _Token = XmlLoginTicketResponse.SelectSingleNode("//token").InnerText _Sign = XmlLoginTicketResponse.SelectSingleNode("//sign").InnerText Dim exStr = XmlLoginTicketResponse.SelectSingleNode("//expirationTime").InnerText Dim genStr = XmlLoginTicketResponse.SelectSingleNode("//generationTime").InnerText ExpirationTime = DateTime.Parse(exStr) GenerationTime = DateTime.Parse(genStr) MsgBox("Exito")
Ok veamos, como después quiero recuperar las cosas después, la mayoría de las cosas las guarde en variables globales de la clase. El documento entero en XmlLoginTicketResponse, El Token en _Token, el Sign o firma en _Sign, y las fechas de generacion y expiracion en las variables ExpirationTime y GenerationTime. Con esto ya tenemos el TA
Entonces cuando hagamos debug, si salio todo bien, deveriamos ver algo como esto:
Si tenemos eso ya estamos logeados contra del servidor de AFIP.
Ahora lo que nos queda es pasarle el informe al servidor de facturación electrónica.
Importante! Este servidor, no necesita que le pasemos los detalles de cada item de la factura, sino un resumen por cada alícuota, es decir, cuanto es el total con 21% de IVA, cuanto con el 10.5%, etc.
Entonces, igual que antes le tenemos que enviar una especie de XML con los datos, a continuación te muestro el XML de muestra, digo especie, porque con el WSDL te lo traduce para que lo manejes como una especie de objetos.
Este seria el XML que tenemos que enviar, ejecutando el método FECAESolicitar (Solicitar CAE de Fact Electronica):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ar="http://ar.gov.afip.dif.fev1/"> <soapenv:Header/> <soapenv:Body> <FECAESolicitar> <Auth> <!-- Autenticacion --> <Token>PD94.....</Token> <!-- TA TOKEN --> <Sign>tYft0........</Sign> <!-- TA Sign --> <Cuit>33693450239</Cuit> <!-- Mi CUIT --> </Auth> <FeCAEReq> <FeCabReq> <CantReg>1</CantReg> <!-- Cant de Facturas --> <PtoVta>12</PtoVta> <!-- Punto de Venta --> <CbteTipo>1</CbteTipo> <!-- Factura A --> </FeCabReq> <FeDetReq> <FEDetRequest> <Concepto>1</Concepto> <!-- 1: Productos, 2: Servicios --> <DocTipo>80</DocTipo> <!-- Tipo Doc 80: CUIT --> <DocNro>20111111112</DocNro> <!-- Doc del facturado --> <CbteDesde>1</CbteDesde> <!-- Nro Factura --> <CbteHasta>1</CbteHasta> <!-- Tambien Nro Factura --> <CbteFch>20100903</CbteFch> <!-- Fecha del Comprobante, yyyymmdd--> <ImpTotal>184.05</ImpTotal> <!-- Total con impuestos --> <ImpTotConc>0</ImpTotConc> <!-- Importe neto no gravado --> <ImpNeto>200</ImpNeto> <!-- Importe neto gravado Total sin impuestos --> <ImpOpEx>0</ImpOpEx> <!-- Importe Exento --> <ImpTrib>0</ImpTrib> <!-- Suma de Tributos --> <ImpIVA>26.25</ImpIVA> <!-- Suma de IVAs --> <FchServDesde></FchServDesde> <!-- Solo Servicios --> <FchServHasta></FchServHasta> <!-- Solo Servicios --> <FchVtoPago></FchVtoPago> <MonId>PES</MonId> <!-- Codigo de Moenda --> <MonCotiz>1</MonCotiz> <!-- Cotizacion, para pesos: 1--> <!-- <Tributos> Por si retiene tributos <Tributo> <Id>99</Id> <Desc>Impuesto Municipal Matanza</Desc> <BaseImp>150</BaseImp> <Alic>5.2</Alic> <Importe>7.8</Importe> </Tributo> </Tributos> --> <Iva> <AlicIva> <Id>5</Id> <!-- Id segun tabla de IVAs (5: 21%)--> <BaseImp>100</BaseImp> <!-- Importe total para esa alicuota --> <Importe>21</Importe> <!-- Monto total del IVA (100 * 0.21) --> </AlicIva> <AlicIva> <Id>4</Id> <!-- 4: 10.5 --> <BaseImp>50</BaseImp> <Importe>5.25</Importe> </AlicIva> </Iva> </FEDetRequest> </FeDetReq> </FeCAEReq> </FECAESolicitar> </soapenv:Body> </soapenv:Envelope>
Como ven en ningún lado nos piden que items tiene la factura. Entonces eso es responsabilidad de ustedes, del lado de su base de datos de guardar la factura. Incluso, se pueden hacer varias facturas, por ejemplo diciendo que desde la factura 5 a la 8 hay un total de $1210 con $210 de IVA 21%, sin especificarle la cantidad de intems ni cuanto es el total por cada comprobante, eso si, después lo tenemos que separar bien en cada factura que vayamos a entregar.
Como tambien se ve, hay muchos campos que requieren un Id de un elemento. Por ejemplo, En Tipo de Documento, necesita el Id del CUIT (80), o la moneda, que esta el Id de la moneda Peso (PES), u otros. Estos son medianamente fijos, el tema es que pueden cambiarlo sin avisar, o pueden agregar nuevos, Para obtener estos campos se puede hacer a travez del mismo WS.
Primero hacemos una ventana como la del programa, recuerdo que esta es de prueba. para que vean que info se necesita para enviar a la AFIP, ustedes tendrán que incorporarlo a su sistema.
Entonces aca tengo un par de CombosBox, estos los rellenaremos con lo que nos da AFIP.
Rellenamos los Cmbs través del botón de Cargar, así que veamos bien que hace:
Private Sub CargaBtn_Click(sender As Object, e As EventArgs) Handles CargaBtn.Click Try authRequest = New FEAuthRequest() authRequest.Cuit = MyCuitTX.Text authRequest.Sign = Login.Sign authRequest.Token = Login.Token Dim service As WSFEHOMO.Service service.Url = url service.ClientCertificates.Add(Login.certificado) puntosventa = service.FEParamGetPtosVenta(authRequest) ptos_venta_cm.DataSource = puntosventa.ResultGet TiposComprobantes = service.FEParamGetTiposCbte(authRequest) TiposComprobantesCMB.DataSource = TiposComprobantes.ResultGet TipoConceptos = service.FEParamGetTiposConcepto(authRequest) TipoConcepto.DataSource = TipoConceptos.ResultGet TipoDoc = service.FEParamGetTiposDoc(authRequest) TipoDocCMB.DataSource = TipoDoc.ResultGet Monedas = service.FEParamGetTiposMonedas(authRequest) MonedaCMB.DataSource = Monedas.ResultGet TiposIVA = service.FEParamGetTiposIva(authRequest) TipoIVACmb.DataSource = TiposIVA.ResultGet Dim lastCbteObj = service.FECompUltimoAutorizado(authRequest, 4, TiposComprobantes.ResultGet(0).Id) NroCbteTX.Text = lastCbteObj.CbteNro + 1 opcionales = service.FEParamGetTiposOpcional(authRequest) Catch ex As Exception MsgBox(ex.Message) End Try End Sub
Entonces vemos que en las primeras lineas completamos el campo Auth del XML, donde le ingresamos el Cuit propio y el Login y Sign del TA que conseguimos en la Autenticación.
En la linea service.ClientCertificates.Add(Login.certificado) Nos encargamos de agregar el certificado que nos fue asignado para trabajar con esto, el mismo que usamos antes. Si se dan cuenta van a ver que me traje el objeto Login del formulario anterior con todo lo necesario.
Luego por cada item que llenemos vamos a tener un par de lineas
TiposComprobantes = service.FEParamGetTiposCbte(authRequest) TiposComprobantesCMB.DataSource = TiposComprobantes.ResultGet
Y la segunda es la que asigna el set de resultado al ComboBox. Asegúrense de tener seteado el atributo DisplayMember de cada Combobox, sino mostrara cualquier cosa.
Esto es para las opciones parametrizadas, como el tipo de comprobante, tipo de moneda, tipo de iva, etc
Y con eso se nos debería llenar todos los CMB, quedándonos algo así.
Para este ejemplo usaremos un solo IVA (suponiendo que todos los items dentro de la factura tienen la misma alícuota. Entonces para este caso, y como la mayoría los precios ya incluyen el IVA, les puse las dos posibilidades, la de ingresar el Total Neto (Sin Iva) y la Alícuota y que te calcule el total, o al revés, Ingresando el Total y la alícuota, te calcule el Total Neto.
No voy a ponerme a explicar todo el código, es bastante simple, y si tienen alguna duda pueden consultarme por mail o en la caja de comentarios.
Ahora paso a explicar como hacer la conexión a la AFIP para pesarla el resumen de la compra, haciendo esto, ellos nos devuelven el Código de Autorización Electrónico (CAE) y su Vencimiento, elementos necesario para que la factura que imprimamos sea valida.
Para eso veremos el código llamado al hacer clic en el botón "Registrar"
Primero en esta parte
Dim service As WSFEHOMO.Service = getServicio() service.ClientCertificates.Add(Login.certificado) Dim punto_seleccionado As PtoVenta = ptos_venta_cm.SelectedItem Dim cm As CbteTipo = TiposComprobantesCMB.SelectedItem Dim req As New FECAERequest Dim cab As New FECAECabRequest Dim det As New FECAEDetRequest cab.CantReg = 1 cab.PtoVta = punto_seleccionado.Nro cab.CbteTipo = cm.Id req.FeCabReq = cab
Luego obtenemos el punto de venta seleccionado al igual que el tipo de comprobante.
Luego empezamos a armar el Request. Primero inicializamos El Request (FECAERequest), la cabecera (FECAECabRequest) y el cuerpo (FECAEDetRequest) vacíos.
Como ya dije, en este procedimiento podemos enviar mas de una factura a la vez, por ahora enviaremos de a una a la vez. Entonces seteamos el campo Cantidad de Registros (CantReg) de la cabecera en 1. Seteamos el campo Pto de Venta y Tipo de Comprobante (PtoVta, CbteTipo) con los parámetros seleccionados. Y no nos olvidemos de setear la cabecera del Request (FeCabReq).
Dim concepto As ConceptoTipo = TipoConcepto.SelectedItem det.Concepto = concepto.Id Dim doctipo As DocTipo = TipoDocCMB.SelectedItem det.DocTipo = doctipo.Id det.DocNro = Long.Parse(DocTX.Text)
Dim este_cbte = ultimo_nro + 1 det.CbteDesde = este_cbte det.CbteHasta = este_cbte det.CbteFch = FechaDTP.Value.ToString("yyyyMMdd") det.ImpNeto = NetoTX.Text det.ImpIVA = ImpIvaTx.Text det.ImpTotal = TotalTx.Text det.ImpTotConc = 0 det.ImpOpEx = 0 det.ImpTrib = 0
Ponemos en cero los totales no gravados (ImpTotConc), Excentos (ImpOpEx) y Tributos (ImpTrib) ya que solo incluiremos Iva 21% sin recaudar tributos.
Dim mon As Moneda = MonedaCMB.SelectedItem det.MonId = mon.Id det.MonCotiz = 1 Dim alicuota As New AlicIva Dim ivat As IvaTipo = TipoIVACmb.SelectedItem alicuota.Id = ivat.Id alicuota.BaseImp = NetoTX.Text alicuota.Importe = ImpIvaTx.Text det.Iva = {alicuota} req.FeDetReq = {det}
Ahora creamos un objeto AlicoutaIva y le setamos los parámetros de IVA según lo seleccionado, la base imponible (a cuanto se le aplica el IVA) y el Importe de IVA.
Seteamos el parámetro IVA del detalle (el cual es un array), si tuviéramos mas de una alícuota de IVA el array IVA tendría que tener mas de un elemento como en el ejemplo.
Por ultimo seteamos el Detalle del Request (El cual tambien es un array) con el objeto que estuvimos configurando. Si tuviéramos mas de un detalle, el array de detalle tendría mas de un objeto.
Con esto ya queda configurado el Request, listo para enviar a la AFIP.
Dim respuesta As FECAEResponse = service.FECAESolicitar(authRequest, req) Dim m As String = "Estado: " & respuesta.FeCabResp.Resultado & vbCrLf m &= "Estado Esp: " & respuesta.FeDetResp(0).Resultado m &= vbCrLf m &= "CAE: " & respuesta.FeDetResp(0).CAE m &= vbCrLf m &= "Vto: " & respuesta.FeDetResp(0).CAEFchVto m &= vbCrLf m &= "Desde-Hasta: " & respuesta.FeDetResp(0).CbteDesde & "-" & respuesta.FeDetResp(0).CbteHasta m &= vbCrLf If respuesta.FeDetResp(0).Observaciones IsNot Nothing Then For Each o In respuesta.FeDetResp(0).Observaciones m &= String.Format("Obs: {0} - {1}", o.Code, o.Msg) & vbCrLf Next End If m &= vbCrLf If respuesta.Errors IsNot Nothing Then For Each er As Err In respuesta.Errors m &= String.Format("Err: {0} - {1}", er.Code, er.Msg) Next End If m &= vbCrLf If respuesta.Events IsNot Nothing Then For Each ev As Evt In respuesta.Events m &= String.Format("Evt: {0} - {1}", ev.Code, ev.Msg) Next End If Resultado.Text = m
Seguido, armamos un resumen re la respuesta para mostrar.
Igual que antes, la respuesta va a tener tantos detalles como detalles tenga la solicitud.
Como solo tenemos un detalle en la solicitud, esperamos un solo detalle en la respuesta.
Cualquier observación particular se va a encontrar en el array Observaciones de cada detalle.
Las observaciones generales sobre la solicitud se encontraran en el Array Events de la respuesta (respuesta.Events) y los Errores del proceso en la variable Errors de la respuesta (respuesta.Errors).
Si todo salio bien. El CAE se va a encontrar en el detalle correspondiente, junto con su vencimiento.
Podemos verificar rápidamente el resultado del proceso a través del atributo Resultado de la cabecera (resultado general del proceso) o de cada detalle (Particular de ese detalle), en donde R significa Rechazado y A Aprobado.
Ya con eso queda registrada la factura con AFIP. Queda como responsabilidad nuestra entonces guardar en nuestra base de datos el detalle de cada factura emitida.
Cada factura que enviemos a la AFIP y este aprueba no solo queda guardado en sus servidores, sino que queda a nuestra entera disposición para consultar si así lo necesitáramos.
Así podemos hacer un sistema de comprobación de integridad, comparando lo que tenemos en nuestra base de datos contra lo que tienen ellos, según lo que nosotros enviamos.
Una vez que completan la parte de homologacion simplemente tienen que cambiar el link al Service de Produccion o tenerlos los dos y usarlo según se quiera.
Hasta acá voy a explicar. Son libres de hurgar por el código del prototipo.
Espero les sirva. Y cualquier duda esta la caja de comentarios.
Bibliografia
https://drive.google.com/drive/folders/0B5Xpb7ydUT4XLTU0VjBFQ3FVTEE?resourcekey=0-NvZkDioiFyg_B_HN0mZ4bQ&usp=sharing
Glosario
AFIP - Administración Federal de Ingresos Públicos
CAE - Codigo de Autorizacion Electronico
CAEA - CAE Anticipado
CSR - Certificate Singin Request, Requisito de Certificado de Firma
FE - Facturacion Electronica
Sign - Firma que autoriza el Token
TA - Ticket de Autenticación
WS - Web Service
WSAA - Web Service de Autenticación y Autorización
WSDL - Web Service Description Lenguage (Lenguaje de descripción de WS)
WSFE - Web Service de Facturacion Electronica
WSN - Web Services de Negocios
Excelente tutorial, se agradece el aporte!
ResponderEliminarBuenas! Che ahi en el codigo que indicas, que solo es necesario madar solo un item, y no discriminado.
ResponderEliminarConsulta, por casualidad, tenes el codigo fuente en el caso que se requiera mandar todos los items?
Desde ya gracias.
Slds.
A la afip no le interesa el detalle, tenes que mandar el total neto y las deferentes totales de cada alicuota. Vos tenes que almacenar los detalles de la factura
EliminarHola Buenas Noches , podrías explicar como reutilizar el TA
ResponderEliminardesde ya muchas gracias
Excelente Tutorial
El TA no es necesario reutilizarlo en Homologacion. En produccion si. Para eso vas a necesitar armar una tabla en tu base con los TA que obtengas y su fecha de expiracion. Recuperarlo es facil, con SQL como el siguiente: << Select * form TA where expiration_date > now() >>.
EliminarSi eso devuelve algo significa que hay un TA sin vencer. De lo contrario, si no devuelve ningun registro, no hay ningun TA sin vencer. Vas a tener que generar uno neuvo y registrarlo en la base.
Guillermo Marcel, consulta, tendrias el codigo fuente para mandar todos los items de una factura en caso que la misma tenga mas de un item.
EliminarSebastian. AFIP no requiere que informemos los detalles de la factura. Lo unico que tenemos que informar es el resumen de la misma, es decir, de cada tipo de iva, cuanto es el subtotal, el monto de IVA, y el monto total de la factura. Y de ser necesario, retenciones y tributos que se pagen.
EliminarGracias.
EliminarBuenas, una consulta... estoy haciendo pruebas, anexando este codigo a mi sistema... ya hice el tema de la reutilizacion del TA, igual ahora estoy con un certificado de prueba, queria saber, en caso de que me salga la respuesta "El CEE ya posee un TA valido para el acceso al WSN solicitado", luego en la facturacion, como cargaria los combos? Porque en el boton "CARGAR"de este ejemplo, los resultGet no me completan nada, es decir, si no hago el login (Si no aparece exito en la ventana principal) luego no funciona la carga de los datos en el formulario de facturacion...en resumen... si ya tengo un TA valido que tengo que hacer para que luego pueda obtener los resultados del WS?
EliminarPerdon ahi vi... creo que ademas del generationTime y ExpirationTime tengo que guardar el WSAA.Token y el WSAA.Sign... que eso es lo que usa el formulario de facturacion...ahora lo veo pero creo que ahi esta el tema.
EliminarSaludos.
Este comentario ha sido eliminado por el autor.
EliminarMuchas gracias por la explicacion, muy completa y didáctica.
ResponderEliminarMe alegro que te sirva!
EliminarEstimado. Gracias por el aporte! muy bueno ya que la documentacion es muy escasa. Estoy intentando consumir el WS de Ventanilla Electronica y me estoy volviendo loco. Algun link o aporte sobre ese WS?!
ResponderEliminarSaludos
No he tenido el agrado de conectarme con otro WS de ellos por suerte.
EliminarPero para esto tendrías que leer a full toda la documentación disponible y hacer mucha investigación propia.
Con algo de perseverancia se puede.
Saludos
Hola Guillermo,
ResponderEliminarTe comento que he seguido el tutorial al pie de la letra y he podido conectarme al WSAA. Pero me he trabado en un problema es que en la carga del punto de venta en el ComboBox (simplemente se mantiene vacío, mientras que los demás campos sí se llenan de datos).
¿Podrías darme un empujoncito para seguir avanzando con esto?
Muchas gracias por el tutorial que hiciste, y también por el tiempo que te tomaste en leerme.
Un abrazo!
Necesito que hagas un debug, te fijes si lo que esta vacio es el campo que se muestra o el contenido de la lista. Puede que tengas mal puesto el DisplayMember, entonces no sabria que propiedad del objeto mostrar, entonces no mostraria nada. Es muy distinto a que los objetos no esten.
EliminarBuenas, hoy empece con las pruebas y ver como funciona todo... hice un certificado con mi cuit (me di de baja al monotributo hace rato), calculo que es por eso que cuando di de alta el pto de venta en AFIP hoy, solo me dio la opcion de REMITO... no aparece otra opcion... y calculo que es por eso en ese combobox no me aparece nada... voy a generar otro certificado de testing con otro cuit para ver si es eso... pero me paso lo mismo, despues aviso.
EliminarIMPORTANTE: para los que no se les llena el combobox ptodeventa... verificar que tengan un punto de vta tipo RECE habilitado aca les desjo el link
Eliminarhttps://www.sos-contador.com/2017/08/02/en-51-pasos-como-obtener-certificado-digital-e-incorporarse-a-factura-electronica-version-ago2017/
saludos brian de dmz-store.net
Esto se soluciono? xq tengo el mismo problema, los puntos de venta estan generados con RECE y no puedo cargar la lista...
EliminarPodes usa esta sentencia que va bien, "Dim cm As CbteTipo = TiposComprobantesCMB.SelectedItem".
Eliminarsuerte
En homologación(entorno de desarrollo no carga los puntos de venta.. Tenes que generar 1 punto ficticio)
EliminarTenes agregar este fragmento de código en la clase FacturaForm en el metodo CargaBtn_clik()
con esto se crea un punto de venta que es ficticio pero sirve igualmente para recuperar comprobantes, asi que si
usas el pto de venta 5, después tenes que usar el mismo para recuperar lo comprobantes que generaste con ese punto de venta.(ACLARO QUE ESTO ES SOLO EN HOMOLOGACION -----NO------ EN PRODUCCION)
If produccion_rb.Checked = CheckState.Checked Then
puntosventa = service.FEParamGetPtosVenta(authRequest)
ptos_venta_cm.DataSource = puntosventa.ResultGet
Else
Dim ptventa As New PtoVenta With {.Bloqueado = "N", .EmisionTipo = "CAE - Monotributo", .FchBaja = "", .Nro = 5}
Dim lista = New List(Of PtoVenta)
lista.Add(ptventa)
ptos_venta_cm.DataSource = lista
End If
Excelente Tutorial. Pero me quede igual que la persona que posteo ultimo. punto de venta en el ComboBox (simplemente se mantiene vacío, mientras que los demás campos sí se llenan de datos). Como se puede solucionar? Saludos
ResponderEliminarConteste arriba
EliminarEn Homologacion no te recupera nada del punto de Venta. Tendras que setearle un valor ficticio, ej: ptoventaCMB.text = "0233", yo tuve el mismo problema y me mate leyendo foros.
EliminarRealizando el seteo de la manera que especificas, a mi no me funciono!! algunos dicen que se hace por base de datos!! podrías darme un poco mas de info por favor?
EliminarHola Guillermo, muy buen tutorial. Quería consultarte sobre la impresión de la factura. Tengo entendido que cuando se registra la venta desde la página web de la AFIP, los comprobantes se generan solos, es decir: se crea una factura con su encabezado correspondiente, tipo de factura, etc. y ya se puede imprimir. Es posible que eso ocurra acá? O esto que vos planteas solo sirve para REGISTRAR la venta en la AFIP? Debería diseñar mi propia factura en, por ejemplo, un reporte e imprimir desde ahí? Gracias!
ResponderEliminarLa factura como documento no es mas que una representacion visual de la informacion de la transaccion, es decir, esto es para registrar la facturacion de una transaccion, para obtener un documento imprimible lo tenes que diseñar y armar vos. La aplicacion de AFIP para facturacion electronica si te genera un documento imprimible. Tu aplicacion deberia tener alguna forma de generar los comprobantes imprimibles, por lo menos en formato PDF, siguiendo la reglamentacion corrrespondiente. (Debe incorporar el CAE, Vencimiento de CAE, Codigo de Barra de CAE, Encabezado, etc...)
EliminarPerfecto! Mi única duda es cómo generar el código de barras, me podrás ayudar?
EliminarEl codigo de barra esta codificado con INTERLEAVED25 (un tipo de codigo de barra como EAN-13 u otros).
EliminarLa mejor solucion es usar un componente externo que genere codigos de barra. Algunos son pagos, otros son gratuitos. Yo uso BarCodeLib http://www.barcodelib.com/
La informacion a codificar es la siguiente:
*Clave Única de Identificación Tributaria (C.U.I.T.) del emisor de la factura (11 caracteres)
*Código de tipo de comprobante (3 caracteres)
*Punto de venta (5 caracteres)
*Código de Autorización de Impresión (C.A.I.) (14 caracteres)
*Fecha de vencimiento (8 caracteres)
*Dígito verificador (1 carácter)
Esa informacion la incertas en el generador de codigo de barra para que te devuelva el codigo de barra que imprimiras en la factura.
Recomiendo que leas la siguiente fuente:
https://www.afip.gob.ar/genericos/guiavirtual/directorio_subcategoria.aspx?id_nivel1=562&id_nivel2=599
Muy Bueno.
ResponderEliminarLo Probe y funciona ok.
Mucha gracia
Me alegra mucho que les haya sido de ayuda!
EliminarMe alegra mucho que les haya sido de ayuda!
ResponderEliminarHola Guillermo, excelente me ayudo de mucho!
ResponderEliminarConsulta hay una forma que debemos seguir para guardar los duplicados de lo que vamos generando?
Gracias!
Hola.
EliminarTienes la obligación de almacenar en detalle cada comprobante, ya que lo que se envia, es simplemente un resumen de los impuestos.
Aparte puedes usarlo como un doble control de los datos para mantener la coherencia e integridad de los datos.
Recomiendo que cuando tengas los datos listos para enviar la request al WS, primero almacenes los datos en la DB (Data Base), seguido envíes la request al WS, en caso que la transacción sea exitosa, actualizas los datos en la DB con la respuesta del WS. Caso contrario, remueves el registro de la DB o reintentas la misma transacción.
Esto te servirá para mantener tu propio registro aparte de la AFIP. También para protegerte ante fallas de comunicación con los servidores.
Con esto, puedes crear un script que revise la integridad de ambas bases de datos y encuentre incoherencias entre los registros.
Espero que te sirva.
Atte. Guillermo Marcel
En que casos debe usarse el web service wsmtxca en el que se envía el detalle de los ítems?
ResponderEliminarMuchas Gracias.
Solamente cunado la AFIP te obligue a informar los detalles. Son pocos casos, como inmoliliarias, exportaciones u otras cosas. Te lo va a decir tu contador. Pero la gran mayoria no informa los detalles, lo que se manejas por el regimen general.
EliminarHola! una pregunta, en la primer pantalla donde pones la ruta del certificado, que pones en Clave? me sale "Contraseña de red especificada no es válida" , lo estoy probando desde el mismo código que compartiste en este post. Muchas gracias!
ResponderEliminarCuando haces el certificado, exactamente cunado haces la ultima conversion de formato, te pregunta si le queres poner clave o no. Esa clave es la que te pide ahi
EliminarLo cree de nuevo al certificado usando tu otro tutorial, ahora sí! funciona! muchas gracias Guillermo, hace mese que estoy luchando con esto.
EliminarDe nada, espero te haya servido.
EliminarBuenas! Necesito revivir esto, me dice contraseña incorrecta, el tema es que no le puse contraseña.. alguna sugerencia?
EliminarHola Guillermo, te hago una consulta, no puedo mandar mas de una alicuota por factura, en el ejemplo dice que es un array pero no entiendo como hacerlo. Desde ya muchas gracias!!!
ResponderEliminarDeberías insertar multiples items AlicIva dentro del bloque IVA, y sumarizarlos dentro del total IMPIVA.
EliminarDe esta forma
Dim alicuota1 As New AlicIva
Dim ivat As IvaTipo = TipoIVACmb.SelectedItem
alicuota.Id = ivat.Id
alicuota.BaseImp = NetoTX.Text
alicuota.Importe = ImpIvaTx.Text
Dim alicuota2 As New AlicIva
Dim ivat As IvaTipo = TipoIVACmb.SelectedItem
alicuota.Id = ivat.Id
alicuota.BaseImp = NetoTX.Text
alicuota.Importe = ImpIvaTx.Text
det.Iva = {alicuota1, alicuota2}
A forma de ejemplo
Hola recién me encuentro con esta maravilla, todavía no la implemente, pero por lo que estuve viendo debería funcionar, sos muy crack y no quería mas de darte las gracias por anticipado! capo! gracias luego comento si pude implementarlo. saludos.
ResponderEliminarMuchas gracias, me alegro que les sirva.
EliminarBuenos dias, estoy viendo esto ya que quiero implementar la factura electronica... la diferencia de esta forma es que deberia armar yo el reporte de la factura no? Y el otro metodo de afip que ya devuelve el PDF de la factura electronica se puede implementar en .NET?
ResponderEliminarHola, el documento de la factura lo vas a tener que armar por tu cuenta, podes usar Algún complemento para trabajar con pdf, o usar el impresor común de .NET y usar la impresora virtual de Windows. En conclusión, la implementación de AFIP es bastante limitada, y te conviene usar tu propia implementación aunque la tengas que hacer uno mismo.
EliminarRecuerdo que vas a necesitar por obligación incorporar el código de barra de la factura que incluye los codigos de CAE y otra información, te podes guiar en el modelo de afip para armar el tuyo.
Hola Muchas gracias, la verdad una muy buena explicación de todo sin tu aporte hubiera sido imposible
ResponderEliminargenerar los servicios web q manejen factura electronica
Muchas gracias. Me alegra que te sirva.
EliminarPodrias generar un codigo para ws CTG estaria barbaro
ResponderEliminarJaja no trabajo con eso... ya suficiente tortura fue hacer esto. Pero si algun dia lo hago lo subire!
EliminarYo lo acabo de generar a todos los metodos
EliminarGuillermo muchísimas gracias por compartir tus conocimientos, la verdad te pasaste! mil gracias capo! Me funciono muy bien en homologación. Ahora me surgió una duda cuando lo estoy empezando a probar contra los servidores de producción.
ResponderEliminarTe pregunto: cuando desde el proyecto de .Net agregas las referencias a los WS de AFIP de WSAA y de WSFE ahí supuestamente indicas los servidores de homologación pero según el ejemplo el WSAA esta haciendo referencia al de producción (https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl) para homologación no debería ser https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl ? o como después desde el código le asignas la url de homologación (en “Private url As String = https://wsaahomo.afip.gov.ar/ws/services/LoginCms” y después servicio.Url = url )no hay problema y le pega directamente al WS de homologación?
Es decir, mientras después desde el código le asigne la URL de homologación es indistinto la referencia que agregue en el proyecto? Espero haber sido claro con mi consulta, de nuevo mil gracias por tu tiempo!
Buenas, si, excelente todo, ya hice todo en HOMOLOGACION, pero ahora en produccion, ademas de la url del servicio, que hay que cambiar??
EliminarEn la declaracion del servicio (Dim service As New WSFEHOMO.Service) hay que modificarlo con Dim service As New WSAA.LoginCMSService??? Porque si es asi el procedimiento service.FECompUltimoAutorizado no existe... no se como obtener el ultimo comprobante como lo hago con HOMOLOGACION... intente solo cambiar la URL y en service.FECompUltimoAutorizado me devuelve siempre 0.
Hola para hacer el login la url de produccion sería: "https://wsaa.afip.gov.ar/ws/services/LoginCms"
Eliminary para hacer la factura la url a utilizar es "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL"
Obviamente a parte de utilizr el certificado generado para producción.
Si te devuelve siempre 0 es porque nunca hiciste una factura en producción con el web service.
Gracias Javier! Justo me di cuenta hace un rato... tenia mal la url del WS de produccion... en este ejemplo siempre la llama url... entonces ahi estaba la confusion... hice 2 variables diferentes para no confundirme y quedo ok!! No era que me devolvia 0... en depuracion vi que daba un error de SOAP... al llamar a obtener ultimo comprobante...ahora si en produccion me devuelve 0 y obviamente porque en el punto de venta nuevo que cree para facturacion electronica, es el primero!
EliminarGuillermo muchísimas gracias por compartir tus conocimientos en la en el wsfe lo pude implementar y funciona perfecto,
ResponderEliminarno tendrías un ejemplo para el Wsmtxca
Hola, no, no lo he trabajado. Lo siento
EliminarHola Guillermo, te hago una consulta, no puedo mandar mas de una alicuota por factura, en el ejemplo dice que es un array pero no entiendo como hacerlo. Desde ya muchas gracias!
ResponderEliminarHola, yo lo resolvi asi:
EliminarEn la parte final donde declara el FECAEDetRequest,
Dim det As New FECAEDetRequest
With det
.Concepto = 1 'Productos
Select Case cboTipo.Text
Case "A"
.ImpNeto = neto21 + neto105
.ImpIVA = iva1 + iva2
Dim alicuota1 As New AlicIva
alicuota1.Id = 5
alicuota1.BaseImp = neto21
alicuota1.Importe = iva1
Dim alicuota2 As New AlicIva
alicuota2.Id = 4
alicuota2.BaseImp = neto105
alicuota2.Importe = iva2
If neto21 > 0 And neto105 > 0 Then
.Iva = {alicuota1, alicuota2}
ElseIf neto21 > 0 Then
.Iva = {alicuota1}
Else
.Iva = {alicuota2}
End If
.DocTipo = 80
.DocNro = cuit
Algo así sería, espero que te ayude.
Este comentario ha sido eliminado por el autor.
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarHola! una pregunta, se puede re utilizar el ticket de acceso? Por ejemplo, ya tengo un ticket de acceso, y se me cierra la aplicacion, cuando vuelvo a acceder me sale este cartel "el cee ya posee un ta valido para el acceso al wsn solicitado" y tengo que esperar como 10 min, para loguearme de nuevo y que pueda tener un nuevo ticket de acceso. Hay alguna manera de volver a solicitar o utilizar el ticket que generé al principio? Ya implemente todo lo que pusiste, y funciona muy bien, salvo este detalle. Gracias!
ResponderEliminarHola Javier, fijate que tenes una variable que te dice cuando vence el TA llamada ExpirationTime o UltimoExpirationTime, yo en mi sistema pregunto si es mayor o menor a la fecha y hora actual y en base a la respuesta pido o no un nuevo TA. Suerte!
EliminarJustamente como dice dkforward, en Homologación tenes la libertad de crear otro TA teniendo otro vigente. En producción no. Tienes solamente un TA valido a la vez. Por lo que deberías almacenar el TA y usarlo hasta que esté vencido. En mi código lo que hago es, antes de establecer la conexión con sus servidores es revisar el último TA, ser si sigue vigente, de ser necesario obtener uno nuevo y recien ahi establecer la conexión.
EliminarHola buenas noches antes que nada agradezco enormemente que hayas compartido tus conocimientos es un excelente tutorial. Quería consultar sobre un inconveniente que me surgió y que sucedió lo mismo a otro usuario. El problema es que no se está cargando el combobox de los puntos de ventas. Hice el debug y verifiqué que no está trayendo los datos de los puntos de ventas para luego poder cargarlos en el combobox pero si trae los otros datos de los demás combobox. Gracias por tu tiempo!
ResponderEliminarDeverias verificar que tenes el Punto de Venta en el registro de afip
Eliminarhttps://www.sos-contador.com/2017/08/02/en-51-pasos-como-obtener-certificado-digital-e-incorporarse-a-factura-electronica-version-ago2017/
Buenas... no se porque al postear aparezco como Unknown... cerre sesion y volvi a entrar y sigo saliendo igual
ResponderEliminarNi idea.
EliminarYO LO RESOLVI INTRODUCIENDO MANUALMENTE EL PUNTO DE VENTA, GUARDADO EN LA BASE DE DATOS, TOTAL ESE DATO NO CAMBIA
ResponderEliminarDeverias verificar que tenes el Punto de venta como RECE
Eliminarhttps://www.sos-contador.com/2017/08/02/en-51-pasos-como-obtener-certificado-digital-e-incorporarse-a-factura-electronica-version-ago2017/
Como dice guillermo y Henry, yo lo tengo agregado al punto de venta en el RECE y no me aparece, como pudieron de esta manera introducir el punto de venta? me podrian ayudar por favor? porque no se como realizar esto. el punto de venta me queda vacio, aunque halla colocado correctamente el certificado digital y el punto de venta agregado
EliminarLa verdad que esto para mi fue la gloria y funciona sin problemas, ahora me están pidiendo generar los archivo de citi venta rg3685 alguien tiene algo avanzado de esto para no empezar de cero a lidiar?
ResponderEliminarCreo que se a que te referis. Los hice medio hardcodeado, Es un archivo de texto plano, pero es un embole hacerlo. Si necesitas ayuda contactame a guille.marcel04@gmail.com
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarHenry como andas, te consulto, ya pude generar un certificado y conectarme al servidor TESTING... lo del combobox de pto ventas le agregue a mano tambien y pude registrar comprobantes. Ahora, queria saber una vez que pase todo el codigo a mi sistema... que es lo que deberia hacer en AFIP para pasar de un certificado de TESTING a uno de PRODUCCION?? Porque ahora obviamente al querer loguearme me dice "CERTIFICADO NO EMITIDO POR AC DE CONFIANZA". Gracias.
ResponderEliminarMas arriba esta en la seccion de "Obtener certificado de AFIP..." en la seccion de Produccion. Al comienzo del post
EliminarSi, gracias Guillermo, ya tengo la app funcionando y facturando sin problemas! Un abrazo.
EliminarHola maestro fijate arriba de todo hay unos links donde explican como obtener los certificados de prueba y los de produccion, una vez que tenga el de produccion lo unico que te toca hacer es cambiar la web a donde busca en el enlace, si te fijas hay 2 web una para cada tipo una dice entro otras cosasa homo y la otra services. cambiando simplemente eso mas el certificado, ya estarias emitiendo comprobantes electronicos.
ResponderEliminarExactamente. Con el certificado de producción y el link del servidor de producción ya esta funcionando.
EliminarHola, muchas gracias por el tutorial antes que nada, me está siendo de gran ayuda. Tengo una duda, si quisiera consumir el WS para hacer facturación eléctronica desde una web app, deberia utilizar alguna otra libreria? o si o si tiene que ser implementado en .NET?
ResponderEliminarAca implemente particularmente .NET, pero les deje concretamente lo que tienen que enviar en forma de XML. Pueden o usar algun complemento para manejar SOAP, o armar los XML a mano y enviarlos como String.
EliminarHola a ver is alguien me puede dar una mano, ya pude poner a facturar un par de pc sin problemas, pero las ultimas dos e tiran el mismo cartel de error"computador no autorizado a acceder al servicio" sin duda algo estoy haciendo mal, por ahi alguien me puede dar una mano le voy a agradecer saludos.
ResponderEliminarYo estoy justo terminando... recien pude hacer las funciones para genrerar el codigo de barras...ahora tengo que cambiar la url para produccion y probar todo... tengo que generar el certificado de produccion para reemplazarlo al que estoy usando... despues te comento a ver si me pasa algo parecido.
EliminarBuenas Henry, ahi hice todo lo de PRODUCCION... y me salio lo mismo que a vos, computador no autorizado.. .fui a AFIP y luego a ADMINISTRADOR DE RELACIONES DE CLAVE FISCAL--> NUEVA RELACION--> BUSCAS EN AFIP/WEBSERVICE/FACTURACION ELECTRONICA y ahi en REPRESENTANTE le das BUSCAR y elegis el COMPUTADOR FISCAL..
Eliminary bueno ahi me dejo hacer el login con el certificado de produccion... pero ahora al ir a facturacion, el procedimiento service.FECompUltimoAutorizado me devuelve error.... no puedo obtener el ultimo comprobante autorizado de cada tipo de comprobante...
Buenas, ya lo pude solucionar, tenia mal la url de produccion.
EliminarConsulta... alguno implemento el Webservice para obtener los datos de la persona? Porque en este excelente ejemplo esta agregado WSPSA4 pero no esta implementado.
Mmm por lo que lei creo que no se pueden obtener esos datos, los usa AFIP en facturacion WEB, es asi? Queria usarlo para verificar el alta nada mas, espero comentarios.
EliminarHola como estas, no tendrías un ejemplo con FACTURAS de CRÉDITO ELECTRÓNICA MiPymes ?
ResponderEliminarsaludos y gracias
Consulta alguien sabe algo del tema remito electrónico, me están empezandoa pedir eso y me parece que esta relacionado algo con todo esto? no se me pueden dar una mano
ResponderEliminarDebe ser un servicio SOAP, del mismo estilo que este servicio. No pongo mis manos en el fuego por los servicios de AFIP pero creo que debe ser muy similar.
EliminarIMPORTANTE: para los que no se les llena el combobox ptodeventa... verificar que tengan un punto de vta tipo RECE habilitado aca les desjo el link
ResponderEliminarhttps://www.sos-contador.com/2017/08/02/en-51-pasos-como-obtener-certificado-digital-e-incorporarse-a-factura-electronica-version-ago2017/
Muchas Gracias! Evidentemente me olvide del paso de que tienen que tener creado el Punto de Venta.
EliminarHola Gente, estoy implementado la factura con detalles con el WsMtxca lo pude hacer funcionar a medias, con un Ítem todo bien cuando tengo que mandar mas de uno ahí se me complica con el ArrayItems no le encuentro la vuelta para mandar mas de uno si alguno me puede echar una mano
ResponderEliminarSaludos y mil Gracias
Daniel tendras la url de test para la WsMtxca ?, Por que el publicado en la documentacion de AFIP no da ping https://fwshomo.afip.gov.ar/wsmtxca/services/MTXCAService?wsdl
EliminarLo lamento, yo particularmente no he trabajado con eso.
EliminarPero te recuerdo que para la gran mayoria de los comerciantes, la AFIP no requiere el detalle de las facturas, solamente la sumarizacion del mismo y el detalle de las alicuotas nomas
Hola, excelente aporte! Muchas gracias por compartir! Una consulta, el Nro del comprobante se tiene que tomar de algún rango de números autorizados para el punto de venta o de donde sale ese dato?
ResponderEliminarEl Número de Comprobantes debe ser el Secuencialmente Siguiente del último. Es decir, si el ultimo fue 1, en número actual es 2, y así. Por esto, recomiendo ir a buscar antes el último comprobante antes de enviar la factura. Asi sabras cual es el último número y con eso sabras que numero corresponde a este.
EliminarMuchas gracias Guillermo por tu pronta respuesta.
EliminarSaludos
Pablo
buenas, en el login, en clave que va ahi?
ResponderEliminarCuando exportas el Certificado de formato pk10 a pk14, tienes la opción de agregarle una clave al certificado. Esa clave es la que va ahi. Si no le pusiste clave al certificado, el campo clave debería ir vacío.
Eliminarhola
ResponderEliminarcomo calculaste el iva seleccionando desde el combobox si es 0 o 16 te agradeceria tu respuesta
Buenas!! Desde ayer no puedo acceder a los servicios web de testing que ofrece afip. Sabes algo?
ResponderEliminarhttps://wswhomo.afip.gov.ar/wsfev1/service.asmx?wsdl
O quien consultar o avisar que esto sucede.. no encontre nada en la web de afip
EliminarGenio, despues de romperme la cabeza, pude lograr realizar el ticket de acceso, ahora cuando realizo el request para enviar la factura, al realizar el detalle, lo cargo todo bien pero cuando cargo el arrays me salta error y no se que hago mal, quizas en tu experiencia podrias ayudarme. Me base en tu ejemplo mas arriba. Gracias y saludos
ResponderEliminarDim alicuota1 As New AlicIva
alicuota1.Id = 5
alicuota1.BaseImp = subtotal21 'el importe gravado sin iva
alicuota1.Importe = subtotal21 + acumular21
det.Iva(0).Id = alicuota1.Id().ToString
det.Iva(0).BaseImp = Convert.ToDouble(alicuota1.BaseImp)
det.Iva(0).Importe = Convert.ToDouble(alicuota1.Importe)
'10.5%
Dim alicuota2 As New AlicIva
alicuota2.Id = 4
alicuota2.BaseImp = subtotal10
alicuota2.Importe = subtotal10 + acumular10
det.Iva(1).Id = alicuota2.Id
det.Iva(1).BaseImp = Convert.ToDouble(alicuota2.BaseImp)
det.Iva(1).Importe = Convert.ToDouble(alicuota2.Importe)
Perdon no puse el error, en det.Iva(0).id salta "referencia a objeto no establecida como instancia de un objeto"
EliminarMuy buen aporte Guillermo! llegue mas lejos de lo que pude llegar solo en menor tiempo. Funciona perfecto y lo tengo implementado en vb. Ahora se me presenta una situación y lo estoy pasando a C# el cual me genera un problema en el paso fin al (obtener la aprobación), ¿ de casualidad alguien lo implemento en ese lenguaje que me pueda dar una mano?
ResponderEliminarBuenas tardes, antes que nada infinitas gracias por el GRAN APORTE!!! Realmente tu manera de explicar es genial incluso para los menos experimentados (como es mi caso). Ademas de agradecerte queria pedirte un poco de ayuda, ya que, me trabe con algo y estoy perdido por donde viene el error.
ResponderEliminarEstoy trabajando en produccion, e hice todo al pie de la letra pero en la parte de obtener el certificado : "certificado.Import(File.ReadAllBytes(cert_path), clave, X509KeyStorageFlags.PersistKeySet)" se me genera el error "La matriz no puede estar vacía o tener un valor null.Nombre del parámetro: rawData".
Voy a tratar de ser claro con lo que hice a ver si con tu generosidad encontras mi falla:
Cuando agregue la refencia, le puse de nombre afip.wsaa y la ruta "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"
Tuve que cambiar en 'Hago el login: Dim servicio As New afip.wsaa.LoginCMSService
En el Login, cambie la url para que apunte a produccion : Private url As String = "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"
y paso los datos por string: l = New CLogin("wsaa", url, "D:\AFIP\CERTIFICADOS\FE\certificado.pfx", "")
A mi se me ocurre que hay un problema con el certificado, o que este faltando alguna referncia o que estoy haciendo algo mal en AFIP.
Con respecto al certificado, hice los pasos que tenes en el otro post y salio todo de 10.
Con respecto a las referencias, agregue System.Security y System.Web.Services, ademas de todos los "Imports" de la Clase LoginClass
Con respecto a AFIP, tengo el cerificado "Valido", el cual descargue y es el que estoy utilizando.
Bueno, te agradezco nuevamente, y me seria de mucha ayuda que me orientes por donde buscar la solucion.
Saludos
muy buena guia!! esto seria wsfev1?
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarExcelente trabajo, muchas gracias por compartir tus conocimientos en forma desinteresada.
ResponderEliminarBuenas... alguien pudo generar el codigo de barras??? Probe varios metodos, con INT2of5, ambos con los ejemplos que busque me quedaron bien en teoria.. ahora... voy a probarlos con el lector de codigos de barra y no me da pelota.... lo raro es que imprimi una factura de AFIP y tampoco lo leo! El lector es nuevo y se que lee esa codificacion.... que podras ser?? Probe tambien generar el string en CODE128C y lo mismo... no lo puedo leer... ahora voy a leer cualquier boludez y el lector me la lee... alguien sabe que puede suceder???
ResponderEliminarHola! excelente aporte y muy bien explicado, gracias! voy a probar tu librería de conexión en un caso real ya que utilizo archivos.dll para conexión con afip pero en C#, en cuanto al código de barras vi controladores fiscales nuevos imprimiendo códigos QR, es fácil de adaptar en caso que alguien lo necesite, descargar desde Nuget el paquete Zxing para generar el QR, Gracias!!!
ResponderEliminar
ResponderEliminarMuchas gracias por el aporte, Ya estoy conectado a afip listo para pedir el CAE. Pero cuando pulso en Registrar me da error de conversion de variable tipo double. es que soy monotributista. y no tengo que descriminar IVA por la opcion importe neto e importe total me da el mismo error. me podrias echar una mano en donde y como puedo convertir la variable double que manda el nerto o el total?. gracias
Hola. ya solucione el problema para facturas C. le elimine todo lo concerniente a IVA para que no diera ese error. porque no puedo discriminar en factura C, asi que no se puede enviar una cadena vacia en IVA. lo comento por si a alguien le hace falta.
ResponderEliminarExcelente Tutorial, excelente trabajo. Ya pude facturar electronicamente en modo Produccion. Te agradezo muchisimo el aporte que hiciste. Solo me queda una inquietud en la fase final, en la presentacion de la factura en crystal reposts. Todo funciona perfecto, solo me falta como ingresar el codigo de barras. No se como ingresar la libreria BarcodeLib.Barcode.WinForms en el crystal reports. Tenes una idea de como tengo que hacer para que me salga el codigo de barras en la factura? Muchas gracias
ResponderEliminarHola!! exelente tutorial, muy bueno, y la verdad muy bien información, lo unico que falta es el punto de venta, yo ya tengo el certificado hecho correctamente, y el punto de venta dado de alta con RECE en afip, el problema es que me queda vacio, muchos le sucede lo mismo, He intentado rellenar el campo desde la base de datos como algunos alegan pero no entiendo como se realiza, podria alguien especificar esto? por favor espero alguien que me sepa ayudar, y comparta esta información, desde ya muchass gracias
ResponderEliminarBuenisimo una guia invaluable. y funciona a la perfeccion. lo pude adaptar a mi proyecto perfectamente. Consulta general: tenes una guia para consulta padron de contribuyentes A5 ?? gracias
ResponderEliminarHola. Muchas gracias por tu trabajo. Lo estoy convirtiendo a C#.
ResponderEliminarTengo una pregunta. Cual puede ser la razon por la que no me carga ningun punto de venta? (En el programa de muestra)
Lei que varios usuarios tienen el mismo problema, estara relacionado con algun delay en la alta del punto de venta RECE?
Eliminaren la práctica a mi me paso que el punto de venta en realidad necesito informarselo yo desde distintas computadoras. saludos.
EliminarEn el entorno de homologacion no los trae, en el entorno de PRODUCCION si los trae, siempre y cuando el CUIT emisor haya ingresado previamente con su clave fiscal y haya creado el punto de venta para facturacion onlines (se llama de una forma para responsable inscriptos y de otra para monotributistas) una vez que este punto de venta fue creado en la pagina de la afip, recien los traerá desde el ws. SALUDOS
EliminarHola, buenisimo el tutorial y me ayudo un monton, tengo una duda, cuando quiero emitir una Factura B, tengo entendido que no necesito enviar el DocNro, pero el programa me exige ingresar un valor sino me tira una exepcion, tienes alguna idea de como se haria en este caso? Muchisimas gracias de antemano
ResponderEliminarsi es menos de 5000 en efectivo no te pide dni podes poner varios ceros si es menos de 10 mil idem para ventas electronica (mercadopago, tarjeta, transferencia, etc) lo mismo, si los importes superan esos valores segun la forma de pago del cliente tenes que mandar dni y nombre y apellido
EliminarBuenas Guillermo,
ResponderEliminarTenes implementado el consumo de Ventanilla Electronica? Podria delegarte este trabajo. espero tus comentarios. Te dejo mi cel: 115-103-6034
Hola venia bien al principio, luego por error mio del sistema y trabajar apurado, me mande varias macanas, ahora quisiera saber si es posible, hacer una consulta de una factura y extrar el iva que se cargo normalmente vendo con iva de 10.5 y 21 deberia saber todos los datos, iva 21 y 10.5 neto, grabado y subtotal, si alguien me pueda dar una mano voy a agradecerles, saludos HErnan.
ResponderEliminarfinalemente lo pude hacer sin problemas si alguien necesita una mano me avisa, me sirvio para generar reportes de iva ventas! saludos
EliminarHola Henry, no puedo lograr resolverlo, como lo hiciste? Trabajo en VB.net muchas gracias
EliminarHay que agradecer a gente como vos, sólo entré para chusmear.. pero hiciste un gran aporte.
ResponderEliminarTe mando un gran saludo!
Hola Guillermo. Muchas gracias por tu aporte, es muy valioso. Mi consulta tiene que ver con el TA. Debido a que el mismo tiene una duración de 12 hs, que sucede si mi sistema no alcanza a almacenar el SIGN y TOKEN del mensaje, porque supongamos, se corta la luz justo cuando AFIP ya autorizó el TA y yo no le podido recibir? Tengo forma de recuperarlo? El sistema quedaría inaccesible por 12 hs? En algunos sistemas, enviando el mismo UNIQUEID devuelve el mismo Resultado original, pero veo que este no es el caso, dado que en mi primer intento, no tenía diseñado el almacenamiento y tuve que esperar 12 horas hasta que se venciera el primer ticket. Gracias
ResponderEliminarHola. Desde donde se puede obtener la letra que identifica el comprobante? (A,B,C,X....)
ResponderEliminarHola, muchas gracias por el aporte, realmente clarisimo. Te consulto tendrias idea como se informan en la factura las percepciones de ingresos brutos y de iva que lleva la misma si el vendedor es agente de percepcion?
ResponderEliminarMuy buena la explicación, tendras código de ejemplo? Saludos
ResponderEliminarBuenas! alguien está intentando hacer la conexion a WS de afip con PHP? si alguien tiene info avise por fa!
ResponderEliminarvi algo en gitgub, si no recuerdo mal era algo de afipSDK algo asi
EliminarHola muchas gracias por el aporte lo seguí y he logrado avances importantes, ahora te hago una pregunta, si es un Monotributista y hace facturas "C" únicamente y no discrimina IVA, al finalizar y a pesar de colocar alícuota "0" y el neto = bruto me da un error "La cadena de entrada no tiene el formato correcto" alguna sugerencia otra vez Muchgas Gracias. Enrique
ResponderEliminarEstoy teniendo un problema a la hora de agregar tributos. ¿Cómo se agregan los tributos?
ResponderEliminarDespués de probar finalmente descubrí como se hace. Si van a agregar tributos al objeto Tributos se le asigna asi: .Tributos = {tributo}. Se crean un objeto Tributo, le agregan los valores a los atributos y lo asignan de esa forma. Si tienen mas de un tributo los van agregando así: .Tributos = {tributo1, tributo2, tributo3}. Recuerden sumar los importes de cada tributo y agregarlo al .ImpTrib
EliminarHola. Estoy teniendo una duda en como recuperar el TA. Yo ya logre grabar en la una tabla el token, el sign y las fechas. Compruebo si esta vencido o no. Ahora mi duda, como armo el TA con eso datos, porque veo q cuando quiero enviar pide el certificado ya realizado anteriormente y si se cerro el programa no lo tengo. Alguien me puede guiar en eso. La verdad me perdi donde usar el token y el sign recuperados.
ResponderEliminarBuen dia, yo lo solucioné modificando el codigo y exporto en txt datos del certificado, entonces si se cerro el programa da la excepcion y lee el txt, si lo necesitas te lo envio a tu correo.
EliminarExcelente explicación. Muchas gracias por compartir tu conocimiento y dedicarnos tu tiempo.
ResponderEliminarEstoy usando mi sistema de ventas con la incorporacion de esta guia/script desde el mes de enero sin problemas, ayer quise sacar junio y me salta "no es pósible comunicarse con el servidor de afip" y cuando consulto ultimos comprobantes sale "no se puede crear un canal seguro SSL/TLS". nada se toco en programacion. y nada cambio en la afip. alguien le paso algo parecido ?? saludos
ResponderEliminarpor si alguien le sirve. logre solucionar el inconveniente agregando antes del login, en loginclass.
ResponderEliminarServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
con eso esta operativo todo de nuevo.
saludos
Hola. También tengo ese problema desde hace unos días y el certificado según el sitio de AFIP esta ok. Dónde pusiste esa línea?. Que es servicepointmanager?. Gracias
EliminarMaster of the universe!
EliminarPaso lo msimo!!! Crack!!!
Eliminargenial! yo lo puse dentro de hacer login, al principio
EliminarDit is echt een handige lijst voor mij! Ik moet toegeven dat je een van de beste bloggers bent die ik ooit heb gezien. Bedankt voor dit bericht over Groepenkast kopen.
ResponderEliminarExcelente aporte, muy bueno, felicitaciones, no es fácil encontrar algo tan complejo y tan bien explicado y desarrollado.
ResponderEliminarMuchas Gracias por compartir tu conocimiento! Siguiendo este tutorial logré la facturación electrónica evitando la instalacion de una impresora fiscal en mi negocio. Deberías poner tu CBU para transferir una donación como agradecimiento.
ResponderEliminarApoyo eso... con lo que me ayudo esto!
EliminarQue me pase el alias que ya hago transferencia, creo que son si ayuda no hubiera llegado a hacerlo. Por más gente como vos!
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarBuen dia, te puedo consultar si es posible, gracias a esto que desarrollaste pude realizar la conexion a FE, uchas gracias por eso, ahora bien, mi consulta es sobre la emision de Tique Factura, comprobantes de afip 081, 082 y 083 respectivamente sobre la tabla de afip, como es eso, en realidad necesito imprimir en comandera,se imprime ese tique, o estoy confundido y la salida por comandera de la FE, es la misma factura que emitis de los items 01, 06, 011, me gustaria saber si me podes aclarar eso. Gracias desde ya
ResponderEliminarCm ago para q me pueda avilitara la costancia d AFIP ya preste ase 3 días es d una coperativa q se llama unidos en Fontana
ResponderEliminarBuenas, alguien implemento lo del QR en .NET? No entiendo de donde se saca el codigo de autorizacion....
ResponderEliminarNo dije nada... es el CAE despues me di cuenta...
EliminarBuenas te adjunto el código que utilice para generar el JSON Serializado en base64.
ResponderEliminarTenes que tener en cuenta que todavía no esta funcional desde el lado de afip, asi que cuando
ingreses a la URL generada, te derivará a https://www.afip.gob.ar/fe/qr/conceptos-generales.asp
Espero les sea de ayuda!
public class QR_DATOS_MODEL
{
public string ver { get; set; }
public string fecha { get; set; }
public string cuit { get; set; }
public string ptoVta { get; set; }
public string tipoCmp { get; set; }
public string nroCmp { get; set; }
public string importe { get; set; }
public string moneda { get; set; }
public string ctz { get; set; }
public string tipoDocRec { get; set; }
public string nroDocRec { get; set; }
public string tipoCodAut { get; set; }
public string codAut { get; set; }
}
public static string QR_GET(DateTime FECHA_EMISION, string EMISOR_CUIT, int COMPROBANTE_ID, string COMPROBANTE_NUMERO, decimal D_IMPORTE, string MONEDA, int RECEPTOR_DOCUMENTO, string RECEPTOR_DOCUMENTO_NUMERO, string CAE)
{
string WS_QR_URL = "https://www.afip.gob.ar/fe/qr/";
string URL = CGLOBAL.WS_QR_URL + "?p=";
string IMPORTE = D_IMPORTE.ToString("N2");
int ENTERO = int.Parse(IMPORTE.Split(',')[0]);
float DECIMAL = float.Parse(IMPORTE.Split(',')[1]);
IMPORTE = DT.CompletarConCerosAlPrincipio(ENTERO.ToString(), 13);
IMPORTE += DT.CompletarConCerosAlPrincipio(DECIMAL.ToString(), 2);
QR_DATOS_MODEL DATOS_Q = new QR_DATOS_MODEL()
{
ver = "1",
fecha = FECHA_EMISION.ToString("yyyy-MM-dd"),
cuit = DT.CompletarConCerosAlPrincipio(CGLOBAL.WS_EMISOR_CUIT, 11),
ptoVta = DT.CompletarConCerosAlPrincipio(CGLOBAL.WS_PV, 5),
tipoCmp = DT.CompletarConCerosAlPrincipio(COMPROBANTE_ID.ToString(), 3),
nroCmp = DT.CompletarConCerosAlPrincipio(COMPROBANTE_NUMERO, 8),
importe = IMPORTE,
moneda = MONEDA,
ctz = DT.CompletarConCerosAlPrincipio("1", 13) + "000000",
tipoDocRec = DT.CompletarConCerosAlPrincipio(RECEPTOR_DOCUMENTO.ToString(), 2),
nroDocRec = DT.CompletarConCerosAlPrincipio(RECEPTOR_DOCUMENTO_NUMERO.ToString(), 20),
tipoCodAut = "E",
codAut = DT.CompletarConCerosAlPrincipio(CAE.ToString(), 14)
};
//SERIALIZAR JSON
var account = DATOS_Q;
string json = JsonConvert.SerializeObject(account);
string base64EncodedExternalAccount = Convert.ToBase64String(Encoding.UTF8.GetBytes(json));
return URL + base64EncodedExternalAccount;
}
Half, usas algún paquete de json para generarlo y convertirlo?
EliminarPerdón la demora en contestar, mucho trabajo estas semanas.
EliminarPara serializar o deszerializar el JSON uso la clase Newtonsoft.Json
Para generar el codigo QR instalo desde el NUGET "QRCoder", en mi caso para ahorrar espacio en la base de datos no guardo la imagen en la base de datos, sino que guardo el código completo, y dinámicamente cuando la necesito genero la imagen que uso en la impresión.
Esta es la función que uso para la creación del QR, pasando como parámetro la URL+base64EncodedExternalAccount anteriormente obtenidos en la función que puse arriba.
public static byte[] QR_CREAR(string DATOS)
{
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode(DATOS, QRCodeGenerator.ECCLevel.Q);
BitmapByteQRCode qrCode = new BitmapByteQRCode(qrCodeData);
byte[] qrCodeAsBitmapByteArr = qrCode.GetGraphic(20);
return qrCodeAsBitmapByteArr;
}
El byte[] que devuelve la función, directamente lo paso al REPORTE, y en el reporte lo asigno al campo imagen.
Espero les sea útil.
Saludos
hola Half, gracias por el código, justo necesito el QR.
EliminarUna vez que generás el array de bytes, veo que decís que lo asignás al campo IMAGEN de REPORTE.
¿A qué llamás REPORTE, o sea qué clase del código de ejemplo que ponés?
Mil gracias!
no dije nada! ya me di cuenta como hacerlo, grax!
Eliminarhola HALF, yo uso VB pero obviamente entiendo tu codigo, ahi el retorno es un string no? como lo convertis a la imagen QR propiamente dicha?
ResponderEliminarUsando una clase Qrcode que podes bajar del nuget
EliminarBuenos dias, ya logre hacer todo, use la libreria de esta web
Eliminarhttps://www.ajpdsoft.com/modules.php?d_op=viewdownloaddetails&lid=298&name=Downloads
Gracias, usando la dll del enlace que pase pude generar el QR en un picturebox y despues guardarlo en BLOB en mi base de datos y usar ese campo en el informe, me quedo todo ok.
Eliminarhola Half, por casualidad usastes esta libreria ??
ResponderEliminarhttps://github.com/codebude/QRCoder/
recien voy a empezar con este tema del QR.
siempre un nuevo invento tienen......
Hace mucho q se implemento en otros países, por lo menos sirve para ver si un comprobante es trucho, hay muchos con comprobantes truchos dando vuelta. Aunque estaría bueno que funcione, aun sigue sin funcionar del lado de la AFIP, redirecciona a un sitio de la AFIP, estaría bueno que muestren el comprobante online así también las empresas pueden ver si concuerda lo presentado en la AFIP y el comprobante enviado por el proveedor.
EliminarAlguien sabe cuándo estará funcional del lado de AFIP el tema del código qr? Sigue derivando a la web de AFIP genérica.
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarBuenas, despues de pelear un largo rato, logre actualizar el sistema al qr.
ResponderEliminarLes dejo el codigo.
Se instala por NUGET los paquetes de System.Text.Json y de ZXing.Net.
Para generar la url:
Primero declaran una clase, no pongo todo el codigo para no hacerlo largo, hacen asi por todos los campos.
Public Class QR
Public Property ver() As Integer
Get
Return m_Ver
End Get
Set
m_Ver = Value
End Set
End Property
Private m_Ver As Integer
end class
Cargan generan el objeto y lo cargan
Dim objQR As New QR
With objQR
.ver = 1
.fecha = Now.ToString("yyyy-MM-dd")
.cuit = EMISOR_CUIT
.ptoVta = PV
.tipoCmp = COMPROBANTE_ID
.nroCmp = COMPROBANTE_NUMERO
.importe = Format(D_IMPORTE, "0000000000000.00")
.moneda = MONEDA
.ctz = "1"
.tipoDocRec = RECEPTOR_DOCUMENTO.ToString()
.nroDocRec = RECEPTOR_DOCUMENTO_NUMERO.ToString()
.tipoCodAut = "E"
.codAut = CAE
End With
Dim WS_QR_URL As String = "https://www.afip.gob.ar/fe/qr/"
Dim url As String = WS_QR_URL + "?p="
Dim json As String = JsonSerializer.Serialize(objQR)
Dim base64EncodedExternalAccount As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(json))
Dim direccion_qr As String = url + base64EncodedExternalAccount
Generamos el qr
Dim GENERADOR As BarcodeWriter = New BarcodeWriter 'INICIALIZA EL GENERADOR
GENERADOR.Format = BarcodeFormat.QR_CODE
GENERADOR.Options.Margin = 2
GENERADOR.Options.Width = 1000
GENERADOR.Options.Height = 1000
Dim IMAGEN_QR As Bitmap
IMAGEN_QR = New Bitmap(GENERADOR.Write(direccion_qr), 600, 600)
Y listo problema resulto...
Use parte del codigo de Half, asi que los correspondientes creditos a el.
buenas noches. trabajo solo en visual, me resulta muy comodo. les comparto el codigo para Qr de las facturas nueva resolucion. Tome data de Half y bnjis, graciassss por el aporte.
ResponderEliminarInstale por nuget Newtonsoft.Json y QRCoder
Finalmente grabo en disco la imagen del codigo Q, porque despues lo toma la rutina que arma el pdf de la factura completa.
Espero que sirva para los que aun usamos vb.net
saludos
Daniel
Public Class QR_DATOS_MODEL
Public Property Ver As String 'version "1"
Public Property Fecha As String 'fecha emision
Public Property Cuit As String 'cuit emisor
Public Property PtoVta As String 'punto venta
Public Property TipoCmp As String '001 FactA /006 FactB
Public Property NroCmp As String 'numero de compro
Public Property Importe As String 'importe total
Public Property Moneda As String 'moneda "PES"
Public Property Ctz As String 'cotizacion = "1"
Public Property TipoDocRec As String 'Documento Cliente 80 CUIT //96 DNI
Public Property NroDocRec As String 'cuit cliente o DNI
Public Property TipoCodAut As String 'tipo Cae = "E"
Public Property CodAut As String 'numero Cae
End Class
Private Sub CodigoQ()
'convierto fechas
Dim nuevoano As String = Module1.mfecha.Substring(6, 4)
Dim nuevomes As String = Module1.mfecha.Substring(3, 2)
Dim nuevodia As String = Module1.mfecha.Substring(0, 2)
Dim fechaemision As String = nuevoano + "-" + nuevomes + "-" + nuevodia
'Cargan generan el objeto y lo cargan
Dim codigoQ As New QR_DATOS_MODEL
With codigoQ
.Ver = 1
.Fecha = fechaemision
.Cuit = "xxxxxxxxxxx"
.PtoVta = Convert.ToString(Convert.ToDecimal(Module1.mptovta))
.TipoCmp = Module1.mcompafip
.NroCmp = Convert.ToString(Convert.ToDecimal(Module1.mnumero))
.Importe = Replace(Module1.mtotal, ",", ".")
.Moneda = "PES"
.Ctz = "1"
If Module1.mtipodoc = "CUIT" Then
qtipodoc = "80"
End If
If Module1.mtipodoc = "DNI" Then
qtipodoc = "96"
End If
.TipoDocRec = qtipodoc
.NroDocRec = Module1.mnumdoc
.TipoCodAut = "E"
.CodAut = Module1.mcae
End With
Dim json As String = JsonConvert.SerializeObject(codigoQ)
Dim base64 As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(json))
Dim url_qr As String = "https://www.afip.gob.ar/fe/qr/" + "?p=" + base64
Dim qrGenerator As QRCodeGenerator = New QRCodeGenerator()
Dim qrCodeData As QRCodeData = qrGenerator.CreateQrCode(url_qr, QRCodeGenerator.ECCLevel.Q)
Dim qrCode As QRCode = New QRCode(qrCodeData)
Dim imagenqr As Bitmap = qrCode.GetGraphic(20)
imagenqr.Save("c:\Sistemas\SistemaDeVentas1.0\SistemaDeVentas1.0\Imagenes\CodigoQR.png", System.Drawing.Imaging.ImageFormat.Png)
End Sub
Hola. funciona perfecto, pero cuando quiero imprimir en una impresora termica Hasar 250 no tiene buena resolucion para ser escaneado por la camara del celular. lo cargo en un picturebox y lo imprimo con e.Graphics.DrawImage
Eliminarconsulta:
ResponderEliminarLa afip me devuelve por ej: {"FACTURA":150}
Es decir es el comprobante número 150.
Ahora si vemos una factura cualquiera, van a ver que empieza tipo 0001-000000000150
Ese primer número que onda? Hay algún servicio para conseguirlo o de donde se saca?
Es el punto de venta... eso se crea en AFIP y despues lo configuras en tu sistema, generalmente empieza con 1 o cambia si ya tenian punto de venta y despues les crearon puntos de venta RECE.
EliminarCorresponde al punto de venta. Para poder facturar online debes crear entrando con el cuit y clave fiscal del titular un punto de venta del tipo RECE. Ese punto de venta es el que enviaras al momento de hacer la factura y es el que aparece delante del número de la factura
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarbuen día gente como va? les hago una consulta yo utilizo el comando FECompConsultaReq para traer los datos de una factura, pero me gustaria poder consulta varias facturas en una sola consulta poder traer una matriz de facturas o una lista, alguien tiene idea si es posible y como?
ResponderEliminar, desde ya gracias, saludos!
Hola buen día, no existe la opción "desde" y "hasta" en la consulta, por lo que veo es solo por un comprobante.
EliminarSaludos.
Hola, consulta, tengo problemas para completar el CbtesAsoc para hacer notas de crédito, probé varias formas y nada, pueden hacer notas drédito? gracias y excelente aporte.
ResponderEliminarNo se si lo pudiste resolver pero yo lo que hago es lo siguiente
EliminarCbteAsoc objcompasoc = new CbteAsoc();
objcompasoc.PtoVta = Convert.ToInt32(NegocioConfigEmpresa.puntoventa);
objcompasoc.Nro = comprobanteasoc;
objcompasoc.Tipo = comprobantefactura;
det.CbtesAsoc = new[] { objcompasoc };
Instancio la clase cbteasoc agrego el punto de venta, el tipo de factura que quiero generar la nota de credito y
el numero de comprobante de la factura
Hola, si, hice algo muy similar instanciando un objeto, pero mirando tu ejemplo le quité la fecha del comprobante y funciona, muchas gracias!!!!
EliminarHola estimado, tendrias un ejemplo de como realizar la nota de credito?
EliminarHola ASD, disculpa no puedo lograr hacer la nota de credito me podrias tirar una idea de como lo hiciste? o el codigo sino es mucho pedir muchas gracias
EliminarAl que generó esta página que es tan útil, estaría bueno crear un foro de WebServices con desarrolladores Visual Studio.
ResponderEliminarDejo la inquietud.
Saludos!
Aparece dentro del servicio MIS COMPROBANTES
ResponderEliminarEs simple. Entras a AFIP con clave fiscal nivel 3. Si no tienes adherido el servicio que se llama MIS COMPROBANTES lo haces desde el servicio que se llama ADMINISTRADOR DE RELACIONES- presionas donde dice nueva relación, luego en AFIP interactivos y ahí buscas MIS COMPROBANTES y le das en adherir. Una vez agregado tendrás que salir y volver a entrar con tu clave fiscal y ya tendrás el servicio MIS COMPROBANTES, donde puedes ver tanto las FE emitidas como recibidas. Cualquier cosa mi mail es carlosalfonsofuentes@gmail.com. saludos
ResponderEliminarHola! Excelente el post! Tengo una pregunta.
ResponderEliminarTengo que emitir facturas tipo C pero con un detalle de ítem sencillo, por servicios. Trabajo en sis temas y la factura debería decir, por ejemplo: "Honorarios implementación sistema de facturación" y por supuesto el importe.
Pero aparentemente el servicio WSFEV1 no permite enviar detalle, y el "WSMTXCA", en su decripción dice que es para facturas tipo "A" y "B"...
¿Se puede usar tb para emitir facturas tipo "C" con un detalle de ítem?
Mil gracias!!
Hay q diferenciar un par de cosas…
ResponderEliminarVos a Afip no le mandas descripción de lo q vendes, solo el total. Vos en tu factura lo armas.
Para hacer factura c el q emite el l comprobante tiene q ser monotributosta y mandar el código correspondiente del comprobante. Sino te va a dar error.
Hola @bnjis :)
EliminarNo sé si estás contestandome a mí (@sheik). Si es así, debe haber algo más básico que no estoy entendiendo: estos servicios de AFIP (ya sea WSFEV1 o WSMTXCA) ¿No permiten emitir facturas? ¿La invocación no implica la generación de una FC de la que luego me puedo descargar el PDF ya completo, y para eso no necesito poder indicar el detalle? ¿Cómo es eso de que "yo en mi factura lo armo"?
Mi idea es emitir facturas listas para descargar e imprimir o enviar por correo para mis posibles clientes, no que que tengan que entrar al sitio de AFIP a armar su factura "luego"... :(
No estás entendiendo cómo funciona esto.
EliminarAquí vos programas tu código en tu sistema el cual se comunica con la Afip y le das los parámetros de facturación como indican en el post. La Afip responde confirmando el comprobante con los datos necesarios para que vos en tu sistema diseñes como te guste (siguiendo los parámetros q te pide Afip) la factura.
Si tu idea es simplemente emitir facturas, sin anexarlo a un aplicativo, usa el facturador q brinda la Afip en su web.
Gracias @bnjis :)
EliminarQué garrón! Lo que pasa es que mis posibles clientes (personal de salud: fonoaudiólogos, psicólogos, etc.) deben emitir decenas de facturas por mes, casi todas con datos muy similares, con datos que pueden estar en base de datos o en un Excel, CSV, etc.
Mi idea era ahorrarles entrar la engorrosa página web de AFIP factura por factura, que les lleva horas al ser tantas facturas, y generarles las facturas de una...
Entonces lo que tengo que hacer es "autorizar" facturas con los servicios web, y por cada FC de la que los WS me dan el OK, generar el PDF yo, en el cual puedo incluir el detalle que yo quiera?
Para ello debo homologar mi sistema con la AFIP, o simplemente cumplir con ciertos requisitos?
Leí bastante documentación, pero nunca encontré nada como lo que te estoy preguntando al respecto...
Mil gracias por tus rápidas respuestas :)
Ups, creo que te aburrí con mis preguntas de newbie :(
ResponderEliminarMe salvarías la vida si me contestaras esas últimas :)
Saludos y gracias por adelantado
Consulta, alguno utilizo los web service para validar los datos del cliente?
ResponderEliminarHola como estas estoy queriendo utilizar esto pero en una app core 3.1 c# y estoy teniendo problemas. Tenes algo para guiar
ResponderEliminarHola. estoy migrando a Net core y tengo problemas con el cmssigner.
ResponderEliminarparece que ya no soporta SHA1 pero no encuenrto nada de documentacion de como solucionarlo.
Alguna mano?
Dim contentInfo As New ContentInfo(argBytesMsg)
Dim signedCms As New SignedCms(contentInfo)
signedCms.ComputeSignature(cmsSigner, False)
Return signedCms.Encode()
Estuve buscando en el WebService y la consulta de la condición frente al IVA no la encontré.
ResponderEliminarHola a todos, como estan? Quisiera saber si alguien sabe como se haria el procedimiento desde Java - Netbeans. Desde ya muchas gracias
ResponderEliminarcreo que es este, FEParamGetTiposIva
ResponderEliminar