package main import ( "bytes" "database/sql" "encoding/json" "fmt" "log" "net/http" "os" "strconv" "time" "github.com/google/uuid" "github.com/gorilla/handlers" _ "github.com/mattn/go-sqlite3" ) // Структура для тела запроса на localhost:5000 type PaymentRequest struct { ID string `json:"id"` Sum float64 `json:"sum"` } // Структура для ответа от localhost:5000 type PaymentResponse struct { Message string `json:"message"` URL string `json:"redir_url"` } var db *sql.DB func initDB() { var err error dbFile := "pay_orders.db" db, err = sql.Open("sqlite3", dbFile) if err != nil { log.Fatal("Ошибка подключения к базе данных:", err) } // Создаем таблицу pay_urls, если она не существует createTableSQL := ` CREATE TABLE IF NOT EXISTS pay_urls ( id TEXT PRIMARY KEY, url TEXT NOT NULL );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal("Ошибка при создании таблицы pay_urls:", err) } createTableSQL = ` CREATE TABLE IF NOT EXISTS order_list ( order_id TEXT PRIMARY KEY, total_price REAL NOT NULL, datetime TEXT NOT NULL );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal("Ошибка при создании таблицы order_list:", err) } createTableSQL = `CREATE TABLE IF NOT EXISTS order_lines ( line_id INTEGER PRIMARY KEY AUTOINCREMENT, order_id TEXT NOT NULL, item_id INTEGER NOT NULL, item_title TEXT NOT NULL, item_price REAL NOT NULL, item_quantity INTEGER NOT NULL, FOREIGN KEY (order_id) REFERENCES order_list(order_id) );` _, err = db.Exec(createTableSQL) if err != nil { log.Fatal("Ошибка при создании таблицы order_lines:", err) } fmt.Println("База данных готова к работе.") } func payHandler(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie("totalPrice") if err != nil { http.Error(w, "Не удалось получить amount из cookies", http.StatusBadRequest) return } // Преобразуем amount из строки в float64 amount, err := strconv.ParseFloat(cookie.Value, 64) if err != nil { http.Error(w, "Некорректное значение amount в cookies", http.StatusBadRequest) return } // Генерируем новый UUID newUUID := uuid.New().String() // Создаем тело запроса для localhost:5000 paymentRequest := PaymentRequest{ ID: newUUID, Sum: amount, } // Преобразуем тело запроса в JSON requestBody, err := json.Marshal(paymentRequest) if err != nil { http.Error(w, "Ошибка при создании запроса", http.StatusInternalServerError) return } // Отправляем POST-запрос на localhost:5000 resp, err := http.Post("http://localhost:5000/pay", "application/json", bytes.NewBuffer(requestBody)) if err != nil { http.Error(w, "Ошибка при отправке запроса на сервер", http.StatusInternalServerError) return } defer resp.Body.Close() // Читаем ответ от сервера var paymentResponse PaymentResponse if err := json.NewDecoder(resp.Body).Decode(&paymentResponse); err != nil { http.Error(w, "Ошибка при чтении ответа от сервера", http.StatusInternalServerError) return } // Сохраняем данные в базу данных insertSQL := `INSERT INTO pay_urls (uuid, url) VALUES (?, ?)` _, err = db.Exec(insertSQL, newUUID, paymentResponse.URL) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) return } // Формируем ответ клиенту в виде простого текста response := fmt.Sprintf("UUID: %s\nURL: %s", newUUID, paymentResponse.URL) // Set uuid cookie cookie = &http.Cookie{ Name: "uuid", Value: newUUID, Expires: time.Now().Add(30 * time.Minute), } http.SetCookie(w, cookie) // Отправляем ответ в виде простого текста w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) w.Write([]byte(response)) } func checkPayHandler(w http.ResponseWriter, r *http.Request) { // Извлекаем uuid из cookie cookie, err := r.Cookie("uuid") if err != nil { http.Error(w, "Не найден cookie с uuid", http.StatusBadRequest) return } uuid := cookie.Value if uuid == "" { http.Error(w, "Пустое значение uuid", http.StatusBadRequest) return } // Проверяем существование uuid в базе данных var exists bool querySQL := `SELECT EXISTS(SELECT 1 FROM pay_urls WHERE uuid = ?)` err = db.QueryRow(querySQL, uuid).Scan(&exists) if err != nil { http.Error(w, "Ошибка при проверке uuid в базе данных", http.StatusInternalServerError) return } if !exists { http.Error(w, "UUID не найден", http.StatusNotFound) return } // Создаем тело запроса для localhost:5000/check_pay checkRequest := struct { UUID string `json:"uuid"` }{ UUID: uuid, } requestBody, err := json.Marshal(checkRequest) if err != nil { http.Error(w, "Ошибка при создании запроса", http.StatusInternalServerError) return } // Отправляем POST-запрос на localhost:5000/check_pay resp, err := http.Post("http://localhost:5000/check_pay", "application/json", bytes.NewBuffer(requestBody)) if err != nil { http.Error(w, "Ошибка при отправке запроса на сервер", http.StatusInternalServerError) return } defer resp.Body.Close() // Читаем ответ от сервера var checkResponse struct { Mes string `json:"mes"` } if err := json.NewDecoder(resp.Body).Decode(&checkResponse); err != nil { http.Error(w, "Ошибка при чтении ответа от сервера", http.StatusInternalServerError) return } // Формируем ответ клиенту в зависимости от полученного результата var response string if checkResponse.Mes == "OK" { response = "OK" } else { response = "GTHO" } // Отправляем ответ в виде простого текста w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) w.Write([]byte(response)) } type CartItem struct { ID int `json:"id"` Title string `json:"title"` Price float64 `json:"price"` Quantity int `json:"quantity"` } type Cart struct { CartItems []CartItem `json:"cart_items"` } func add_to_cart(w http.ResponseWriter, r *http.Request) { cartCookie, err := r.Cookie("cart") if err != nil { http.Error(w, "Cart cookie not found", http.StatusBadRequest) return } fmt.Print("cartCookie.Value: ", cartCookie.Value) var cart Cart // Разбираем JSON err = json.Unmarshal([]byte(cartCookie.Value), &cart) if err != nil { fmt.Println("Ошибка при разборе JSON:", err) return } del_cookie, err := r.Cookie("uuid") if err != nil { http.Error(w, "Не найден cookie с uuid", http.StatusBadRequest) return } total_cookie, err := r.Cookie("total_price") if err != nil { http.Error(w, "Не найден cookie с total_price", http.StatusBadRequest) return } total_price := total_cookie.Value order_id := del_cookie.Value insertSql := `INSERT INTO order_list VALUES (?, ?, ?)` _, err = db.Exec(insertSql, order_id, total_price, time.Now().Format("2006-01-02 15:04:05")) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) return } for _, item := range cart.CartItems { insertSQL := `INSERT INTO order_lines VALUES (?, ?, ?, ?, ?)` _, err = db.Exec(insertSQL, order_id, item.ID, item.Title, item.Price, item.Quantity) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) return } } // insertSQL := `DELETE FROM url_pays WHERE uuid = ?` // _, err = db.Exec(insertSQL, del_cookie.Value) // if err != nil { // http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) // return // } // // Clear uuid cookie // del_cookie = &http.Cookie{ // Name: "uuid", // Value: "", // MaxAge: -1, // } // http.SetCookie(w, del_cookie) // Send success response w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) } func main() { initDB() defer db.Close() // Setup CORS cors := handlers.CORS( handlers.AllowedOrigins([]string{"*"}), handlers.AllowedMethods([]string{"GET", "POST"}), handlers.AllowedHeaders([]string{"Content-Type"}), ) // Register handlers http.HandleFunc("/api/pay", payHandler) http.HandleFunc("/api/check_pay", checkPayHandler) http.HandleFunc("/api/add_to_cart", add_to_cart) // Start server with CORS middleware port := os.Getenv("PORT") if port == "" { port = "8081" } fmt.Println("Go-сервер запущен на порту", port) log.Fatal(http.ListenAndServe(":"+port, cors(http.DefaultServeMux))) }