Consulta ruc a SUNAT - con CSHAP
Programación

Consulta RUC sin ingresar código captcha

Hace poco estuve trabajando en un proyecto, en uno de los modulos tenía que contar con una opción para consultar el RUC,  lo cual consistía en ingresar el numero de RUC de la empresa y el sistema debe consultar directamente a SUNAT sin ingresar el código captcha. 

Después de tanta investigación en internet logro completar el requerimiento. Recuerda, la perseverancia y la capacidad de investigación nos hace grandes desarrolladores. 

Antes, se podía consulta el RUC en el portal de SUNAT sin ingresar el código captcha, pero, ahora se complica un poco con el famoso captcha. Antes la consulta era a la siguiente url: 

http://www.sunat.gob.pe/w/wapS01Alias?ruc={nímero de RUC}

Ahora:

http://www.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias

Entonces, tuve que buscar un OCR(Reconocimiento óptico de caracteres) que me permita convertir la imagen captcha a un texto para mandar en la url de la consulta.

La OCR se llama Tesseract, lo mejor es que es de Open Source, lo que significa que es gratuito y de código libre. Código Fuente

Vamos a crear nuestro proyecto en Visual Studio y luego diseñamos el siguiente formulario. Para este ejemplo no voy a mostrar todos los datos de la empresa, solamente los datos necesarios.

Formulario de consulta RUC a SUNAT

Luego vamos a agregar las librerías necesarias desde el administrador de paquetes NuGet de nuestro proyecto. 

Para ello, click derecho en nuestra solución -> Administrador de paquetes NuGet para la solución y luego buscamos los siguientes paquetes:

  1. Agregar Tessnet2: Este es una extención de Tesseract para C#. 
  2. Agregar HtmlAgilityPack: Este es una librería que nos permite manipular Etiquetas HTML de manera muy simple.

Ya tenemos todo listo para escribir código. 

En el botón de consulta a SUNAT.

Pegamos el siguiente código.

try
{
    ConsultaRucSunat consultaRucSunat = new ConsultaRucSunat();
    btnConsultaSunat.Text = "Consultando...";
    Contribuyente contribuyente = await consultaRucSunat.ConsultaRuc(txtRuc.Text);
    txtRazonSocial.Text = contribuyente.RazonSocial;
    txtDirección.Text = contribuyente.Direccion;
    btnConsultaSunat.Text = "Consultar a SUNAT";
}
catch (Exception ex)
{
    throw new Exception("Error en btnConsultaSunat_Click : " + ex.Message);
}

En el proyecto creamos una clase que se llama ConsultaRucSunat

y pegamos el siguiente código

public class ConsultaRucSunat
{
    string captcha = "";
    Encoding objEncoding = Encoding.GetEncoding("UTF-8");
    private static HttpClient httpClient = new HttpClient(new HttpClientHandler { UseProxy = true, });
    string rutaTessData = string.Empty;
    public ConsultaRucSunat()
    {
        // Inicializa por unica vez la direcciÓn base
        if(httpClient.BaseAddress == null)
            httpClient.BaseAddress = new Uri("http://www.sunat.gob.pe/");

        // IndicaNDO la ruta de la librería. 
        rutaTessData = Application.StartupPath + @"tessdata";
    }

    public async Task<Contribuyente> ConsultaRuc(string ruc)
    {
        Contribuyente contribuyente = new Contribuyente();
        try
        {
            ServicePointManager.DefaultConnectionLimit = 2;

            // Descarga la imagen captcha
            HttpResponseMessage responseMessage = await httpClient.GetAsync($"cl-ti-itmrconsruc/captcha?accion=image");
            if (responseMessage.IsSuccessStatusCode)
            {
                Stream responseStream = await responseMessage.Content.ReadAsStreamAsync(); ;
                var image = new Bitmap(responseStream);
                var ocr = new Tesseract();

                // Indicamos la ruta de la libreria
                ocr.Init(rutaTessData, "eng", false);

                // Convertir la imagen a texto plano
                var result = ocr.DoOCR(image, Rectangle.Empty);
                foreach (Word word in result)
                {
                    captcha += word.Text;
                }

            }
            else
                return null;

            // Consulta el RUC enviando el codigo captcha
            var ConsultaRuc = await httpClient.GetAsync($"cl-ti-itmrconsruc/jcrS00Alias?accion=consPorRuc&nroRuc={ruc}&codigo={captcha.Trim().ToUpper()}&tipodocumento=1");

            // Si la consulta es exitosa
            if (ConsultaRuc.IsSuccessStatusCode)
            {
                string msg = string.Empty;

                // Libreria que permite trabajar con etiquetas HTML
                HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();

                // Carga el contenido html de la consulta
                document.LoadHtml(await ConsultaRuc.Content.ReadAsStringAsync());
                var NodeTable = document.DocumentNode
                                        .SelectNodes("//table")
                                        .FirstOrDefault();
                if (NodeTable != null)
                {
                    var listNodeTr = NodeTable.Elements("tr").ToArray();
                    if (listNodeTr != null)
                    {
                        // Extrae los valores de las celdas de la tabla. 
                        var nodeRazonSocial = listNodeTr[0].Elements("td").ToArray();
                        if (nodeRazonSocial != null)
                        {
                            string ConsultaCliente = LimpiarEspacios(nodeRazonSocial[1].InnerHtml.Trim());
                            contribuyente.RUC = ConsultaCliente.Substring(0, 11).Trim();
                            contribuyente.RazonSocial = ConsultaCliente.Substring(13, ConsultaCliente.Length - 13).Trim();
                        }
                        var nodeDireccion = listNodeTr[6].Elements("td").ToArray();
                        if (ruc.StartsWith("10"))
                        {
                            nodeDireccion = listNodeTr[7].Elements("td").ToArray();
                        }
                        if (nodeDireccion != null)
                        {
                            string ConsultaDireccion = LimpiarEspacios(nodeDireccion[1].InnerHtml.Trim());
                            contribuyente.Direccion = ConsultaDireccion.Trim();
                        }
                    }
                }
            }

        }
        catch (Exception ex)
        {              
        }
        return await Task.Run(() => contribuyente);
    }

    private string LimpiarEspacios(string cadena)
    {
        while (cadena.Contains("  "))
        {
            cadena = cadena.Replace("  ", " ");
        }
        return cadena;
    }
}

Listo, ya podemos consultar el RUC directamente a SUNAT.

Consulta RUC a SUNAT – Resultado

Si tienes un proyecto existente simplemente puedes copiar la clase a tu proyecto y llamar el método ConsultaRuc(ruc).

Código fuente en mi repositorio GitHub

Gracias por leer el post. Comparte !!!

Desarrollador, Consultor, Arquitecto de Software, con mas de 3 años de experiencia. Interesado en la innovación y preocupado por la calidad del servicio.