206 lines
7.6 KiB
Go
206 lines
7.6 KiB
Go
package models
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/sujit-baniya/fiber-boilerplate/app"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type DlocalApi struct {
|
|
gorm.Model
|
|
AccessKeyID string `gorm:"not null" json:"access_key_id"` // Access Key ID
|
|
AccessKeySecret string `gorm:"not null" json:"access_key_secret"` // Access Key Secret
|
|
AccessKeyIDdev string `gorm:"not null" json:"access_key_id_dev"` // Access Key ID
|
|
AccessKeySecretdev string `gorm:"not null" json:"access_key_secret_dev"`
|
|
IsActive bool `gorm:"default:true" json:"is_active"` // Activar o desactivar config
|
|
UrlDev string `gorm:"type:text" json:"url_dev"`
|
|
UrlProd string `gorm:"type:text" json:"url_prod"`
|
|
Modo string `gorm:"default:'prod'" json:"modo"`
|
|
}
|
|
type PlanRequest struct {
|
|
Name string `json:"name" validate:"required"`
|
|
Description string `json:"description" validate:"required"`
|
|
Currency string `json:"currency" validate:"required"`
|
|
Amount float64 `json:"amount" validate:"required"`
|
|
FrequencyType string `json:"frequency_type" validate:"required"`
|
|
|
|
Country string `json:"country,omitempty"`
|
|
FrequencyValue int `json:"frequency_value,omitempty"`
|
|
DayOfMonth int `json:"day_of_month,omitempty"`
|
|
NotificationURL string `json:"notification_url,omitempty"`
|
|
SuccessURL string `json:"success_url,omitempty"`
|
|
BackURL string `json:"back_url,omitempty"`
|
|
ErrorURL string `json:"error_url,omitempty"`
|
|
}
|
|
|
|
// TableName asegura que GORM use la tabla 'qrvcard'
|
|
func (DlocalApi) TableName() string {
|
|
return "dlocal_api"
|
|
}
|
|
|
|
// GetAllQrVcard obtiene todos los registros de QrVcard con paginación y búsqueda
|
|
func GetAllDlocalApi(limit, offset int, search string) ([]DlocalApi, int64, error) {
|
|
var items []DlocalApi
|
|
var total int64
|
|
db := app.Http.Database.DB.Model(&DlocalApi{})
|
|
|
|
// Contamos el total de registros
|
|
if err := db.Count(&total).Error; err != nil {
|
|
log.Printf("Error counting DlocalApi: %v", err)
|
|
return nil, 0, err
|
|
}
|
|
|
|
// Obtenemos los registros con paginación
|
|
if err := db.Order("id DESC").Limit(limit).Offset(offset).Find(&items).Error; err != nil {
|
|
log.Printf("Error retrieving DlocalApi: %v", err)
|
|
return nil, 0, err
|
|
}
|
|
|
|
return items, total, nil
|
|
}
|
|
|
|
// CreateQrVcard crea un nuevo registro de QrVcard en la base de datos
|
|
func CreateDlocalApi(DlocalApi *DlocalApi) error {
|
|
if err := app.Http.Database.DB.Create(&DlocalApi).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// UpdateQrVcard actualiza un registro de QrVcard existente
|
|
func UpdateDlocalApi(DlocalApi *DlocalApi) error {
|
|
if err := app.Http.Database.DB.Model(&DlocalApi).Updates(DlocalApi).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeleteQrVcard elimina un registro de QrVcard de la base de datos
|
|
func DeleteDlocalApi(DlocalApi *DlocalApi) error {
|
|
if err := app.Http.Database.DB.Delete(&DlocalApi).Error; err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetLastActiveDlocalApi obtiene el último registro activo
|
|
func GetLastActiveDlocalApi() (*DlocalApi, error) {
|
|
var dlocalConfig DlocalApi
|
|
err := app.Http.Database.DB.
|
|
Where("is_active = ?", true).
|
|
Order("id DESC").
|
|
First(&dlocalConfig).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &dlocalConfig, nil
|
|
}
|
|
|
|
// ─── DlocalPaymentLog ─────────────────────────────────────────────────────────
|
|
|
|
// DlocalPaymentLog registra cada pago/notificación de dLocal.
|
|
// Cubre webhooks automáticos y registros manuales del backoffice.
|
|
type DlocalPaymentLog struct {
|
|
gorm.Model
|
|
// notification_id único; para entradas manuales se genera con prefijo "manual-"
|
|
NotificationID string `json:"notification_id" gorm:"column:notification_id;uniqueIndex;type:varchar(128);not null"`
|
|
Fuente string `json:"fuente" gorm:"column:fuente;type:varchar(20)"` // "webhook" | "manual"
|
|
Tipo string `json:"tipo" gorm:"column:tipo;type:varchar(50)"` // PAYMENT, SUBSCRIPTION_CHARGE, …
|
|
Estado string `json:"estado" gorm:"column:estado;type:varchar(30)"` // PAID, PENDING, REJECTED, CANCELLED, EXPIRED
|
|
PaymentID string `json:"payment_id" gorm:"column:payment_id;type:varchar(64)"`
|
|
OrderID string `json:"order_id" gorm:"column:order_id;type:varchar(120)"`
|
|
Referencia string `json:"referencia" gorm:"column:referencia;type:varchar(120)"`
|
|
PayerEmail string `json:"payer_email" gorm:"column:payer_email;type:varchar(255)"`
|
|
Monto float64 `json:"monto" gorm:"column:monto"`
|
|
Moneda string `json:"moneda" gorm:"column:moneda;type:varchar(10)"`
|
|
Procesado bool `json:"procesado" gorm:"column:procesado;default:false"`
|
|
Nota string `json:"nota" gorm:"column:nota;type:text"`
|
|
Raw string `json:"raw" gorm:"column:raw;type:text"`
|
|
}
|
|
|
|
func (DlocalPaymentLog) TableName() string { return "dlocal_payment_log" }
|
|
|
|
// IsDlocalNotificationDuplicate devuelve true si el notification_id ya existe.
|
|
func IsDlocalNotificationDuplicate(notificationID string) bool {
|
|
result := app.Http.Database.DB.
|
|
Where("notification_id = ?", notificationID).
|
|
First(&DlocalPaymentLog{})
|
|
return result.Error == nil
|
|
}
|
|
|
|
// SaveDlocalPaymentLog inserta un nuevo registro de pago.
|
|
func SaveDlocalPaymentLog(entry DlocalPaymentLog) error {
|
|
return app.Http.Database.DB.Create(&entry).Error
|
|
}
|
|
|
|
// MarkDlocalPaymentProcessed marca el registro como procesado.
|
|
func MarkDlocalPaymentProcessed(notificationID string) {
|
|
app.Http.Database.DB.Model(&DlocalPaymentLog{}).
|
|
Where("notification_id = ?", notificationID).
|
|
Update("procesado", true)
|
|
}
|
|
|
|
// GetDlocalPaymentLogs devuelve los últimos N registros ordenados por fecha.
|
|
func GetDlocalPaymentLogs(limit int) ([]DlocalPaymentLog, error) {
|
|
var logs []DlocalPaymentLog
|
|
if err := app.Http.Database.DB.Order("id DESC").Limit(limit).Find(&logs).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return logs, nil
|
|
}
|
|
|
|
// GetDlocalPaymentLogsPaginated devuelve los logs con paginación y filtro por estado.
|
|
// El valor especial "APROBADOS" agrupa PAID + AUTHORIZED.
|
|
func GetDlocalPaymentLogsPaginated(page, limit int, estado string) ([]DlocalPaymentLog, int64, error) {
|
|
var logs []DlocalPaymentLog
|
|
var total int64
|
|
db := app.Http.Database.DB.Model(&DlocalPaymentLog{})
|
|
switch estado {
|
|
case "", "TODOS":
|
|
// sin filtro
|
|
case "APROBADOS":
|
|
db = db.Where("estado IN ?", []string{"PAID", "AUTHORIZED"})
|
|
default:
|
|
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
|
|
}
|
|
|
|
// GetDlocalPaymentLogByID carga un registro por su PK.
|
|
func GetDlocalPaymentLogByID(id uint, out *DlocalPaymentLog) error {
|
|
return app.Http.Database.DB.First(out, id).Error
|
|
}
|
|
|
|
// UpdateDlocalPaymentLogDatos actualiza email y monto de un log existente.
|
|
func UpdateDlocalPaymentLogDatos(id uint, payerEmail string, monto float64) error {
|
|
updates := map[string]interface{}{}
|
|
if payerEmail != "" {
|
|
updates["payer_email"] = payerEmail
|
|
}
|
|
if monto > 0 {
|
|
updates["monto"] = monto
|
|
}
|
|
if len(updates) == 0 {
|
|
return nil
|
|
}
|
|
return app.Http.Database.DB.Model(&DlocalPaymentLog{}).Where("id = ?", id).Updates(updates).Error
|
|
}
|
|
|
|
// GetDlocalPaymentLogsByRef devuelve todos los registros que coinciden con una referencia/order_id.
|
|
func GetDlocalPaymentLogsByRef(ref string) ([]DlocalPaymentLog, error) {
|
|
var logs []DlocalPaymentLog
|
|
if err := app.Http.Database.DB.
|
|
Where("referencia = ? OR order_id = ?", ref, ref).
|
|
Order("id DESC").
|
|
Find(&logs).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return logs, nil
|
|
}
|