up
This commit is contained in:
@@ -208,11 +208,12 @@ func GetEstadoPago(contratoID uint) (bool, *time.Time, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetContratoParaVerificacion devuelve los campos necesarios para verificar el pago directamente
|
// GetContratoParaVerificacion devuelve los campos necesarios para verificar el pago directamente
|
||||||
// con la pasarela (pago_confirmado, enlace_pago_link_id).
|
// con la pasarela (pago_confirmado, enlace_pago_link_id). Preload de Cliente para poder usar el email.
|
||||||
func GetContratoParaVerificacion(contratoID uint) (*Contrato, error) {
|
func GetContratoParaVerificacion(contratoID uint) (*Contrato, error) {
|
||||||
var c Contrato
|
var c Contrato
|
||||||
if err := app.Http.Database.DB.
|
if err := app.Http.Database.DB.
|
||||||
Select("id", "pago_confirmado", "fecha_pago", "enlace_pago_link_id").
|
Preload("Cliente").
|
||||||
|
Select("contratos.id", "contratos.pago_confirmado", "contratos.fecha_pago", "contratos.enlace_pago_link_id", "contratos.cliente_id").
|
||||||
First(&c, contratoID).Error; err != nil {
|
First(&c, contratoID).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,23 +172,24 @@ type BoldLinkStatus struct {
|
|||||||
|
|
||||||
// CheckBoldLinkStatus consulta la API de Bold y devuelve el status del link.
|
// CheckBoldLinkStatus consulta la API de Bold y devuelve el status del link.
|
||||||
// Posibles valores: ACTIVE, PROCESSING, PAID, REJECTED, CANCELLED, EXPIRED.
|
// Posibles valores: ACTIVE, PROCESSING, PAID, REJECTED, CANCELLED, EXPIRED.
|
||||||
func CheckBoldLinkStatus(cfg *models.BoldConfig, linkID string) (status string, transactionID string, err error) {
|
func CheckBoldLinkStatus(cfg *models.BoldConfig, linkID string) (status string, transactionID string, monto int64, err error) {
|
||||||
raw, err := GetBoldPaymentLinkStatus(cfg, linkID)
|
raw, err := GetBoldPaymentLinkStatus(cfg, linkID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", 0, err
|
||||||
}
|
}
|
||||||
var result BoldLinkStatus
|
var result BoldLinkStatus
|
||||||
if err := json.Unmarshal(raw, &result); err != nil {
|
if err := json.Unmarshal(raw, &result); err != nil {
|
||||||
return "", "", fmt.Errorf("bold: parse link status: %w", err)
|
return "", "", 0, fmt.Errorf("bold: parse link status: %w", err)
|
||||||
}
|
}
|
||||||
return result.Status, result.TransactionID, nil
|
return result.Status, result.TransactionID, result.Total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckBoldLinkPaid es un wrapper de compatibilidad sobre CheckBoldLinkStatus.
|
// CheckBoldLinkPaid es un wrapper de compatibilidad sobre CheckBoldLinkStatus.
|
||||||
func CheckBoldLinkPaid(cfg *models.BoldConfig, linkID string) (bool, string, error) {
|
// Devuelve (pagado, transactionID, monto, error).
|
||||||
st, txID, err := CheckBoldLinkStatus(cfg, linkID)
|
func CheckBoldLinkPaid(cfg *models.BoldConfig, linkID string) (bool, string, int64, error) {
|
||||||
|
st, txID, monto, err := CheckBoldLinkStatus(cfg, linkID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", err
|
return false, "", 0, err
|
||||||
}
|
}
|
||||||
return st == "PAID" || st == "APPROVED", txID, nil
|
return st == "PAID" || st == "APPROVED", txID, monto, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -609,8 +609,8 @@ type dlocalPaymentListResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckDlocalPaymentByOrderID busca en la API de dLocal un pago con el order_id dado
|
// CheckDlocalPaymentByOrderID busca en la API de dLocal un pago con el order_id dado
|
||||||
// y devuelve (pagado bool, paymentID string, error).
|
// y devuelve (pagado bool, paymentID string, monto float64, payerEmail string, error).
|
||||||
func CheckDlocalPaymentByOrderID(cfg models.DlocalApi, orderID string) (bool, string, error) {
|
func CheckDlocalPaymentByOrderID(cfg models.DlocalApi, orderID string) (bool, string, float64, string, error) {
|
||||||
baseURL := cfg.UrlDev
|
baseURL := cfg.UrlDev
|
||||||
accessKeyID := cfg.AccessKeyIDdev
|
accessKeyID := cfg.AccessKeyIDdev
|
||||||
accessKeySecret := cfg.AccessKeySecretdev
|
accessKeySecret := cfg.AccessKeySecretdev
|
||||||
@@ -623,7 +623,7 @@ func CheckDlocalPaymentByOrderID(cfg models.DlocalApi, orderID string) (bool, st
|
|||||||
url := fmt.Sprintf("%s/v1/payments?order_id=%s", baseURL, orderID)
|
url := fmt.Sprintf("%s/v1/payments?order_id=%s", baseURL, orderID)
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", err
|
return false, "", 0, "", err
|
||||||
}
|
}
|
||||||
authToken := fmt.Sprintf("Bearer %s:%s", accessKeyID, accessKeySecret)
|
authToken := fmt.Sprintf("Bearer %s:%s", accessKeyID, accessKeySecret)
|
||||||
req.Header.Set("Authorization", authToken)
|
req.Header.Set("Authorization", authToken)
|
||||||
@@ -632,16 +632,16 @@ func CheckDlocalPaymentByOrderID(cfg models.DlocalApi, orderID string) (bool, st
|
|||||||
client := &http.Client{Timeout: 15 * time.Second}
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", err
|
return false, "", 0, "", err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", err
|
return false, "", 0, "", err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return false, "", fmt.Errorf("dlocal status %d: %s", resp.StatusCode, string(body))
|
return false, "", 0, "", fmt.Errorf("dlocal status %d: %s", resp.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// La respuesta puede ser lista o un objeto directo
|
// La respuesta puede ser lista o un objeto directo
|
||||||
@@ -649,16 +649,16 @@ func CheckDlocalPaymentByOrderID(cfg models.DlocalApi, orderID string) (bool, st
|
|||||||
if err := json.Unmarshal(body, &list); err == nil && len(list.Data) > 0 {
|
if err := json.Unmarshal(body, &list); err == nil && len(list.Data) > 0 {
|
||||||
for _, p := range list.Data {
|
for _, p := range list.Data {
|
||||||
if p.Status == "PAID" || p.Status == "AUTHORIZED" {
|
if p.Status == "PAID" || p.Status == "AUTHORIZED" {
|
||||||
return true, p.ID, nil
|
return true, p.ID, p.Amount, p.Payer.Email, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, "", nil
|
return false, "", 0, "", nil
|
||||||
}
|
}
|
||||||
// Si no es lista, intentar objeto directo
|
// Si no es lista, intentar objeto directo
|
||||||
var single dlocalPaymentResp
|
var single dlocalPaymentResp
|
||||||
if err := json.Unmarshal(body, &single); err == nil && single.ID != "" {
|
if err := json.Unmarshal(body, &single); err == nil && single.ID != "" {
|
||||||
paid := single.Status == "PAID" || single.Status == "AUTHORIZED"
|
paid := single.Status == "PAID" || single.Status == "AUTHORIZED"
|
||||||
return paid, single.ID, nil
|
return paid, single.ID, single.Amount, single.Payer.Email, nil
|
||||||
}
|
}
|
||||||
return false, "", nil
|
return false, "", 0, "", nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ func verificarPago(ref string) (confirmado bool, fechaPago string) {
|
|||||||
if contrato.EnlacePagoLinkID != "" {
|
if contrato.EnlacePagoLinkID != "" {
|
||||||
boldCfg, boldErr := models.GetBoldConfig()
|
boldCfg, boldErr := models.GetBoldConfig()
|
||||||
if boldErr == nil {
|
if boldErr == nil {
|
||||||
paid, paymentID, boldApiErr := services.CheckBoldLinkPaid(boldCfg, contrato.EnlacePagoLinkID)
|
paid, paymentID, monto, boldApiErr := services.CheckBoldLinkPaid(boldCfg, contrato.EnlacePagoLinkID)
|
||||||
if boldApiErr != nil {
|
if boldApiErr != nil {
|
||||||
log.Printf("[PAGO-ESTADO] Bold API error para link %s: %v", contrato.EnlacePagoLinkID, boldApiErr)
|
log.Printf("[PAGO-ESTADO] Bold API error para link %s: %v", contrato.EnlacePagoLinkID, boldApiErr)
|
||||||
} else if paid {
|
} else if paid {
|
||||||
@@ -141,6 +141,8 @@ func verificarPago(ref string) (confirmado bool, fechaPago string) {
|
|||||||
Tipo: "API_CHECK",
|
Tipo: "API_CHECK",
|
||||||
PaymentID: paymentID,
|
PaymentID: paymentID,
|
||||||
Referencia: ref,
|
Referencia: ref,
|
||||||
|
PayerEmail: contrato.Cliente.Email,
|
||||||
|
Monto: monto,
|
||||||
Procesado: true,
|
Procesado: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -152,7 +154,7 @@ func verificarPago(ref string) (confirmado bool, fechaPago string) {
|
|||||||
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
// ─── 4. dLocal API ───────────────────────────────────────────────────────
|
||||||
dlocalCfg, dlocalErr := models.GetLastActiveDlocalApi()
|
dlocalCfg, dlocalErr := models.GetLastActiveDlocalApi()
|
||||||
if dlocalErr == nil {
|
if dlocalErr == nil {
|
||||||
paid, paymentID, dlocalApiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, ref)
|
paid, paymentID, monto, payerEmail, dlocalApiErr := services.CheckDlocalPaymentByOrderID(*dlocalCfg, ref)
|
||||||
if dlocalApiErr != nil {
|
if dlocalApiErr != nil {
|
||||||
log.Printf("[PAGO-ESTADO] dLocal API error para order_id %s: %v", ref, dlocalApiErr)
|
log.Printf("[PAGO-ESTADO] dLocal API error para order_id %s: %v", ref, dlocalApiErr)
|
||||||
} else if paid {
|
} else if paid {
|
||||||
@@ -168,6 +170,8 @@ func verificarPago(ref string) (confirmado bool, fechaPago string) {
|
|||||||
Estado: "PAID",
|
Estado: "PAID",
|
||||||
PaymentID: paymentID,
|
PaymentID: paymentID,
|
||||||
Referencia: ref,
|
Referencia: ref,
|
||||||
|
PayerEmail: payerEmail,
|
||||||
|
Monto: monto,
|
||||||
Procesado: true,
|
Procesado: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user