update orderflow
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -124,6 +125,14 @@ func (s *CheckoutPoolServer) AdyenHookHandler(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
//}
|
||||
|
||||
// CAPTURE is the moment the Adyen payment is fully settled — the
|
||||
// Adyen analogue of the Klarna push. Create the event-sourced
|
||||
// order now (mirrors KlarnaPushHandler). Idempotent on
|
||||
// "checkout-{checkoutId}", so a retried CAPTURE won't duplicate.
|
||||
if isSuccess && s.orderClient != nil {
|
||||
s.createAdyenOrder(r.Context(), *checkoutId, item)
|
||||
}
|
||||
|
||||
case "AUTHORISATION":
|
||||
|
||||
isSuccess := item.Success == "true"
|
||||
@@ -176,11 +185,11 @@ func (s *CheckoutPoolServer) AdyenHookHandler(w http.ResponseWriter, r *http.Req
|
||||
if err != nil {
|
||||
log.Printf("Error capturing payment: %v", err)
|
||||
} else {
|
||||
log.Printf("Payment captured successfully: %+v", res)
|
||||
s.ApplyAnywhere(r.Context(), *checkoutId, &messages.OrderCreated{
|
||||
OrderId: res.PaymentPspReference,
|
||||
Status: item.EventCode,
|
||||
})
|
||||
// Capture requested. The order is NOT created here — we
|
||||
// only have a PSP reference, not an order. Adyen sends a
|
||||
// CAPTURE notification once the capture settles, and the
|
||||
// CAPTURE branch above creates the event-sourced order.
|
||||
log.Printf("Payment capture requested successfully: %+v", res)
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -209,6 +218,45 @@ func (s *CheckoutPoolServer) AdyenHookHandler(w http.ResponseWriter, r *http.Req
|
||||
|
||||
}
|
||||
|
||||
// createAdyenOrder turns a settled (captured) Adyen payment into an
|
||||
// event-sourced order, mirroring KlarnaPushHandler. The Adyen webhook carries
|
||||
// the charged amount + currency but not the shopper's country/locale, so those
|
||||
// are derived from the currency. Failures are logged and left for the next
|
||||
// CAPTURE notification to retry — the from-checkout endpoint is idempotent on
|
||||
// "checkout-{checkoutId}".
|
||||
func (s *CheckoutPoolServer) createAdyenOrder(ctx context.Context, checkoutId cart.CartId, item webhook.NotificationRequestItem) {
|
||||
grain, err := s.GetAnywhere(ctx, checkoutId)
|
||||
if err != nil {
|
||||
log.Printf("from-checkout: could not load checkout grain %s: %v", checkoutId.String(), err)
|
||||
return
|
||||
}
|
||||
|
||||
// Reserve inventory once, guarded by the grain flag so a retried CAPTURE
|
||||
// does not decrement stock twice. (Same as the Klarna path.)
|
||||
if s.inventoryService != nil && grain.CartState != nil && !grain.InventoryReserved {
|
||||
if rerr := s.inventoryService.ReserveInventory(ctx, getInventoryRequests(grain.CartState.Items)...); rerr != nil {
|
||||
log.Printf("from-checkout: inventory reservation failed for %s: %v", checkoutId.String(), rerr)
|
||||
} else {
|
||||
s.Apply(ctx, uint64(grain.Id), &messages.InventoryReserved{
|
||||
Id: grain.Id.String(),
|
||||
Status: "success",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
country := getCountryFromCurrency(item.Amount.Currency)
|
||||
if _, oerr := createOrderFromSettledCheckout(ctx, s, grain, settledPayment{
|
||||
Provider: "adyen",
|
||||
Reference: item.PspReference,
|
||||
Amount: item.Amount.Value,
|
||||
Currency: item.Amount.Currency,
|
||||
Country: country,
|
||||
Locale: getLocale(country),
|
||||
}); oerr != nil {
|
||||
log.Printf("from-checkout failed for checkout %s; will retry on next CAPTURE: %v", checkoutId.String(), oerr)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CheckoutPoolServer) AdyenReturnHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("Redirect received")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user