Saltar al contenido
Tarifa anual desde S/ 37 al mes + IGV. Pide tu demo sin costo. Reserva tu demo
Sistema Facturación Perú
Menú del portal

Empezar

Autenticación

Las tres formas de llamar a la API: claves de empresa con alcances, token de socio con client_credentials y la conexión con un botón (OAuth 2.0 con PKCE).

Actualizado el

Hay tres formas de autenticarte. Elige según de quién es la cuenta que vas a usar:

Si eres… Usa Token
La empresa (o su programador) y emites con tu propia cuenta Clave de empresa sfp_live_… / sfp_test_…
Un socio que da de alta a sus clientes como empresas Clave de socio (OAuth 2 client_credentials) sfp_pat_… (1 hora)
Un sistema cuyos clientes ya tienen cuenta en Sistema Facturación Perú Conectar con Sistema Facturación Perú (OAuth 2 + PKCE) sfp_oat_… (1 hora)

En los tres casos el token va solo en la cabecera Authorization: Bearer <token>. En la URL o en el cuerpo responde 401 (clave_en_url en la API v1, token_en_url en la de socios), porque quedaría guardado en los registros de los servidores.

Claves de empresa

Se crean en Configuración › Sistema › Integraciones › API (desde el Plan PRO). Cada empresa puede tener varias, cada una con:

  • un nombre (por ejemplo, «Tienda en línea»), para reconocerla en el registro de llamadas;
  • un usuario: la clave actúa como él, con sus funciones, su local y sus series;
  • alcances: lo que la clave puede hacer, aunque el usuario pueda más;
  • un local fijo, si quieres que solo emita en uno;
  • una fecha de vencimiento, si quieres.

Formato: sfp_live_ + 40 caracteres en producción y sfp_test_ + 40 en pruebas. Guardamos solo su huella: la ves una sola vez al crearla. Si la pierdes, revócala y crea otra. La pantalla muestra cuándo se usó por última vez.

Alcances

Alcance Permite
comprobantes.emitir Emitir comprobantes, notas de venta, cotizaciones, retenciones, percepciones y liquidaciones; reenviar a SUNAT
comprobantes.leer Ver comprobantes, descargar PDF, XML y CDR, enviarlos por correo o WhatsApp
comprobantes.anular Anular (baja o resumen)
guias.emitir / guias.leer Emitir y ver guías de remisión
cobros.registrar Registrar cobros
catalogo.leer / catalogo.escribir Ver y cambiar clientes, productos y locales
stock.leer Ver stock por almacén, lote y serie
consultas RUC, DNI y tipo de cambio
webhooks.gestionar Crear y borrar webhooks

Cada llamada revisa dos cosas: que la clave tenga el alcance y que su usuario tenga la función en el sistema.

  • Falta el alcance → 403 scope_faltante, con la cabecera X-SFP-Scope-Required que dice cuál.
  • Falta la función del usuario → 403 sin_permiso.
  • El plan no incluye la API → 403 plan_sin_api.
  • Pago vencido o cuenta suspendida → 423 cuenta_bloqueada.

Da a cada clave solo lo que necesita. Una tienda en línea que emite boletas no necesita comprobantes.anular ni catalogo.escribir. Si la clave se filtra, el daño queda acotado.

El token antiguo

El token del usuario que usa la app móvil también vale en la v1, con todos los alcances; en el registro de llamadas sale como «legacy». Funciona, pero te recomendamos pasar a una clave v1: tiene alcances, vencimiento y se revoca sin tocar al usuario.

curl https://miempresa.sistemafacturacionperu.com/api/v1/yo \
  -H "Authorization: Bearer $SFP_API_KEY"
<?php
$headers = ['Authorization: Bearer ' . getenv('SFP_API_KEY'), 'Accept: application/json'];
const headers = { Authorization: `Bearer ${process.env.SFP_API_KEY}`, Accept: 'application/json' };
headers = {"Authorization": f"Bearer {os.environ['SFP_API_KEY']}", "Accept": "application/json"}

Claves de socio

Si tienes muchos clientes propios y quieres darlos de alta tú mismo, eres socio. Te entregamos una credencial (client_id sfp_partner_… y client_secret sfp_secret_…) y con ella pides un token de 1 hora. Es OAuth 2 client_credentials: cualquier librería de OAuth sirve.

curl -s https://api.sistemafacturacionperu.com/socios/v1/token \
  -u "$SFP_CLIENT_ID:$SFP_CLIENT_SECRET" \
  -d grant_type=client_credentials
<?php
$ch = curl_init('https://api.sistemafacturacionperu.com/socios/v1/token');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD => getenv('SFP_CLIENT_ID') . ':' . getenv('SFP_CLIENT_SECRET'),
    CURLOPT_POSTFIELDS => http_build_query(['grant_type' => 'client_credentials']),
]);
$token = json_decode(curl_exec($ch), true)['access_token'];   // sfp_pat_…, vale 1 hora
const basic = Buffer.from(`${process.env.SFP_CLIENT_ID}:${process.env.SFP_CLIENT_SECRET}`).toString('base64');
const res = await fetch('https://api.sistemafacturacionperu.com/socios/v1/token', {
  method: 'POST',
  headers: { Authorization: `Basic ${basic}`, 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({ grant_type: 'client_credentials' }),
});
const { access_token } = await res.json(); // sfp_pat_…, vale 1 hora
r = requests.post(
    "https://api.sistemafacturacionperu.com/socios/v1/token",
    auth=(os.environ["SFP_CLIENT_ID"], os.environ["SFP_CLIENT_SECRET"]),
    data={"grant_type": "client_credentials"},
    timeout=30,
)
token = r.json()["access_token"]  # sfp_pat_…, vale 1 hora

Con ese token das de alta empresas y creas, para cada una, una clave de empresa sfp_live_ con la que emites en su API v1. Todo el detalle, los precios y las bolsas están en la API de socios.

Conectar con Sistema Facturación Perú

Si tu sistema tiene clientes que ya usan Sistema Facturación Perú, no les pidas que copien una clave: ponles un botón «Conectar con Sistema Facturación Perú». Es OAuth 2.0 con authorization code y PKCE S256 obligatorio, como Google, Mercado Pago o Stripe.

  1. Tu botón abre una ventana emergente en https://api.sistemafacturacionperu.com/conectar con tu client_id, tu redirect_uri, un state y el code_challenge de PKCE.
  2. El usuario escribe su RUC y entra con su usuario y contraseña de siempre, en el subdominio de su empresa. Su contraseña nunca pasa por tu sistema.
  3. Pulsa «Permitir» en la pantalla que le muestra tu aplicación y los permisos que pides.
  4. Vuelve a tu redirect_uri con un code de un solo uso (5 minutos) y tu state.
  5. Tu servidor canjea el código en POST /oauth/token con tu secreto y el code_verifier, y recibe un token de 1 hora, uno de renovación y la dirección de la API de esa empresa.
  6. Emites en empresa.api_url con Authorization: Bearer sfp_oat_….

Así se genera el par PKCE:

import { randomBytes, createHash } from 'node:crypto';

const b64url = (buf) => buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const codeVerifier = b64url(randomBytes(48)); // 64 caracteres: guárdalo en la sesión
const codeChallenge = b64url(createHash('sha256').update(codeVerifier).digest());
const state = b64url(randomBytes(24));
<?php
$b64url = fn (string $bin) => rtrim(strtr(base64_encode($bin), '+/', '-_'), '=');
$codeVerifier = $b64url(random_bytes(48));
$codeChallenge = $b64url(hash('sha256', $codeVerifier, true));
$state = $b64url(random_bytes(24));
$_SESSION['sfp'] = ['verifier' => $codeVerifier, 'state' => $state];
import base64, hashlib, secrets

b64url = lambda b: base64.urlsafe_b64encode(b).rstrip(b"=").decode()
code_verifier = b64url(secrets.token_bytes(48))
code_challenge = b64url(hashlib.sha256(code_verifier.encode()).digest())
state = b64url(secrets.token_bytes(24))

En el Plan Básico la conexión sirve solo para emitir; en PRO y Empresa, para todo. El botón completo, el canje, la renovación y la desconexión están en Conectar con Sistema Facturación Perú.

Buenas prácticas

  • Guarda claves, secretos y tokens en variables de entorno o en un gestor de secretos. Nunca en el repositorio, en una app móvil ni en el navegador.
  • Una clave por sistema o integración: si un sistema se da de baja, revocas su clave y los demás siguen.
  • Pon fecha de vencimiento a las claves de integraciones temporales.
  • Revisa el Registro de llamadas (Configuración › Sistema › Integraciones › API › Registro): guarda 30 días de llamadas con fecha, clave, ruta, resultado, tiempo e IP.

Portal para desarrolladores · ¿Algo no está claro o te falta un ejemplo? Escríbenos y lo mejoramos.