apachiy / laravel
Cliente oficial de Apachiy para Laravel: consultas SUNAT (DNI/RUC), validación de comprobantes, tipo de cambio y envío de WhatsApp.
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.2
- illuminate/http: ^9.0|^10.0|^11.0|^12.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0
Requires (Dev)
- phpunit/phpunit: ^9.5|^10.0|^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Apachiy para Laravel
Cliente oficial de Apachiy para Perú: consultas SUNAT (DNI/RUC), validación de comprobantes electrónicos, tipo de cambio y envío de WhatsApp — sin armar URLs ni manejar JSON a mano.
Instalación
composer require apachiy/laravel
Laravel detecta el ServiceProvider y la fachada Apachiy automáticamente (auto-discovery). Publica la
configuración si quieres personalizarla:
php artisan vendor:publish --tag=apachiy-config
Agrega tu token en .env. Usa un token myt_test_… (modo de pruebas, datos simulados, no consume tu cupo)
mientras desarrollas, y cámbialo por uno myt_live_… en producción. Ambos se generan desde tu panel en
apachiy.mytems.cloud:
APACHIY_TOKEN=myt_test_1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Uso rápido
use Apachiy\Laravel\Facades\Apachiy; $persona = Apachiy::dni('12345678'); echo $persona->nombreCompleto; // PRUEBA SANDBOX JUAN $empresa = Apachiy::ruc('20123456789'); echo $empresa->razonSocial; // EMPRESA DE PRUEBA SANDBOX S.A.C. echo $empresa->activo(); // true Apachiy::whatsapp(1)->sendText('51999888777', 'Tu comprobante F001-234 ha sido emitido.');
También puedes inyectar Apachiy\Laravel\ApachiyClient o resolverlo con app('apachiy') si prefieres no usar
la fachada.
Consultas SUNAT
$dni = Apachiy::dni('12345678'); // $dni->tipoDocumento, ->documento, ->nombres, ->apellidoPaterno, ->apellidoMaterno, // ->nombreCompleto, ->direccion, ->ubigeo (Ubigeo|null), ->telefono $ruc = Apachiy::ruc('20123456789'); // $ruc->razonSocial, ->direccion, ->ubigeo, ->estadoContribuyente, ->condicionDomicilio, // ->correo, ->telefonos, ->tributos $ruc->activo(); // estado_contribuyente === 'ACTIVO' $ruc->habido(); // condicion_domicilio === 'HABIDO'
Por lotes (hasta 25 documentos por llamada)
Solo se descuenta cupo por cada documento único que SUNAT encuentra; los repetidos, inválidos o no encontrados dentro del mismo lote no consumen cuota.
$lote = Apachiy::batchDni(['12345678', '87654321', '00000000']); $lote->total; // 3 $lote->consultados; // documentos que descontaron cupo foreach ($lote->exitosos() as $item) { echo $item->data->nombreCompleto; } foreach ($lote->fallidos() as $item) { echo "{$item->documento}: {$item->errorCode}"; }
Validar un comprobante de pago (CPE)
$resultado = Apachiy::cpe( numRuc: '20123456789', codComp: '01', // 01 factura, 03 boleta, 07/08 notas de crédito/débito... numeroSerie: 'F001', numero: 234, fechaEmision: '12/11/2026', monto: 350.00, ); if ($resultado->aceptado()) { // $resultado->estadoComprobante === 'ACEPTADO' }
Tipo de cambio
$tc = Apachiy::tipoCambio(); // hoy $tc = Apachiy::tipoCambio('2026-11-01'); // fecha específica echo "{$tc->compra} / {$tc->venta}";
Enviar WhatsApp
use Apachiy\Laravel\Facades\Apachiy; $whatsapp = Apachiy::whatsapp($instanciaId); // el ID numérico de tu instancia conectada $whatsapp->sendText('51999888777', 'Tu pedido fue confirmado.'); // Acepta ruta de archivo, binario o base64 — el SDK lo codifica por ti $whatsapp->sendMedia('51999888777', 'document', storage_path('comprobantes/F001-234.pdf'), 'comprobante.pdf'); $whatsapp->sendMedia('51999888777', 'image', $rutaOContenido, caption: 'Así quedó tu pedido'); $whatsapp->sendAudio('51999888777', $notaDeVoz);
Manejo de errores
Cada error de la API lanza una excepción específica, todas heredan de ApachiyException:
| Excepción | Código(s) | Cuándo ocurre |
|---|---|---|
AuthenticationException |
unauthorized |
Token ausente, inválido, revocado o vencido |
ForbiddenException |
forbidden |
El token no tiene el permiso del endpoint |
ValidationException |
invalid_request, invalid_document |
Datos de entrada inválidos — usa fields() |
NotFoundException |
not_found |
El documento no existe |
MonthlyLimitReachedException |
monthly_limit_reached |
Se agotó el cupo mensual del plan |
RateLimitedException |
rate_limited |
Demasiadas solicitudes por minuto — usa retryAfter() |
WhatsAppInstanceException |
instance_not_found, instance_disconnected, instance_unavailable |
Problema con la instancia de WhatsApp |
ServiceUnavailableException |
sunat_unavailable, provider_error, etc. |
Falla temporal de Apachiy o de la fuente oficial |
use Apachiy\Laravel\Exceptions\NotFoundException; use Apachiy\Laravel\Exceptions\RateLimitedException; use Apachiy\Laravel\Exceptions\ApachiyException; try { $persona = Apachiy::dni($dni); } catch (NotFoundException $e) { // documento no encontrado } catch (RateLimitedException $e) { sleep($e->retryAfter() ?? 5); } catch (ApachiyException $e) { report($e); Log::warning($e->getMessage(), [ 'code' => $e->errorCode(), 'request_id' => $e->requestId(), // compártelo con soporte 'retryable' => $e->isRetryable(), ]); }
Modo de pruebas (sandbox) y escenarios simulados
Con un token myt_test_…, cada llamada responde con datos simulados y nunca consume tu cupo. Puedes forzar
un escenario de error específico para probar tu manejo de fallos sin esperar a que ocurra en producción:
Apachiy::withScenario('not_found')->dni('12345678'); // NotFoundException Apachiy::withScenario('rate_limited')->ruc('20123456789'); // RateLimitedException Apachiy::withScenario('monthly_limit_reached')->dni('...'); Apachiy::withScenario('provider_unavailable')->dni('...'); Apachiy::withScenario('server_error')->dni('...');
withScenario() no tiene efecto con un token myt_live_…: la API lo ignora en producción.
Testear tu aplicación
Usa Http::fake() de Laravel; el cliente usa Illuminate\Http\Client\Factory internamente:
use Illuminate\Support\Facades\Http; Http::fake([ 'apachiy.mytems.cloud/api/v1/consulta/dni/*' => Http::response([ 'success' => true, 'data' => ['tipo_documento' => 'DNI', 'documento' => '12345678', 'nombres' => 'JUAN', 'nombre_o_razon_social' => 'JUAN PEREZ'], ], 200), ]);
Requisitos
- PHP 8.1+
- Laravel 9, 10, 11 o 12
Contribuir
Los pull requests son bienvenidos. Corre la suite antes de enviar uno:
composer install vendor/bin/phpunit
Licencia
MIT. Ver LICENSE.