up
This commit is contained in:
@@ -83,9 +83,26 @@ func BoldWebhook(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(fiber.Map{"ok": true})
|
||||
}
|
||||
|
||||
// ─── 6. Solo procesar SALE_APPROVED ─────────────────────────────────────
|
||||
// ─── 6. Actualizar estado en callback_log para TODOS los eventos ─────────
|
||||
if referencia != "" {
|
||||
estimado := "pendiente"
|
||||
switch tipo {
|
||||
case "SALE_APPROVED":
|
||||
estimado = "pagado"
|
||||
case "SALE_REJECTED":
|
||||
estimado = "fallido"
|
||||
case "SALE_REVERSED", "CHARGEBACK":
|
||||
estimado = "revertido"
|
||||
}
|
||||
models.UpdateBoldCallbackEstado(referencia, estimado)
|
||||
if paymentID != "" {
|
||||
models.UpdateBoldCallbackEstado(paymentID, estimado)
|
||||
}
|
||||
}
|
||||
|
||||
// Solo continuar lógica de negocio para SALE_APPROVED ─────────────────────
|
||||
if tipo != "SALE_APPROVED" {
|
||||
log.Printf("[BOLD] Webhook: tipo '%s' ignorado", tipo)
|
||||
log.Printf("[BOLD] Webhook: tipo '%s' registrado", tipo)
|
||||
return c.Status(fiber.StatusOK).JSON(fiber.Map{"ok": true})
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,52 @@ import (
|
||||
)
|
||||
|
||||
// PagoExitosoPage renderiza la página pública de confirmación de pago.
|
||||
// Bold redirige al cliente aquí tras el pago. La URL puede incluir ?ref=contrato-{id}.
|
||||
// Bold redirige al cliente aquí tras el pago. Registra el intento en bold_callback_log.
|
||||
func PagoExitosoPage(c *fiber.Ctx) error {
|
||||
ref := c.Query("ref", "")
|
||||
// Recolectar todos los parámetros posibles que Bold puede enviar
|
||||
params := map[string]string{}
|
||||
for _, k := range []string{"bold-order-id", "order_id", "payment_link", "reference", "id", "ref"} {
|
||||
if v := c.Query(k, ""); v != "" {
|
||||
params[k] = v
|
||||
}
|
||||
}
|
||||
c.Request().URI().QueryArgs().VisitAll(func(k, v []byte) {
|
||||
params[string(k)] = string(v)
|
||||
})
|
||||
|
||||
// Resolver la referencia principal (orden de prioridad)
|
||||
ref := ""
|
||||
for _, k := range []string{"ref", "reference", "bold-order-id", "payment_link", "order_id", "id"} {
|
||||
if v := params[k]; v != "" {
|
||||
ref = v
|
||||
break
|
||||
}
|
||||
}
|
||||
paymentLink := params["payment_link"]
|
||||
|
||||
// Serializar todos los params para auditoría
|
||||
paramsJSON := "{"
|
||||
for k, v := range params {
|
||||
paramsJSON += `"` + k + `":"` + v + `",`
|
||||
}
|
||||
if len(paramsJSON) > 1 {
|
||||
paramsJSON = paramsJSON[:len(paramsJSON)-1]
|
||||
}
|
||||
paramsJSON += "}"
|
||||
|
||||
// Registrar el intento de pago en la tabla de callbacks
|
||||
if ref != "" || paymentLink != "" {
|
||||
entry := models.BoldCallbackLog{
|
||||
Referencia: ref,
|
||||
PaymentLink: paymentLink,
|
||||
Params: paramsJSON,
|
||||
Estado: "pendiente",
|
||||
IP: c.IP(),
|
||||
UserAgent: string(c.Request().Header.UserAgent()),
|
||||
}
|
||||
_ = models.SaveBoldCallbackLog(entry)
|
||||
}
|
||||
|
||||
return c.Render("pago_exitoso", fiber.Map{"Ref": ref}, "layouts/landing")
|
||||
}
|
||||
|
||||
|
||||
@@ -129,13 +129,46 @@ func GetDlocalConfigAPI(c *fiber.Ctx) error {
|
||||
|
||||
// ─── Logs Bold ────────────────────────────────────────────────────────────────
|
||||
|
||||
// BoldWebhookLogs devuelve los últimos 50 registros del log de webhooks de Bold.
|
||||
// BoldWebhookLogs devuelve los logs de notificaciones con paginación y filtro por tipo.
|
||||
// Query params: page (default 1), limit (default 25), tipo (SALE_APPROVED|SALE_REJECTED|...|TODOS)
|
||||
func BoldWebhookLogs(c *fiber.Ctx) error {
|
||||
logs, err := models.GetBoldWebhookLogs(50)
|
||||
page := c.QueryInt("page", 1)
|
||||
limit := c.QueryInt("limit", 25)
|
||||
tipo := c.Query("tipo", "")
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
logs, total, err := models.GetBoldWebhookLogsPaginated(page, limit, tipo)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{"data": logs})
|
||||
return c.JSON(fiber.Map{
|
||||
"data": logs,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
// BoldCallbackLogs devuelve los intentos de pago (visitas al callback) con paginación y filtro.
|
||||
// Query params: page (default 1), limit (default 25), estado (pendiente|pagado|fallido|revertido|TODOS)
|
||||
func BoldCallbackLogs(c *fiber.Ctx) error {
|
||||
page := c.QueryInt("page", 1)
|
||||
limit := c.QueryInt("limit", 25)
|
||||
estado := c.Query("estado", "")
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
logs, total, err := models.GetBoldCallbackLogsPaginated(page, limit, estado)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
return c.JSON(fiber.Map{
|
||||
"data": logs,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
// ─── Logs dLocal ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -135,6 +135,7 @@ func UserRoutes(app fiber.Router) {
|
||||
protected.Get("/pasarelas/bold/config", controllers.GetBoldConfigAPI)
|
||||
protected.Post("/pasarelas/bold/save", controllers.SaveBoldConfig)
|
||||
protected.Get("/pasarelas/bold/logs", controllers.BoldWebhookLogs)
|
||||
protected.Get("/pasarelas/bold/callbacks", controllers.BoldCallbackLogs)
|
||||
// dLocal
|
||||
protected.Get("/pasarelas/dlocal/config", controllers.GetDlocalConfigAPI)
|
||||
protected.Post("/pasarelas/dlocal/save", controllers.SaveDlocalConfigWeb)
|
||||
|
||||
Reference in New Issue
Block a user