Download the PHP package invoka/sdk without Composer
On this page you can find all versions of the php package invoka/sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package sdk
Short Description SDK oficial de PHP para la API de Invoka: facturación electrónica del SRI de Ecuador para programadores (emisión de comprobantes, consulta y descarga, consultas al SRI, créditos, empresas y webhooks).
License MIT
Homepage https://invoka.com.ec
Informations about the package sdk
SDK oficial de PHP para Invoka
Facturación electrónica del SRI de Ecuador desde PHP, con la API de Invoka: emita facturas, notas de crédito y débito, guías de remisión, retenciones y liquidaciones de compra; consulte su estado y descargue el XML y el PDF; consulte RUC y cédulas en el SRI; y reciba avisos en vivo por webhook.
- PHP 8.1 o superior y Guzzle 7.
- Reintentos automáticos con espera exponencial (429, 502/503/504 y cortes de red), sin duplicar comprobantes.
- Excepciones tipadas:
Validacion,SaldoInsuficiente,ComprobanteDuplicado,CredencialInvalida… - Verificación de webhooks (firma V2 con sello de tiempo, HMAC-SHA256 en tiempo constante).
- Cálculo de la clave de acceso antes de emitir.
Índice
- Instalación
- Ambientes: pruebas y producción
- Primeros pasos
- Emitir comprobantes
- Consultar, descargar y reprocesar
- Consultas al SRI
- Créditos
- Empresas, firma y logo
- Webhooks
- Invoka ID
- Errores
- Reintentos
- Opciones del cliente
- Referencia rápida
- Pruebas
Instalación
La API key (API_…) está en el panel de Invoka → Mi Perfil. Guárdela en una variable de
entorno, nunca en el código.
Ambientes: pruebas y producción
Cada comprobante lleva un ambiente:
ambiente |
Qué es | Créditos |
|---|---|---|
| 1 · pruebas | El SRI lo procesa pero no tiene validez tributaria. | Gratis e ilimitado |
| 2 · producción | Comprobante REAL con validez tributaria. | 1 crédito por comprobante autorizado |
El SDK usa 1 por defecto. Para producción, póngalo en el cliente ('ambiente' => 2) o en el
comprobante ('ambiente' => 2; el del comprobante manda). Antes de pasar a 2:
- Pruebe toda su integración en 1.
- Tenga créditos (
$invoka->creditos->saldo()). - Tenga aprobados sus datos de Proveedor SRI (Res. NAC-DGERCGC26-00000027) en el panel → Proveedor SRI.
Sin ellos, la emisión en producción se rechaza con
ProveedorSriNoAprobado. Mientras no estén aprobados, cada respuesta traeaviso_proveedor_sri($r->avisoProveedorSri()).
Primeros pasos
La respuesta (Invoka\Sdk\Respuesta) es el JSON de Invoka, de solo lectura: $r['campo'],
$r->get('a.b.c') con puntos, $r->toArray(), y atajos como claveAcceso(), autorizado(),
requiereCorreccion(), avisoProveedorSri() y limiteRestante().
Emitir comprobantes
| Recurso | Comprobante | Endpoint |
|---|---|---|
$invoka->facturas |
Factura (01) | POST /api/factura/emision |
$invoka->notasCredito |
Nota de crédito (04) | POST /api/credito/emision |
$invoka->notasDebito |
Nota de débito (05) | POST /api/debito/emision |
$invoka->guias |
Guía de remisión (06) | POST /api/guia/emision |
$invoka->retenciones |
Retención 2.0 / ATS (07) — recomendada | POST /api/retencionats/emision |
$invoka->retenciones->emitirV1() |
Retención 1.0 (07) — obsoleta | POST /api/retencion/emision |
$invoka->liquidaciones |
Liquidación de compra (03) | POST /api/liquidacion/emision |
En la factura, emisor.razon_social es obligatoria (venga en el comprobante o en la
opción emisor del cliente): sin ella el SDK lanza Validacion (datos_invalidos) sin llamar a la API.
Todos tienen emitir(array $datos). El cuerpo es el JSON de la
referencia de la API. Antes de enviarlo el SDK completa, sin pisar
lo que usted mande:
ambiente: el del cliente (1).emisor: los datos de la opciónemisordel cliente.emisor.fecha_emision: hoy en Ecuador (aaaa/mm/dd). El SRI solo acepta la fecha del día. Si mandaaaaa-mm-ddo unDateTime, se convierte.codigo_establecimientoycodigo_puntoemisiona 3 dígitos, ysecuenciala 9.
La emisión es asíncrona: Invoka responde enseguida y después genera el XML, lo firma, lo
manda al SRI, arma el PDF y envía el correo al comprador (en segundos). Para saber cómo terminó:
esperar(), consultar() o, mejor en producción, el webhook.
No ponga RUC Proveedor en informacion_adicional: lo añade Invoka.
Retenciones
emitirV1() (retención 1.0) sigue funcionando pero está marcada @deprecated: use la 2.0 en
integraciones nuevas.
Si se corta la red
Invoka identifica cada comprobante por su clave de acceso (RUC + tipo + serie + secuencial +
fecha + ambiente) y no registra dos veces la misma. Por eso el SDK sí reintenta las emisiones
ante un corte, y si el primer intento llegó (el reintento recibe «clave ya existe»), devuelve la
consulta del comprobante con recuperado: true en vez de un error. Si el error de red llega hasta
usted (ErrorRed), consulte la clave que calculó con claveAcceso() antes de reintentar.
Clave de acceso
Consultar, descargar y reprocesar
xml() y pdf() lanzan Conflicto (codigo = no_autorizado) si el comprobante aún no está
autorizado.
Consultas al SRI
20 consultas gratuitas al mes; después, 1 de la billetera de consultas por cada consulta que
devuelve datos (meta dice cuántas quedan). Sin cupo: SaldoInsuficiente con
codigo = sin_consultas. Como pueden cobrarse, no se reintentan solas ante un corte de red.
Créditos
Empresas, firma y logo
Ojo: subirFirma() responde bien aunque la contraseña no abra el .p12 (Invoka le avisa por
correo y los comprobantes fallarán al firmar). Emita una factura en ambiente 1 para comprobarlo.
Webhooks
Invoka avisa a su URL cuando un comprobante queda autorizado (comprobante.autorizado) o
con error (comprobante.error). Reintenta 5 veces (1, 5, 15, 60 y 180 minutos) si su
servidor no responde 2xx.
- El
secretcompleto solo viene en la respuesta deguardar()(POST /api/webhook);ver()lo devuelve enmascarado (••••••••XXXX) y no sirve para verificar. - La URL tiene que ser pública:
localhosty las IP privadas se rechazan con 422 (Validacion). Para probar en local use un túnel (ngrok, cloudflared…).
Cabeceras de cada aviso:
| Cabecera | Contenido |
|---|---|
X-Invoka-Event |
comprobante.autorizado, comprobante.error o webhook.prueba |
X-Invoka-Delivery |
UUID estable entre reintentos del mismo aviso: deduplique por él |
X-Invoka-Timestamp |
Segundos Unix del envío |
X-Invoka-Signature-V2 |
t=<unix>,v1=<hex HMAC-SHA256(t . "." . cuerpo, secret)> — la que se verifica |
X-Invoka-Signature |
sha256=<hex HMAC-SHA256(cuerpo, secret)> — V1, por compatibilidad |
Laravel
PHP puro
- Use el cuerpo crudo: si lo decodifica y lo vuelve a codificar, la firma no coincide.
- Si llega
X-Invoka-Signature-V2, el SDK verifica esa (tiempo constante) y exige que sutesté a menos de 300 s de ahora: pasetoleranciapara cambiarlo (0= no comprobar). Un aviso capturado no se puede reenviar más tarde. - Si no llega la V2, cae a la V1 (
X-Invoka-Signature), que no lleva sello de tiempo; ahítolerancia> 0 compara conenviado_en(los reintentos lo conservan: ≥ 16000 s). ConexigirV2: truese rechazan los avisos que solo traen V1. - Procese cada aviso de forma idempotente, deduplicando por
$aviso['entrega'](X-Invoka-Delivery, estable entre reintentos).$aviso['version']dice qué firma se verificó. - Para probar su receptor:
Webhook::avisoDePrueba([...], $secret)arma cuerpo y cabeceras firmados (V1 y V2);Webhook::firmarV2($cuerpo, $secret, $t)da solo la V2.
Invoka ID
Beta privada. Por ahora la API responde 403
beta_privadasalvo a las cuentas habilitadas.
Verificación de identidad (prueba de vida, cédula, biometría). Cada verificación tiene costo.
Errores
Todas las excepciones heredan de Invoka\Sdk\Excepciones\InvokaException.
| Excepción | Cuándo | getCodigo() |
|---|---|---|
Validacion |
Datos inválidos (HTTP 200 con creado: false, 400 o 422) |
datos_invalidos |
ComprobanteDuplicado (es un Conflicto) |
Ese secuencial ya se usó hoy en la empresa | comprobante_duplicado |
Conflicto |
XML/PDF de algo no autorizado; empresa ya registrada | no_autorizado, empresa_existente |
NoEncontrado |
Comprobante de otra cuenta o inexistente; emisor.ruc que no es suyo; el SRI sin datos |
no_encontrado, empresa_no_encontrada |
SaldoInsuficiente |
Sin créditos (ambiente 2) o sin consultas SRI (402) | saldo_insuficiente, sin_consultas |
ProveedorSriNoAprobado |
Ambiente 2 sin datos de Proveedor SRI aprobados | proveedor_sri_no_aprobado |
CredencialInvalida |
Falta la API key o no existe (401) | credencial_invalida |
LimiteExcedido |
Más de 300 peticiones por minuto, tras agotar los reintentos | demasiadas_peticiones |
ErrorServidor |
5xx o respuesta inesperada | error_servidor, respuesta_invalida |
ErrorRed |
Sin respuesta (DNS, TLS, tiempo agotado) | error_red |
FirmaWebhookInvalida |
Aviso de webhook que no pasó la verificación | firma_invalida, … |
Además: getEstadoHttp(), getRespuesta() (el JSON completo), getCuerpo(),
esReintentable() y getAvisoProveedorSri().
Reintentos
| Situación | ¿Reintenta? |
|---|---|
| 429 (límite de 300/min) | Siempre: el límite se aplica antes de procesar nada. Respeta Retry-After si viene. |
| 502, 503, 504 o corte de red en lecturas | Sí |
| … en emisiones, reproceso, webhook, editar empresa, firma, logo | Sí: no pueden duplicar nada |
| … en consultas SRI, crear empresa, probar webhook, Invoka ID | No: podrían cobrarse o repetirse |
4xx, creado: false |
No (son definitivos) |
Espera exponencial con jitter: espera_base · 2^(intento-1), recortada a espera_maxima.
Opciones del cliente
Para lo que el SDK no envuelva: $invoka->solicitar('GET', 'ruta', $query, $cuerpo).
Referencia rápida
| Método | Endpoint |
|---|---|
ping() |
GET /api/ping (no valida la API key) |
facturas, notasCredito, notasDebito, guias, liquidaciones ->emitir() |
POST /api/{tipo}/emision |
retenciones->emitir() / ->emitirV1() |
POST /api/retencionats/emision / POST /api/retencion/emision |
comprobantes->consultar() |
GET /api/comprobante/consulta/{clave} |
comprobantes->xml() / ->pdf() |
GET /api/comprobante/xml/{clave} / pdf/{clave} |
comprobantes->reprocesar() |
POST /api/comprobante/reprocesar |
comprobantes->consultarYProcesar() |
POST /api/consultaprocesar |
sri->ruc(), cedula(), consultar(), establecimientos(), razonSocial() |
GET /api/sri/… |
creditos->saldo() / ->historial() |
GET /api/creditos/saldo / historial |
webhook->ver() (secret enmascarado), guardar() (secret completo), eliminar(), probar() |
GET/POST/DELETE /api/webhook, POST /api/webhook/probar |
empresa->crear(), editar(), subirFirma(), subirLogo() |
POST /api/empresa/crear, PUT editar, POST subirfirma, POST subirlogo |
invokaId->crear(), listar(), consultar(), verificarDirecto() (beta privada) |
/api/id/… |
publico->estado(), planes(), calcularCreditos() |
GET /api/status, GET /api/public/pricing/tiers, calculate |
Pruebas
El test CoberturaOpenApiTest comprueba que cada operación pública del
OpenAPI tiene su método en el SDK.
Soporte: [email protected]
Licencia
MIT. Ver LICENSE.