update orderflow
This commit is contained in:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user