SDK PHP — Documentación
Integra facturación electrónica SRI con PHP 8.3+, Guzzle y excepciones tipadas. Publicado en Packagist.
Instalación
Requisitos: PHP 8.3+, Composer, Git.
Desde Packagist (recomendado):
composer require factus-easy/factus-easy-sdk:^0.1
Opción avanzada: última rama dev-main via GitHub VCS
{
"minimum-stability": "dev",
"prefer-stable": true,
"repositories": [
{ "type": "vcs", "url": "https://github.com/dj-Andres/Factus-Easy-SDK" }
],
"config": { "github-protocols": ["https"] },
"require": { "factus-easy/factus-easy-sdk": "dev-main" }
}
La URL base del API es fija: https://factuseasy.kreativesofts.com.
Autenticación
<?php
require __DIR__.'/vendor/autoload.php';
use FactusEasy\FactusEasy;
$sdk = new FactusEasy();
// Registrar nuevo usuario (opcional)
$sdk->auth()->register('Nombre', '[email protected]', 'contraseña');
// Iniciar sesión
$sdk->auth()->login('[email protected]', 'contraseña');
// Cerrar sesión
$sdk->auth()->logout();
Error: 401 → AuthenticationException.
Empresas
<?php
use FactusEasy\Exceptions\ValidationException;
// Listar empresas
$companies = $sdk->company()->list();
// Crear empresa
$created = $sdk->company()->create([
'ruc' => '1234567890001',
'business_name' => 'Mi Empresa',
'email' => '[email protected]',
]);
// Actualizar
$updated = $sdk->company()->update('1234567890001', [
'business_name' => 'Mi Empresa S.A.',
]);
// Subir certificado .p12
$sdk->company()->uploadCertificate('1234567890001', __DIR__.'/firma.p12', 'CONTRASENA_DEL_P12');
// Subir logo
$sdk->company()->uploadLogo('1234567890001', __DIR__.'/logo.png');
Errores: 404 → NotFoundException, 422 → ValidationException.
Documentos
IVA 15%: usar codigo 2 y codigoPorcentaje 4 en los impuestos del detalle.
Emitir factura (tipo 01)
<?php
$invoice = $sdk->document()->register([
'ruc' => '1234567890001',
'tipo' => '01',
'id_externo' => 'fact-' . time(),
'factura' => [
'fecha' => date('d/m/Y'),
'establecimiento' => '001',
'puntoEmision' => '001',
'secuencial' => '000000001',
'descuento' => 0,
'propina' => 0,
'total' => 115.00,
'cliente' => [
'tipoIdentificacion' => '05',
'documento' => '1712345678',
'nombre' => 'Cliente de Prueba',
],
],
'detalles' => [[
'codigoPrincipal' => 'P001',
'descripcion' => 'Producto A',
'cantidad' => 1,
'precioUnitario' => 100.00,
'descuento' => 0,
'precioTotalSinImpuesto' => 100.00,
'impuestos' => [[
'codigo' => '2',
'codigoPorcentaje' => '4',
'tarifa' => 15.00,
'baseImponible' => 100.00,
'valor' => 15.00,
]],
]],
'pagos' => [
['formaPago' => '01', 'total' => 115.00],
],
'notificaciones' => [
'email' => null,
'webhook_url' => null,
],
], $sdk->idempotency());
// Consultar estado y descargar RIDE
$accessKey = $invoice['data']['access_key'] ?? null;
if ($accessKey) {
$status = $sdk->document()->status($accessKey);
$sdk->document()->downloadRideTo($accessKey, '1234567890001', __DIR__.'/rides/factura.pdf');
}
Registro por lotes (registerBatch)
<?php
$batch = $sdk->document()->registerBatch([
// arreglo de documentos (misma estructura que register)
], $sdk->idempotency());
Nota de crédito (tipo 04)
<?php
$creditNote = $sdk->document()->register([
'ruc' => '1234567890001',
'tipo' => '04',
'id_externo' => 'nc-' . time(),
'notaCredito' => [
'fecha' => date('d/m/Y'),
'establecimiento' => '001',
'puntoEmision' => '001',
'secuencial' => '000000001',
'tipoIdentificacion' => '05',
'documento' => '1712345678',
'nombre' => 'Cliente de Prueba',
'total' => 115.00,
],
'detalles' => [[
'codigoPrincipal' => 'P001',
'descripcion' => 'Producto A',
'cantidad' => 1,
'precioUnitario' => 100.00,
'descuento' => 0,
'precioTotalSinImpuesto' => 100.00,
'impuestos' => [[
'codigo' => '2',
'codigoPorcentaje' => '4',
'tarifa' => 15.00,
'baseImponible' => 100.00,
'valor' => 15.00,
]],
]],
'pagos' => [
['formaPago' => '01', 'total' => 115.00],
],
], $sdk->idempotency());
Comprobante de retención (tipo 07)
<?php
$retention = $sdk->document()->register([
'ruc' => '1234567890001',
'tipo' => '07',
'id_externo' => 'ret-' . time(),
'retencion' => [
'fecha' => date('d/m/Y'),
'establecimiento' => '001',
'puntoEmision' => '001',
'secuencial' => '000000001',
'tipoIdentificacion' => '05',
'documento' => '1712345678',
'nombre' => 'Proveedor de Prueba',
'total' => 100.00,
],
'detalles' => [[
'codigoPrincipal' => 'S001',
'descripcion' => 'Servicio Profesional',
'cantidad' => 1,
'precioUnitario' => 100.00,
'descuento' => 0,
'precioTotalSinImpuesto' => 100.00,
'impuestos' => [[
'codigo' => '2',
'codigoPorcentaje' => '4',
'tarifa' => 15.00,
'baseImponible' => 100.00,
'valor' => 15.00,
]],
]],
], $sdk->idempotency());
Errores
Cada código HTTP tiene su propia excepción. Todas extienden de FactusEasyException.
| Excepción | Código | Causa |
|---|---|---|
AuthenticationException | 401 | Token inválido o expirado |
NotFoundException | 404 | Recurso no encontrado |
ConflictException | 409 | Idempotencia duplicada |
ValidationException | 422 | Datos inválidos (getErrors()) |
RateLimitException | 429 | Demasiadas solicitudes |
Ejemplos
El SDK incluye ejemplos listos para ejecutar en la carpeta examples/ del repositorio:
- Auth: login.php, register.php, logout.php
- Empresas: list.php, create.php, update.php, certificate.php, logo.php
- Documentos: register-invoice.php, register-credit-note.php, register-retention.php, batch.php, status.php, ride.php
Recursos adicionales:
FAQ
¿Puedo usar el SDK sin Laravel?
Sí. Es PHP puro con Guzzle. Solo necesitas Composer y PHP 8.3+.
¿Cómo reintento un POST de forma segura?
Usa $sdk->idempotency(). Si obtienes 409 (ConflictException), el servidor ya procesó esa solicitud.
¿Dónde se guarda el RIDE PDF?
Usa downloadRideTo($accessKey, $ruc, $destino). El directorio debe existir y ser escribible.
¿El SDK soporta lotes?
Sí, con registerBatch().
¿Puedo cambiar la URL base del API?
No. La URL base es fija: https://factuseasy.kreativesofts.com.
Solución de problemas
"Could not find a matching version"
Usa composer require factus-easy/factus-easy-sdk:^0.1. Si usas VCS, agrega "minimum-stability": "dev".
"Failed to clone" al usar VCS
Agrega "config": { "github-protocols": ["https"] } y verifica que Git esté instalado.
PHP 8.3 requerido
Verifica con php -v. Si tienes una versión inferior, actualiza PHP.
Error 401 (AuthenticationException)
Credenciales inválidas. Si aún no tienes cuenta, regístrate aquí.
Permisos al descargar RIDE
Asegúrate de que el directorio de destino exista y tenga permisos de escritura.