diff --git a/cmd/checkout/adyen-handlers.go b/cmd/checkout/adyen-handlers.go index 787e44f..dc98c76 100644 --- a/cmd/checkout/adyen-handlers.go +++ b/cmd/checkout/adyen-handlers.go @@ -8,6 +8,7 @@ import ( "log" "net/http" "net/url" + "time" "git.k6n.net/go-cart-actor/pkg/actor" "git.k6n.net/go-cart-actor/pkg/cart" @@ -18,6 +19,8 @@ import ( "github.com/adyen/adyen-go-api-library/v21/src/hmacvalidator" "github.com/adyen/adyen-go-api-library/v21/src/webhook" "github.com/google/uuid" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/timestamppb" ) type SessionRequest struct { @@ -88,60 +91,109 @@ func (s *CheckoutPoolServer) AdyenHookHandler(w http.ResponseWriter, r *http.Req http.Error(w, "Invalid HMAC", http.StatusUnauthorized) return } else { + checkoutId, err := getCheckoutIdFromNotificationItem(item) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // Check if this checkout is owned by another host + if host, ok := s.OwnerHost(checkoutId); ok { + cartHostMap[host] = append(cartHostMap[host], notificationItem) + continue + } + + // Marshal item data for PaymentEvent + dataBytes, err := json.Marshal(item) + if err != nil { + log.Printf("error marshaling item: %v", err) + http.Error(w, "Error marshaling item", http.StatusInternalServerError) + return + } + switch item.EventCode { case "CAPTURE": log.Printf("Capture status: %v", item.Success) - // dataBytes, err := json.Marshal(item) - // if err != nil { - // log.Printf("error marshaling item: %v", err) - // http.Error(w, "Error marshaling item", http.StatusInternalServerError) - // return - // } - //s.ApplyAnywhere(r.Context(),0, &messages.PaymentEvent{PaymentId: item.PspReference, Success: item.Success, Name: item.EventCode, Data: &pbany.Any{Value: dataBytes}}) + isSuccess := item.Success == "true" + // Apply payment event for capture + if err := s.applyAnywhere(r.Context(), checkoutId, &messages.PaymentEvent{ + PaymentId: item.PspReference, + Success: isSuccess, + Name: item.EventCode, + Data: &anypb.Any{Value: dataBytes}, + }); err != nil { + log.Printf("error applying capture event: %v", err) + } + + // If successful, apply payment completed + if isSuccess { + if err := s.applyAnywhere(r.Context(), checkoutId, &messages.PaymentCompleted{ + PaymentId: item.PspReference, + Status: "captured", + Amount: item.Amount.Value, + Currency: item.Amount.Currency, + ProcessorReference: &item.PspReference, + CompletedAt: timestamppb.New(time.Now()), + }); err != nil { + log.Printf("error applying payment completed: %v", err) + } + } + case "AUTHORISATION": - - cartId, err := getCheckoutIdFromNotificationItem(item) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - //s.Apply() - - if host, ok := s.OwnerHost(uint64(cartId)); ok { - cartHostMap[host] = append(cartHostMap[host], notificationItem) - continue + isSuccess := item.Success == "true" + // Apply payment event for authorization + if err := s.applyAnywhere(r.Context(), checkoutId, &messages.PaymentEvent{ + PaymentId: item.PspReference, + Success: isSuccess, + Name: item.EventCode, + Data: &anypb.Any{Value: dataBytes}, + }); err != nil { + log.Printf("error applying authorization event: %v", err) } - grain, err := s.Get(r.Context(), uint64(cartId)) - if err != nil { - log.Printf("Error getting cart: %v", err) - http.Error(w, "Cart not found", http.StatusBadRequest) - return - } - meta := GetCheckoutMetaFromRequest(r) - pspReference := item.PspReference - uid := uuid.New().String() - ref := uuid.New().String() - req := service.ModificationsApi.CaptureAuthorisedPaymentInput(pspReference).IdempotencyKey(uid).PaymentCaptureRequest(adyenCheckout.PaymentCaptureRequest{ - Amount: adyenCheckout.Amount{ - Currency: meta.Currency, - Value: grain.CartTotalPrice.IncVat, - }, - MerchantAccount: "ElgigantenECOM", - Reference: &ref, - }) - res, _, err := service.ModificationsApi.CaptureAuthorisedPayment(r.Context(), req) - if err != nil { - log.Printf("Error capturing payment: %v", err) - } else { - log.Printf("Payment captured successfully: %+v", res) - s.Apply(r.Context(), uint64(cartId), &messages.OrderCreated{ - OrderId: res.PaymentPspReference, - Status: item.EventCode, + // If successful authorization, trigger capture + if isSuccess { + grain, err := s.Get(r.Context(), checkoutId) + if err != nil { + log.Printf("Error getting checkout: %v", err) + http.Error(w, "Checkout not found", http.StatusBadRequest) + return + } + meta := GetCheckoutMetaFromRequest(r) + pspReference := item.PspReference + uid := uuid.New().String() + ref := uuid.New().String() + req := service.ModificationsApi.CaptureAuthorisedPaymentInput(pspReference).IdempotencyKey(uid).PaymentCaptureRequest(adyenCheckout.PaymentCaptureRequest{ + Amount: adyenCheckout.Amount{ + Currency: meta.Currency, + Value: grain.CartTotalPrice.IncVat, + }, + MerchantAccount: "ElgigantenECOM", + Reference: &ref, }) + res, _, err := service.ModificationsApi.CaptureAuthorisedPayment(r.Context(), req) + if err != nil { + log.Printf("Error capturing payment: %v", err) + } else { + log.Printf("Payment captured successfully: %+v", res) + s.Apply(r.Context(), checkoutId, &messages.OrderCreated{ + OrderId: res.PaymentPspReference, + Status: item.EventCode, + }) + } } default: log.Printf("Unknown event code: %s", item.EventCode) + isSuccess := item.Success == "true" + // Apply generic payment event for other event codes + if err := s.applyAnywhere(r.Context(), checkoutId, &messages.PaymentEvent{ + PaymentId: item.PspReference, + Success: isSuccess, + Name: item.EventCode, + Data: &anypb.Any{Value: dataBytes}, + }); err != nil { + log.Printf("error applying payment event: %v", err) + } } } }