PHP / Laravel SDK
Disponible — paquete
factulink/factulink-phpen Packagist. Tipos nativos, integración Laravel lista para usar, compatible con PHP 8.1+.
El SDK oficial de FactuLink para PHP plano y Laravel. Cubre todos los endpoints públicos de la API con clases tipadas, auto-paginación y errores estructurados.
Instalación
composer require factulink/factulink-phpRequiere PHP 8.1+ y la extensión ext-json. Compatible con Laravel 9, 10
y 11 (auto-discovery del service provider).
Quickstart (PHP plano)
use FactuLink\FactuLink;
$fc = new FactuLink([
'apiKey' => getenv('FC_API_KEY'), // sk_test_... o sk_live_...
]);
$cfdi = $fc->cfdis->create([
'tipo' => 'I',
'receptor' => [
'rfc' => 'XAXX010101000',
'nombre' => 'Cliente de Prueba',
'regimen_fiscal' => '601',
'domicilio_fiscal' => '06600',
'uso_cfdi' => 'G03',
],
'conceptos' => [[
'clave_prod_serv' => '43211503',
'descripcion' => 'Laptop',
'cantidad' => 1,
'clave_unidad' => 'H87',
'valor_unitario' => 15000,
]],
]);
echo $cfdi->uuid;Quickstart (Laravel)
- Publica la configuración (opcional):
php artisan vendor:publish --tag=factulink-config- Define en
.env:
FACTULINK_API_KEY=sk_test_...
FACTULINK_BASE_URL=https://api.factulink.com.mx- Usa por inyección o Facade:
use FactuLink\FactuLink;
use FactuLink\Laravel\Facades\FactuLink as FactuLinkFacade;
// Inyección
public function emitir(FactuLink $fc) {
return $fc->cfdis->create([...]);
}
// Facade
$cfdi = FactuLinkFacade::cfdis()->create([...]);Configuración
$fc = new FactuLink([
'apiKey' => 'sk_live_...', // Requerido
'baseUrl' => 'https://api.factulink.com.mx', // Default
'timeout' => 30, // Default 30s
'retries' => 2, // Default 2 reintentos en 429/5xx
]);Recursos disponibles
| Recurso | Métodos |
|---|---|
$fc->cfdis | create, list, get, cancel, downloadXml, downloadPdf, satStatus, validate, listAutoPaginate |
$fc->clients | create, list, get, update, delete |
$fc->certificates | upload, list, get, update, delete |
$fc->catalogs | products, units, taxRegimes, cfdiUsages, paymentForms, paymentMethods, currencies, countries |
$fc->webhooks | create, list, update, delete, deliveries, test |
$fc->ai | createFromText, confirmInvoice, copilot |
$fc->apiKeys | create, list, revoke |
Operaciones comunes
Descargar PDF / XML
$pdf = $fc->cfdis->downloadPdf($cfdi->uuid);
file_put_contents('factura.pdf', $pdf);
$xml = $fc->cfdis->downloadXml($cfdi->uuid);
file_put_contents('factura.xml', $xml);Cancelar CFDI
$resultado = $fc->cfdis->cancel($cfdi->uuid, [
'motivo' => '02',
]);Auto-paginación
foreach ($fc->cfdis->listAutoPaginate(['estado' => 'timbrado']) as $cfdi) {
echo $cfdi->uuid . PHP_EOL;
}Webhooks
$webhook = $fc->webhooks->create([
'url' => 'https://tu-servidor.com/fc-webhook',
'events' => ['cfdi.timbrado', 'cfdi.cancelado'],
]);
echo "Guarda este secret: {$webhook->secret}";
$fc->webhooks->test($webhook->id);Manejo de errores
use FactuLink\Errors\ApiError;
use FactuLink\Errors\AuthError;
use FactuLink\Errors\RateLimitError;
try {
$fc->cfdis->create($params);
} catch (RateLimitError $e) {
echo "Rate limited — reintenta en {$e->retryAfter}s";
} catch (AuthError $e) {
echo "API key inválida o expirada";
} catch (ApiError $e) {
echo "{$e->code}: {$e->getMessage()}";
print_r($e->details);
}Jerarquía: RateLimitError y AuthError heredan de ApiError, que hereda de
FactuLinkError. El cliente reintenta automáticamente en 429 y 5xx
(configurable con retries).
Ambientes
- Sandbox: API Keys con prefijo
sk_test_.... Timbrado simulado, no se envía al SAT y no consume folios reales. - Producción: API Keys con prefijo
sk_live_.... Timbrado con el PAC autorizado y registro ante el SAT.
El mismo baseUrl (https://api.factulink.com.mx) atiende ambos ambientes —
el prefijo de la API Key determina cuál usar.
Código fuente
- GitHub: github.com/IYair/fc-sdk-php
- Packagist: factulink/factulink-php
Reportes de bugs y feature requests bienvenidos en el repo.