up
This commit is contained in:
@@ -56,59 +56,56 @@ func PagoExitosoPage(c *fiber.Ctx) error {
|
||||
_ = models.SaveBoldCallbackLog(entry)
|
||||
}
|
||||
|
||||
return c.Render("pago_exitoso", fiber.Map{"Ref": ref}, "layouts/landing")
|
||||
// Verificar inmediatamente el estado del pago en el servidor
|
||||
estado, fechaPago := verificarPago(ref)
|
||||
|
||||
return c.Render("pago_exitoso", fiber.Map{
|
||||
"Ref": ref,
|
||||
"Estado": estado,
|
||||
"FechaPago": fechaPago,
|
||||
}, "layouts/landing")
|
||||
}
|
||||
|
||||
// PagoEstadoAPI devuelve el estado de pago de un contrato para polling desde el frontend.
|
||||
// GET /api/pago-estado?ref=contrato-{id}
|
||||
// verificarPago centraliza la lógica de verificación de pago para una referencia dada.
|
||||
// Devuelve (confirmado, fechaPago). Lo usan tanto PagoExitosoPage como PagoEstadoAPI.
|
||||
//
|
||||
// Flujo de verificación (en orden):
|
||||
// 1. Lee pago_confirmado de la DB → si ya confirmado, retorna ok.
|
||||
// 2. Si no confirmado, revisa dlocal_payment_log buscando ref con estado PAID.
|
||||
// 3. Si aún no confirmado, consulta Bold API directamente usando enlace_pago_link_id.
|
||||
// 4. Si la pasarela confirma el pago, marca el contrato y retorna confirmado.
|
||||
func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
ref := c.Query("ref", "")
|
||||
if ref == "" {
|
||||
return c.JSON(fiber.Map{"confirmado": false, "error": "ref requerido"})
|
||||
}
|
||||
|
||||
// Flujo (en orden):
|
||||
// 1. DB: si pago_confirmado = true → listo.
|
||||
// 2. dlocal_payment_log: si hay log con estado PAID/AUTHORIZED → marca y confirma.
|
||||
// 3. Bold API: consulta directo usando enlace_pago_link_id si existe.
|
||||
// 4. dLocal API: consulta directo por order_id.
|
||||
func verificarPago(ref string) (confirmado bool, fechaPago string) {
|
||||
var contratoID uint
|
||||
if _, err := fmt.Sscanf(ref, "contrato-%d", &contratoID); err != nil || contratoID == 0 {
|
||||
return c.JSON(fiber.Map{"confirmado": false, "error": "ref inválido"})
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// ─── 1. Consultar DB ──────────────────────────────────────────────────────
|
||||
// ─── 1. DB ────────────────────────────────────────────────────────────────
|
||||
contrato, err := models.GetContratoParaVerificacion(contratoID)
|
||||
if err != nil {
|
||||
return c.JSON(fiber.Map{"confirmado": false, "error": "contrato no encontrado"})
|
||||
return false, ""
|
||||
}
|
||||
if contrato.PagoConfirmado {
|
||||
resp := fiber.Map{"confirmado": true, "fuente": "db"}
|
||||
fp := ""
|
||||
if contrato.FechaPago != nil {
|
||||
resp["fecha_pago"] = contrato.FechaPago.Format("02/01/2006 15:04")
|
||||
fp = contrato.FechaPago.Format("02/01/2006 15:04")
|
||||
}
|
||||
return c.JSON(resp)
|
||||
return true, fp
|
||||
}
|
||||
|
||||
// ─── 2. Revisar log de dLocal (puede haber llegado antes que el webhook) ──
|
||||
// ─── 2. dlocal_payment_log ────────────────────────────────────────────────
|
||||
dlocalLogs, err := models.GetDlocalPaymentLogsByRef(ref)
|
||||
if err == nil {
|
||||
for _, l := range dlocalLogs {
|
||||
if l.Estado == "PAID" || l.Estado == "AUTHORIZED" {
|
||||
log.Printf("[PAGO-ESTADO] Contrato %d confirmado via dlocal_payment_log (id=%d)", contratoID, l.ID)
|
||||
_ = models.MarcarContratoPagado(contratoID)
|
||||
now := l.CreatedAt
|
||||
return c.JSON(fiber.Map{
|
||||
"confirmado": true,
|
||||
"fuente": "dlocal_log",
|
||||
"fecha_pago": now.Format("02/01/2006 15:04"),
|
||||
})
|
||||
return true, l.CreatedAt.Format("02/01/2006 15:04")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 3. Consultar Bold API directamente si hay link_id almacenado ─────────
|
||||
// ─── 3. Bold API ─────────────────────────────────────────────────────────
|
||||
if contrato.EnlacePagoLinkID != "" {
|
||||
boldCfg, boldErr := models.GetBoldConfig()
|
||||
if boldErr == nil {
|
||||
@@ -118,7 +115,6 @@ func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
} else if paid {
|
||||
log.Printf("[PAGO-ESTADO] Contrato %d confirmado via Bold API (payment_id=%s)", contratoID, paymentID)
|
||||
_ = models.MarcarContratoPagado(contratoID)
|
||||
// Guardar en bold_webhook_log como registro de esta verificación activa
|
||||
if paymentID != "" && !models.IsBoldNotificationDuplicate("api-check-"+paymentID) {
|
||||
_ = models.SaveBoldWebhookLog(models.BoldWebhookLog{
|
||||
NotificationID: "api-check-" + paymentID,
|
||||
@@ -128,15 +124,12 @@ func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
Procesado: true,
|
||||
})
|
||||
}
|
||||
return c.JSON(fiber.Map{
|
||||
"confirmado": true,
|
||||
"fuente": "bold_api",
|
||||
})
|
||||
return true, ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 4. Consultar dLocal API directamente por order_id ────────────────────
|
||||
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
||||
dlocalCfg, dlocalErr := models.GetLastActiveDlocalApi()
|
||||
if dlocalErr == nil {
|
||||
paid, paymentID, dlocalApiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, ref)
|
||||
@@ -145,7 +138,6 @@ func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
} else if paid {
|
||||
log.Printf("[PAGO-ESTADO] Contrato %d confirmado via dLocal API (payment_id=%s)", contratoID, paymentID)
|
||||
_ = models.MarcarContratoPagado(contratoID)
|
||||
// Guardar en dlocal_payment_log como registro de esta verificación activa
|
||||
notifID := "api-check-" + ref
|
||||
if !models.IsDlocalNotificationDuplicate(notifID) {
|
||||
_ = models.SaveDlocalPaymentLog(models.DlocalPaymentLog{
|
||||
@@ -158,13 +150,23 @@ func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
Procesado: true,
|
||||
})
|
||||
}
|
||||
return c.JSON(fiber.Map{
|
||||
"confirmado": true,
|
||||
"fuente": "dlocal_api",
|
||||
})
|
||||
return true, ""
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Sin confirmación aún ─────────────────────────────────────────────────
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// PagoEstadoAPI devuelve el estado de pago de un contrato para polling desde el frontend.
|
||||
// GET /api/pago-estado?ref=contrato-{id}
|
||||
func PagoEstadoAPI(c *fiber.Ctx) error {
|
||||
ref := c.Query("ref", "")
|
||||
if ref == "" {
|
||||
return c.JSON(fiber.Map{"confirmado": false, "error": "ref requerido"})
|
||||
}
|
||||
confirmado, fechaPago := verificarPago(ref)
|
||||
if confirmado {
|
||||
return c.JSON(fiber.Map{"confirmado": true, "fecha_pago": fechaPago})
|
||||
}
|
||||
return c.JSON(fiber.Map{"confirmado": false})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user