543 lines
20 KiB
Go
543 lines
20 KiB
Go
package controllers
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
|
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
|
|
)
|
|
|
|
// PasarelasPage renderiza la vista unificada de pasarelas de pago.
|
|
func PasarelasPage(c *fiber.Ctx) error {
|
|
boldCfg, _ := models.GetBoldConfig()
|
|
dlocalCfg, _ := models.GetLastActiveDlocalApi()
|
|
|
|
data := fiber.Map{
|
|
"Title": "Pasarelas de Pago",
|
|
"Bold": boldCfg,
|
|
"Dlocal": dlocalCfg,
|
|
"user": c.Locals("user"),
|
|
"modules": c.Locals("userModules"),
|
|
}
|
|
if err := c.Render("pasarelas_pago", data, "layouts/main"); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ─── Bold ─────────────────────────────────────────────────────────────────────
|
|
|
|
// SaveBoldConfig guarda o actualiza la configuración de Bold.
|
|
func SaveBoldConfig(c *fiber.Ctx) error {
|
|
type body struct {
|
|
ID uint `json:"id" form:"id"`
|
|
ApiKeyProd string `json:"api_key_prod" form:"api_key_prod"`
|
|
SecretKeyProd string `json:"secret_key_prod" form:"secret_key_prod"`
|
|
ApiKeyTest string `json:"api_key_test" form:"api_key_test"`
|
|
SecretKeyTest string `json:"secret_key_test" form:"secret_key_test"`
|
|
Modo string `json:"modo" form:"modo"`
|
|
CallbackUrl string `json:"callback_url" form:"callback_url"`
|
|
Nota string `json:"nota" form:"nota"`
|
|
}
|
|
var b body
|
|
if err := c.BodyParser(&b); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
if b.Modo == "" {
|
|
b.Modo = "test"
|
|
}
|
|
|
|
cfg := models.BoldConfig{
|
|
ApiKeyProd: b.ApiKeyProd,
|
|
SecretKeyProd: b.SecretKeyProd,
|
|
ApiKeyTest: b.ApiKeyTest,
|
|
SecretKeyTest: b.SecretKeyTest,
|
|
Modo: b.Modo,
|
|
CallbackUrl: b.CallbackUrl,
|
|
Nota: b.Nota,
|
|
}
|
|
cfg.ID = b.ID
|
|
|
|
if err := models.SaveBoldConfig(cfg); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"message": "Configuración Bold guardada"})
|
|
}
|
|
|
|
// GetBoldConfig devuelve la configuración activa de Bold (para cargar el form).
|
|
func GetBoldConfigAPI(c *fiber.Ctx) error {
|
|
cfg, err := models.GetBoldConfig()
|
|
if err != nil {
|
|
return c.JSON(fiber.Map{"data": nil})
|
|
}
|
|
return c.JSON(fiber.Map{"data": cfg})
|
|
}
|
|
|
|
// ─── dLocal ───────────────────────────────────────────────────────────────────
|
|
|
|
// SaveDlocalConfig guarda o actualiza la configuración de dLocal.
|
|
func SaveDlocalConfigWeb(c *fiber.Ctx) error {
|
|
type body struct {
|
|
ID uint `json:"id" form:"id"`
|
|
AccessKeyID string `json:"access_key_id" form:"access_key_id"`
|
|
AccessKeySecret string `json:"access_key_secret" form:"access_key_secret"`
|
|
AccessKeyIDdev string `json:"access_key_id_dev" form:"access_key_id_dev"`
|
|
AccessKeySecretdev string `json:"access_key_secret_dev" form:"access_key_secret_dev"`
|
|
UrlProd string `json:"url_prod" form:"url_prod"`
|
|
UrlDev string `json:"url_dev" form:"url_dev"`
|
|
Modo string `json:"modo" form:"modo"`
|
|
}
|
|
var b body
|
|
if err := c.BodyParser(&b); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
|
|
}
|
|
if b.Modo == "" {
|
|
b.Modo = "dev"
|
|
}
|
|
|
|
cfg := models.DlocalApi{
|
|
AccessKeyID: b.AccessKeyID,
|
|
AccessKeySecret: b.AccessKeySecret,
|
|
AccessKeyIDdev: b.AccessKeyIDdev,
|
|
AccessKeySecretdev: b.AccessKeySecretdev,
|
|
UrlProd: b.UrlProd,
|
|
UrlDev: b.UrlDev,
|
|
Modo: b.Modo,
|
|
IsActive: true,
|
|
}
|
|
cfg.ID = b.ID
|
|
|
|
// Desactivar configs previas
|
|
if cfg.ID == 0 {
|
|
if err := models.CreateDlocalApi(&cfg); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
} else {
|
|
if err := models.UpdateDlocalApi(&cfg); err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
}
|
|
return c.JSON(fiber.Map{"message": "Configuración dLocal guardada"})
|
|
}
|
|
|
|
// GetDlocalConfigAPI devuelve la configuración activa de dLocal.
|
|
func GetDlocalConfigAPI(c *fiber.Ctx) error {
|
|
cfg, err := models.GetLastActiveDlocalApi()
|
|
if err != nil {
|
|
return c.JSON(fiber.Map{"data": nil})
|
|
}
|
|
return c.JSON(fiber.Map{"data": cfg})
|
|
}
|
|
|
|
// ─── Logs 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 {
|
|
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,
|
|
"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 ──────────────────────────────────────────────────────────────
|
|
|
|
// DlocalPaymentLogs devuelve los últimos 100 registros de pagos de dLocal (legacy).
|
|
func DlocalPaymentLogs(c *fiber.Ctx) error {
|
|
logs, err := models.GetDlocalPaymentLogs(100)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
|
|
}
|
|
return c.JSON(fiber.Map{"data": logs})
|
|
}
|
|
|
|
// DlocalPaymentLogsPaginated devuelve los logs con paginación y filtro por estado.
|
|
// Query params: page (default 1), limit (default 25), estado (PAID|PENDING|REJECTED|APROBADOS|TODOS)
|
|
func DlocalPaymentLogsPaginated(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.GetDlocalPaymentLogsPaginated(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,
|
|
})
|
|
}
|
|
|
|
// ValidarDlocalLog verifica el estado de pago real de un log dLocal consultando
|
|
// todas las fuentes disponibles (dlocal_payment_log → Bold API → dLocal API).
|
|
// Si se confirma el pago, marca el contrato como pagado y envía confirmación.
|
|
// POST /app/pasarelas/dlocal/logs/:id/validar
|
|
func ValidarDlocalLog(c *fiber.Ctx) error {
|
|
logID, err := c.ParamsInt("id")
|
|
if err != nil || logID <= 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "ID inválido"})
|
|
}
|
|
|
|
var entry models.DlocalPaymentLog
|
|
if err := models.GetDlocalPaymentLogByID(uint(logID), &entry); err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Log no encontrado"})
|
|
}
|
|
|
|
ref := entry.Referencia
|
|
if ref == "" {
|
|
ref = entry.OrderID
|
|
}
|
|
|
|
var contratoID uint
|
|
if _, err := fmt.Sscanf(ref, "contrato-%d", &contratoID); err != nil || contratoID == 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Referencia no tiene formato contrato-{id}"})
|
|
}
|
|
|
|
contrato, err := models.GetContratoParaVerificacion(contratoID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Contrato no encontrado"})
|
|
}
|
|
|
|
payerEmail := entry.PayerEmail
|
|
if payerEmail == "" {
|
|
payerEmail = contrato.Cliente.Email
|
|
}
|
|
monto := entry.Monto
|
|
pagoConfirmado := contrato.PagoConfirmado
|
|
fuenteConfirmacion := ""
|
|
|
|
// ─── 1. Ya confirmado en DB ───────────────────────────────────────────────
|
|
if pagoConfirmado {
|
|
fuenteConfirmacion = "db"
|
|
}
|
|
|
|
// ─── 2. Mismo log si ya tiene estado PAID ────────────────────────────────
|
|
if !pagoConfirmado && (entry.Estado == "PAID" || entry.Estado == "AUTHORIZED") {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "dlocal_log"
|
|
}
|
|
|
|
// ─── 3. Bold API ─────────────────────────────────────────────────────────
|
|
if !pagoConfirmado && contrato.EnlacePagoLinkID != "" {
|
|
boldCfg, boldErr := models.GetBoldConfig()
|
|
if boldErr == nil {
|
|
paid, _, apiMonto, apiErr := services.CheckBoldLinkPaid(boldCfg, contrato.EnlacePagoLinkID)
|
|
if apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "bold_api"
|
|
if apiMonto > 0 {
|
|
monto = float64(apiMonto)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
|
if !pagoConfirmado {
|
|
dlocalCfg, dlErr := models.GetLastActiveDlocalApi()
|
|
if dlErr == nil {
|
|
paid, _, apiMonto, apiEmail, apiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, ref)
|
|
if apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "dlocal_api"
|
|
if apiMonto > 0 {
|
|
monto = apiMonto
|
|
}
|
|
if apiEmail != "" {
|
|
payerEmail = apiEmail
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Si el pago se confirmó ahora (no estaba marcado antes), actualizar contrato
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
_ = models.MarcarContratoPagado(contratoID)
|
|
go services.EnviarCorreoConfirmacionPago(contratoID, fuenteConfirmacion)
|
|
}
|
|
|
|
_ = models.UpdateDlocalPaymentLogDatos(uint(logID), payerEmail, monto)
|
|
_ = models.GetDlocalPaymentLogByID(uint(logID), &entry)
|
|
|
|
msg := "Datos actualizados"
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
msg = fmt.Sprintf("Pago confirmado via %s — contrato marcado como pagado", fuenteConfirmacion)
|
|
} else if pagoConfirmado {
|
|
msg = fmt.Sprintf("Pago ya confirmado (%s)", fuenteConfirmacion)
|
|
} else {
|
|
msg = "Pago aún no confirmado — datos actualizados"
|
|
}
|
|
|
|
return c.JSON(fiber.Map{
|
|
"ok": true,
|
|
"confirmado": pagoConfirmado,
|
|
"fuente": fuenteConfirmacion,
|
|
"mensaje": msg,
|
|
"data": entry,
|
|
})
|
|
}
|
|
|
|
// ─── Validación de intento de pago (callback) ───────────────────────────────
|
|
|
|
// ValidarBoldCallback verifica si el pago de un intento pendiente realmente se realizó.
|
|
// Recorre las mismas fuentes que verificarPago() y, si confirma, marca el contrato + actualiza el callback.
|
|
// POST /app/pasarelas/bold/callbacks/:id/validar
|
|
func ValidarBoldCallback(c *fiber.Ctx) error {
|
|
cbID, err := c.ParamsInt("id")
|
|
if err != nil || cbID <= 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "ID inválido"})
|
|
}
|
|
|
|
var cb models.BoldCallbackLog
|
|
if err := models.GetBoldCallbackLogByID(uint(cbID), &cb); err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Intento no encontrado"})
|
|
}
|
|
|
|
var contratoID uint
|
|
if _, err := fmt.Sscanf(cb.Referencia, "contrato-%d", &contratoID); err != nil || contratoID == 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Referencia no tiene formato contrato-{id}"})
|
|
}
|
|
|
|
contrato, err := models.GetContratoParaVerificacion(contratoID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Contrato no encontrado"})
|
|
}
|
|
|
|
pagoConfirmado := contrato.PagoConfirmado
|
|
fuente := ""
|
|
|
|
// ─── 1. Ya confirmado en DB ───────────────────────────────────────────────
|
|
if pagoConfirmado {
|
|
fuente = "db"
|
|
}
|
|
|
|
// ─── 2. dlocal_payment_log ───────────────────────────────────────────────
|
|
if !pagoConfirmado {
|
|
if dlLogs, dlErr := models.GetDlocalPaymentLogsByRef(cb.Referencia); dlErr == nil {
|
|
for _, l := range dlLogs {
|
|
if l.Estado == "PAID" || l.Estado == "AUTHORIZED" {
|
|
pagoConfirmado = true
|
|
fuente = "dlocal_log"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── 3. Bold API ─────────────────────────────────────────────────────────
|
|
if !pagoConfirmado && contrato.EnlacePagoLinkID != "" {
|
|
if boldCfg, boldErr := models.GetBoldConfig(); boldErr == nil {
|
|
if paid, _, _, apiErr := services.CheckBoldLinkPaid(boldCfg, contrato.EnlacePagoLinkID); apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuente = "bold_api"
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
|
if !pagoConfirmado {
|
|
if dlocalCfg, dlErr := models.GetLastActiveDlocalApi(); dlErr == nil {
|
|
if paid, _, _, _, apiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, cb.Referencia); apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuente = "dlocal_api"
|
|
}
|
|
}
|
|
}
|
|
|
|
// Actualizar contrato si se confirmó ahora
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
_ = models.MarcarContratoPagado(contratoID)
|
|
go services.EnviarCorreoConfirmacionPago(contratoID, fuente)
|
|
}
|
|
|
|
// Actualizar estado del callback
|
|
nuevoEstado := cb.Estado
|
|
if pagoConfirmado && cb.Estado == "pendiente" {
|
|
nuevoEstado = "pagado"
|
|
_ = models.UpdateBoldCallbackEstadoByID(uint(cbID), "pagado")
|
|
cb.Estado = "pagado"
|
|
}
|
|
|
|
msg := "Pago aún no confirmado"
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
msg = fmt.Sprintf("Pago confirmado via %s — contrato marcado como pagado", fuente)
|
|
} else if pagoConfirmado {
|
|
msg = fmt.Sprintf("Pago ya confirmado (%s)", fuente)
|
|
}
|
|
_ = nuevoEstado
|
|
|
|
return c.JSON(fiber.Map{
|
|
"ok": true,
|
|
"confirmado": pagoConfirmado,
|
|
"fuente": fuente,
|
|
"mensaje": msg,
|
|
"data": cb,
|
|
})
|
|
}
|
|
|
|
// ─── Validación de log API_CHECK ─────────────────────────────────────────────
|
|
|
|
// ValidarBoldLog verifica el estado de pago real de un log API_CHECK consultando
|
|
// todas las fuentes disponibles (dlocal_payment_log → Bold API → dLocal API).
|
|
// Si se confirma el pago, marca el contrato como pagado y envía el email de confirmación.
|
|
// También rellena email y monto faltantes. Funciona para cualquier tipo de log Bold.
|
|
// POST /app/pasarelas/bold/logs/:id/validar
|
|
func ValidarBoldLog(c *fiber.Ctx) error {
|
|
logID, err := c.ParamsInt("id")
|
|
if err != nil || logID <= 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "ID inválido"})
|
|
}
|
|
|
|
// Cargar el registro existente
|
|
var entry models.BoldWebhookLog
|
|
if err := models.GetBoldWebhookLogByID(uint(logID), &entry); err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Log no encontrado"})
|
|
}
|
|
|
|
// Parsear contrato ID de la referencia (contrato-{id})
|
|
var contratoID uint
|
|
if _, err := fmt.Sscanf(entry.Referencia, "contrato-%d", &contratoID); err != nil || contratoID == 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Referencia no tiene formato contrato-{id}"})
|
|
}
|
|
|
|
// Cargar contrato con cliente
|
|
contrato, err := models.GetContratoParaVerificacion(contratoID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Contrato no encontrado"})
|
|
}
|
|
|
|
// Valores iniciales: reutilizar lo que ya hay en el log, fallback al cliente
|
|
payerEmail := entry.PayerEmail
|
|
if payerEmail == "" {
|
|
payerEmail = contrato.Cliente.Email
|
|
}
|
|
monto := entry.Monto
|
|
pagoConfirmado := contrato.PagoConfirmado
|
|
fuenteConfirmacion := ""
|
|
|
|
// ─── 1. Ya confirmado en DB ───────────────────────────────────────────────
|
|
if pagoConfirmado {
|
|
fuenteConfirmacion = "db"
|
|
}
|
|
|
|
// ─── 2. dlocal_payment_log ────────────────────────────────────────────────
|
|
if !pagoConfirmado {
|
|
dlocalLogs, dlErr := models.GetDlocalPaymentLogsByRef(entry.Referencia)
|
|
if dlErr == nil {
|
|
for _, l := range dlocalLogs {
|
|
if l.Estado == "PAID" || l.Estado == "AUTHORIZED" {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "dlocal_log"
|
|
if l.PayerEmail != "" {
|
|
payerEmail = l.PayerEmail
|
|
}
|
|
if l.Monto > 0 {
|
|
monto = int64(l.Monto)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── 3. Bold API ─────────────────────────────────────────────────────────
|
|
if !pagoConfirmado && contrato.EnlacePagoLinkID != "" {
|
|
boldCfg, boldErr := models.GetBoldConfig()
|
|
if boldErr == nil {
|
|
paid, _, apiMonto, apiErr := services.CheckBoldLinkPaid(boldCfg, contrato.EnlacePagoLinkID)
|
|
if apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "bold_api"
|
|
if apiMonto > 0 {
|
|
monto = apiMonto
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
|
if !pagoConfirmado {
|
|
dlocalCfg, dlErr := models.GetLastActiveDlocalApi()
|
|
if dlErr == nil {
|
|
paid, _, apiMonto, apiEmail, apiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, entry.Referencia)
|
|
if apiErr == nil && paid {
|
|
pagoConfirmado = true
|
|
fuenteConfirmacion = "dlocal_api"
|
|
if apiMonto > 0 {
|
|
monto = int64(apiMonto)
|
|
}
|
|
if apiEmail != "" {
|
|
payerEmail = apiEmail
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Si el pago se confirmó ahora (no estaba marcado antes), actualizar contrato
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
_ = models.MarcarContratoPagado(contratoID)
|
|
go services.EnviarCorreoConfirmacionPago(contratoID, fuenteConfirmacion)
|
|
}
|
|
|
|
// Actualizar log con los mejores datos disponibles
|
|
_ = models.UpdateBoldWebhookLogDatos(uint(logID), payerEmail, monto)
|
|
|
|
// Devolver el log actualizado
|
|
_ = models.GetBoldWebhookLogByID(uint(logID), &entry)
|
|
|
|
msg := "Datos actualizados"
|
|
if pagoConfirmado && !contrato.PagoConfirmado {
|
|
msg = fmt.Sprintf("Pago confirmado via %s — contrato marcado como pagado", fuenteConfirmacion)
|
|
} else if pagoConfirmado {
|
|
msg = fmt.Sprintf("Pago ya confirmado (%s)", fuenteConfirmacion)
|
|
} else {
|
|
msg = "Pago aún no confirmado — datos del contrato actualizados"
|
|
}
|
|
|
|
return c.JSON(fiber.Map{
|
|
"ok": true,
|
|
"confirmado": pagoConfirmado,
|
|
"fuente": fuenteConfirmacion,
|
|
"mensaje": msg,
|
|
"data": entry,
|
|
})
|
|
}
|