endpoint.pe

Checklist para validar un cliente antes de facturar

Validar cliente antes de facturar: RUC válido, ACTIVO y HABIDO, razón social, dirección, tipo de comprobante, moneda y tipo de cambio. Cómo automatizarlo.

eEquipo endpoint.pe•20 jun. 20269 min de lectura

La mayoría de las facturas que terminan anuladas con nota de crédito no fallaron en SUNAT. Fallaron antes: un RUC digitado con un número cambiado, una razón social copiada de un correo con una letra de menos, un cliente que estaba en baja desde hace meses y nadie lo sabía. SUNAT aceptó el XML; el que lo rechazó fue el cliente, o su contador, dos semanas después.

Validar antes de emitir es barato; corregir después cuesta una nota de crédito, una factura nueva, dos CDR y una conversación incómoda. Este artículo es un checklist de lo que debes verificar y, en la segunda mitad, cómo convertirlo en código que corre solo al presionar "emitir".


El checklist completo

Estos son los puntos, en el orden en que conviene verificarlos. Los primeros son baratos y locales; los últimos requieren consultar a SUNAT o decidir reglas de negocio.

#Qué validarCómoSi falla
1Formato del documentoRUC de 11 dígitos con dígito verificador correcto; DNI de 8 dígitosBloquea: corrige antes de seguir
2El RUC existe en SUNATConsulta al padrónBloquea
3Estado ACTIVOCampo estado de la consultaBloquea o alerta según política
4Condición HABIDOCampo condicionAlerta fuerte
5Razón social exactaComparar con la que registra SUNATCorrige automáticamente
6DirecciónTomar el domicilio fiscal del padrónCompleta o alerta
7Tipo de comprobanteRUC: factura; DNI o sin documento: boletaDecide el sistema, no el usuario
8Moneda y tipo de cambioMoneda del contrato; tipo de cambio de la fecha de emisiónBloquea si falta el tipo de cambio

La idea general: lo que puede decidirse con una regla lo decide el sistema; lo que requiere criterio humano se muestra como alerta con contexto.

Documento, estado y condición

Formato. Un RUC tiene 11 dígitos, empieza en 10 (persona natural) o 20 (persona jurídica), entre otros prefijos, y su último dígito se calcula a partir de los anteriores. Esa verificación es local y detecta el error más común: un número mal digitado. El algoritmo está en cómo validar un RUC con el dígito verificador. Un DNI tiene exactamente 8 dígitos, con sus ceros a la izquierda.

Existencia. Un RUC con formato válido puede no existir. Solo el padrón de SUNAT confirma que está registrado. Si la consulta devuelve "no encontrado", no emitas: ese cliente no puede recibir una factura.

Estado. El estado del contribuyente dice si el RUC está operativo. Los valores son ACTIVO, SUSPENSIÓN TEMPORAL, BAJA PROVISIONAL, BAJA DEFINITIVA y BAJA DE OFICIO. Facturar a un RUC en baja es un problema para los dos lados: el cliente no está operando ante SUNAT y el documento va a generar observaciones. La política razonable es bloquear si el estado no es ACTIVO y exigir confirmación de un supervisor para las excepciones.

Condición. La condición de domicilio dice si SUNAT ubica al contribuyente en su dirección declarada: HABIDO, NO HABIDO, NO HALLADO o PENDIENTE. Un cliente NO HABIDO no te impide emitir, pero es una señal de riesgo (y si fuera tu proveedor, el sustento del gasto y del crédito fiscal se complica). Trátalo como alerta visible, nunca silenciosa. Si estos conceptos son nuevos para ti, lee primero qué significan ACTIVO y HABIDO.

Razón social, dirección y tipo de comprobante

Razón social. La factura debe llevar la razón social tal como está registrada en SUNAT. "Inversiones ABC SAC" y "INVERSIONES ABC S.A.C." son la misma empresa, pero si tu cliente concilia por texto exacto, una diferencia de puntos o mayúsculas le genera trabajo. La regla más simple: no dejes que el usuario la escriba; precárgala desde el padrón y guárdala tal cual.

Para comparar lo que escribió el usuario con lo oficial, normaliza ambos lados (mayúsculas, sin tildes ni puntos, espacios colapsados). Si coinciden normalizados, reemplaza en silencio por el oficial. Si no, muestra ambos y pide confirmación: puede ser un cambio reciente de razón social o un RUC equivocado.

Dirección. El domicilio fiscal también está en el padrón. Aunque el XML no siempre exige la dirección del cliente, muchas empresas la piden para su control interno y figura en la representación impresa. Precárgala y permite editarla solo para una dirección de entrega distinta. Guarda el ubigeo junto a la dirección: sirve para guías de remisión y reportes por zona.

Tipo de comprobante. Es la decisión que tu sistema debería tomar sin preguntar:

  • Cliente con RUC: factura.
  • Cliente con DNI, carnet de extranjería o pasaporte: boleta.
  • Venta sin identificar al comprador: boleta, pero recuerda que desde S/ 700 la boleta debe consignar el DNI del comprador.

El tipo y número de documento del cliente van en el XML con un código del catálogo de SUNAT (DNI, carnet de extranjería, RUC, pasaporte, entre otros). Mapea cada tipo de documento a ese código una sola vez. Los criterios en detalle están en factura o boleta: cuándo emitir cada una.

Un detalle que se olvida: una persona natural con RUC (empieza en 10) puede pedir factura; si no te da el RUC, es boleta aunque sepas que lo tiene. El comprobante lo determina el documento que el cliente presenta para esa operación.

Moneda y tipo de cambio

Si facturas en dólares, el comprobante lleva la moneda y los montos en dólares, pero tu registro de ventas y el IGV se expresan en soles. Para eso necesitas el tipo de cambio que corresponde a la fecha de emisión. Tres reglas para que no falle:

  1. La moneda es del contrato, no del día. Un cliente que acordó precios en dólares recibe factura en dólares aunque pague en soles. Guarda la moneda en el cliente o en la cotización, no la elijas al emitir.
  2. El tipo de cambio es de la fecha de emisión. No del día del pedido ni del día del cobro. Los días sin publicación (fines de semana, feriados) se usa el último publicado.
  3. Si no tienes el tipo de cambio, no emitas. Un valor en cero o uno copiado de la semana pasada produce un IGV en soles incorrecto que después hay que ajustar. Mejor bloquear la emisión hasta tener el dato.

El valor que necesitas es el que publica SUNAT (el promedio ponderado que calcula la SBS del día anterior). Para las ventas se usa el tipo venta; confirma con tu contador el criterio de cada caso. La API de tipo de cambio devuelve compra y venta del día, y en tipo de cambio SUNAT: cuál usar está el detalle.

Cómo automatizarlo paso a paso

Un validador de clientes es una función que recibe los datos del formulario y devuelve un veredicto: puede emitir o no, problemas con su gravedad y datos corregidos para precargar. Así sirve igual desde el formulario, desde una importación masiva o desde una tarea nocturna.

Paso 1: validación local. Formato del RUC con dígito verificador, formato del DNI, moneda válida. Nada de red. Si falla aquí, devuelves el error de inmediato.

Paso 2: caché. Antes de consultar a SUNAT, busca el RUC en tu tabla de clientes validados. Si lo consultaste hace menos de un día, usa ese resultado: el estado rara vez cambia en horas. Ahorra créditos y tiempo de respuesta.

Paso 3: consulta al padrón. Si no hay caché o venció, consulta. Con endpoint.pe es una llamada con el RUC y tu token:

curl https://api.endpoint.pe/v1/ruc/20131312955 \
  -H "Authorization: Bearer TU_TOKEN"

La respuesta trae ruc, razon_social, estado, condicion, direccion y ubigeo. Un 404 significa que el RUC no existe en el padrón, y esa consulta no se cobra.

Paso 4: reglas. Aplica las del checklist y arma el veredicto. En Node.js, de forma resumida:

const BASE = 'https://api.endpoint.pe/v1';
const TOKEN = process.env.ENDPOINT_PE_TOKEN; // nunca en el navegador

function normalizar(texto) {
  return texto
    .normalize('NFD')
    .replace(/[̀-ͯ]/g, '')
    .toUpperCase()
    .replace(/[.,]/g, '')
    .replace(/\s+/g, ' ')
    .trim();
}

async function validarClienteRuc({ ruc, razonSocial, moneda, tipoCambio }) {
  const problemas = [];

  if (!rucFormatoValido(ruc)) {
    return { puedeEmitir: false, problemas: [{ nivel: 'bloquea', msg: 'RUC con formato inválido' }] };
  }

  const res = await fetch(`${BASE}/ruc/${ruc}`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
  });
  if (res.status === 404) {
    return { puedeEmitir: false, problemas: [{ nivel: 'bloquea', msg: 'RUC no existe en SUNAT' }] };
  }
  if (!res.ok) throw new Error(`Consulta RUC falló con HTTP ${res.status}`);
  const { data: sunat } = await res.json();

  if (sunat.estado !== 'ACTIVO') {
    problemas.push({ nivel: 'bloquea', msg: `Estado ${sunat.estado}` });
  }
  if (sunat.condicion !== 'HABIDO') {
    problemas.push({ nivel: 'alerta', msg: `Condición ${sunat.condicion}` });
  }
  if (normalizar(razonSocial || '') !== normalizar(sunat.razon_social)) {
    problemas.push({ nivel: 'corrige', msg: 'Razón social distinta a SUNAT', valor: sunat.razon_social });
  }
  if (moneda === 'USD' && !(tipoCambio > 0)) {
    problemas.push({ nivel: 'bloquea', msg: 'Falta el tipo de cambio de la fecha de emisión' });
  }

  return {
    puedeEmitir: !problemas.some((p) => p.nivel === 'bloquea'),
    problemas,
    datos: {
      razonSocial: sunat.razon_social,
      direccion: sunat.direccion,
      ubigeo: sunat.ubigeo,
      tipoComprobante: 'factura',
    },
  };
}

La función rucFormatoValido es el algoritmo del dígito verificador; no lo repetimos aquí. Observa tres decisiones: el token vive en el servidor, un 404 es una respuesta válida y no una excepción, y el resultado siempre devuelve los datos oficiales para que el formulario se autocomplete.

Paso 5: interfaz. Al salir del campo RUC se llama a esta función. Los problemas "bloquea" deshabilitan el botón de emitir y se muestran en rojo; los "alerta" van en ámbar y exigen confirmación; los "corrige" reemplazan el valor con un aviso discreto. El usuario nunca ve un JSON, ve tres colores.

Paso 6: revalidación periódica. Una tarea diaria recorre los clientes con facturas recientes, repite la consulta y marca a los que cambiaron de estado o condición. Así el vendedor se entera de que un cliente pasó a baja antes de emitirle la siguiente factura.

Si aún no tienes proveedor de consultas, en cómo elegir una API de consulta RUC y DNI en Perú comparamos los criterios que importan para que este checklist corra sobre datos oficiales y al día.

En resumen

  • Valida en orden: formato, existencia, estado, condición, razón social, dirección, tipo de comprobante, moneda y tipo de cambio.
  • Lo que puede resolverse con una regla lo decide el sistema; lo que requiere criterio se muestra como alerta con contexto.
  • No dejes escribir la razón social: precárgala desde SUNAT y compárala normalizada.
  • El estado y la condición cambian; revalida al emitir o al menos a diario.
  • Factura en dólares sin tipo de cambio de la fecha de emisión no se emite.
  • Un validador único (función que devuelve veredicto, problemas y datos oficiales) sirve para el formulario, la carga masiva y la tarea nocturna.

Preguntas frecuentes

¿Debo bloquear la factura si el cliente está NO HABIDO?

No necesariamente. La condición NO HABIDO es un problema del cliente ante SUNAT y una señal de riesgo comercial para ti, pero no te impide emitir. Muéstrala como alerta que requiere confirmación. Si el NO HABIDO es tu proveedor, ahí sí conviene frenar, porque el sustento de tu gasto y de tu crédito fiscal se complica.

¿Cada cuánto conviene volver a consultar un RUC?

Para emitir, consulta en el momento si la última consulta tiene más de un día. Para revisar la cartera, una tarea diaria sobre los clientes activos basta. Los nombres casi nunca cambian; el estado y la condición sí, y son los que importan para facturar.

¿Qué pasa si el cliente insiste en una razón social distinta a la de SUNAT?

El comprobante debe llevar la razón social registrada en SUNAT. Si el cliente quiere ver un nombre comercial, puedes incluirlo como dato adicional o en observaciones, pero el campo del adquirente lleva el nombre oficial. Si el cliente dice que cambió de razón social, repite la consulta: el padrón se actualiza.

¿Puedo validar al cliente en el navegador para ahorrar una llamada al servidor?

La validación de formato (longitud, dígito verificador) sí va en el navegador: es instantánea y no expone nada. La consulta al padrón va siempre en tu backend, porque el token no debe salir del servidor; si necesitas respuesta rápida, el backend responde desde su caché.

Deja de copiar datos a mano. Automatízalo hoy mismo

Crea tu cuenta, copia tu token y empieza hoy con 150 consultas gratis al mes.