Appearance
Manual de Plantilla de Recibo de Pago
Esta guía documenta la plantilla de recibo de pago (payment_receipt.html) usada por el servicio de órdenes/pagos. Explica los datos disponibles en el contexto, cómo mostrar información del miembro que registró el pago, y las consideraciones de seguridad.
Cuándo se usa
- Se renderiza al aprobar un pago (
OrderApproved) y se guarda en la orden. - La plantilla puede personalizarse vía
Configuration.ReceiptTemplate(camporeceiptTemplate). - Se entrega al deudor como comprobante del pago aplicado a su crédito.
Datos disponibles en la plantilla
El contexto corresponde a ReceiptConfig:
.Configuration // Configuración de la organización (logos, divisa, etc.)
.ConsecutivePayments // Prefijo+consecutivo del recibo
.Payment // Pago aplicado (montos, impuestos, costos)
.Order // Orden asociada al pago
.Credit // Crédito al que aplica el pago
.Entity // Organización (acreedor) configurada
.Installments // Cuotas afectadas por el pago (slice)
.Installment // Cuota principal para este pago (si aplica)
.OrganizationMember // Miembro que registró el pago (perfil compartido con la organización)Campos clave de .Payment (ejemplos)
.Payment.RegisteredAt(fecha/hora de registro).Payment.Amount(valor pagado).Payment.CollectionCosts,.Payment.TaxesPaid,.Payment.CapitalPaid,.Payment.InterestPaid, etc.
Datos del miembro que registró el pago
.OrganizationMember contiene el perfil compartido del miembro de la organización que registró el pago. El perfil se carga usando FindByIDOrgIDWithProfile(), que precarga:
- Perfil compartido (
Personal.Profile) filtrado porshared_with = orgIDyis_copy = FALSE - Datos completos del perfil natural (
Personal.Profile.Natural) incluyendo relaciones con ciudades, estados, países, entidades bancarias, etc. - Datos completos del perfil legal (
Personal.Profile.Legal) incluyendo relaciones con ciudades, estados, países, etc.
Nota de seguridad: Aunque el repositorio precarga el perfil completo, en el template solo se debe exponer información básica de identificación. No se deben mostrar correos, teléfonos, direcciones completas ni otros datos sensibles del miembro.
Mostrar el nombre del miembro que registró el pago
El template por defecto incluye una sección condicional que muestra "Registrado por" cuando el miembro está disponible:
{{ if and .OrganizationMember .OrganizationMember.Personal .OrganizationMember.Personal.Profile }}
<tr>
<td style="width: 40%; padding: 8px 16px 8px 8px; font-weight: 500; text-align: left; white-space: nowrap;">Registrado por</td>
<td style="width: 60%; padding: 8px 8px 8px 16px; text-align: right; word-break: break-word;">{{ .OrganizationMember.Personal.Profile.SafeCommonData.Name }}</td>
</tr>
{{ end }}Explicación del código:
Verificación condicional:
{{ if and .OrganizationMember .OrganizationMember.Personal .OrganizationMember.Personal.Profile }}verifica que:.OrganizationMemberexiste.OrganizationMember.Personalexiste.OrganizationMember.Personal.Profileexiste
Acceso al nombre:
{{ .OrganizationMember.Personal.Profile.SafeCommonData.Name }}utilizaSafeCommonDataque:- Para perfiles naturales: retorna
FirstName + " " + LastName - Para perfiles legales: retorna
NameoTradingNamesegún disponibilidad - Maneja automáticamente valores nulos o vacíos
- Para perfiles naturales: retorna
Estructura del objeto OrganizationMember
go
.OrganizationMember
└── Personal
└── Profile
├── Natural // Perfil de persona natural (si aplica)
│ ├── FirstName
│ ├── LastName
│ ├── IDType
│ ├── IDNumber
│ └── ... (otros campos precargados)
├── Legal // Perfil de persona jurídica (si aplica)
│ ├── Name
│ ├── TradingName
│ ├── OrgIDType
│ ├── OrgIDNumber
│ └── ... (otros campos precargados)
└── SafeCommonData // Método helper para obtener nombre de forma segura
└── Name // Nombre unificado (natural o legal)Funciones útiles
La plantilla usa las funciones estándar de Go Templates y las utilidades de Kuenta:
commonData- Obtiene datos comunes de un perfil (nombre, documento, etc.)currencyEntity- Formatea montos según la divisa de la organizacióndecimalAdd- Suma decimales de forma seguraSafeCommonData- Método del perfil que retorna nombre unificado
Para detalles completos, ver Referencia Completa de Funciones.
Estructura del template por defecto
El template payment_receipt.html incluye las siguientes secciones:
Información de registro
- Fecha de registro (
.Payment.RegisteredAt) - Registrado por (
.OrganizationMember.Personal.Profile.SafeCommonData.Name) - condicional - Número de recibo (
.ConsecutivePayments)
- Fecha de registro (
Información del crédito (si
.Creditestá disponible)- Nombre del cliente
- Documento
- Número de crédito
Montos
- Valor total pagado
- Total pagado + costos adicionales
Aplicación de pagos (campos condicionales según el tipo de pago)
- Capital (
.Payment.CapitalPaid) - Intereses (
.Payment.InterestPaid) - Intereses adicionales (
.Payment.AdditionalInterestPaid) - Costos (
.Payment.CostsPaid) - Costos adicionales (
.Payment.CollectionCosts) - Impuestos (
.Payment.TaxesPaid) - Intereses de mora (
.Payment.DebtInterestPaid) - Multas (
.Payment.PenaltyPaid)
- Capital (
Saldo pendiente
- Por pagar (
.Credit.Summary.Balance)
- Por pagar (
Información de contacto
- Teléfono y correo de la entidad (
.Entity.Profile.Legal.Phone,.Entity.Profile.Legal.OrgEmail)
- Teléfono y correo de la entidad (
Buenas prácticas
- ✅ Usa
SafeCommonData.Namepara mostrar el nombre del miembro que registró el pago de forma segura - ✅ Verifica la existencia de
.OrganizationMemberantes de acceder a sus propiedades - ✅ Muestra solo montos relevantes al pago (ej. capital, intereses, costos adicionales)
- ✅ Incluye el número de recibo (
.ConsecutivePayments) y la fecha de registro (.Payment.RegisteredAt) - ✅ Usa condiciones para mostrar campos opcionales solo cuando tienen valor
- ❌ No expongas datos sensibles del miembro (correos, teléfonos, direcciones completas)
- ❌ No insertes credenciales, URLs firmadas ni tokens en el recibo
- ❌ No accedas directamente a campos del perfil sin verificar su existencia
Personalización del template
Para personalizar el template de recibo:
- Accede a la configuración de tu organización
- Modifica el campo
receiptTemplatecon tu HTML personalizado - Mantén la estructura de datos disponible en
ReceiptConfig - Asegúrate de incluir las verificaciones condicionales necesarias
Ejemplo de personalización mínima:
<h2>Recibo de Pago #{{ .ConsecutivePayments }}</h2>
<p>Fecha: {{ .Payment.RegisteredAt.Format "02/01/2006 03:04 PM" }}</p>
{{ if and .OrganizationMember .OrganizationMember.Personal .OrganizationMember.Personal.Profile }}
<p>Registrado por: {{ .OrganizationMember.Personal.Profile.SafeCommonData.Name }}</p>
{{ end }}
<p>Monto: {{ currencyEntity .Payment.Amount .Configuration }}</p>