From 560359173bc03a6c3fae338613f691a42b509c21 Mon Sep 17 00:00:00 2001
From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com>
Date: Fri, 1 May 2026 22:55:51 -0500
Subject: [PATCH] up
---
migrations/migrate.go | 1 +
pkg/models/bold_config.go | 71 ++++
resources/views/pasarelas_pago.html | 419 ++++++++++++++++++++---
resources/views/query_runner.html | 236 ++++++++++++-
rest/controllers/api/bold_controller.go | 21 +-
rest/controllers/api/pago_controller.go | 47 ++-
rest/controllers/pasarelas_controller.go | 39 ++-
rest/routes/user.go | 1 +
8 files changed, 755 insertions(+), 80 deletions(-)
diff --git a/migrations/migrate.go b/migrations/migrate.go
index e647837..f141559 100755
--- a/migrations/migrate.go
+++ b/migrations/migrate.go
@@ -58,6 +58,7 @@ func Migrate() {
// Pasarelas de pago
&models.BoldConfig{},
&models.BoldWebhookLog{},
+ &models.BoldCallbackLog{},
&models.DlocalPaymentLog{},
); err != nil {
log.Fatalf("Error during main migration: %v", err)
diff --git a/pkg/models/bold_config.go b/pkg/models/bold_config.go
index 15c1502..f74db14 100644
--- a/pkg/models/bold_config.go
+++ b/pkg/models/bold_config.go
@@ -104,3 +104,74 @@ func GetBoldWebhookLogs(limit int) ([]BoldWebhookLog, error) {
}
return logs, nil
}
+
+// GetBoldWebhookLogsPaginated devuelve los logs con paginación y filtro por tipo.
+func GetBoldWebhookLogsPaginated(page, limit int, tipo string) ([]BoldWebhookLog, int64, error) {
+ var logs []BoldWebhookLog
+ var total int64
+ db := app.Http.Database.DB.Model(&BoldWebhookLog{})
+ if tipo != "" && tipo != "TODOS" {
+ db = db.Where("tipo = ?", tipo)
+ }
+ db.Count(&total)
+ offset := (page - 1) * limit
+ if err := db.Order("id DESC").Limit(limit).Offset(offset).Find(&logs).Error; err != nil {
+ return nil, 0, err
+ }
+ return logs, total, nil
+}
+
+// ─── Callback log (intentos de pago) ─────────────────────────────────────────
+
+// BoldCallbackLog registra cada visita a la URL de retorno de Bold.
+// Esto captura usuarios que iniciaron el proceso de pago (llegaron al checkout)
+// pero pueden haber abandonado, fallado o completado el pago.
+type BoldCallbackLog struct {
+ gorm.Model
+ // Referencia principal recibida de Bold (bold-order-id / payment_link / reference)
+ Referencia string `json:"referencia" gorm:"column:referencia;type:varchar(120);index"`
+ PaymentLink string `json:"payment_link" gorm:"column:payment_link;type:varchar(80)"`
+ // Todos los parámetros GET recibidos en JSON (para depuración)
+ Params string `json:"params" gorm:"column:params;type:text"`
+ // Estado: pendiente | pagado | fallido | revertido
+ Estado string `json:"estado" gorm:"column:estado;type:varchar(20);default:'pendiente'"`
+ // Datos del cliente si están disponibles
+ PayerEmail string `json:"payer_email" gorm:"column:payer_email;type:varchar(255)"`
+ // Datos de red (para análisis)
+ IP string `json:"ip" gorm:"column:ip;type:varchar(45)"`
+ UserAgent string `json:"user_agent" gorm:"column:user_agent;type:text"`
+}
+
+func (BoldCallbackLog) TableName() string { return "bold_callback_log" }
+
+// SaveBoldCallbackLog guarda un registro de intento de pago.
+func SaveBoldCallbackLog(entry BoldCallbackLog) error {
+ return app.Http.Database.DB.Create(&entry).Error
+}
+
+// UpdateBoldCallbackEstado actualiza el estado de los intentos que coincidan con la referencia.
+// Se llama desde el webhook cuando llega un evento SALE_APPROVED, SALE_REJECTED, etc.
+func UpdateBoldCallbackEstado(referencia, estado string) {
+ if referencia == "" {
+ return
+ }
+ app.Http.Database.DB.Model(&BoldCallbackLog{}).
+ Where("referencia = ? AND estado = 'pendiente'", referencia).
+ Update("estado", estado)
+}
+
+// GetBoldCallbackLogsPaginated devuelve los intentos de pago con paginación y filtro.
+func GetBoldCallbackLogsPaginated(page, limit int, estado string) ([]BoldCallbackLog, int64, error) {
+ var logs []BoldCallbackLog
+ var total int64
+ db := app.Http.Database.DB.Model(&BoldCallbackLog{})
+ if estado != "" && estado != "TODOS" {
+ db = db.Where("estado = ?", estado)
+ }
+ db.Count(&total)
+ offset := (page - 1) * limit
+ if err := db.Order("id DESC").Limit(limit).Offset(offset).Find(&logs).Error; err != nil {
+ return nil, 0, err
+ }
+ return logs, total, nil
+}
diff --git a/resources/views/pasarelas_pago.html b/resources/views/pasarelas_pago.html
index 99d2e28..de22a4b 100644
--- a/resources/views/pasarelas_pago.html
+++ b/resources/views/pasarelas_pago.html
@@ -68,6 +68,33 @@
+
+
+
+
+
+
+
@@ -199,7 +226,7 @@
Registra esta URL en el panel Bold → Configuración → Webhooks
- /webhooks/bold
+ /webhooks/bold
-
- La firma se verifica con HMAC-SHA256. En modo test la secret key puede ser vacía.
-
+
La firma se verifica con HMAC-SHA256. En modo test la secret key puede ser vacía.
@@ -234,48 +259,269 @@
+
+
+
-
-
-
-
Últimas notificaciones
-
-
-
- Sin notificaciones recibidas aún.
-
-
-
-
-
-
Tipo
-
Payment ID
-
Monto
-
Estado
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sin notificaciones recibidas aún.
+
+
+
+
+
+
Evento
+
Payment ID
+
Referencia
+
Email pagador
+
Monto
+
Estado
+
Fecha
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Mostrando de registros
+
+
+ Pág
+
+
+
+
+
+
+
+ ¿Qué es este registro? Cada vez que un usuario llega a la página de retorno
+ de Bold (callback URL) se registra un intento. Si el webhook posterior confirma el pago,
+ el estado cambia a pagado. Si el usuario abandonó antes de pagar queda en pendiente.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sin intentos registrados aún. Los intentos aparecen cuando un usuario llega al checkout de Bold.
+