Guía de Notas de Crédito - Alanube Panamá
Descripción General
Las notas de crédito electrónicas en Panamá son documentos fiscales que permiten anular o corregir facturas previamente emitidas. El servicio AlanubeService incluye soporte completo para la emisión de notas de crédito según las normativas de la DGI de Panamá.
🎯 Características Principales
- ✅ Documentos referenciados obligatorios
- ✅ 4 tipos de referencia (ID, CUFE, PAPER, PRINTER)
- ✅ Validaciones DGI específicas para notas de crédito
- ✅ Procesamiento síncrono y asíncrono
- ✅ Endpoint dedicado
/pan/v1/credit-notes
📋 Diferencias con Facturas
| Aspecto | Facturas | Notas de Crédito |
|---|---|---|
| Endpoint | /pan/v1/invoices |
/pan/v1/credit-notes |
| Documentos Referenciados | Opcional | Obligatorio |
| Naturaleza por Defecto | 01 (Venta) |
11 (Devolución) |
| Tipo de Documento | 01-03, 08-10 |
04 |
| Validaciones Adicionales | - | Validación de referencias |
🔧 Uso Básico
1. Método Principal del Servicio
use App\Services\AlanubeService;
use App\Models\Organization;
$service = new AlanubeService();
$organization = Organization::find($organizationId);
$creditNoteData = [
'information' => [
'issueType' => '01',
'numeration' => '0000000001',
'billingPoint' => '001',
'nature' => '11', // Devolución
'operationType' => 1,
'destination' => '1',
'issueDate' => now()->toISOString()
],
'receiver' => [
'type' => '01',
'name' => 'Cliente para Nota de Crédito',
'ruc' => [
'type' => 1,
'ruc' => '8-123-456'
],
'country' => 'PA'
],
'items' => [
[
'description' => 'Devolución - Producto',
'quantity' => 1,
'prices' => ['transfer' => 100.00],
'itbms' => ['rate' => '01']
]
],
'totals' => [
'paymentTime' => 1,
'change' => 0
],
'paymentMethods' => [
[
'type' => '02', // Efectivo
'amount' => 107.00
]
],
'referencedDocuments' => [ // OBLIGATORIO
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'ID',
'apiIdentification' => 'ALANUBE_ID_123456789012345678'
]
]
];
$result = $service->emitCreditNote($organization, $creditNoteData);
if ($result['success']) {
echo "Nota de crédito emitida: " . $result['data']['id'];
} else {
echo "Error: " . $result['message'];
}
2. Usando el Helper para Módulos Externos
use App\Utils\AlanubeEmissionHelper;
// Emisión síncrona
$result = AlanubeEmissionHelper::emitCreditNote($organization, $creditNoteData, $userId, false);
// Emisión asíncrona
$result = AlanubeEmissionHelper::emitCreditNote($organization, $creditNoteData, $userId, true);
// Transformar desde formato DocuCenter
$referencedDocs = [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'PAPER',
'otherIdentification' => '001-001-0000000123'
]
];
$creditNoteData = AlanubeEmissionHelper::transformDocuCenterToCreditNote($docuCenterData, $referencedDocs);
$result = AlanubeEmissionHelper::emitCreditNote($organization, $creditNoteData);
📄 Documentos Referenciados
Las notas de crédito DEBEN incluir al menos un documento referenciado. Hay 4 tipos de referencia:
1. Referencia por ID de Alanube (ID)
'referencedDocuments' => [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'ID',
'apiIdentification' => 'ALANUBE_INVOICE_ID_26_CHARS' // ID de 26 caracteres
]
]
2. Referencia por CUFE (CUFE)
'referencedDocuments' => [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'CUFE',
'cufeIdentification' => 'CUFE_66_CARACTERES_DE_LA_FACTURA_ELECTRONICA_ORIGINAL' // 66 caracteres
]
]
3. Referencia a Factura en Papel (PAPER)
'referencedDocuments' => [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'PAPER',
'otherIdentification' => '001-001-0000000123' // Número de factura en papel (22 caracteres)
]
]
4. Referencia a Impresora Fiscal (PRINTER)
'referencedDocuments' => [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'PRINTER',
'otherIdentification' => '001-001-0000000123' // Número de impresora fiscal (22 caracteres)
]
]
🔍 Validaciones Automáticas
El sistema valida automáticamente:
1. Validaciones de Documentos Referenciados
// El helper incluye validación automática
$validation = AlanubeEmissionHelper::validateCreditNoteData($creditNoteData);
if (!$validation['valid']) {
foreach ($validation['errors'] as $error) {
echo "Error: $error\n";
}
}
2. Validaciones por Tipo de Emisión
- ID: Requiere
apiIdentificationde 26 caracteres - CUFE: Requiere
cufeIdentificationde 66 caracteres - PAPER/PRINTER: Requiere
otherIdentificationde 22 caracteres
3. Validaciones Generales
- Receptor con nombre obligatorio
- Al menos un ítem requerido
- Documentos referenciados obligatorios
- Configuración PAC válida
🚀 Procesamiento Asíncrono
Job Específico para Notas de Crédito
use App\Jobs\CreateInvoiceAlanubeJob;
// Crear job para nota de crédito
CreateInvoiceAlanubeJob::dispatch(
$creditNoteData,
$organizationId,
$userId,
'credit_note' // Tipo específico
)->onQueue('pac_integrations');
Estados del Job
- INIT - Inicializando
- VALIDATING - Validando documentos referenciados
- PROCESSING - Enviando a Alanube
- FINALIZING - Procesando respuesta
- COMPLETED - Completado exitosamente
🧪 Testing Completo
1. Comando Artisan
# Probar nota de crédito síncrona
php artisan test:alanube 1 --credit-note
# Probar nota de crédito asíncrona
php artisan test:alanube 1 --credit-note --async
2. Script Shell Interactivo
# Ejecutar pruebas específicas de notas de crédito
./scripts/test-alanube-panama.sh credit-note 1
# Modo interactivo (opción 8)
./scripts/test-alanube-panama.sh interactive
3. Suite Completa
# Incluye pruebas de notas de crédito
./scripts/test-alanube-panama.sh complete 1
📊 Ejemplos de Datos Completos
Nota de Crédito Básica
$basicCreditNote = [
'information' => [
'issueType' => '01',
'numeration' => '0000000001',
'billingPoint' => '001',
'securityCode' => '123456789',
'cafe' => [
'format' => 1,
'delivery' => 1
],
'nature' => '11', // Devolución
'operationType' => 1,
'destination' => '1',
'receiverContainer' => 1,
'issueDate' => '2025-01-22T10:30:00Z'
],
'receiver' => [
'type' => '01', // Contribuyente
'name' => 'Empresa Cliente S.A.',
'address' => 'Avenida Balboa, Ciudad de Panamá',
'telephones' => ['+507-123-4567'],
'emails' => ['cliente@empresa.com'],
'country' => 'PA',
'ruc' => [
'type' => 2, // Jurídico
'ruc' => '123456789-1-123456'
],
'location' => [
'code' => '08010001' // Provincia, distrito, corregimiento
]
],
'items' => [
[
'number' => '0001',
'description' => 'Devolución - Producto de Software',
'code' => 'SOFT001',
'unit' => 'UND',
'quantity' => 2,
'prices' => [
'transfer' => 150.00,
'discount' => 0,
'transport' => 0,
'insurance' => 0
],
'itbms' => [
'rate' => '01' // 7%
]
]
],
'totals' => [
'change' => 0,
'transport' => 0,
'insurance' => 0,
'otherExpenses' => 0,
'paymentTime' => 1 // Contado
],
'paymentMethods' => [
[
'type' => '02', // Efectivo
'amount' => 321.00 // 300 + 21 ITBMS
]
],
'referencedDocuments' => [
[
'issueDate' => '2025-01-21T15:20:00Z',
'emissionType' => 'ID',
'apiIdentification' => 'ALANUBE_ID_123456789012345678'
]
]
];
Nota de Crédito con Múltiples Referencias
$multipleRefCreditNote = [
// ... información y receptor igual ...
'referencedDocuments' => [
[
'issueDate' => '2025-01-20T10:00:00Z',
'emissionType' => 'ID',
'apiIdentification' => 'ALANUBE_ID_123456789012345678'
],
[
'issueDate' => '2025-01-19T14:30:00Z',
'emissionType' => 'PAPER',
'otherIdentification' => '001-001-0000000999'
],
[
'issueDate' => '2025-01-18T09:15:00Z',
'emissionType' => 'CUFE',
'cufeIdentification' => 'CUFE123456789012345678901234567890123456789012345678901234567890123456'
]
]
];
Nota de Crédito de Exportación
$exportCreditNote = [
'information' => [
// ... campos básicos ...
'nature' => '11', // Devolución
'destination' => '2' // Extranjero
],
'receiver' => [
'type' => '04', // Extranjero
'name' => 'International Company LLC',
'country' => 'US',
'foreign' => [
'number' => 'US123456789',
'country' => 'Estados Unidos'
]
],
'exportation' => [
'incoterm' => 'FOB',
'currency' => 'USD',
'exchangeRate' => 1.0,
'amount' => 500.00,
'port' => 'Puerto de Balboa'
],
'items' => [
[
'description' => 'Devolución - Producto de Exportación',
'quantity' => 5,
'prices' => ['transfer' => 100.00],
'itbms' => ['rate' => '00'] // 0% para exportación
]
],
'referencedDocuments' => [
[
'issueDate' => '2025-01-15T12:00:00Z',
'emissionType' => 'CUFE',
'cufeIdentification' => 'EXPORT_CUFE_66_CHARS_1234567890123456789012345678901234567890123456'
]
]
];
🔄 Integración con Módulos Existentes
Para Módulos de Ventas
// En el módulo de ventas, cuando se requiere una nota de crédito
class SalesController extends Controller
{
public function createCreditNote(Request $request)
{
$saleData = $request->all();
$organization = auth()->user()->organization;
// Agregar documentos referenciados
$saleData['referencedDocuments'] = [
[
'issueDate' => $request->original_invoice_date,
'emissionType' => $request->reference_type, // ID, CUFE, PAPER, PRINTER
'apiIdentification' => $request->alanube_invoice_id // Si es tipo ID
]
];
// Emitir nota de crédito
$result = AlanubeEmissionHelper::emitCreditNote(
$organization,
$saleData,
auth()->id(),
true // async
);
return response()->json($result);
}
}
Para Módulos de Devoluciones
// En el módulo de devoluciones
class ReturnsController extends Controller
{
public function processReturn(Request $request)
{
$returnData = $request->all();
$organization = auth()->user()->organization;
// Transformar datos de devolución a nota de crédito
$referencedDocs = [
[
'issueDate' => $returnData['original_invoice_date'],
'emissionType' => 'ID',
'apiIdentification' => $returnData['alanube_invoice_id']
]
];
$creditNoteData = AlanubeEmissionHelper::transformDocuCenterToCreditNote(
$returnData,
$referencedDocs
);
// Validar antes de emitir
$validation = AlanubeEmissionHelper::validateCreditNoteData($creditNoteData);
if (!$validation['valid']) {
return response()->json([
'success' => false,
'errors' => $validation['errors']
], 400);
}
// Emitir nota de crédito
$result = AlanubeEmissionHelper::emitCreditNote(
$organization,
$creditNoteData,
auth()->id(),
false // sync para devoluciones inmediatas
);
return response()->json($result);
}
}
📈 Monitoreo y Logging
Logs Automáticos
El sistema genera logs automáticos para:
// Logs de información
Log::info('[AlanubeService] Emitiendo nota de crédito', [
'organization_id' => $organization->id,
'referenced_docs_count' => count($creditNoteData['referencedDocuments'])
]);
// Logs de éxito
Log::info('Nota de crédito emitida exitosamente con Alanube Panamá', [
'organization_id' => $organization->id,
'response_data' => $responseData
]);
// Logs de error
Log::error('[AlanubeService] Error emitiendo nota de crédito: ' . $e->getMessage(), [
'organization_id' => $organization->id,
'error_trace' => $e->getTraceAsString()
]);
Métricas Recomendadas
- Tiempo de procesamiento de notas de crédito
- Tasa de éxito vs errores
- Tipos de referencia más utilizados
- Errores de validación más comunes
🚨 Manejo de Errores Comunes
1. Documentos Referenciados Faltantes
// Error: "Documentos referenciados son obligatorios"
// Solución: Siempre incluir al menos un documento referenciado
$creditNoteData['referencedDocuments'] = [
[
'issueDate' => '2025-01-21T10:00:00Z',
'emissionType' => 'ID',
'apiIdentification' => 'INVOICE_ID_26_CHARACTERS'
]
];
2. Tipo de Emisión Inválido
// Error: "Tipo de emisión inválido"
// Solución: Usar solo ID, CUFE, PAPER, PRINTER
$doc['emissionType'] = 'ID'; // ✅ Correcto
$doc['emissionType'] = 'INVALID'; // ❌ Incorrecto
3. Identificación Faltante
// Error: "apiIdentification requerido cuando emissionType es ID"
// Solución: Incluir el campo correspondiente según el tipo
switch ($emissionType) {
case 'ID':
$doc['apiIdentification'] = 'ALANUBE_ID_26_CHARS';
break;
case 'CUFE':
$doc['cufeIdentification'] = 'CUFE_66_CHARS';
break;
case 'PAPER':
case 'PRINTER':
$doc['otherIdentification'] = 'PAPER_ID_22_CHARS';
break;
}
💡 Mejores Prácticas
1. Validación Previa
// Siempre validar antes de emitir
$validation = AlanubeEmissionHelper::validateCreditNoteData($creditNoteData);
if (!$validation['valid']) {
return response()->json([
'success' => false,
'message' => 'Datos de nota de crédito inválidos',
'errors' => $validation['errors']
], 400);
}
2. Manejo de Referencias
// Mantener registro de facturas originales para referencias futuras
class Invoice extends Model
{
public function getCreditNoteReferences(): array
{
return [
[
'issueDate' => $this->issue_date,
'emissionType' => 'ID',
'apiIdentification' => $this->alanube_id
]
];
}
}
3. Procesamiento Asíncrono para Volumen
// Para múltiples notas de crédito, usar procesamiento asíncrono
if (count($creditNotes) > 5) {
foreach ($creditNotes as $creditNote) {
AlanubeEmissionHelper::emitCreditNote(
$organization,
$creditNote,
$userId,
true // async
);
}
} else {
// Procesamiento síncrono para pocas notas
foreach ($creditNotes as $creditNote) {
AlanubeEmissionHelper::emitCreditNote(
$organization,
$creditNote,
$userId,
false // sync
);
}
}
✅ Checklist de Implementación
- [ ] Configuración PAC con
pac_type = 'alanube_panama' - [ ] Token de Alanube configurado
- [ ] Documentos referenciados incluidos
- [ ] Validación de datos implementada
- [ ] Manejo de errores configurado
- [ ] Logging habilitado
- [ ] Testing realizado
- [ ] Monitoreo configurado
Esta guía proporciona toda la información necesaria para implementar notas de crédito electrónicas con Alanube Panamá en DocuCenter. Para soporte adicional, consulte la documentación técnica principal o ejecute las pruebas automatizadas.