2 Commits

Author SHA1 Message Date
e703b71d35 Merge branch 'main' of https://git.tornberg.me/mats/go-cart-actor
Some checks failed
Build and Publish / Metadata (push) Successful in 11s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 1m1s
Build and Publish / BuildAndDeployArm64 (push) Has been cancelled
2025-11-13 18:23:09 +01:00
5bd0bdb44c notification url 2025-11-13 18:14:43 +01:00
3 changed files with 52 additions and 11 deletions

View File

@@ -14,6 +14,7 @@ type CheckoutMeta struct {
Terms string
Checkout string
Confirmation string
Notification string
Validation string
Push string
Country string
@@ -107,6 +108,7 @@ func BuildCheckoutOrderPayload(grain *cart.CartGrain, meta *CheckoutMeta) ([]byt
Terms: meta.Terms,
Checkout: meta.Checkout,
Confirmation: meta.Confirmation,
Notification: meta.Notification,
Validation: meta.Validation,
Push: meta.Push,
},

View File

@@ -27,6 +27,18 @@ var tpl = `<!DOCTYPE html>
</html>
`
func (a *App) getGrainFromOrder(order *CheckoutOrder) (*cart.CartGrain, error) {
cartId, ok := cart.ParseCartId(order.MerchantReference1)
if !ok {
return nil, fmt.Errorf("invalid cart id in order reference: %s", order.MerchantReference1)
}
grain, err := a.pool.Get(uint64(cartId))
if err != nil {
return nil, fmt.Errorf("failed to get cart grain: %w", err)
}
return grain, nil
}
func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, inventoryService inventory.InventoryService) {
conn, err := amqp.Dial(amqpUrl)
if err != nil {
@@ -117,6 +129,38 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, tpl, order.HTMLSnippet)
})
mux.HandleFunc("/notification", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Klarna order notification, method: %s", r.Method)
logger.InfoContext(r.Context(), "Klarna order notification received", "method", 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 notification: %s", order.ID)
logger.InfoContext(r.Context(), "Klarna order notification received", "order_id", order.ID)
grain, err := a.getGrainFromOrder(order)
if err != nil {
logger.ErrorContext(r.Context(), "Unable to get grain from klarna order", "error", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
if inventoryService != nil {
inventoryRequests := getInventoryRequests(grain.Items)
err = inventoryService.ReserveInventory(inventoryRequests...)
if err != nil {
logger.WarnContext(r.Context(), "placeorder inventory reservation failed")
w.WriteHeader(http.StatusNotAcceptable)
return
}
}
w.WriteHeader(http.StatusOK)
})
mux.HandleFunc("POST /validate", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Klarna order validation, method: %s", r.Method)
if r.Method != "POST" {
@@ -128,24 +172,18 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento
if err != nil {
w.WriteHeader(http.StatusBadRequest)
}
log.Printf("Klarna order validation: %s, cart id: %s", order.ID, order.MerchantReference1)
cartId, ok := cart.ParseCartId(order.MerchantReference1)
if !ok {
log.Printf("Invalid cart id in order reference: %s", order.MerchantReference1)
w.WriteHeader(http.StatusBadRequest)
return
}
grain, err := a.pool.Get(uint64(cartId))
logger.InfoContext(r.Context(), "Klarna order validation received", "order_id", order.ID, "cart_id", order.MerchantReference1)
grain, err := a.getGrainFromOrder(order)
if err != nil {
logger.ErrorContext(r.Context(), "Unable to get grain from klarna order", "error", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
if inventoryService != nil {
inventoryRequests := getInventoryRequests(grain.Items)
err = inventoryService.ReserveInventory(inventoryRequests...)
_, err = inventoryService.ReservationCheck(inventoryRequests...)
if err != nil {
logger.WarnContext(r.Context(), "placeorder inventory reservation failed")
logger.WarnContext(r.Context(), "placeorder inventory check failed")
w.WriteHeader(http.StatusNotAcceptable)
return
}

View File

@@ -341,6 +341,7 @@ func (s *PoolServer) CreateOrUpdateCheckout(ctx context.Context, host string, id
Terms: fmt.Sprintf("https://%s/terms", host),
Checkout: fmt.Sprintf("https://%s/checkout?order_id={checkout.order.id}", host),
Confirmation: fmt.Sprintf("https://%s/confirmation/{checkout.order.id}", host),
Notification: "https://cart.tornberg.me/notification",
Validation: "https://cart.tornberg.me/validate",
Push: "https://cart.tornberg.me/push?order_id={checkout.order.id}",
Country: country,