Guía de Uso del Servicio AlanubeService (Panamá)
Descripción General
El AlanubeService es el servicio principal para la emisión de documentos electrónicos a través del proveedor PAC Alanube Panamá. Este servicio incluye detección automática de tipos de documento y manejo específico para cada tipo de factura según las normativas fiscales panameñas de la DGI.
Características Principales
- ✅ Detección automática de tipo de documento
- ✅ 6 tipos de factura soportados
- ✅ Validaciones DGI completas
- ✅ Procesamiento asíncrono opcional
- ✅ Transformación automática de datos
- ✅ Helper para módulos externos
Uso Básico del Servicio
1. Importación y Configuración
use App\Services\AlanubeService;
use App\Models\Organization;
// Crear instancia del servicio
$service = new AlanubeService();
// Obtener organización
$organization = Organization::find($organizationId);
2. Método Principal con Detección Automática
// El servicio detecta automáticamente el tipo y emite la factura correspondiente
$result = $service->emitInvoice($organization, $invoiceData);
if ($result['success']) {
echo "Factura emitida: " . $result['data']['id'];
echo "Tipo: " . $result['document_type'];
echo "Código: " . $result['type_code'];
} else {
echo "Error: " . $result['message'];
}
Detección Automática de Tipos
🌍 Factura de Exportación (03)
Indicadores de Detección: - Datos de exportación presentes - Receptor extranjero - País destino diferente a 'PA' - Destino = '2' (Extranjero)
$exportData = [
'information' => [
'destination' => '2', // Extranjero
'nature' => '02' // Exportación
],
'receiver' => [
'type' => '04', // Extranjero
'country' => 'US', // Estados Unidos
'foreign' => [
'number' => 'US123456789', // ID extranjero
'country' => 'Estados Unidos'
]
],
'exportation' => [
'incoterm' => 'FOB',
'currency' => 'USD',
'exchangeRate' => 1.0,
'amount' => 1000.00,
'port' => 'Puerto de Balboa'
],
'items' => [
[
'description' => 'Producto de Exportación',
'quantity' => 10,
'prices' => ['transfer' => 100.00],
'itbms' => ['rate' => '00'] // 0% para exportación
]
]
];
$result = $service->emitInvoice($organization, $exportData);
🏭 Factura de Importación (02)
Indicadores de Detección: - Naturaleza de operación = '21' (NATURE_IMPORT) - Documentación de importación
$importData = [
'information' => [
'nature' => '21', // Importación
'operationType' => 2 // Entrada o compra
],
'receiver' => [
'type' => '01', // Contribuyente
'ruc' => [
'type' => 2, // Jurídico
'ruc' => '123456789-1-123456'
],
'name' => 'Empresa Importadora S.A.'
],
'items' => [
[
'description' => 'Producto Importado',
'quantity' => 5,
'prices' => ['transfer' => 200.00],
'itbms' => ['rate' => '01'] // 7%
]
]
];
$result = $service->emitInvoice($organization, $importData);
🏢 Factura de Operación Interna (01)
Indicadores de Detección: - Tipo por defecto para ventas locales - No cumple criterios de otros tipos
$internalData = [
'information' => [
'nature' => '01', // Venta
'operationType' => 1, // Salida o venta
'destination' => '1' // Panamá
],
'receiver' => [
'type' => '01', // Contribuyente
'country' => 'PA',
'ruc' => [
'type' => 1, // Natural
'ruc' => '8-123-456'
],
'name' => 'Juan Pérez'
],
'items' => [
[
'description' => 'Producto Local',
'quantity' => 2,
'prices' => ['transfer' => 150.00],
'itbms' => ['rate' => '01'] // 7%
]
]
];
$result = $service->emitInvoice($organization, $internalData);
🏭 Factura de Zona Franca (08)
Indicadores de Detección: - Información de zona franca presente - Operación en zona franca
$freeZoneData = [
'information' => [
'freeZone' => true,
'nature' => '01' // Venta
],
'receiver' => [
'type' => '01',
'name' => 'Empresa Zona Franca S.A.'
],
'items' => [
[
'description' => 'Producto Zona Franca',
'quantity' => 3,
'prices' => ['transfer' => 120.00],
'itbms' => ['rate' => '00'] // 0% zona franca
]
]
];
$result = $service->emitInvoice($organization, $freeZoneData);
Métodos Específicos por Tipo
Llamada Directa por Tipo
// Factura de Exportación
$result = $service->emitExportInvoice($organization, $exportData);
// Factura de Importación
$result = $service->emitImportInvoice($organization, $importData);
// Factura de Zona Franca
$result = $service->emitFreeZoneInvoice($organization, $freeZoneData);
Usando Helper para Módulos Externos
use App\Utils\AlanubeEmissionHelper;
// Emisión automática con detección de tipo
$result = AlanubeEmissionHelper::emitDocument($organization, $saleData);
// Emisión asíncrona
$result = AlanubeEmissionHelper::emitDocument($organization, $saleData, $userId, null, true);
// Emisión de tipo específico
$result = AlanubeEmissionHelper::emitExportInvoice($organization, $saleData);
Transformación desde Formato DocuCenter
// Transformar datos de DocuCenter a formato Alanube
$docuCenterData = [
'customer' => [
'name' => 'Cliente Ejemplo',
'tax_id' => '123456789-1-123456',
'email' => 'cliente@ejemplo.com',
'phone' => '+507-123-4567'
],
'items' => [
[
'product_name' => 'Producto Ejemplo',
'quantity' => 2,
'price' => 100.00,
'tax_rate' => 7
]
],
'payments' => [
[
'payment_method' => 'cash',
'pay_amount' => 214.00
]
],
'total' => 214.00
];
$alanubeData = AlanubeEmissionHelper::transformDocuCenterToAlanube($docuCenterData);
$result = $service->emitInvoice($organization, $alanubeData);
Estructura de Datos de Entrada
Información General (information)
'information' => [
'issueType' => '01', // Tipo de emisión (01-04)
'numeration' => '0000000001', // Número de 10 dígitos
'billingPoint' => '001', // Punto de facturación (3 dígitos)
'securityCode' => '123456789', // Código de seguridad (9 dígitos)
'cafe' => [
'format' => 1, // Formato CAFE
'delivery' => 1, // Entrega CAFE
'information' => 'Info adicional' // Opcional
],
'nature' => '01', // Naturaleza operación
'operationType' => 1, // Tipo operación (1-2)
'destination' => '1', // Destino (1=Panamá, 2=Extranjero)
'receiverContainer' => 1, // Envío contenedor
'issueDate' => '2025-01-22T10:30:00Z' // Fecha emisión ISO
]
Receptor (receiver)
'receiver' => [
'type' => '01', // Tipo receptor (01-04)
'name' => 'Nombre del Receptor',
'address' => 'Dirección completa',
'telephones' => ['+507-123-4567'],
'emails' => ['correo@receptor.com'],
'country' => 'PA', // Código país (PA para Panamá)
// Para contribuyentes panameños
'ruc' => [
'type' => 1, // 1=Natural, 2=Jurídico
'ruc' => '8-123-456' // RUC panameño
],
// Para ubicación
'location' => [
'code' => '08010001' // Código de 8 dígitos
],
// Para extranjeros
'foreign' => [
'number' => 'US123456789', // ID extranjero
'country' => 'Estados Unidos' // Nombre del país
]
]
Ítems (items)
'items' => [
[
'description' => 'Descripción del producto/servicio',
'code' => 'PROD001', // Código interno opcional
'unit' => 'UND', // Unidad de medida
'quantity' => 2, // Cantidad
'prices' => [
'transfer' => 100.00, // Precio unitario
'discount' => 5.00, // Descuento opcional
'transport' => 0.00, // Transporte opcional
'insurance' => 0.00 // Seguro opcional
],
'itbms' => [
'rate' => '01' // Tasa ITBMS (00,01,02,03)
],
// Campos opcionales
'cpbs' => [ // Codificación Panameña
'code' => 12345,
'unit' => 'Unidad CPBS'
],
'gtin' => [ // Códigos GTIN
'commercializationCode' => 1234567890123,
'commercializationQuantity' => 2,
'inventoryCode' => 1234567890124,
'inventoryQuantity' => 2
]
]
]
Totales (totals)
'totals' => [
'change' => 0.00, // Vuelto
'transport' => 0.00, // Transporte total
'insurance' => 0.00, // Seguro total
'otherExpenses' => 0.00, // Otros gastos
'paymentTime' => 1, // Tiempo pago (1=Contado, 2=Crédito)
// Descuentos adicionales opcionales
'discounts' => [
[
'description' => 'Descuento especial',
'amount' => 10.00
]
]
]
Métodos de Pago (paymentMethods)
'paymentMethods' => [
[
'type' => '02', // Tipo pago (01-99)
'amount' => 214.00, // Monto
'otherType' => 'Descripción' // Si type='99'
]
]
Configuración de Endpoints
Mapeo Interno de Endpoints
protected $endpoints = [
'01' => 'invoices', // Operación interna
'02' => 'invoices', // Importación
'03' => 'invoices', // Exportación
'08' => 'invoices', // Zona Franca
'09' => 'invoices', // Reembolso
'10' => 'invoices', // Operación extranjera
];
URLs Completas
// Base URL: https://api.alanube.co/pan/v1/
// Ejemplo: https://api.alanube.co/pan/v1/invoices
Estructura de Respuesta
Respuesta Exitosa
[
'success' => true,
'message' => 'Factura emitida exitosamente',
'data' => [
'id' => 'ALN-PAN-123456',
'status' => 'approved',
'pdf_url' => 'https://api.alanube.co/documents/123456.pdf',
// ... otros campos de respuesta de Alanube
],
'document_type' => 'Factura de Exportación',
'type_code' => '03',
'url_used' => 'https://api.alanube.co/pan/v1/invoices'
]
Respuesta de Error
[
'success' => false,
'message' => 'Error al emitir factura electrónica',
'error' => 'Detalles específicos del error',
'error_details' => [
// Detalles completos del error de la API
],
'status_code' => 400,
'document_type' => 'Factura de Operación Interna',
'type_code' => '01'
]
Manejo de Errores
Errores Comunes
try {
$result = $service->emitInvoice($organization, $invoiceData);
} catch (\Exception $e) {
switch ($e->getMessage()) {
case 'No se encontró configuración PAC para la organización':
// Configurar conexión PAC para la organización
break;
case 'La configuración PAC no es para Alanube Panamá':
// Verificar pac_type = 'alanube_panama'
break;
case 'Token PAC no configurado':
// Configurar token en pacconnection
break;
default:
// Error de red o PAC
Log::error('Error AlanubeService: ' . $e->getMessage());
}
}
Logging Automático
El servicio incluye logging automático:
// Logs de información
Log::info('[AlanubeService] Tipo de documento detectado: export');
Log::info('[AlanubeService] Factura emitida exitosamente', ['data' => $data]);
// Logs de error
Log::error('[AlanubeService] Error emitiendo factura: ' . $error);
Log::warning('[AlanubeService] Error en respuesta', ['result' => $result]);
Ejemplos de Implementación
Controlador Laravel
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\AlanubeService;
use App\Models\Organization;
class InvoiceController extends Controller
{
protected $alanubeService;
public function __construct(AlanubeService $alanubeService)
{
$this->alanubeService = $alanubeService;
}
/**
* Emitir factura con detección automática
*/
public function emit(Request $request)
{
try {
$organization = Organization::find($request->organization_id);
if (!$organization) {
return response()->json([
'success' => false,
'message' => 'Organización no encontrada'
], 404);
}
// El servicio detecta automáticamente el tipo
$result = $this->alanubeService->emitInvoice(
$organization,
$request->all()
);
return response()->json($result);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Error interno del servidor',
'error' => $e->getMessage()
], 500);
}
}
/**
* Emitir factura de exportación específica
*/
public function emitExport(Request $request)
{
try {
$organization = Organization::find($request->organization_id);
// Llamada directa para factura de exportación
$result = $this->alanubeService->emitExportInvoice(
$organization,
$request->all()
);
return response()->json($result);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Error emitiendo factura de exportación',
'error' => $e->getMessage()
], 500);
}
}
}
Job Asíncrono
<?php
namespace App\Jobs;
use App\Services\AlanubeService;
use App\Models\Organization;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessInvoiceJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $organizationId;
protected $invoiceData;
public function __construct($organizationId, $invoiceData)
{
$this->organizationId = $organizationId;
$this->invoiceData = $invoiceData;
}
public function handle()
{
$organization = Organization::find($this->organizationId);
$alanubeService = new AlanubeService();
$result = $alanubeService->emitInvoice($organization, $this->invoiceData);
if ($result['success']) {
// Procesar resultado exitoso
// Enviar notificaciones, actualizar BD, etc.
} else {
// Manejar error
// Logging, notificaciones de error, etc.
}
}
}
Mejores Prácticas
1. Detección Automática vs Manual
// Recomendado: Usar detección automática
$result = $service->emitInvoice($organization, $invoiceData);
// Solo usar métodos específicos cuando sea necesario forzar el tipo
$result = $service->emitExportInvoice($organization, $exportData);
2. Manejo de Respuestas
$result = $service->emitInvoice($organization, $invoiceData);
if ($result['success']) {
// Procesar éxito
$documentId = $result['data']['id'];
$documentType = $result['document_type'];
// Guardar en BD, enviar notificaciones, etc.
} else {
// Manejar error
$errorMessage = $result['message'];
$errorDetails = $result['error_details'] ?? [];
// Logging, notificaciones de error, retry si aplica
}
3. Logging y Monitoreo
// Logging antes de emisión
Log::info('Iniciando emisión Alanube Panamá', [
'organization_id' => $organization->id,
'data_summary' => $this->getSummary($invoiceData)
]);
// Logging después de emisión
Log::info('Resultado emisión Alanube Panamá', [
'organization_id' => $organization->id,
'success' => $result['success'],
'document_type' => $result['document_type'] ?? 'N/A'
]);
4. Validación de Configuración PAC
// Verificar configuración antes de emitir
$pacConnection = $organization->pacConnection;
if (!$pacConnection || $pacConnection->pac_type !== 'alanube_panama') {
throw new \Exception('Configuración PAC Alanube Panamá requerida');
}
if (empty($pacConnection->token)) {
throw new \Exception('Token PAC no configurado');
}
5. Procesamiento Asíncrono para Volumen
// Para múltiples facturas o facturas complejas
use App\Jobs\CreateInvoiceAlanubeJob;
CreateInvoiceAlanubeJob::dispatch($invoiceData, $organizationId, $userId)
->onQueue('pac_integrations')
->delay(now()->addSeconds(5));
Constantes Disponibles
Tipos de Documento
AlanubeService::INTERNAL_OPERATION = '01';
AlanubeService::IMPORT = '02';
AlanubeService::EXPORT = '03';
AlanubeService::FREE_ZONE = '08';
AlanubeService::REIMBURSEMENT = '09';
AlanubeService::FOREIGN_OPERATION = '10';
Tipos de Emisión
AlanubeService::ISSUE_TYPE_PRIOR_AUTH_NORMAL = '01';
AlanubeService::ISSUE_TYPE_PRIOR_AUTH_CONTINGENCY = '02';
AlanubeService::ISSUE_TYPE_POSTERIOR_AUTH_NORMAL = '03';
AlanubeService::ISSUE_TYPE_POSTERIOR_AUTH_CONTINGENCY = '04';
Naturaleza de Operación
AlanubeService::NATURE_SALE = '01';
AlanubeService::NATURE_EXPORT = '02';
AlanubeService::NATURE_IMPORT = '21';
// ... y más
Tipos de Receptor
AlanubeService::RECEIVER_CONTRIBUTOR = '01';
AlanubeService::RECEIVER_FINAL_CONSUMER = '02';
AlanubeService::RECEIVER_GOVERNMENT = '03';
AlanubeService::RECEIVER_FOREIGN = '04';
Tasas ITBMS
AlanubeService::ITBMS_0_PERCENT = '00';
AlanubeService::ITBMS_7_PERCENT = '01';
AlanubeService::ITBMS_10_PERCENT = '02';
AlanubeService::ITBMS_15_PERCENT = '03';
Métodos de Pago
AlanubeService::PAYMENT_CASH = '02';
AlanubeService::PAYMENT_CREDIT_CARD = '03';
AlanubeService::PAYMENT_BANK_TRANSFER = '08';
// ... y más
Testing y Debugging
Comando de Testing
# Test básico
php artisan test:alanube 1 --test-data
# Test tipo específico
php artisan test:alanube 1 --test-data --type=03
# Test asíncrono
php artisan test:alanube 1 --test-data --async
Script de Testing Completo
# Suite completa
./scripts/test-alanube-panama.sh complete 1
# Modo interactivo
./scripts/test-alanube-panama.sh interactive
Esta guía proporciona toda la información necesaria para implementar y usar el servicio AlanubeService para emisión de facturas electrónicas en Panamá a través de DocuCenter.