package main import ( "encoding/json" "fmt" "log" "net/http" "time" "git.tornberg.me/go-cart-actor/pkg/actor" "git.tornberg.me/go-cart-actor/pkg/cart" amqp "github.com/rabbitmq/amqp091-go" ) func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux) { conn, err := amqp.Dial(amqpUrl) if err != nil { log.Fatalf("failed to connect to RabbitMQ: %v", err) } amqpListener := actor.NewAmqpListener(conn, func(id uint64, msg []actor.ApplyResult) (any, error) { return &CartChangeEvent{ CartId: cart.CartId(id), Mutations: msg, }, nil }) amqpListener.DefineTopics() a.pool.AddListener(amqpListener) orderHandler := NewAmqpOrderHandler(conn) orderHandler.DefineTopics() mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } orderId := r.URL.Query().Get("order_id") log.Printf("Order confirmation push: %s", orderId) order, err := a.klarnaClient.GetOrder(orderId) if err != nil { log.Printf("Error creating request: %v\n", err) w.WriteHeader(http.StatusInternalServerError) return } err = confirmOrder(order, orderHandler) if err != nil { log.Printf("Error confirming order: %v\n", err) w.WriteHeader(http.StatusInternalServerError) return } err = triggerOrderCompleted(a.server, order) if err != nil { log.Printf("Error processing cart message: %v\n", err) w.WriteHeader(http.StatusInternalServerError) return } err = a.klarnaClient.AcknowledgeOrder(orderId) if err != nil { log.Printf("Error acknowledging order: %v\n", err) } w.WriteHeader(http.StatusOK) }) mux.HandleFunc("GET /checkout", a.server.CheckoutHandler(func(order *CheckoutOrder, w http.ResponseWriter) error { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Permissions-Policy", "payment=(self \"https://js.stripe.com\" \"https://m.stripe.network\" \"https://js.playground.kustom.co\")") w.WriteHeader(http.StatusOK) _, err := fmt.Fprintf(w, tpl, order.HTMLSnippet) return err })) mux.HandleFunc("GET /confirmation/{order_id}", func(w http.ResponseWriter, r *http.Request) { orderId := r.PathValue("order_id") order, err := a.klarnaClient.GetOrder(orderId) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") if order.Status == "checkout_complete" { http.SetCookie(w, &http.Cookie{ Name: "cartid", Value: "", Path: "/", Secure: true, HttpOnly: true, Expires: time.Unix(0, 0), SameSite: http.SameSiteLaxMode, }) } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, tpl, order.HTMLSnippet) }) mux.HandleFunc("POST /validate", func(w http.ResponseWriter, r *http.Request) { log.Printf("Klarna order validation, method: %s", r.Method) if r.Method != "POST" { w.WriteHeader(http.StatusMethodNotAllowed) return } order := &CheckoutOrder{} err := json.NewDecoder(r.Body).Decode(order) if err != nil { w.WriteHeader(http.StatusBadRequest) } log.Printf("Klarna order validation: %s", order.ID) w.WriteHeader(http.StatusOK) }) }