package db import ( "database/sql" "fmt" "gestion/models" "log" ) func (d *Database) CreateCryptoPayment(commandID int, nowPaymentID, status, priceCurrency, payCurrency, payAddress string, priceAmount, payAmount float64) (*models.CryptoPayment, error) { var p models.CryptoPayment err := d.DB.QueryRow(` INSERT INTO crypto_payments (command_id, nowpayment_id, status, price_amount, price_currency, pay_currency, pay_address, pay_amount) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, command_id, nowpayment_id, status, price_amount, price_currency, pay_currency, pay_address, pay_amount, created_at, updated_at`, commandID, nowPaymentID, status, priceAmount, priceCurrency, payCurrency, payAddress, payAmount, ).Scan(&p.ID, &p.CommandID, &p.NowPaymentID, &p.Status, &p.PriceAmount, &p.PriceCurrency, &p.PayCurrency, &p.PayAddress, &p.PayAmount, &p.CreatedAt, &p.UpdatedAt) if err != nil { return nil, fmt.Errorf("CreateCryptoPayment: %w", err) } return &p, nil } func (d *Database) GetCryptoPaymentByCommandID(commandID int) (*models.CryptoPayment, error) { var p models.CryptoPayment err := d.DB.QueryRow(` SELECT id, command_id, nowpayment_id, status, price_amount, price_currency, pay_currency, pay_address, pay_amount, created_at, updated_at FROM crypto_payments WHERE command_id = $1 ORDER BY created_at DESC LIMIT 1`, commandID, ).Scan(&p.ID, &p.CommandID, &p.NowPaymentID, &p.Status, &p.PriceAmount, &p.PriceCurrency, &p.PayCurrency, &p.PayAddress, &p.PayAmount, &p.CreatedAt, &p.UpdatedAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &p, nil } func (d *Database) GetCryptoPaymentByNowPaymentID(nowPaymentID string) (*models.CryptoPayment, error) { var p models.CryptoPayment err := d.DB.QueryRow(` SELECT id, command_id, nowpayment_id, status, price_amount, price_currency, pay_currency, pay_address, pay_amount, created_at, updated_at FROM crypto_payments WHERE nowpayment_id = $1`, nowPaymentID, ).Scan(&p.ID, &p.CommandID, &p.NowPaymentID, &p.Status, &p.PriceAmount, &p.PriceCurrency, &p.PayCurrency, &p.PayAddress, &p.PayAmount, &p.CreatedAt, &p.UpdatedAt) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &p, nil } func (d *Database) GetPendingCryptoPayments() ([]models.CryptoPayment, error) { rows, err := d.DB.Query(` SELECT id, command_id, nowpayment_id, status, price_amount, price_currency, pay_currency, pay_address, pay_amount, created_at, updated_at FROM crypto_payments WHERE status NOT IN ('finished', 'failed', 'expired', 'refunded') ORDER BY created_at ASC`) if err != nil { return nil, err } defer rows.Close() var payments []models.CryptoPayment for rows.Next() { var p models.CryptoPayment if err := rows.Scan(&p.ID, &p.CommandID, &p.NowPaymentID, &p.Status, &p.PriceAmount, &p.PriceCurrency, &p.PayCurrency, &p.PayAddress, &p.PayAmount, &p.CreatedAt, &p.UpdatedAt); err != nil { continue } payments = append(payments, p) } return payments, nil } func (d *Database) UpdateCryptoPaymentStatus(id int, status string, payAmount float64) error { _, err := d.DB.Exec(` UPDATE crypto_payments SET status = $1, pay_amount = $2, updated_at = NOW() WHERE id = $3`, status, payAmount, id) return err } // ActivateCryptoCommand passe la commande de 'pending_payment' → 'pending' une fois le paiement confirmé func (d *Database) ActivateCryptoCommand(commandID int) error { _, err := d.DB.Exec(` UPDATE commandes SET status = 'pending', updated_at = NOW() WHERE id = $1 AND status = 'pending_payment'`, commandID) return err } // CancelCryptoCommand annule une commande en attente de paiement et restaure le stock func (d *Database) CancelCryptoCommand(commandID int) error { tx, err := d.DB.Begin() if err != nil { return err } defer tx.Rollback() rows, err := tx.Query(`SELECT product_id, quantite FROM command_items WHERE command_id = $1`, commandID) if err != nil { return err } defer rows.Close() for rows.Next() { var productID int var qty float64 if err := rows.Scan(&productID, &qty); err != nil { continue } if _, err := tx.Exec(`UPDATE products SET stock = stock + $1 WHERE id = $2`, qty, productID); err != nil { log.Printf("[CANCEL CRYPTO] erreur restauration stock produit %d: %v", productID, err) } } if _, err := tx.Exec(`UPDATE commandes SET status = 'cancelled', updated_at = NOW() WHERE id = $1 AND status = 'pending_payment'`, commandID); err != nil { return err } return tx.Commit() }