up
This commit is contained in:
+62
-3
@@ -187,15 +187,74 @@ func LimpiarEnlacePago(contratoID uint) error {
|
|||||||
}).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 {
|
func MarcarContratoPagado(contratoID uint) error {
|
||||||
now := time.Now()
|
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,
|
"pago_confirmado": true,
|
||||||
"fecha_pago": now,
|
"fecha_pago": now,
|
||||||
"enlace_pago": "",
|
"enlace_pago": "",
|
||||||
"enlace_pago_link_id": "",
|
"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).
|
// GetEstadoPago devuelve si el contrato tiene pago confirmado (para polling desde el frontend).
|
||||||
|
|||||||
@@ -61,6 +61,24 @@ func PagoExitosoPage(c *fiber.Ctx) error {
|
|||||||
}, "layouts/landing")
|
}, "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
|
// Registrar el intento de pago en la tabla de callbacks
|
||||||
if ref != "" || paymentLink != "" {
|
if ref != "" || paymentLink != "" {
|
||||||
entry := models.BoldCallbackLog{
|
entry := models.BoldCallbackLog{
|
||||||
|
|||||||
Reference in New Issue
Block a user