Agrega API de pagos externos: tokens por servicio, atados a pasarela e IP
Permite emitir credenciales (token hasheado + IP/CIDR opcional) desde
/app/pagos-externos para que aplicaciones de terceros pidan cobros a
través de Bold/dLocal/PayPal sin acceso a nada más del sistema:
- POST /api/v1/pagos-externos/solicitar genera el link de cobro real
usando solo las pasarelas habilitadas para ese servicio.
- Los webhooks existentes de Bold/dLocal/PayPal (firma obligatoria,
idempotentes) ahora también resuelven referencias "extpay-…" sin
tocar el flujo de contratos ("contrato-{id}").
- Al confirmarse el pago se notifica por webhook firmado (HMAC) y/o
Telegram, configurable por servicio.
- CRUD de servicios protegido con SoloAdmin; token y callback_secret
solo se muestran una vez, en DB se guardan hasheados.
This commit is contained in:
@@ -263,7 +263,8 @@ func AuthAdmin(c *fiber.Ctx) error {
|
||||
func AuthApi() func(*fiber.Ctx) error {
|
||||
return func(c *fiber.Ctx) error {
|
||||
// Excluir rutas públicas y /api/v2 (tiene su propio middleware)
|
||||
if c.Path() == "/api/v1/oauth/token" || c.Path() == "/api/sms/send" || strings.HasPrefix(c.Path(), "/api/v2") {
|
||||
if c.Path() == "/api/v1/oauth/token" || c.Path() == "/api/sms/send" || strings.HasPrefix(c.Path(), "/api/v2") ||
|
||||
strings.HasPrefix(c.Path(), "/api/v1/pagos-externos") {
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
)
|
||||
|
||||
// AuthServicioPago protege los endpoints públicos de la API de pagos externos
|
||||
// (/api/v1/pagos-externos/*). Es independiente de la sesión/JWT interna: el
|
||||
// caller es una aplicación de un tercero que solo tiene un token largo
|
||||
// (Bearer) y opcionalmente está restringido a una o varias IPs/CIDRs. Si pasa,
|
||||
// deja el *models.ServicioPagoExterno resuelto en Locals("servicio_pago").
|
||||
func AuthServicioPago(c *fiber.Ctx) error {
|
||||
auth := c.Get("Authorization")
|
||||
token := strings.TrimSpace(strings.TrimPrefix(auth, "Bearer "))
|
||||
if token == "" || token == auth {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": "Falta el header Authorization: Bearer <token>"})
|
||||
}
|
||||
|
||||
servicio, err := models.FindServicioPagoExternoActivoByToken(token)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": true, "message": "Token inválido o servicio inactivo"})
|
||||
}
|
||||
|
||||
if !servicio.IPPermitida(c.IP()) {
|
||||
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": true, "message": "IP no autorizada para este servicio"})
|
||||
}
|
||||
|
||||
c.Locals("servicio_pago", servicio)
|
||||
return c.Next()
|
||||
}
|
||||
Reference in New Issue
Block a user