Complete refactor to new grpc control plane and only http proxy for carts (#4)
Co-authored-by: matst80 <mats.tornberg@gmail.com> Reviewed-on: https://git.tornberg.me/mats/go-cart-actor/pulls/4 Co-authored-by: Mats Törnberg <mats@tornberg.me> Co-committed-by: Mats Törnberg <mats@tornberg.me>
This commit was merged in pull request #4.
This commit is contained in:
119
cmd/cart/checkout_builder.go
Normal file
119
cmd/cart/checkout_builder.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// CheckoutMeta carries the external / URL metadata required to build a
|
||||
// Klarna CheckoutOrder from a CartGrain snapshot. It deliberately excludes
|
||||
// any Klarna-specific response fields (HTML snippet, client token, etc.).
|
||||
type CheckoutMeta struct {
|
||||
Terms string
|
||||
Checkout string
|
||||
Confirmation string
|
||||
Validation string
|
||||
Push string
|
||||
Country string
|
||||
Currency string // optional override (defaults to "SEK" if empty)
|
||||
Locale string // optional override (defaults to "sv-se" if empty)
|
||||
}
|
||||
|
||||
// BuildCheckoutOrderPayload converts the current cart grain + meta information
|
||||
// into a CheckoutOrder domain struct and returns its JSON-serialized payload
|
||||
// (to send to Klarna) alongside the structured CheckoutOrder object.
|
||||
//
|
||||
// This function is PURE: it does not perform any network I/O or mutate the
|
||||
// grain. The caller is responsible for:
|
||||
//
|
||||
// 1. Choosing whether to create or update the Klarna order.
|
||||
// 2. Invoking KlarnaClient.CreateOrder / UpdateOrder with the returned payload.
|
||||
// 3. Applying an InitializeCheckout mutation (or equivalent) with the
|
||||
// resulting Klarna order id + status.
|
||||
//
|
||||
// If you later need to support different tax rates per line, you can extend
|
||||
// CartItem / Delivery to expose that data and propagate it here.
|
||||
func BuildCheckoutOrderPayload(grain *CartGrain, meta *CheckoutMeta) ([]byte, *CheckoutOrder, error) {
|
||||
if grain == nil {
|
||||
return nil, nil, fmt.Errorf("nil grain")
|
||||
}
|
||||
if meta == nil {
|
||||
return nil, nil, fmt.Errorf("nil checkout meta")
|
||||
}
|
||||
|
||||
currency := meta.Currency
|
||||
if currency == "" {
|
||||
currency = "SEK"
|
||||
}
|
||||
locale := meta.Locale
|
||||
if locale == "" {
|
||||
locale = "sv-se"
|
||||
}
|
||||
country := meta.Country
|
||||
if country == "" {
|
||||
country = "SE" // sensible default; adjust if multi-country support changes
|
||||
}
|
||||
|
||||
lines := make([]*Line, 0, len(grain.Items)+len(grain.Deliveries))
|
||||
|
||||
// Item lines
|
||||
for _, it := range grain.Items {
|
||||
if it == nil {
|
||||
continue
|
||||
}
|
||||
lines = append(lines, &Line{
|
||||
Type: "physical",
|
||||
Reference: it.Sku,
|
||||
Name: it.Meta.Name,
|
||||
Quantity: it.Quantity,
|
||||
UnitPrice: int(it.Price.IncVat),
|
||||
TaxRate: 2500, // TODO: derive if variable tax rates are introduced
|
||||
QuantityUnit: "st",
|
||||
TotalAmount: int(it.TotalPrice.IncVat),
|
||||
TotalTaxAmount: int(it.TotalPrice.TotalVat()),
|
||||
ImageURL: fmt.Sprintf("https://www.elgiganten.se%s", it.Meta.Image),
|
||||
})
|
||||
}
|
||||
|
||||
// Delivery lines
|
||||
for _, d := range grain.Deliveries {
|
||||
if d == nil || d.Price.IncVat <= 0 {
|
||||
continue
|
||||
}
|
||||
lines = append(lines, &Line{
|
||||
Type: "shipping_fee",
|
||||
Reference: d.Provider,
|
||||
Name: "Delivery",
|
||||
Quantity: 1,
|
||||
UnitPrice: int(d.Price.IncVat),
|
||||
TaxRate: 2500,
|
||||
QuantityUnit: "st",
|
||||
TotalAmount: int(d.Price.IncVat),
|
||||
TotalTaxAmount: int(d.Price.TotalVat()),
|
||||
})
|
||||
}
|
||||
|
||||
order := &CheckoutOrder{
|
||||
PurchaseCountry: country,
|
||||
PurchaseCurrency: currency,
|
||||
Locale: locale,
|
||||
OrderAmount: int(grain.TotalPrice.IncVat),
|
||||
OrderTaxAmount: int(grain.TotalPrice.TotalVat()),
|
||||
OrderLines: lines,
|
||||
MerchantReference1: grain.Id.String(),
|
||||
MerchantURLS: &CheckoutMerchantURLS{
|
||||
Terms: meta.Terms,
|
||||
Checkout: meta.Checkout,
|
||||
Confirmation: meta.Confirmation,
|
||||
Validation: meta.Validation,
|
||||
Push: meta.Push,
|
||||
},
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(order)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("marshal checkout order: %w", err)
|
||||
}
|
||||
|
||||
return payload, order, nil
|
||||
}
|
||||
Reference in New Issue
Block a user