add cancel
Some checks failed
Build and Publish / BuildAndDeployAmd64 (push) Successful in 45s
Build and Publish / BuildAndDeployArm64 (push) Has been cancelled

This commit is contained in:
matst80
2025-12-05 08:30:59 +01:00
parent b4ffb9da85
commit ea3eb2f0f3
7 changed files with 172 additions and 52 deletions

View File

@@ -195,6 +195,19 @@ func (s *CheckoutPoolServer) ContactDetailsUpdatedHandler(w http.ResponseWriter,
return s.WriteResult(w, result)
}
func (s *CheckoutPoolServer) CancelPaymentHandler(w http.ResponseWriter, r *http.Request, checkoutId checkout.CheckoutId) error {
paymentId := r.PathValue("id")
result, err := s.ApplyLocal(r.Context(), checkoutId, &messages.CancelPayment{
PaymentId: paymentId,
CancelledAt: timestamppb.New(time.Now()),
})
if err != nil {
return err
}
return s.WriteResult(w, result)
}
func (s *CheckoutPoolServer) StartCheckoutHandler(w http.ResponseWriter, r *http.Request) {
cartIdStr := r.PathValue("cartid")
if cartIdStr == "" {
@@ -530,6 +543,7 @@ func (s *CheckoutPoolServer) Serve(mux *http.ServeMux) {
handleFunc("POST /api/checkout/contact-details", CookieCheckoutIdHandler(s.ProxyHandler(s.ContactDetailsUpdatedHandler)))
handleFunc("POST /payment", CookieCheckoutIdHandler(s.ProxyHandler(s.StartPaymentHandler)))
handleFunc("POST /payment/{id}/session", CookieCheckoutIdHandler(s.ProxyHandler(s.GetPaymentSessionHandler)))
handleFunc("DELETE /payment/{id}", CookieCheckoutIdHandler(s.ProxyHandler(s.CancelPaymentHandler)))
// handleFunc("POST /api/checkout/initialize", CookieCheckoutIdHandler(s.ProxyHandler(s.InitializeCheckoutHandler)))
// handleFunc("POST /api/checkout/inventory-reserved", CookieCheckoutIdHandler(s.ProxyHandler(s.InventoryReservedHandler)))
// handleFunc("POST /api/checkout/order-created", CookieCheckoutIdHandler(s.ProxyHandler(s.OrderCreatedHandler)))

View File

@@ -27,6 +27,7 @@ func NewCheckoutMutationRegistry(ctx *CheckoutMutationContext) actor.MutationReg
actor.NewMutation(HandleSetPickupPoint),
actor.NewMutation(HandleRemoveDelivery),
actor.NewMutation(HandleContactDetailsUpdated),
actor.NewMutation(HandlePaymentCancelled),
)
return reg
}

View File

@@ -0,0 +1,30 @@
package checkout
import (
"errors"
"slices"
messages "git.k6n.net/go-cart-actor/proto/checkout"
)
func HandlePaymentCancelled(g *CheckoutGrain, m *messages.PaymentDeclined) error {
payment, found := g.FindPayment(m.PaymentId)
if !found {
return ErrPaymentNotFound
}
if payment.CompletedAt != nil {
return errors.New("payment already completed")
}
g.PaymentInProgress--
g.AmountInCentsStarted -= payment.Amount
g.Payments = removePayment(g.Payments, payment.PaymentId)
return nil
}
func removePayment(payment []*Payment, s string) []*Payment {
return slices.DeleteFunc(payment, func(p *Payment) bool {
return p.PaymentId == s
})
}

View File

@@ -11,13 +11,21 @@ func asPickupPoint(p *messages.PickupPoint, deliveryId uint32) *PickupPoint {
if p == nil {
return nil
}
if p.Address == nil {
return &PickupPoint{
Id: p.Id,
Name: p.Name,
DeliveryId: deliveryId,
}
}
return &PickupPoint{
Id: p.Id,
Name: p.Name,
Address: p.Address,
City: p.City,
Country: p.Country,
Zip: p.Zip,
DeliveryId: deliveryId,
Id: p.Id,
Name: p.Name,
Address: &p.Address.AddressLine1,
City: &p.Address.City,
Zip: &p.Address.Zip,
Country: &p.Address.Country,
}
}

View File

@@ -36,14 +36,7 @@ func HandleSetPickupPoint(g *CheckoutGrain, m *messages.SetPickupPoint) error {
for _, d := range g.Deliveries {
if d.Id == uint32(m.DeliveryId) {
d.PickupPoint = &PickupPoint{
Id: m.PickupPoint.Id,
Name: m.PickupPoint.Name,
Address: m.PickupPoint.Address,
City: m.PickupPoint.City,
Zip: m.PickupPoint.Zip,
Country: m.PickupPoint.Country,
}
d.PickupPoint = asPickupPoint(m.PickupPoint, d.Id)
return nil
}
}

View File

@@ -95,6 +95,12 @@ message ContactDetailsUpdated {
optional string name = 3;
}
message CancelPayment {
string paymentId = 1;
optional string reason = 2;
google.protobuf.Timestamp cancelledAt = 3;
}
message InventoryReserved {
string id = 1;
string status = 2;

View File

@@ -915,6 +915,66 @@ func (x *ContactDetailsUpdated) GetName() string {
return ""
}
type CancelPayment struct {
state protoimpl.MessageState `protogen:"open.v1"`
PaymentId string `protobuf:"bytes,1,opt,name=paymentId,proto3" json:"paymentId,omitempty"`
Reason *string `protobuf:"bytes,2,opt,name=reason,proto3,oneof" json:"reason,omitempty"`
CancelledAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=cancelledAt,proto3" json:"cancelledAt,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *CancelPayment) Reset() {
*x = CancelPayment{}
mi := &file_checkout_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *CancelPayment) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CancelPayment) ProtoMessage() {}
func (x *CancelPayment) ProtoReflect() protoreflect.Message {
mi := &file_checkout_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CancelPayment.ProtoReflect.Descriptor instead.
func (*CancelPayment) Descriptor() ([]byte, []int) {
return file_checkout_proto_rawDescGZIP(), []int{13}
}
func (x *CancelPayment) GetPaymentId() string {
if x != nil {
return x.PaymentId
}
return ""
}
func (x *CancelPayment) GetReason() string {
if x != nil && x.Reason != nil {
return *x.Reason
}
return ""
}
func (x *CancelPayment) GetCancelledAt() *timestamppb.Timestamp {
if x != nil {
return x.CancelledAt
}
return nil
}
type InventoryReserved struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
@@ -926,7 +986,7 @@ type InventoryReserved struct {
func (x *InventoryReserved) Reset() {
*x = InventoryReserved{}
mi := &file_checkout_proto_msgTypes[13]
mi := &file_checkout_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -938,7 +998,7 @@ func (x *InventoryReserved) String() string {
func (*InventoryReserved) ProtoMessage() {}
func (x *InventoryReserved) ProtoReflect() protoreflect.Message {
mi := &file_checkout_proto_msgTypes[13]
mi := &file_checkout_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -951,7 +1011,7 @@ func (x *InventoryReserved) ProtoReflect() protoreflect.Message {
// Deprecated: Use InventoryReserved.ProtoReflect.Descriptor instead.
func (*InventoryReserved) Descriptor() ([]byte, []int) {
return file_checkout_proto_rawDescGZIP(), []int{13}
return file_checkout_proto_rawDescGZIP(), []int{14}
}
func (x *InventoryReserved) GetId() string {
@@ -998,7 +1058,7 @@ type Mutation struct {
func (x *Mutation) Reset() {
*x = Mutation{}
mi := &file_checkout_proto_msgTypes[14]
mi := &file_checkout_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1010,7 +1070,7 @@ func (x *Mutation) String() string {
func (*Mutation) ProtoMessage() {}
func (x *Mutation) ProtoReflect() protoreflect.Message {
mi := &file_checkout_proto_msgTypes[14]
mi := &file_checkout_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1023,7 +1083,7 @@ func (x *Mutation) ProtoReflect() protoreflect.Message {
// Deprecated: Use Mutation.ProtoReflect.Descriptor instead.
func (*Mutation) Descriptor() ([]byte, []int) {
return file_checkout_proto_rawDescGZIP(), []int{14}
return file_checkout_proto_rawDescGZIP(), []int{15}
}
func (x *Mutation) GetType() isMutation_Type {
@@ -1311,7 +1371,12 @@ const file_checkout_proto_rawDesc = "" +
"\x06_emailB\r\n" +
"\v_postalCodeB\b\n" +
"\x06_phoneB\a\n" +
"\x05_name\"f\n" +
"\x05_name\"\x93\x01\n" +
"\rCancelPayment\x12\x1c\n" +
"\tpaymentId\x18\x01 \x01(\tR\tpaymentId\x12\x1b\n" +
"\x06reason\x18\x02 \x01(\tH\x00R\x06reason\x88\x01\x01\x12<\n" +
"\vcancelledAt\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\vcancelledAtB\t\n" +
"\a_reason\"f\n" +
"\x11InventoryReserved\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
"\x06status\x18\x02 \x01(\tR\x06status\x12\x1d\n" +
@@ -1346,7 +1411,7 @@ func file_checkout_proto_rawDescGZIP() []byte {
return file_checkout_proto_rawDescData
}
var file_checkout_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_checkout_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
var file_checkout_proto_goTypes = []any{
(*SetDelivery)(nil), // 0: checkout_messages.SetDelivery
(*Address)(nil), // 1: checkout_messages.Address
@@ -1361,40 +1426,42 @@ var file_checkout_proto_goTypes = []any{
(*OrderCreated)(nil), // 10: checkout_messages.OrderCreated
(*InitializeCheckout)(nil), // 11: checkout_messages.InitializeCheckout
(*ContactDetailsUpdated)(nil), // 12: checkout_messages.ContactDetailsUpdated
(*InventoryReserved)(nil), // 13: checkout_messages.InventoryReserved
(*Mutation)(nil), // 14: checkout_messages.Mutation
(*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
(*anypb.Any)(nil), // 16: google.protobuf.Any
(*CancelPayment)(nil), // 13: checkout_messages.CancelPayment
(*InventoryReserved)(nil), // 14: checkout_messages.InventoryReserved
(*Mutation)(nil), // 15: checkout_messages.Mutation
(*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp
(*anypb.Any)(nil), // 17: google.protobuf.Any
}
var file_checkout_proto_depIdxs = []int32{
3, // 0: checkout_messages.SetDelivery.pickupPoint:type_name -> checkout_messages.PickupPoint
3, // 1: checkout_messages.SetPickupPoint.pickupPoint:type_name -> checkout_messages.PickupPoint
1, // 2: checkout_messages.PickupPoint.address:type_name -> checkout_messages.Address
1, // 3: checkout_messages.PaymentStarted.billingAddress:type_name -> checkout_messages.Address
15, // 4: checkout_messages.PaymentStarted.startedAt:type_name -> google.protobuf.Timestamp
16, // 5: checkout_messages.PaymentStarted.sessionData:type_name -> google.protobuf.Any
15, // 6: checkout_messages.PaymentCompleted.completedAt:type_name -> google.protobuf.Timestamp
16, // 7: checkout_messages.PaymentEvent.data:type_name -> google.protobuf.Any
15, // 8: checkout_messages.ConfirmationViewed.viewedAt:type_name -> google.protobuf.Timestamp
15, // 9: checkout_messages.OrderCreated.createdAt:type_name -> google.protobuf.Timestamp
16, // 10: checkout_messages.InitializeCheckout.cartState:type_name -> google.protobuf.Any
0, // 11: checkout_messages.Mutation.set_delivery:type_name -> checkout_messages.SetDelivery
2, // 12: checkout_messages.Mutation.set_pickup_point:type_name -> checkout_messages.SetPickupPoint
4, // 13: checkout_messages.Mutation.remove_delivery:type_name -> checkout_messages.RemoveDelivery
7, // 14: checkout_messages.Mutation.payment_declined:type_name -> checkout_messages.PaymentDeclined
9, // 15: checkout_messages.Mutation.confirmation_viewed:type_name -> checkout_messages.ConfirmationViewed
12, // 16: checkout_messages.Mutation.contact_details_updated:type_name -> checkout_messages.ContactDetailsUpdated
10, // 17: checkout_messages.Mutation.order_created:type_name -> checkout_messages.OrderCreated
11, // 18: checkout_messages.Mutation.initialize_checkout:type_name -> checkout_messages.InitializeCheckout
13, // 19: checkout_messages.Mutation.inventory_reserved:type_name -> checkout_messages.InventoryReserved
5, // 20: checkout_messages.Mutation.payment_started:type_name -> checkout_messages.PaymentStarted
6, // 21: checkout_messages.Mutation.payment_completed:type_name -> checkout_messages.PaymentCompleted
8, // 22: checkout_messages.Mutation.payment_event:type_name -> checkout_messages.PaymentEvent
23, // [23:23] is the sub-list for method output_type
23, // [23:23] is the sub-list for method input_type
23, // [23:23] is the sub-list for extension type_name
23, // [23:23] is the sub-list for extension extendee
0, // [0:23] is the sub-list for field type_name
16, // 4: checkout_messages.PaymentStarted.startedAt:type_name -> google.protobuf.Timestamp
17, // 5: checkout_messages.PaymentStarted.sessionData:type_name -> google.protobuf.Any
16, // 6: checkout_messages.PaymentCompleted.completedAt:type_name -> google.protobuf.Timestamp
17, // 7: checkout_messages.PaymentEvent.data:type_name -> google.protobuf.Any
16, // 8: checkout_messages.ConfirmationViewed.viewedAt:type_name -> google.protobuf.Timestamp
16, // 9: checkout_messages.OrderCreated.createdAt:type_name -> google.protobuf.Timestamp
17, // 10: checkout_messages.InitializeCheckout.cartState:type_name -> google.protobuf.Any
16, // 11: checkout_messages.CancelPayment.cancelledAt:type_name -> google.protobuf.Timestamp
0, // 12: checkout_messages.Mutation.set_delivery:type_name -> checkout_messages.SetDelivery
2, // 13: checkout_messages.Mutation.set_pickup_point:type_name -> checkout_messages.SetPickupPoint
4, // 14: checkout_messages.Mutation.remove_delivery:type_name -> checkout_messages.RemoveDelivery
7, // 15: checkout_messages.Mutation.payment_declined:type_name -> checkout_messages.PaymentDeclined
9, // 16: checkout_messages.Mutation.confirmation_viewed:type_name -> checkout_messages.ConfirmationViewed
12, // 17: checkout_messages.Mutation.contact_details_updated:type_name -> checkout_messages.ContactDetailsUpdated
10, // 18: checkout_messages.Mutation.order_created:type_name -> checkout_messages.OrderCreated
11, // 19: checkout_messages.Mutation.initialize_checkout:type_name -> checkout_messages.InitializeCheckout
14, // 20: checkout_messages.Mutation.inventory_reserved:type_name -> checkout_messages.InventoryReserved
5, // 21: checkout_messages.Mutation.payment_started:type_name -> checkout_messages.PaymentStarted
6, // 22: checkout_messages.Mutation.payment_completed:type_name -> checkout_messages.PaymentCompleted
8, // 23: checkout_messages.Mutation.payment_event:type_name -> checkout_messages.PaymentEvent
24, // [24:24] is the sub-list for method output_type
24, // [24:24] is the sub-list for method input_type
24, // [24:24] is the sub-list for extension type_name
24, // [24:24] is the sub-list for extension extendee
0, // [0:24] is the sub-list for field type_name
}
func init() { file_checkout_proto_init() }
@@ -1410,7 +1477,8 @@ func file_checkout_proto_init() {
file_checkout_proto_msgTypes[7].OneofWrappers = []any{}
file_checkout_proto_msgTypes[12].OneofWrappers = []any{}
file_checkout_proto_msgTypes[13].OneofWrappers = []any{}
file_checkout_proto_msgTypes[14].OneofWrappers = []any{
file_checkout_proto_msgTypes[14].OneofWrappers = []any{}
file_checkout_proto_msgTypes[15].OneofWrappers = []any{
(*Mutation_SetDelivery)(nil),
(*Mutation_SetPickupPoint)(nil),
(*Mutation_RemoveDelivery)(nil),
@@ -1430,7 +1498,7 @@ func file_checkout_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_checkout_proto_rawDesc), len(file_checkout_proto_rawDesc)),
NumEnums: 0,
NumMessages: 15,
NumMessages: 16,
NumExtensions: 0,
NumServices: 0,
},