up
This commit is contained in:
@@ -115,6 +115,18 @@ func GetContratosYaVencidos() ([]Contrato, error) {
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// GetContratosConEnlacePendiente devuelve contratos que tienen un enlace de pago Bold generado
|
||||
// pero cuyo pago aún no ha sido confirmado. Usado para polling periódico de la API de Bold.
|
||||
func GetContratosConEnlacePendiente() ([]Contrato, error) {
|
||||
var items []Contrato
|
||||
if err := app.Http.Database.DB.Preload("Cliente").
|
||||
Where("enlace_pago_link_id != '' AND pago_confirmado = false AND deleted_at IS NULL").
|
||||
Find(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// syncContratoServicios sincroniza la tabla join contrato_servicios usando SQL directo
|
||||
// para evitar que GORM intente hacer upsert de los servicios existentes.
|
||||
func syncContratoServicios(contratoID uint, servicioIDs []uint) error {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
@@ -25,8 +26,14 @@ func IniciarCron() {
|
||||
return
|
||||
}
|
||||
|
||||
// Polling Bold — cada 15 minutos para detectar pagos sin webhook
|
||||
if _, err := cronScheduler.AddFunc("*/15 * * * *", VerificarPagosBoldPendientes); err != nil {
|
||||
log.Printf("[CRON] Error registrando tarea bold_polling: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
cronScheduler.Start()
|
||||
log.Println("[CRON] Scheduler iniciado — vencimientos próximos 8AM, ya vencidos 9AM")
|
||||
log.Println("[CRON] Scheduler iniciado — vencimientos próximos 8AM, ya vencidos 9AM, Bold polling cada 15min")
|
||||
}
|
||||
|
||||
// DetenerCron para graceful shutdown
|
||||
@@ -141,3 +148,63 @@ func procesarContratos(regla *models.NotificacionRegla, contratos []models.Contr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VerificarPagosBoldPendientes consulta la API de Bold para cada contrato que tiene un
|
||||
// enlace de pago generado pero aún no confirmado. Se ejecuta cada 15 minutos via cron.
|
||||
// Esto compensa la ausencia de webhooks de Bold.
|
||||
func VerificarPagosBoldPendientes() {
|
||||
contratos, err := models.GetContratosConEnlacePendiente()
|
||||
if err != nil {
|
||||
log.Printf("[BOLD-POLL] Error obteniendo contratos pendientes: %v", err)
|
||||
return
|
||||
}
|
||||
if len(contratos) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
boldCfg, err := models.GetBoldConfig()
|
||||
if err != nil {
|
||||
log.Printf("[BOLD-POLL] Sin configuración Bold activa: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("[BOLD-POLL] Verificando %d contrato(s) con enlace pendiente...", len(contratos))
|
||||
|
||||
for _, c := range contratos {
|
||||
paid, paymentID, monto, err := CheckBoldLinkPaid(boldCfg, c.EnlacePagoLinkID)
|
||||
if err != nil {
|
||||
log.Printf("[BOLD-POLL] Error consultando link %s (contrato %d): %v", c.EnlacePagoLinkID, c.ID, err)
|
||||
continue
|
||||
}
|
||||
if !paid {
|
||||
continue
|
||||
}
|
||||
|
||||
ref := fmt.Sprintf("contrato-%d", c.ID)
|
||||
log.Printf("[BOLD-POLL] Pago detectado para %s (payment_id=%s, monto=%d)", ref, paymentID, monto)
|
||||
|
||||
if ok, _ := models.MarcarContratoPagado(c.ID); ok {
|
||||
go EnviarCorreoConfirmacionPago(c.ID, "bold")
|
||||
log.Printf("[BOLD-POLL] Contrato %d marcado como pagado", c.ID)
|
||||
}
|
||||
|
||||
// Enriquecer callback log si existe
|
||||
go models.EnrichBoldCallbackLog(ref, c.Cliente.Email, monto)
|
||||
|
||||
// Guardar en webhook log como API_CHECK para trazabilidad
|
||||
notifID := "api-check-" + paymentID
|
||||
if paymentID != "" && !models.IsBoldNotificationDuplicate(notifID) {
|
||||
_ = models.SaveBoldWebhookLog(models.BoldWebhookLog{
|
||||
NotificationID: notifID,
|
||||
Tipo: "API_CHECK",
|
||||
PaymentID: paymentID,
|
||||
Referencia: ref,
|
||||
PayerEmail: c.Cliente.Email,
|
||||
Monto: monto,
|
||||
Procesado: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("[BOLD-POLL] Verificación completada")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user