diff --git a/cmd/checkout/klarna-handlers.go b/cmd/checkout/klarna-handlers.go index 42697d5..af98af9 100644 --- a/cmd/checkout/klarna-handlers.go +++ b/cmd/checkout/klarna-handlers.go @@ -26,54 +26,54 @@ import ( }) */ -func (s *CheckoutPoolServer) KlarnaHtmlCheckoutHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { +// func (s *CheckoutPoolServer) KlarnaHtmlCheckoutHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { - orderId := r.URL.Query().Get("order_id") - var order *CheckoutOrder - var err error - if orderId == "" { - order, err = s.CreateOrUpdateCheckout(r, checkoutId) - if err != nil { - logger.Error("unable to create klarna session", "error", err) - return err - } - // s.ApplyKlarnaPaymentStarted(r.Context(), order, checkoutId) +// orderId := r.URL.Query().Get("order_id") +// var order *CheckoutOrder +// var err error +// if orderId == "" { +// order, err = s.CreateOrUpdateCheckout(r, checkoutId) +// if err != nil { +// logger.Error("unable to create klarna session", "error", err) +// return err +// } +// // s.ApplyKlarnaPaymentStarted(r.Context(), order, checkoutId) - } - order, err = s.klarnaClient.GetOrder(r.Context(), orderId) - if err != nil { - return err - } - 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 +// } +// order, err = s.klarnaClient.GetOrder(r.Context(), orderId) +// if err != nil { +// return err +// } +// 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 -} +// } -func (s *CheckoutPoolServer) KlarnaSessionHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { +// func (s *CheckoutPoolServer) KlarnaSessionHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { - orderId := r.URL.Query().Get("order_id") - var order *CheckoutOrder - var err error - if orderId == "" { - order, err = s.CreateOrUpdateCheckout(r, checkoutId) - if err != nil { - logger.Error("unable to create klarna session", "error", err) - return err - } - // s.ApplyKlarnaPaymentStarted(r.Context(), order, checkoutId) +// orderId := r.URL.Query().Get("order_id") +// var order *CheckoutOrder +// var err error +// if orderId == "" { +// order, err = s.CreateOrUpdateCheckout(r, checkoutId) +// if err != nil { +// logger.Error("unable to create klarna session", "error", err) +// return err +// } +// // s.ApplyKlarnaPaymentStarted(r.Context(), order, checkoutId) - } - order, err = s.klarnaClient.GetOrder(r.Context(), orderId) - if err != nil { - return err - } - w.Header().Set("Content-Type", "application/json; charset=utf-8") - return json.NewEncoder(w).Encode(order) +// } +// order, err = s.klarnaClient.GetOrder(r.Context(), orderId) +// if err != nil { +// return err +// } +// w.Header().Set("Content-Type", "application/json; charset=utf-8") +// return json.NewEncoder(w).Encode(order) -} +// } func (s *CheckoutPoolServer) KlarnaConfirmationHandler(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/checkout/pool-server.go b/cmd/checkout/pool-server.go index 4862578..c2c9c34 100644 --- a/cmd/checkout/pool-server.go +++ b/cmd/checkout/pool-server.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "log" "net/http" "os" @@ -263,26 +264,30 @@ func (s *CheckoutPoolServer) WriteResult(w http.ResponseWriter, result any) erro return err } -func (s *CheckoutPoolServer) CreateOrUpdateCheckout(r *http.Request, id checkout.CheckoutId) (*CheckoutOrder, error) { +func (s *CheckoutPoolServer) CreateOrUpdateCheckout(r *http.Request, grain *checkout.CheckoutGrain, orderId *string) (*CheckoutOrder, error) { // Get cart state from cart service - cartGrain, err := s.Get(r.Context(), uint64(id)) - if err != nil { - return nil, err - } + // cartGrain, err := s.Get(r.Context(), uint64(id)) + // if err != nil { + // return nil, err + // } meta := GetCheckoutMetaFromRequest(r) - payload, _, err := BuildCheckoutOrderPayload(cartGrain, meta) + payload, _, err := BuildCheckoutOrderPayload(grain, meta) if err != nil { return nil, err } - grain, err := s.Get(r.Context(), uint64(id)) - if err != nil { - return nil, err + // grain, err := s.Get(r.Context(), uint64(id)) + // if err != nil { + // return nil, err + // } + var payment *checkout.Payment + if orderId != nil { + payment, _ = grain.FindPayment(*orderId) } - if grain.OrderId != nil { + if payment != nil && payment.PaymentId != "" { return s.klarnaClient.UpdateOrder(r.Context(), *grain.OrderId, bytes.NewReader(payload)) } else { return s.klarnaClient.CreateOrder(r.Context(), bytes.NewReader(payload)) @@ -363,6 +368,70 @@ func (s *CheckoutPoolServer) getAnywhere(ctx context.Context, id uint64) (*check return ret, nil } +type StartPayment struct { + Provider string `json:"provider"` + Method string `json:"method,omitempty"` +} + +func (s *CheckoutPoolServer) GetPaymentSessionHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { + paymentId := r.PathValue("id") + grain, err := s.Get(r.Context(), uint64(checkoutId)) + if err != nil { + return err + } + payment, ok := grain.FindPayment(paymentId) + if !ok { + http.Error(w, "payment not found", http.StatusNotFound) + return nil + } + switch payment.Provider { + case "adyen": + return errors.New("not implemented") + case "klarna": + order, err := s.CreateOrUpdateCheckout(r, grain, &payment.PaymentId) + if err != nil { + return err + } + return s.WriteResult(w, order) + } + + return errors.New("unsupported payment provider") +} + +func (s *CheckoutPoolServer) StartPaymentHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error { + grain, err := s.Get(r.Context(), uint64(checkoutId)) + if err != nil { + return err + } + payload := &StartPayment{} + if err := json.NewDecoder(r.Body).Decode(payload); err != nil { + return err + } + switch payload.Provider { + case "adyen": + return errors.New("adyen not implemented yet") + case "klarna": + order, err := s.CreateOrUpdateCheckout(r, grain, nil) + if err != nil { + logger.Error("unable to create klarna session", "error", err) + return err + } + res, err := s.ApplyLocal(r.Context(), checkoutId, &messages.PaymentStarted{ + PaymentId: order.ID, + Amount: int64(order.OrderAmount), + Currency: order.PurchaseCurrency, + Provider: "klarna", + Method: &payload.Method, + StartedAt: timestamppb.New(time.Now()), + }) + return s.WriteResult(w, res) + + default: + http.Error(w, "unsupported payment provider", http.StatusBadRequest) + return nil + } +} + func (s *CheckoutPoolServer) Serve(mux *http.ServeMux) { handleFunc := func(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) { attr := attribute.String("http.route", pattern) @@ -399,13 +468,15 @@ func (s *CheckoutPoolServer) Serve(mux *http.ServeMux) { handleFunc("POST /api/checkout/delivery", CookieCheckoutIdHandler(s.ProxyHandler(s.SetDeliveryHandler))) handleFunc("DELETE /api/checkout/delivery/{id}", CookieCheckoutIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler))) handleFunc("POST /api/checkout/pickup-point", CookieCheckoutIdHandler(s.ProxyHandler(s.SetPickupPointHandler))) + handleFunc("POST /payment", CookieCheckoutIdHandler(s.ProxyHandler(s.StartPaymentHandler))) + handleFunc("GET /payment/{id}/session", CookieCheckoutIdHandler(s.ProxyHandler(s.GetPaymentSessionHandler))) // handleFunc("POST /api/checkout/initialize", CookieCheckoutIdHandler(s.ProxyHandler(s.InitializeCheckoutHandler))) // handleFunc("POST /api/checkout/inventory-reserved", CookieCheckoutIdHandler(s.ProxyHandler(s.InventoryReservedHandler))) // handleFunc("POST /api/checkout/order-created", CookieCheckoutIdHandler(s.ProxyHandler(s.OrderCreatedHandler))) // handleFunc("POST /api/checkout/confirmation-viewed", CookieCheckoutIdHandler(s.ProxyHandler(s.ConfirmationViewedHandler))) - handleFunc("GET /payment/klarna/session", CookieCheckoutIdHandler(s.ProxyHandler(s.KlarnaSessionHandler))) - handleFunc("GET /payment/klarna/checkout", CookieCheckoutIdHandler(s.ProxyHandler(s.KlarnaHtmlCheckoutHandler))) + //handleFunc("GET /payment/klarna/session", CookieCheckoutIdHandler(s.ProxyHandler(s.KlarnaSessionHandler))) + //handleFunc("GET /payment/klarna/checkout", CookieCheckoutIdHandler(s.ProxyHandler(s.KlarnaHtmlCheckoutHandler))) handleFunc("GET /payment/klarna/confirmation/{order_id}", s.KlarnaConfirmationHandler)