update orderflow
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled

This commit is contained in:
2026-06-21 23:26:37 +02:00
parent 1a365de071
commit 716a66562e
10 changed files with 651 additions and 29 deletions
+86 -12
View File
@@ -205,19 +205,24 @@ func (s *CheckoutPoolServer) KlarnaPushHandler(w http.ResponseWriter, r *http.Re
CompletedAt: timestamppb.Now(),
})
// err = confirmOrder(r.Context(), order, orderHandler)
// if err != nil {
// log.Printf("Error confirming order: %v\n", err)
// w.WriteHeader(http.StatusInternalServerError)
// return
// }
// ── Create the event-sourced order grain (dual-write with AMQP) ────
if s.orderClient != nil {
if _, orderErr := createOrderFromCheckout(r.Context(), s, grain, order, "klarna"); orderErr != nil {
// Non-fatal: the checkout grain is updated, the order can be
// created on retry (idempotency key guards against duplicates).
logger.WarnContext(r.Context(), "from-checkout failed; will retry on next push",
"err", orderErr, "checkoutId", grain.Id.String())
}
}
// ── Dual-write: AMQP order-queue for legacy consumers ───────────────
if s.orderHandler != nil {
legacyBody, _ := buildLegacyOrderJSON(grain, order, "klarna", orderId)
if pubErr := s.orderHandler.OrderCompleted(legacyBody); pubErr != nil {
logger.WarnContext(r.Context(), "order-queue publish failed", "err", pubErr)
}
}
// err = triggerOrderCompleted(r.Context(), a.server, order)
// if err != nil {
// log.Printf("Error processing cart message: %v\n", err)
// w.WriteHeader(http.StatusInternalServerError)
// return
// }
err = s.klarnaClient.AcknowledgeOrder(r.Context(), orderId)
if err != nil {
log.Printf("Error acknowledging order: %v\n", err)
@@ -240,6 +245,75 @@ var tpl = `<!DOCTYPE html>
</html>
`
// createOrderFromCheckout builds and sends the from-checkout request to the
// order service, creating an event-sourced order grain from the settled checkout.
// The idempotency key is "checkout-{checkoutId}" so that retries (Klarna may
// push the same order multiple times) are safe.
func createOrderFromCheckout(ctx context.Context, s *CheckoutPoolServer, grain *checkout.CheckoutGrain, klarnaOrder *CheckoutOrder, provider string) (*CreateOrderResult, error) {
return createOrderFromSettledCheckout(ctx, s, grain, settledPayment{
Provider: provider,
Reference: klarnaOrder.ID,
Amount: int64(klarnaOrder.OrderAmount),
Currency: klarnaOrder.PurchaseCurrency,
Country: klarnaOrder.PurchaseCountry,
Locale: klarnaOrder.Locale,
})
}
// buildLegacyOrderJSON builds the go-order-manager compatible JSON for AMQP
// dual-write, so existing downstream consumers on the order-queue still receive
// order events during the migration period.
func buildLegacyOrderJSON(grain *checkout.CheckoutGrain, klarnaOrder *CheckoutOrder, provider string, orderId string) ([]byte, error) {
if grain.CartState == nil {
return nil, fmt.Errorf("buildLegacyOrderJSON: checkout %s has no cart state", grain.Id)
}
type legacyLine struct {
Reference string `json:"reference"`
Name string `json:"name"`
Quantity int `json:"quantity"`
UnitPrice int `json:"unit_price"`
TaxRate int `json:"tax_rate"`
TotalAmount int `json:"total_amount"`
TotalTaxAmount int `json:"total_tax_amount"`
}
type legacyOrder struct {
ID string `json:"order_id"`
PurchaseCountry string `json:"purchase_country"`
PurchaseCurrency string `json:"purchase_currency"`
Locale string `json:"locale"`
OrderAmount int `json:"order_amount"`
OrderTaxAmount int `json:"order_tax_amount"`
OrderLines []legacyLine `json:"order_lines"`
}
lines := make([]legacyLine, 0, len(grain.CartState.Items)+len(grain.Deliveries))
for _, it := range grain.CartState.Items {
if it == nil {
continue
}
lines = append(lines, legacyLine{
Reference: it.Sku,
Name: it.Meta.Name,
Quantity: int(it.Quantity),
UnitPrice: int(it.Price.IncVat),
TaxRate: it.Tax,
TotalAmount: int(it.TotalPrice.IncVat),
TotalTaxAmount: int(it.TotalPrice.TotalVat()),
})
}
lo := legacyOrder{
ID: orderId,
PurchaseCountry: klarnaOrder.PurchaseCountry,
PurchaseCurrency: klarnaOrder.PurchaseCurrency,
Locale: klarnaOrder.Locale,
OrderAmount: klarnaOrder.OrderAmount,
OrderTaxAmount: klarnaOrder.OrderTaxAmount,
OrderLines: lines,
}
return json.Marshal(lo)
}
func getLocationId(item *cart.CartItem) inventory.LocationID {
if item.StoreId == nil || *item.StoreId == "" {
return "se"