This commit is contained in:
Lizandro Guarnizo
2026-05-12 21:33:54 -05:00
parent fbd75d8cc6
commit 9ca202b3bd
2 changed files with 80 additions and 3 deletions
+62 -3
View File
@@ -187,15 +187,74 @@ func LimpiarEnlacePago(contratoID uint) error {
}).Error
}
// MarcarContratoPagado marca el contrato como pagado al recibir confirmación de la pasarela.
// periodicidadAMeses convierte el string de periodicidad en número de meses.
func periodicidadAMeses(p string) int {
switch p {
case "mensual":
return 1
case "trimestral":
return 3
case "semestral":
return 6
case "anual":
return 12
default:
return 12
}
}
// MarcarContratoPagado marca el contrato como pagado y renueva la fecha de vencimiento
// según la periodicidad del servicio renovable asociado.
func MarcarContratoPagado(contratoID uint) error {
now := time.Now()
return app.Http.Database.DB.Model(&Contrato{}).Where("id = ?", contratoID).Updates(map[string]interface{}{
// Cargar contrato con servicios para calcular nueva fecha de vencimiento
var c Contrato
if err := app.Http.Database.DB.Preload("Servicios").First(&c, contratoID).Error; err != nil {
log.Printf("[PAGO] No se pudo cargar contrato %d para renovar: %v", contratoID, err)
// Fallback: solo marcar pago sin renovar fecha
return app.Http.Database.DB.Model(&Contrato{}).Where("id = ?", contratoID).Updates(map[string]interface{}{
"pago_confirmado": true,
"fecha_pago": now,
"enlace_pago": "",
"enlace_pago_link_id": "",
}).Error
}
updates := map[string]interface{}{
"pago_confirmado": true,
"fecha_pago": now,
"enlace_pago": "",
"enlace_pago_link_id": "",
}).Error
"estado": "activo",
}
// Buscar el servicio renovable con mayor período para calcular nueva fecha
meses := 0
for _, s := range c.Servicios {
if s.Tipo == "renovable" {
if m := periodicidadAMeses(s.Periodicidad); m > meses {
meses = m
}
}
}
if meses > 0 {
// Extender desde la fecha de vencimiento actual; si ya venció, extender desde hoy
base := c.FechaVencimiento
if base.Before(now) {
base = now
}
nuevaFecha := base.AddDate(0, meses, 0)
updates["fecha_vencimiento"] = nuevaFecha
log.Printf("[PAGO] Contrato %d renovado: %s → %s (%d meses)",
contratoID,
c.FechaVencimiento.Format("02/01/2006"),
nuevaFecha.Format("02/01/2006"),
meses,
)
}
return app.Http.Database.DB.Model(&Contrato{}).Where("id = ?", contratoID).Updates(updates).Error
}
// GetEstadoPago devuelve si el contrato tiene pago confirmado (para polling desde el frontend).
+18
View File
@@ -61,6 +61,24 @@ func PagoExitosoPage(c *fiber.Ctx) error {
}, "layouts/landing")
}
// Bold confirmó el pago directamente en la URL de retorno
if boldTxStatus == "approved" {
_ = models.SaveBoldCallbackLog(models.BoldCallbackLog{
Referencia: ref, PaymentLink: paymentLink, Params: paramsJSON,
Estado: "pagado", IP: c.IP(), UserAgent: string(c.Request().Header.UserAgent()),
})
// Marcar contrato si aún no está confirmado
var contratoID uint
if _, err := fmt.Sscanf(ref, "contrato-%d", &contratoID); err == nil && contratoID > 0 {
_ = models.MarcarContratoPagado(contratoID)
go services.EnviarCorreoConfirmacionPago(contratoID)
}
estado, fechaPago := verificarPago(ref)
return c.Render("pago_exitoso", fiber.Map{
"Ref": ref, "Estado": estado, "FechaPago": fechaPago,
}, "layouts/landing")
}
// Registrar el intento de pago en la tabla de callbacks
if ref != "" || paymentLink != "" {
entry := models.BoldCallbackLog{