From 0b428fc9c7e997329f7fcecd9fa19380ea2c9b6b Mon Sep 17 00:00:00 2001 From: zhx Date: Tue, 26 May 2026 01:02:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=92=B1=E5=8C=85=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/proto/wallet/v1/wallet.pb.go | 972 +++++++++++------- api/proto/wallet/v1/wallet.proto | 27 + api/proto/wallet/v1/wallet_grpc.pb.go | 38 + docs/ExploreTab-Flutter-App对接文档.md | 268 +++++ .../flutter对接/Google Play充值Flutter对接.md | 30 +- docs/openapi/gateway.swagger.yaml | 108 ++ .../internal/modules/resource/handler.go | 31 + .../internal/modules/resource/request.go | 21 + .../admin/internal/modules/resource/routes.go | 1 + .../internal/client/wallet_client.go | 5 + .../transport/http/httproutes/router.go | 2 + .../internal/transport/http/response_test.go | 67 ++ .../http/walletapi/app_wallet_handler.go | 117 +++ .../transport/http/walletapi/handler.go | 1 + .../wallet-service/configs/config.docker.yaml | 9 + .../configs/config.tencent.example.yaml | 9 + services/wallet-service/configs/config.yaml | 9 + .../mysql/initdb/001_wallet_service.sql | 29 + services/wallet-service/internal/app/app.go | 14 + .../internal/client/googleplay/client.go | 281 +++++ .../wallet-service/internal/config/config.go | 43 + .../internal/domain/ledger/ledger.go | 49 + .../internal/service/wallet/service.go | 104 ++ .../mysql/google_payment_repository.go | 358 +++++++ .../internal/storage/mysql/repository.go | 1 + .../internal/transport/grpc/server.go | 31 + 26 files changed, 2262 insertions(+), 363 deletions(-) create mode 100644 docs/ExploreTab-Flutter-App对接文档.md create mode 100644 services/wallet-service/internal/client/googleplay/client.go create mode 100644 services/wallet-service/internal/storage/mysql/google_payment_repository.go diff --git a/api/proto/wallet/v1/wallet.pb.go b/api/proto/wallet/v1/wallet.pb.go index 01bfd65a..6d9176c8 100644 --- a/api/proto/wallet/v1/wallet.pb.go +++ b/api/proto/wallet/v1/wallet.pb.go @@ -6663,6 +6663,238 @@ func (x *ListRechargeProductsResponse) GetChannels() []string { return nil } +type ConfirmGooglePaymentRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + AppCode string `protobuf:"bytes,2,opt,name=app_code,json=appCode,proto3" json:"app_code,omitempty"` + CommandId string `protobuf:"bytes,3,opt,name=command_id,json=commandId,proto3" json:"command_id,omitempty"` + UserId int64 `protobuf:"varint,4,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + RegionId int64 `protobuf:"varint,5,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` + ProductId int64 `protobuf:"varint,6,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductCode string `protobuf:"bytes,7,opt,name=product_code,json=productCode,proto3" json:"product_code,omitempty"` + PackageName string `protobuf:"bytes,8,opt,name=package_name,json=packageName,proto3" json:"package_name,omitempty"` + PurchaseToken string `protobuf:"bytes,9,opt,name=purchase_token,json=purchaseToken,proto3" json:"purchase_token,omitempty"` + OrderId string `protobuf:"bytes,10,opt,name=order_id,json=orderId,proto3" json:"order_id,omitempty"` + PurchaseTimeMs int64 `protobuf:"varint,11,opt,name=purchase_time_ms,json=purchaseTimeMs,proto3" json:"purchase_time_ms,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfirmGooglePaymentRequest) Reset() { + *x = ConfirmGooglePaymentRequest{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfirmGooglePaymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmGooglePaymentRequest) ProtoMessage() {} + +func (x *ConfirmGooglePaymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[70] + 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 ConfirmGooglePaymentRequest.ProtoReflect.Descriptor instead. +func (*ConfirmGooglePaymentRequest) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{70} +} + +func (x *ConfirmGooglePaymentRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetAppCode() string { + if x != nil { + return x.AppCode + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetCommandId() string { + if x != nil { + return x.CommandId + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *ConfirmGooglePaymentRequest) GetRegionId() int64 { + if x != nil { + return x.RegionId + } + return 0 +} + +func (x *ConfirmGooglePaymentRequest) GetProductId() int64 { + if x != nil { + return x.ProductId + } + return 0 +} + +func (x *ConfirmGooglePaymentRequest) GetProductCode() string { + if x != nil { + return x.ProductCode + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetPackageName() string { + if x != nil { + return x.PackageName + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetPurchaseToken() string { + if x != nil { + return x.PurchaseToken + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetOrderId() string { + if x != nil { + return x.OrderId + } + return "" +} + +func (x *ConfirmGooglePaymentRequest) GetPurchaseTimeMs() int64 { + if x != nil { + return x.PurchaseTimeMs + } + return 0 +} + +type ConfirmGooglePaymentResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + PaymentOrderId string `protobuf:"bytes,1,opt,name=payment_order_id,json=paymentOrderId,proto3" json:"payment_order_id,omitempty"` + TransactionId string `protobuf:"bytes,2,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` + ProductId int64 `protobuf:"varint,4,opt,name=product_id,json=productId,proto3" json:"product_id,omitempty"` + ProductCode string `protobuf:"bytes,5,opt,name=product_code,json=productCode,proto3" json:"product_code,omitempty"` + CoinAmount int64 `protobuf:"varint,6,opt,name=coin_amount,json=coinAmount,proto3" json:"coin_amount,omitempty"` + Balance *AssetBalance `protobuf:"bytes,7,opt,name=balance,proto3" json:"balance,omitempty"` + IdempotentReplay bool `protobuf:"varint,8,opt,name=idempotent_replay,json=idempotentReplay,proto3" json:"idempotent_replay,omitempty"` + ConsumeState string `protobuf:"bytes,9,opt,name=consume_state,json=consumeState,proto3" json:"consume_state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConfirmGooglePaymentResponse) Reset() { + *x = ConfirmGooglePaymentResponse{} + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConfirmGooglePaymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmGooglePaymentResponse) ProtoMessage() {} + +func (x *ConfirmGooglePaymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[71] + 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 ConfirmGooglePaymentResponse.ProtoReflect.Descriptor instead. +func (*ConfirmGooglePaymentResponse) Descriptor() ([]byte, []int) { + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{71} +} + +func (x *ConfirmGooglePaymentResponse) GetPaymentOrderId() string { + if x != nil { + return x.PaymentOrderId + } + return "" +} + +func (x *ConfirmGooglePaymentResponse) GetTransactionId() string { + if x != nil { + return x.TransactionId + } + return "" +} + +func (x *ConfirmGooglePaymentResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ConfirmGooglePaymentResponse) GetProductId() int64 { + if x != nil { + return x.ProductId + } + return 0 +} + +func (x *ConfirmGooglePaymentResponse) GetProductCode() string { + if x != nil { + return x.ProductCode + } + return "" +} + +func (x *ConfirmGooglePaymentResponse) GetCoinAmount() int64 { + if x != nil { + return x.CoinAmount + } + return 0 +} + +func (x *ConfirmGooglePaymentResponse) GetBalance() *AssetBalance { + if x != nil { + return x.Balance + } + return nil +} + +func (x *ConfirmGooglePaymentResponse) GetIdempotentReplay() bool { + if x != nil { + return x.IdempotentReplay + } + return false +} + +func (x *ConfirmGooglePaymentResponse) GetConsumeState() string { + if x != nil { + return x.ConsumeState + } + return "" +} + // ListAdminRechargeProductsRequest 是后台内购配置列表查询,不参与用户充值主链路。 type ListAdminRechargeProductsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -6680,7 +6912,7 @@ type ListAdminRechargeProductsRequest struct { func (x *ListAdminRechargeProductsRequest) Reset() { *x = ListAdminRechargeProductsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[70] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6692,7 +6924,7 @@ func (x *ListAdminRechargeProductsRequest) String() string { func (*ListAdminRechargeProductsRequest) ProtoMessage() {} func (x *ListAdminRechargeProductsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[70] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6705,7 +6937,7 @@ func (x *ListAdminRechargeProductsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminRechargeProductsRequest.ProtoReflect.Descriptor instead. func (*ListAdminRechargeProductsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{70} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{72} } func (x *ListAdminRechargeProductsRequest) GetRequestId() string { @@ -6774,7 +7006,7 @@ type ListAdminRechargeProductsResponse struct { func (x *ListAdminRechargeProductsResponse) Reset() { *x = ListAdminRechargeProductsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[71] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6786,7 +7018,7 @@ func (x *ListAdminRechargeProductsResponse) String() string { func (*ListAdminRechargeProductsResponse) ProtoMessage() {} func (x *ListAdminRechargeProductsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[71] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6799,7 +7031,7 @@ func (x *ListAdminRechargeProductsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListAdminRechargeProductsResponse.ProtoReflect.Descriptor instead. func (*ListAdminRechargeProductsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{71} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{73} } func (x *ListAdminRechargeProductsResponse) GetProducts() []*RechargeProduct { @@ -6835,7 +7067,7 @@ type CreateRechargeProductRequest struct { func (x *CreateRechargeProductRequest) Reset() { *x = CreateRechargeProductRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[72] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6847,7 +7079,7 @@ func (x *CreateRechargeProductRequest) String() string { func (*CreateRechargeProductRequest) ProtoMessage() {} func (x *CreateRechargeProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[72] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6860,7 +7092,7 @@ func (x *CreateRechargeProductRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRechargeProductRequest.ProtoReflect.Descriptor instead. func (*CreateRechargeProductRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{72} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{74} } func (x *CreateRechargeProductRequest) GetRequestId() string { @@ -6952,7 +7184,7 @@ type UpdateRechargeProductRequest struct { func (x *UpdateRechargeProductRequest) Reset() { *x = UpdateRechargeProductRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[73] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6964,7 +7196,7 @@ func (x *UpdateRechargeProductRequest) String() string { func (*UpdateRechargeProductRequest) ProtoMessage() {} func (x *UpdateRechargeProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[73] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6977,7 +7209,7 @@ func (x *UpdateRechargeProductRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRechargeProductRequest.ProtoReflect.Descriptor instead. func (*UpdateRechargeProductRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{73} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{75} } func (x *UpdateRechargeProductRequest) GetRequestId() string { @@ -7069,7 +7301,7 @@ type DeleteRechargeProductRequest struct { func (x *DeleteRechargeProductRequest) Reset() { *x = DeleteRechargeProductRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[74] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7081,7 +7313,7 @@ func (x *DeleteRechargeProductRequest) String() string { func (*DeleteRechargeProductRequest) ProtoMessage() {} func (x *DeleteRechargeProductRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[74] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7094,7 +7326,7 @@ func (x *DeleteRechargeProductRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRechargeProductRequest.ProtoReflect.Descriptor instead. func (*DeleteRechargeProductRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{74} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{76} } func (x *DeleteRechargeProductRequest) GetRequestId() string { @@ -7134,7 +7366,7 @@ type RechargeProductResponse struct { func (x *RechargeProductResponse) Reset() { *x = RechargeProductResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[75] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7146,7 +7378,7 @@ func (x *RechargeProductResponse) String() string { func (*RechargeProductResponse) ProtoMessage() {} func (x *RechargeProductResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[75] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7159,7 +7391,7 @@ func (x *RechargeProductResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RechargeProductResponse.ProtoReflect.Descriptor instead. func (*RechargeProductResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{75} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{77} } func (x *RechargeProductResponse) GetProduct() *RechargeProduct { @@ -7178,7 +7410,7 @@ type DeleteRechargeProductResponse struct { func (x *DeleteRechargeProductResponse) Reset() { *x = DeleteRechargeProductResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[76] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7190,7 +7422,7 @@ func (x *DeleteRechargeProductResponse) String() string { func (*DeleteRechargeProductResponse) ProtoMessage() {} func (x *DeleteRechargeProductResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[76] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7203,7 +7435,7 @@ func (x *DeleteRechargeProductResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRechargeProductResponse.ProtoReflect.Descriptor instead. func (*DeleteRechargeProductResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{76} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{78} } func (x *DeleteRechargeProductResponse) GetDeleted() bool { @@ -7227,7 +7459,7 @@ type DiamondExchangeRule struct { func (x *DiamondExchangeRule) Reset() { *x = DiamondExchangeRule{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[77] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7239,7 +7471,7 @@ func (x *DiamondExchangeRule) String() string { func (*DiamondExchangeRule) ProtoMessage() {} func (x *DiamondExchangeRule) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[77] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7252,7 +7484,7 @@ func (x *DiamondExchangeRule) ProtoReflect() protoreflect.Message { // Deprecated: Use DiamondExchangeRule.ProtoReflect.Descriptor instead. func (*DiamondExchangeRule) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{77} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{79} } func (x *DiamondExchangeRule) GetExchangeType() string { @@ -7308,7 +7540,7 @@ type GetDiamondExchangeConfigRequest struct { func (x *GetDiamondExchangeConfigRequest) Reset() { *x = GetDiamondExchangeConfigRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[78] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7320,7 +7552,7 @@ func (x *GetDiamondExchangeConfigRequest) String() string { func (*GetDiamondExchangeConfigRequest) ProtoMessage() {} func (x *GetDiamondExchangeConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[78] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7333,7 +7565,7 @@ func (x *GetDiamondExchangeConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDiamondExchangeConfigRequest.ProtoReflect.Descriptor instead. func (*GetDiamondExchangeConfigRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{78} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{80} } func (x *GetDiamondExchangeConfigRequest) GetRequestId() string { @@ -7366,7 +7598,7 @@ type GetDiamondExchangeConfigResponse struct { func (x *GetDiamondExchangeConfigResponse) Reset() { *x = GetDiamondExchangeConfigResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[79] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7378,7 +7610,7 @@ func (x *GetDiamondExchangeConfigResponse) String() string { func (*GetDiamondExchangeConfigResponse) ProtoMessage() {} func (x *GetDiamondExchangeConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[79] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7391,7 +7623,7 @@ func (x *GetDiamondExchangeConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDiamondExchangeConfigResponse.ProtoReflect.Descriptor instead. func (*GetDiamondExchangeConfigResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{79} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{81} } func (x *GetDiamondExchangeConfigResponse) GetRules() []*DiamondExchangeRule { @@ -7421,7 +7653,7 @@ type WalletTransaction struct { func (x *WalletTransaction) Reset() { *x = WalletTransaction{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[80] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7433,7 +7665,7 @@ func (x *WalletTransaction) String() string { func (*WalletTransaction) ProtoMessage() {} func (x *WalletTransaction) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[80] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7446,7 +7678,7 @@ func (x *WalletTransaction) ProtoReflect() protoreflect.Message { // Deprecated: Use WalletTransaction.ProtoReflect.Descriptor instead. func (*WalletTransaction) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{80} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{82} } func (x *WalletTransaction) GetEntryId() int64 { @@ -7540,7 +7772,7 @@ type ListWalletTransactionsRequest struct { func (x *ListWalletTransactionsRequest) Reset() { *x = ListWalletTransactionsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[81] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7552,7 +7784,7 @@ func (x *ListWalletTransactionsRequest) String() string { func (*ListWalletTransactionsRequest) ProtoMessage() {} func (x *ListWalletTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[81] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7565,7 +7797,7 @@ func (x *ListWalletTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWalletTransactionsRequest.ProtoReflect.Descriptor instead. func (*ListWalletTransactionsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{81} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{83} } func (x *ListWalletTransactionsRequest) GetRequestId() string { @@ -7620,7 +7852,7 @@ type ListWalletTransactionsResponse struct { func (x *ListWalletTransactionsResponse) Reset() { *x = ListWalletTransactionsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[82] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7632,7 +7864,7 @@ func (x *ListWalletTransactionsResponse) String() string { func (*ListWalletTransactionsResponse) ProtoMessage() {} func (x *ListWalletTransactionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[82] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7645,7 +7877,7 @@ func (x *ListWalletTransactionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWalletTransactionsResponse.ProtoReflect.Descriptor instead. func (*ListWalletTransactionsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{82} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{84} } func (x *ListWalletTransactionsResponse) GetTransactions() []*WalletTransaction { @@ -7679,7 +7911,7 @@ type WithdrawalRequest struct { func (x *WithdrawalRequest) Reset() { *x = WithdrawalRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[83] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7691,7 +7923,7 @@ func (x *WithdrawalRequest) String() string { func (*WithdrawalRequest) ProtoMessage() {} func (x *WithdrawalRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[83] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7704,7 +7936,7 @@ func (x *WithdrawalRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WithdrawalRequest.ProtoReflect.Descriptor instead. func (*WithdrawalRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{83} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{85} } func (x *WithdrawalRequest) GetWithdrawalId() string { @@ -7784,7 +8016,7 @@ type ApplyWithdrawalRequest struct { func (x *ApplyWithdrawalRequest) Reset() { *x = ApplyWithdrawalRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[84] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7796,7 +8028,7 @@ func (x *ApplyWithdrawalRequest) String() string { func (*ApplyWithdrawalRequest) ProtoMessage() {} func (x *ApplyWithdrawalRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[84] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7809,7 +8041,7 @@ func (x *ApplyWithdrawalRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyWithdrawalRequest.ProtoReflect.Descriptor instead. func (*ApplyWithdrawalRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{84} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{86} } func (x *ApplyWithdrawalRequest) GetCommandId() string { @@ -7864,7 +8096,7 @@ type ApplyWithdrawalResponse struct { func (x *ApplyWithdrawalResponse) Reset() { *x = ApplyWithdrawalResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[85] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7876,7 +8108,7 @@ func (x *ApplyWithdrawalResponse) String() string { func (*ApplyWithdrawalResponse) ProtoMessage() {} func (x *ApplyWithdrawalResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[85] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7889,7 +8121,7 @@ func (x *ApplyWithdrawalResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyWithdrawalResponse.ProtoReflect.Descriptor instead. func (*ApplyWithdrawalResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{85} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{87} } func (x *ApplyWithdrawalResponse) GetWithdrawal() *WithdrawalRequest { @@ -7920,7 +8152,7 @@ type VipRewardItem struct { func (x *VipRewardItem) Reset() { *x = VipRewardItem{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[86] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7932,7 +8164,7 @@ func (x *VipRewardItem) String() string { func (*VipRewardItem) ProtoMessage() {} func (x *VipRewardItem) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[86] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7945,7 +8177,7 @@ func (x *VipRewardItem) ProtoReflect() protoreflect.Message { // Deprecated: Use VipRewardItem.ProtoReflect.Descriptor instead. func (*VipRewardItem) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{86} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{88} } func (x *VipRewardItem) GetResourceId() int64 { @@ -8013,7 +8245,7 @@ type VipLevel struct { func (x *VipLevel) Reset() { *x = VipLevel{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[87] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8025,7 +8257,7 @@ func (x *VipLevel) String() string { func (*VipLevel) ProtoMessage() {} func (x *VipLevel) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[87] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8038,7 +8270,7 @@ func (x *VipLevel) ProtoReflect() protoreflect.Message { // Deprecated: Use VipLevel.ProtoReflect.Descriptor instead. func (*VipLevel) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{87} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{89} } func (x *VipLevel) GetLevel() int32 { @@ -8161,7 +8393,7 @@ type UserVip struct { func (x *UserVip) Reset() { *x = UserVip{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[88] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8173,7 +8405,7 @@ func (x *UserVip) String() string { func (*UserVip) ProtoMessage() {} func (x *UserVip) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[88] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8186,7 +8418,7 @@ func (x *UserVip) ProtoReflect() protoreflect.Message { // Deprecated: Use UserVip.ProtoReflect.Descriptor instead. func (*UserVip) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{88} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{90} } func (x *UserVip) GetUserId() int64 { @@ -8249,7 +8481,7 @@ type ListVipPackagesRequest struct { func (x *ListVipPackagesRequest) Reset() { *x = ListVipPackagesRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[89] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8261,7 +8493,7 @@ func (x *ListVipPackagesRequest) String() string { func (*ListVipPackagesRequest) ProtoMessage() {} func (x *ListVipPackagesRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[89] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8274,7 +8506,7 @@ func (x *ListVipPackagesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVipPackagesRequest.ProtoReflect.Descriptor instead. func (*ListVipPackagesRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{89} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{91} } func (x *ListVipPackagesRequest) GetRequestId() string { @@ -8308,7 +8540,7 @@ type ListVipPackagesResponse struct { func (x *ListVipPackagesResponse) Reset() { *x = ListVipPackagesResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[90] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8320,7 +8552,7 @@ func (x *ListVipPackagesResponse) String() string { func (*ListVipPackagesResponse) ProtoMessage() {} func (x *ListVipPackagesResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[90] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8333,7 +8565,7 @@ func (x *ListVipPackagesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVipPackagesResponse.ProtoReflect.Descriptor instead. func (*ListVipPackagesResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{90} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{92} } func (x *ListVipPackagesResponse) GetCurrentVip() *UserVip { @@ -8361,7 +8593,7 @@ type GetMyVipRequest struct { func (x *GetMyVipRequest) Reset() { *x = GetMyVipRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[91] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8373,7 +8605,7 @@ func (x *GetMyVipRequest) String() string { func (*GetMyVipRequest) ProtoMessage() {} func (x *GetMyVipRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[91] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8386,7 +8618,7 @@ func (x *GetMyVipRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMyVipRequest.ProtoReflect.Descriptor instead. func (*GetMyVipRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{91} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{93} } func (x *GetMyVipRequest) GetRequestId() string { @@ -8419,7 +8651,7 @@ type GetMyVipResponse struct { func (x *GetMyVipResponse) Reset() { *x = GetMyVipResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[92] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8431,7 +8663,7 @@ func (x *GetMyVipResponse) String() string { func (*GetMyVipResponse) ProtoMessage() {} func (x *GetMyVipResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[92] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8444,7 +8676,7 @@ func (x *GetMyVipResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetMyVipResponse.ProtoReflect.Descriptor instead. func (*GetMyVipResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{92} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{94} } func (x *GetMyVipResponse) GetVip() *UserVip { @@ -8466,7 +8698,7 @@ type PurchaseVipRequest struct { func (x *PurchaseVipRequest) Reset() { *x = PurchaseVipRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[93] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8478,7 +8710,7 @@ func (x *PurchaseVipRequest) String() string { func (*PurchaseVipRequest) ProtoMessage() {} func (x *PurchaseVipRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[93] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8491,7 +8723,7 @@ func (x *PurchaseVipRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PurchaseVipRequest.ProtoReflect.Descriptor instead. func (*PurchaseVipRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{93} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{95} } func (x *PurchaseVipRequest) GetCommandId() string { @@ -8536,7 +8768,7 @@ type PurchaseVipResponse struct { func (x *PurchaseVipResponse) Reset() { *x = PurchaseVipResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[94] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8548,7 +8780,7 @@ func (x *PurchaseVipResponse) String() string { func (*PurchaseVipResponse) ProtoMessage() {} func (x *PurchaseVipResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[94] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8561,7 +8793,7 @@ func (x *PurchaseVipResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PurchaseVipResponse.ProtoReflect.Descriptor instead. func (*PurchaseVipResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{94} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{96} } func (x *PurchaseVipResponse) GetOrderId() string { @@ -8621,7 +8853,7 @@ type GrantVipRequest struct { func (x *GrantVipRequest) Reset() { *x = GrantVipRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[95] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8633,7 +8865,7 @@ func (x *GrantVipRequest) String() string { func (*GrantVipRequest) ProtoMessage() {} func (x *GrantVipRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[95] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8646,7 +8878,7 @@ func (x *GrantVipRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantVipRequest.ProtoReflect.Descriptor instead. func (*GrantVipRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{95} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{97} } func (x *GrantVipRequest) GetCommandId() string { @@ -8710,7 +8942,7 @@ type GrantVipResponse struct { func (x *GrantVipResponse) Reset() { *x = GrantVipResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[96] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8722,7 +8954,7 @@ func (x *GrantVipResponse) String() string { func (*GrantVipResponse) ProtoMessage() {} func (x *GrantVipResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[96] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8735,7 +8967,7 @@ func (x *GrantVipResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GrantVipResponse.ProtoReflect.Descriptor instead. func (*GrantVipResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{96} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{98} } func (x *GrantVipResponse) GetTransactionId() string { @@ -8782,7 +9014,7 @@ type AdminVipLevelInput struct { func (x *AdminVipLevelInput) Reset() { *x = AdminVipLevelInput{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[97] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8794,7 +9026,7 @@ func (x *AdminVipLevelInput) String() string { func (*AdminVipLevelInput) ProtoMessage() {} func (x *AdminVipLevelInput) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[97] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8807,7 +9039,7 @@ func (x *AdminVipLevelInput) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminVipLevelInput.ProtoReflect.Descriptor instead. func (*AdminVipLevelInput) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{97} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{99} } func (x *AdminVipLevelInput) GetLevel() int32 { @@ -8876,7 +9108,7 @@ type ListAdminVipLevelsRequest struct { func (x *ListAdminVipLevelsRequest) Reset() { *x = ListAdminVipLevelsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[98] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8888,7 +9120,7 @@ func (x *ListAdminVipLevelsRequest) String() string { func (*ListAdminVipLevelsRequest) ProtoMessage() {} func (x *ListAdminVipLevelsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[98] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8901,7 +9133,7 @@ func (x *ListAdminVipLevelsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminVipLevelsRequest.ProtoReflect.Descriptor instead. func (*ListAdminVipLevelsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{98} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{100} } func (x *ListAdminVipLevelsRequest) GetRequestId() string { @@ -8928,7 +9160,7 @@ type ListAdminVipLevelsResponse struct { func (x *ListAdminVipLevelsResponse) Reset() { *x = ListAdminVipLevelsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[99] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8940,7 +9172,7 @@ func (x *ListAdminVipLevelsResponse) String() string { func (*ListAdminVipLevelsResponse) ProtoMessage() {} func (x *ListAdminVipLevelsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[99] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8953,7 +9185,7 @@ func (x *ListAdminVipLevelsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminVipLevelsResponse.ProtoReflect.Descriptor instead. func (*ListAdminVipLevelsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{99} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{101} } func (x *ListAdminVipLevelsResponse) GetLevels() []*VipLevel { @@ -8982,7 +9214,7 @@ type UpdateAdminVipLevelsRequest struct { func (x *UpdateAdminVipLevelsRequest) Reset() { *x = UpdateAdminVipLevelsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[100] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8994,7 +9226,7 @@ func (x *UpdateAdminVipLevelsRequest) String() string { func (*UpdateAdminVipLevelsRequest) ProtoMessage() {} func (x *UpdateAdminVipLevelsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[100] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9007,7 +9239,7 @@ func (x *UpdateAdminVipLevelsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateAdminVipLevelsRequest.ProtoReflect.Descriptor instead. func (*UpdateAdminVipLevelsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{100} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{102} } func (x *UpdateAdminVipLevelsRequest) GetRequestId() string { @@ -9048,7 +9280,7 @@ type UpdateAdminVipLevelsResponse struct { func (x *UpdateAdminVipLevelsResponse) Reset() { *x = UpdateAdminVipLevelsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[101] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9060,7 +9292,7 @@ func (x *UpdateAdminVipLevelsResponse) String() string { func (*UpdateAdminVipLevelsResponse) ProtoMessage() {} func (x *UpdateAdminVipLevelsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[101] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9073,7 +9305,7 @@ func (x *UpdateAdminVipLevelsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateAdminVipLevelsResponse.ProtoReflect.Descriptor instead. func (*UpdateAdminVipLevelsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{101} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{103} } func (x *UpdateAdminVipLevelsResponse) GetLevels() []*VipLevel { @@ -9107,7 +9339,7 @@ type CreditTaskRewardRequest struct { func (x *CreditTaskRewardRequest) Reset() { *x = CreditTaskRewardRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[102] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9119,7 +9351,7 @@ func (x *CreditTaskRewardRequest) String() string { func (*CreditTaskRewardRequest) ProtoMessage() {} func (x *CreditTaskRewardRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[102] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9132,7 +9364,7 @@ func (x *CreditTaskRewardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreditTaskRewardRequest.ProtoReflect.Descriptor instead. func (*CreditTaskRewardRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{102} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{104} } func (x *CreditTaskRewardRequest) GetCommandId() string { @@ -9204,7 +9436,7 @@ type CreditTaskRewardResponse struct { func (x *CreditTaskRewardResponse) Reset() { *x = CreditTaskRewardResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[103] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9216,7 +9448,7 @@ func (x *CreditTaskRewardResponse) String() string { func (*CreditTaskRewardResponse) ProtoMessage() {} func (x *CreditTaskRewardResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[103] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9229,7 +9461,7 @@ func (x *CreditTaskRewardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreditTaskRewardResponse.ProtoReflect.Descriptor instead. func (*CreditTaskRewardResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{103} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{105} } func (x *CreditTaskRewardResponse) GetTransactionId() string { @@ -9281,7 +9513,7 @@ type ApplyGameCoinChangeRequest struct { func (x *ApplyGameCoinChangeRequest) Reset() { *x = ApplyGameCoinChangeRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[104] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9293,7 +9525,7 @@ func (x *ApplyGameCoinChangeRequest) String() string { func (*ApplyGameCoinChangeRequest) ProtoMessage() {} func (x *ApplyGameCoinChangeRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[104] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9306,7 +9538,7 @@ func (x *ApplyGameCoinChangeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyGameCoinChangeRequest.ProtoReflect.Descriptor instead. func (*ApplyGameCoinChangeRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{104} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{106} } func (x *ApplyGameCoinChangeRequest) GetRequestId() string { @@ -9405,7 +9637,7 @@ type ApplyGameCoinChangeResponse struct { func (x *ApplyGameCoinChangeResponse) Reset() { *x = ApplyGameCoinChangeResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[105] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9417,7 +9649,7 @@ func (x *ApplyGameCoinChangeResponse) String() string { func (*ApplyGameCoinChangeResponse) ProtoMessage() {} func (x *ApplyGameCoinChangeResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[105] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9430,7 +9662,7 @@ func (x *ApplyGameCoinChangeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyGameCoinChangeResponse.ProtoReflect.Descriptor instead. func (*ApplyGameCoinChangeResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{105} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{107} } func (x *ApplyGameCoinChangeResponse) GetWalletTransactionId() string { @@ -9472,7 +9704,7 @@ type RedPacketConfig struct { func (x *RedPacketConfig) Reset() { *x = RedPacketConfig{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9484,7 +9716,7 @@ func (x *RedPacketConfig) String() string { func (*RedPacketConfig) ProtoMessage() {} func (x *RedPacketConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[106] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9497,7 +9729,7 @@ func (x *RedPacketConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use RedPacketConfig.ProtoReflect.Descriptor instead. func (*RedPacketConfig) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{106} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{108} } func (x *RedPacketConfig) GetAppCode() string { @@ -9589,7 +9821,7 @@ type RedPacketClaim struct { func (x *RedPacketClaim) Reset() { *x = RedPacketClaim{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9601,7 +9833,7 @@ func (x *RedPacketClaim) String() string { func (*RedPacketClaim) ProtoMessage() {} func (x *RedPacketClaim) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[107] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9614,7 +9846,7 @@ func (x *RedPacketClaim) ProtoReflect() protoreflect.Message { // Deprecated: Use RedPacketClaim.ProtoReflect.Descriptor instead. func (*RedPacketClaim) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{107} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{109} } func (x *RedPacketClaim) GetAppCode() string { @@ -9721,7 +9953,7 @@ type RedPacket struct { func (x *RedPacket) Reset() { *x = RedPacket{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9733,7 +9965,7 @@ func (x *RedPacket) String() string { func (*RedPacket) ProtoMessage() {} func (x *RedPacket) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[108] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9746,7 +9978,7 @@ func (x *RedPacket) ProtoReflect() protoreflect.Message { // Deprecated: Use RedPacket.ProtoReflect.Descriptor instead. func (*RedPacket) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{108} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{110} } func (x *RedPacket) GetAppCode() string { @@ -9892,7 +10124,7 @@ type GetRedPacketConfigRequest struct { func (x *GetRedPacketConfigRequest) Reset() { *x = GetRedPacketConfigRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9904,7 +10136,7 @@ func (x *GetRedPacketConfigRequest) String() string { func (*GetRedPacketConfigRequest) ProtoMessage() {} func (x *GetRedPacketConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[109] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9917,7 +10149,7 @@ func (x *GetRedPacketConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRedPacketConfigRequest.ProtoReflect.Descriptor instead. func (*GetRedPacketConfigRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{109} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{111} } func (x *GetRedPacketConfigRequest) GetRequestId() string { @@ -9944,7 +10176,7 @@ type GetRedPacketConfigResponse struct { func (x *GetRedPacketConfigResponse) Reset() { *x = GetRedPacketConfigResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9956,7 +10188,7 @@ func (x *GetRedPacketConfigResponse) String() string { func (*GetRedPacketConfigResponse) ProtoMessage() {} func (x *GetRedPacketConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[110] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9969,7 +10201,7 @@ func (x *GetRedPacketConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRedPacketConfigResponse.ProtoReflect.Descriptor instead. func (*GetRedPacketConfigResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{110} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{112} } func (x *GetRedPacketConfigResponse) GetConfig() *RedPacketConfig { @@ -10003,7 +10235,7 @@ type UpdateRedPacketConfigRequest struct { func (x *UpdateRedPacketConfigRequest) Reset() { *x = UpdateRedPacketConfigRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10015,7 +10247,7 @@ func (x *UpdateRedPacketConfigRequest) String() string { func (*UpdateRedPacketConfigRequest) ProtoMessage() {} func (x *UpdateRedPacketConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[111] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10028,7 +10260,7 @@ func (x *UpdateRedPacketConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRedPacketConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateRedPacketConfigRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{111} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{113} } func (x *UpdateRedPacketConfigRequest) GetRequestId() string { @@ -10104,7 +10336,7 @@ type UpdateRedPacketConfigResponse struct { func (x *UpdateRedPacketConfigResponse) Reset() { *x = UpdateRedPacketConfigResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10116,7 +10348,7 @@ func (x *UpdateRedPacketConfigResponse) String() string { func (*UpdateRedPacketConfigResponse) ProtoMessage() {} func (x *UpdateRedPacketConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[112] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10129,7 +10361,7 @@ func (x *UpdateRedPacketConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRedPacketConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateRedPacketConfigResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{112} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{114} } func (x *UpdateRedPacketConfigResponse) GetConfig() *RedPacketConfig { @@ -10163,7 +10395,7 @@ type CreateRedPacketRequest struct { func (x *CreateRedPacketRequest) Reset() { *x = CreateRedPacketRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10175,7 +10407,7 @@ func (x *CreateRedPacketRequest) String() string { func (*CreateRedPacketRequest) ProtoMessage() {} func (x *CreateRedPacketRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[113] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10188,7 +10420,7 @@ func (x *CreateRedPacketRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRedPacketRequest.ProtoReflect.Descriptor instead. func (*CreateRedPacketRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{113} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{115} } func (x *CreateRedPacketRequest) GetRequestId() string { @@ -10265,7 +10497,7 @@ type CreateRedPacketResponse struct { func (x *CreateRedPacketResponse) Reset() { *x = CreateRedPacketResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10277,7 +10509,7 @@ func (x *CreateRedPacketResponse) String() string { func (*CreateRedPacketResponse) ProtoMessage() {} func (x *CreateRedPacketResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[114] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10290,7 +10522,7 @@ func (x *CreateRedPacketResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRedPacketResponse.ProtoReflect.Descriptor instead. func (*CreateRedPacketResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{114} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{116} } func (x *CreateRedPacketResponse) GetPacket() *RedPacket { @@ -10327,7 +10559,7 @@ type ClaimRedPacketRequest struct { func (x *ClaimRedPacketRequest) Reset() { *x = ClaimRedPacketRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10339,7 +10571,7 @@ func (x *ClaimRedPacketRequest) String() string { func (*ClaimRedPacketRequest) ProtoMessage() {} func (x *ClaimRedPacketRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[115] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10352,7 +10584,7 @@ func (x *ClaimRedPacketRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimRedPacketRequest.ProtoReflect.Descriptor instead. func (*ClaimRedPacketRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{115} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{117} } func (x *ClaimRedPacketRequest) GetRequestId() string { @@ -10401,7 +10633,7 @@ type ClaimRedPacketResponse struct { func (x *ClaimRedPacketResponse) Reset() { *x = ClaimRedPacketResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10413,7 +10645,7 @@ func (x *ClaimRedPacketResponse) String() string { func (*ClaimRedPacketResponse) ProtoMessage() {} func (x *ClaimRedPacketResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[116] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10426,7 +10658,7 @@ func (x *ClaimRedPacketResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimRedPacketResponse.ProtoReflect.Descriptor instead. func (*ClaimRedPacketResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{116} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{118} } func (x *ClaimRedPacketResponse) GetClaim() *RedPacketClaim { @@ -10470,7 +10702,7 @@ type ListRedPacketsRequest struct { func (x *ListRedPacketsRequest) Reset() { *x = ListRedPacketsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10482,7 +10714,7 @@ func (x *ListRedPacketsRequest) String() string { func (*ListRedPacketsRequest) ProtoMessage() {} func (x *ListRedPacketsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[117] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10495,7 +10727,7 @@ func (x *ListRedPacketsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRedPacketsRequest.ProtoReflect.Descriptor instead. func (*ListRedPacketsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{117} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{119} } func (x *ListRedPacketsRequest) GetRequestId() string { @@ -10593,7 +10825,7 @@ type ListRedPacketsResponse struct { func (x *ListRedPacketsResponse) Reset() { *x = ListRedPacketsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10605,7 +10837,7 @@ func (x *ListRedPacketsResponse) String() string { func (*ListRedPacketsResponse) ProtoMessage() {} func (x *ListRedPacketsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[118] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10618,7 +10850,7 @@ func (x *ListRedPacketsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRedPacketsResponse.ProtoReflect.Descriptor instead. func (*ListRedPacketsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{118} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{120} } func (x *ListRedPacketsResponse) GetPackets() []*RedPacket { @@ -10655,7 +10887,7 @@ type GetRedPacketRequest struct { func (x *GetRedPacketRequest) Reset() { *x = GetRedPacketRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10667,7 +10899,7 @@ func (x *GetRedPacketRequest) String() string { func (*GetRedPacketRequest) ProtoMessage() {} func (x *GetRedPacketRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[119] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10680,7 +10912,7 @@ func (x *GetRedPacketRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRedPacketRequest.ProtoReflect.Descriptor instead. func (*GetRedPacketRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{119} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{121} } func (x *GetRedPacketRequest) GetRequestId() string { @@ -10728,7 +10960,7 @@ type GetRedPacketResponse struct { func (x *GetRedPacketResponse) Reset() { *x = GetRedPacketResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10740,7 +10972,7 @@ func (x *GetRedPacketResponse) String() string { func (*GetRedPacketResponse) ProtoMessage() {} func (x *GetRedPacketResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[120] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10753,7 +10985,7 @@ func (x *GetRedPacketResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRedPacketResponse.ProtoReflect.Descriptor instead. func (*GetRedPacketResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{120} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{122} } func (x *GetRedPacketResponse) GetPacket() *RedPacket { @@ -10781,7 +11013,7 @@ type ExpireRedPacketsRequest struct { func (x *ExpireRedPacketsRequest) Reset() { *x = ExpireRedPacketsRequest{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10793,7 +11025,7 @@ func (x *ExpireRedPacketsRequest) String() string { func (*ExpireRedPacketsRequest) ProtoMessage() {} func (x *ExpireRedPacketsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[121] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10806,7 +11038,7 @@ func (x *ExpireRedPacketsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExpireRedPacketsRequest.ProtoReflect.Descriptor instead. func (*ExpireRedPacketsRequest) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{121} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{123} } func (x *ExpireRedPacketsRequest) GetRequestId() string { @@ -10841,7 +11073,7 @@ type ExpireRedPacketsResponse struct { func (x *ExpireRedPacketsResponse) Reset() { *x = ExpireRedPacketsResponse{} - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10853,7 +11085,7 @@ func (x *ExpireRedPacketsResponse) String() string { func (*ExpireRedPacketsResponse) ProtoMessage() {} func (x *ExpireRedPacketsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_wallet_v1_wallet_proto_msgTypes[122] + mi := &file_proto_wallet_v1_wallet_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10866,7 +11098,7 @@ func (x *ExpireRedPacketsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExpireRedPacketsResponse.ProtoReflect.Descriptor instead. func (*ExpireRedPacketsResponse) Descriptor() ([]byte, []int) { - return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{122} + return file_proto_wallet_v1_wallet_proto_rawDescGZIP(), []int{124} } func (x *ExpireRedPacketsResponse) GetExpiredCount() int32 { @@ -11613,7 +11845,35 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" + "\bplatform\x18\x05 \x01(\tR\bplatform\"x\n" + "\x1cListRechargeProductsResponse\x12<\n" + "\bproducts\x18\x01 \x03(\v2 .hyapp.wallet.v1.RechargeProductR\bproducts\x12\x1a\n" + - "\bchannels\x18\x02 \x03(\tR\bchannels\"\xf8\x01\n" + + "\bchannels\x18\x02 \x03(\tR\bchannels\"\xfd\x02\n" + + "\x1bConfirmGooglePaymentRequest\x12\x1d\n" + + "\n" + + "request_id\x18\x01 \x01(\tR\trequestId\x12\x19\n" + + "\bapp_code\x18\x02 \x01(\tR\aappCode\x12\x1d\n" + + "\n" + + "command_id\x18\x03 \x01(\tR\tcommandId\x12\x17\n" + + "\auser_id\x18\x04 \x01(\x03R\x06userId\x12\x1b\n" + + "\tregion_id\x18\x05 \x01(\x03R\bregionId\x12\x1d\n" + + "\n" + + "product_id\x18\x06 \x01(\x03R\tproductId\x12!\n" + + "\fproduct_code\x18\a \x01(\tR\vproductCode\x12!\n" + + "\fpackage_name\x18\b \x01(\tR\vpackageName\x12%\n" + + "\x0epurchase_token\x18\t \x01(\tR\rpurchaseToken\x12\x19\n" + + "\border_id\x18\n" + + " \x01(\tR\aorderId\x12(\n" + + "\x10purchase_time_ms\x18\v \x01(\x03R\x0epurchaseTimeMs\"\xf5\x02\n" + + "\x1cConfirmGooglePaymentResponse\x12(\n" + + "\x10payment_order_id\x18\x01 \x01(\tR\x0epaymentOrderId\x12%\n" + + "\x0etransaction_id\x18\x02 \x01(\tR\rtransactionId\x12\x16\n" + + "\x06status\x18\x03 \x01(\tR\x06status\x12\x1d\n" + + "\n" + + "product_id\x18\x04 \x01(\x03R\tproductId\x12!\n" + + "\fproduct_code\x18\x05 \x01(\tR\vproductCode\x12\x1f\n" + + "\vcoin_amount\x18\x06 \x01(\x03R\n" + + "coinAmount\x127\n" + + "\abalance\x18\a \x01(\v2\x1d.hyapp.wallet.v1.AssetBalanceR\abalance\x12+\n" + + "\x11idempotent_replay\x18\b \x01(\bR\x10idempotentReplay\x12#\n" + + "\rconsume_state\x18\t \x01(\tR\fconsumeState\"\xf8\x01\n" + " ListAdminRechargeProductsRequest\x12\x1d\n" + "\n" + "request_id\x18\x01 \x01(\tR\trequestId\x12\x19\n" + @@ -12020,7 +12280,7 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" + "\x18ExpireRedPacketsResponse\x12#\n" + "\rexpired_count\x18\x01 \x01(\x05R\fexpiredCount\x12'\n" + "\x0frefunded_amount\x18\x02 \x01(\x03R\x0erefundedAmount\x12$\n" + - "\x0eserver_time_ms\x18\x03 \x01(\x03R\fserverTimeMs2\x91,\n" + + "\x0eserver_time_ms\x18\x03 \x01(\x03R\fserverTimeMs2\x86-\n" + "\rWalletService\x12R\n" + "\tDebitGift\x12!.hyapp.wallet.v1.DebitGiftRequest\x1a\".hyapp.wallet.v1.DebitGiftResponse\x12X\n" + "\vGetBalances\x12#.hyapp.wallet.v1.GetBalancesRequest\x1a$.hyapp.wallet.v1.GetBalancesResponse\x12g\n" + @@ -12052,7 +12312,8 @@ const file_proto_wallet_v1_wallet_proto_rawDesc = "" + "\x11GetWalletOverview\x12).hyapp.wallet.v1.GetWalletOverviewRequest\x1a*.hyapp.wallet.v1.GetWalletOverviewResponse\x12v\n" + "\x15GetWalletValueSummary\x12-.hyapp.wallet.v1.GetWalletValueSummaryRequest\x1a..hyapp.wallet.v1.GetWalletValueSummaryResponse\x12d\n" + "\x0fGetUserGiftWall\x12'.hyapp.wallet.v1.GetUserGiftWallRequest\x1a(.hyapp.wallet.v1.GetUserGiftWallResponse\x12s\n" + - "\x14ListRechargeProducts\x12,.hyapp.wallet.v1.ListRechargeProductsRequest\x1a-.hyapp.wallet.v1.ListRechargeProductsResponse\x12\x82\x01\n" + + "\x14ListRechargeProducts\x12,.hyapp.wallet.v1.ListRechargeProductsRequest\x1a-.hyapp.wallet.v1.ListRechargeProductsResponse\x12s\n" + + "\x14ConfirmGooglePayment\x12,.hyapp.wallet.v1.ConfirmGooglePaymentRequest\x1a-.hyapp.wallet.v1.ConfirmGooglePaymentResponse\x12\x82\x01\n" + "\x19ListAdminRechargeProducts\x121.hyapp.wallet.v1.ListAdminRechargeProductsRequest\x1a2.hyapp.wallet.v1.ListAdminRechargeProductsResponse\x12p\n" + "\x15CreateRechargeProduct\x12-.hyapp.wallet.v1.CreateRechargeProductRequest\x1a(.hyapp.wallet.v1.RechargeProductResponse\x12p\n" + "\x15UpdateRechargeProduct\x12-.hyapp.wallet.v1.UpdateRechargeProductRequest\x1a(.hyapp.wallet.v1.RechargeProductResponse\x12v\n" + @@ -12088,7 +12349,7 @@ func file_proto_wallet_v1_wallet_proto_rawDescGZIP() []byte { return file_proto_wallet_v1_wallet_proto_rawDescData } -var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 123) +var file_proto_wallet_v1_wallet_proto_msgTypes = make([]protoimpl.MessageInfo, 125) var file_proto_wallet_v1_wallet_proto_goTypes = []any{ (*DebitGiftRequest)(nil), // 0: hyapp.wallet.v1.DebitGiftRequest (*DebitGiftResponse)(nil), // 1: hyapp.wallet.v1.DebitGiftResponse @@ -12160,59 +12421,61 @@ var file_proto_wallet_v1_wallet_proto_goTypes = []any{ (*RechargeProduct)(nil), // 67: hyapp.wallet.v1.RechargeProduct (*ListRechargeProductsRequest)(nil), // 68: hyapp.wallet.v1.ListRechargeProductsRequest (*ListRechargeProductsResponse)(nil), // 69: hyapp.wallet.v1.ListRechargeProductsResponse - (*ListAdminRechargeProductsRequest)(nil), // 70: hyapp.wallet.v1.ListAdminRechargeProductsRequest - (*ListAdminRechargeProductsResponse)(nil), // 71: hyapp.wallet.v1.ListAdminRechargeProductsResponse - (*CreateRechargeProductRequest)(nil), // 72: hyapp.wallet.v1.CreateRechargeProductRequest - (*UpdateRechargeProductRequest)(nil), // 73: hyapp.wallet.v1.UpdateRechargeProductRequest - (*DeleteRechargeProductRequest)(nil), // 74: hyapp.wallet.v1.DeleteRechargeProductRequest - (*RechargeProductResponse)(nil), // 75: hyapp.wallet.v1.RechargeProductResponse - (*DeleteRechargeProductResponse)(nil), // 76: hyapp.wallet.v1.DeleteRechargeProductResponse - (*DiamondExchangeRule)(nil), // 77: hyapp.wallet.v1.DiamondExchangeRule - (*GetDiamondExchangeConfigRequest)(nil), // 78: hyapp.wallet.v1.GetDiamondExchangeConfigRequest - (*GetDiamondExchangeConfigResponse)(nil), // 79: hyapp.wallet.v1.GetDiamondExchangeConfigResponse - (*WalletTransaction)(nil), // 80: hyapp.wallet.v1.WalletTransaction - (*ListWalletTransactionsRequest)(nil), // 81: hyapp.wallet.v1.ListWalletTransactionsRequest - (*ListWalletTransactionsResponse)(nil), // 82: hyapp.wallet.v1.ListWalletTransactionsResponse - (*WithdrawalRequest)(nil), // 83: hyapp.wallet.v1.WithdrawalRequest - (*ApplyWithdrawalRequest)(nil), // 84: hyapp.wallet.v1.ApplyWithdrawalRequest - (*ApplyWithdrawalResponse)(nil), // 85: hyapp.wallet.v1.ApplyWithdrawalResponse - (*VipRewardItem)(nil), // 86: hyapp.wallet.v1.VipRewardItem - (*VipLevel)(nil), // 87: hyapp.wallet.v1.VipLevel - (*UserVip)(nil), // 88: hyapp.wallet.v1.UserVip - (*ListVipPackagesRequest)(nil), // 89: hyapp.wallet.v1.ListVipPackagesRequest - (*ListVipPackagesResponse)(nil), // 90: hyapp.wallet.v1.ListVipPackagesResponse - (*GetMyVipRequest)(nil), // 91: hyapp.wallet.v1.GetMyVipRequest - (*GetMyVipResponse)(nil), // 92: hyapp.wallet.v1.GetMyVipResponse - (*PurchaseVipRequest)(nil), // 93: hyapp.wallet.v1.PurchaseVipRequest - (*PurchaseVipResponse)(nil), // 94: hyapp.wallet.v1.PurchaseVipResponse - (*GrantVipRequest)(nil), // 95: hyapp.wallet.v1.GrantVipRequest - (*GrantVipResponse)(nil), // 96: hyapp.wallet.v1.GrantVipResponse - (*AdminVipLevelInput)(nil), // 97: hyapp.wallet.v1.AdminVipLevelInput - (*ListAdminVipLevelsRequest)(nil), // 98: hyapp.wallet.v1.ListAdminVipLevelsRequest - (*ListAdminVipLevelsResponse)(nil), // 99: hyapp.wallet.v1.ListAdminVipLevelsResponse - (*UpdateAdminVipLevelsRequest)(nil), // 100: hyapp.wallet.v1.UpdateAdminVipLevelsRequest - (*UpdateAdminVipLevelsResponse)(nil), // 101: hyapp.wallet.v1.UpdateAdminVipLevelsResponse - (*CreditTaskRewardRequest)(nil), // 102: hyapp.wallet.v1.CreditTaskRewardRequest - (*CreditTaskRewardResponse)(nil), // 103: hyapp.wallet.v1.CreditTaskRewardResponse - (*ApplyGameCoinChangeRequest)(nil), // 104: hyapp.wallet.v1.ApplyGameCoinChangeRequest - (*ApplyGameCoinChangeResponse)(nil), // 105: hyapp.wallet.v1.ApplyGameCoinChangeResponse - (*RedPacketConfig)(nil), // 106: hyapp.wallet.v1.RedPacketConfig - (*RedPacketClaim)(nil), // 107: hyapp.wallet.v1.RedPacketClaim - (*RedPacket)(nil), // 108: hyapp.wallet.v1.RedPacket - (*GetRedPacketConfigRequest)(nil), // 109: hyapp.wallet.v1.GetRedPacketConfigRequest - (*GetRedPacketConfigResponse)(nil), // 110: hyapp.wallet.v1.GetRedPacketConfigResponse - (*UpdateRedPacketConfigRequest)(nil), // 111: hyapp.wallet.v1.UpdateRedPacketConfigRequest - (*UpdateRedPacketConfigResponse)(nil), // 112: hyapp.wallet.v1.UpdateRedPacketConfigResponse - (*CreateRedPacketRequest)(nil), // 113: hyapp.wallet.v1.CreateRedPacketRequest - (*CreateRedPacketResponse)(nil), // 114: hyapp.wallet.v1.CreateRedPacketResponse - (*ClaimRedPacketRequest)(nil), // 115: hyapp.wallet.v1.ClaimRedPacketRequest - (*ClaimRedPacketResponse)(nil), // 116: hyapp.wallet.v1.ClaimRedPacketResponse - (*ListRedPacketsRequest)(nil), // 117: hyapp.wallet.v1.ListRedPacketsRequest - (*ListRedPacketsResponse)(nil), // 118: hyapp.wallet.v1.ListRedPacketsResponse - (*GetRedPacketRequest)(nil), // 119: hyapp.wallet.v1.GetRedPacketRequest - (*GetRedPacketResponse)(nil), // 120: hyapp.wallet.v1.GetRedPacketResponse - (*ExpireRedPacketsRequest)(nil), // 121: hyapp.wallet.v1.ExpireRedPacketsRequest - (*ExpireRedPacketsResponse)(nil), // 122: hyapp.wallet.v1.ExpireRedPacketsResponse + (*ConfirmGooglePaymentRequest)(nil), // 70: hyapp.wallet.v1.ConfirmGooglePaymentRequest + (*ConfirmGooglePaymentResponse)(nil), // 71: hyapp.wallet.v1.ConfirmGooglePaymentResponse + (*ListAdminRechargeProductsRequest)(nil), // 72: hyapp.wallet.v1.ListAdminRechargeProductsRequest + (*ListAdminRechargeProductsResponse)(nil), // 73: hyapp.wallet.v1.ListAdminRechargeProductsResponse + (*CreateRechargeProductRequest)(nil), // 74: hyapp.wallet.v1.CreateRechargeProductRequest + (*UpdateRechargeProductRequest)(nil), // 75: hyapp.wallet.v1.UpdateRechargeProductRequest + (*DeleteRechargeProductRequest)(nil), // 76: hyapp.wallet.v1.DeleteRechargeProductRequest + (*RechargeProductResponse)(nil), // 77: hyapp.wallet.v1.RechargeProductResponse + (*DeleteRechargeProductResponse)(nil), // 78: hyapp.wallet.v1.DeleteRechargeProductResponse + (*DiamondExchangeRule)(nil), // 79: hyapp.wallet.v1.DiamondExchangeRule + (*GetDiamondExchangeConfigRequest)(nil), // 80: hyapp.wallet.v1.GetDiamondExchangeConfigRequest + (*GetDiamondExchangeConfigResponse)(nil), // 81: hyapp.wallet.v1.GetDiamondExchangeConfigResponse + (*WalletTransaction)(nil), // 82: hyapp.wallet.v1.WalletTransaction + (*ListWalletTransactionsRequest)(nil), // 83: hyapp.wallet.v1.ListWalletTransactionsRequest + (*ListWalletTransactionsResponse)(nil), // 84: hyapp.wallet.v1.ListWalletTransactionsResponse + (*WithdrawalRequest)(nil), // 85: hyapp.wallet.v1.WithdrawalRequest + (*ApplyWithdrawalRequest)(nil), // 86: hyapp.wallet.v1.ApplyWithdrawalRequest + (*ApplyWithdrawalResponse)(nil), // 87: hyapp.wallet.v1.ApplyWithdrawalResponse + (*VipRewardItem)(nil), // 88: hyapp.wallet.v1.VipRewardItem + (*VipLevel)(nil), // 89: hyapp.wallet.v1.VipLevel + (*UserVip)(nil), // 90: hyapp.wallet.v1.UserVip + (*ListVipPackagesRequest)(nil), // 91: hyapp.wallet.v1.ListVipPackagesRequest + (*ListVipPackagesResponse)(nil), // 92: hyapp.wallet.v1.ListVipPackagesResponse + (*GetMyVipRequest)(nil), // 93: hyapp.wallet.v1.GetMyVipRequest + (*GetMyVipResponse)(nil), // 94: hyapp.wallet.v1.GetMyVipResponse + (*PurchaseVipRequest)(nil), // 95: hyapp.wallet.v1.PurchaseVipRequest + (*PurchaseVipResponse)(nil), // 96: hyapp.wallet.v1.PurchaseVipResponse + (*GrantVipRequest)(nil), // 97: hyapp.wallet.v1.GrantVipRequest + (*GrantVipResponse)(nil), // 98: hyapp.wallet.v1.GrantVipResponse + (*AdminVipLevelInput)(nil), // 99: hyapp.wallet.v1.AdminVipLevelInput + (*ListAdminVipLevelsRequest)(nil), // 100: hyapp.wallet.v1.ListAdminVipLevelsRequest + (*ListAdminVipLevelsResponse)(nil), // 101: hyapp.wallet.v1.ListAdminVipLevelsResponse + (*UpdateAdminVipLevelsRequest)(nil), // 102: hyapp.wallet.v1.UpdateAdminVipLevelsRequest + (*UpdateAdminVipLevelsResponse)(nil), // 103: hyapp.wallet.v1.UpdateAdminVipLevelsResponse + (*CreditTaskRewardRequest)(nil), // 104: hyapp.wallet.v1.CreditTaskRewardRequest + (*CreditTaskRewardResponse)(nil), // 105: hyapp.wallet.v1.CreditTaskRewardResponse + (*ApplyGameCoinChangeRequest)(nil), // 106: hyapp.wallet.v1.ApplyGameCoinChangeRequest + (*ApplyGameCoinChangeResponse)(nil), // 107: hyapp.wallet.v1.ApplyGameCoinChangeResponse + (*RedPacketConfig)(nil), // 108: hyapp.wallet.v1.RedPacketConfig + (*RedPacketClaim)(nil), // 109: hyapp.wallet.v1.RedPacketClaim + (*RedPacket)(nil), // 110: hyapp.wallet.v1.RedPacket + (*GetRedPacketConfigRequest)(nil), // 111: hyapp.wallet.v1.GetRedPacketConfigRequest + (*GetRedPacketConfigResponse)(nil), // 112: hyapp.wallet.v1.GetRedPacketConfigResponse + (*UpdateRedPacketConfigRequest)(nil), // 113: hyapp.wallet.v1.UpdateRedPacketConfigRequest + (*UpdateRedPacketConfigResponse)(nil), // 114: hyapp.wallet.v1.UpdateRedPacketConfigResponse + (*CreateRedPacketRequest)(nil), // 115: hyapp.wallet.v1.CreateRedPacketRequest + (*CreateRedPacketResponse)(nil), // 116: hyapp.wallet.v1.CreateRedPacketResponse + (*ClaimRedPacketRequest)(nil), // 117: hyapp.wallet.v1.ClaimRedPacketRequest + (*ClaimRedPacketResponse)(nil), // 118: hyapp.wallet.v1.ClaimRedPacketResponse + (*ListRedPacketsRequest)(nil), // 119: hyapp.wallet.v1.ListRedPacketsRequest + (*ListRedPacketsResponse)(nil), // 120: hyapp.wallet.v1.ListRedPacketsResponse + (*GetRedPacketRequest)(nil), // 121: hyapp.wallet.v1.GetRedPacketRequest + (*GetRedPacketResponse)(nil), // 122: hyapp.wallet.v1.GetRedPacketResponse + (*ExpireRedPacketsRequest)(nil), // 123: hyapp.wallet.v1.ExpireRedPacketsRequest + (*ExpireRedPacketsResponse)(nil), // 124: hyapp.wallet.v1.ExpireRedPacketsResponse } var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{ 2, // 0: hyapp.wallet.v1.GetBalancesResponse.balances:type_name -> hyapp.wallet.v1.AssetBalance @@ -12245,142 +12508,145 @@ var file_proto_wallet_v1_wallet_proto_depIdxs = []int32{ 11, // 27: hyapp.wallet.v1.GiftWallItem.resource:type_name -> hyapp.wallet.v1.Resource 64, // 28: hyapp.wallet.v1.GetUserGiftWallResponse.items:type_name -> hyapp.wallet.v1.GiftWallItem 67, // 29: hyapp.wallet.v1.ListRechargeProductsResponse.products:type_name -> hyapp.wallet.v1.RechargeProduct - 67, // 30: hyapp.wallet.v1.ListAdminRechargeProductsResponse.products:type_name -> hyapp.wallet.v1.RechargeProduct - 67, // 31: hyapp.wallet.v1.RechargeProductResponse.product:type_name -> hyapp.wallet.v1.RechargeProduct - 77, // 32: hyapp.wallet.v1.GetDiamondExchangeConfigResponse.rules:type_name -> hyapp.wallet.v1.DiamondExchangeRule - 80, // 33: hyapp.wallet.v1.ListWalletTransactionsResponse.transactions:type_name -> hyapp.wallet.v1.WalletTransaction - 83, // 34: hyapp.wallet.v1.ApplyWithdrawalResponse.withdrawal:type_name -> hyapp.wallet.v1.WithdrawalRequest - 2, // 35: hyapp.wallet.v1.ApplyWithdrawalResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance - 86, // 36: hyapp.wallet.v1.VipLevel.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem - 88, // 37: hyapp.wallet.v1.ListVipPackagesResponse.current_vip:type_name -> hyapp.wallet.v1.UserVip - 87, // 38: hyapp.wallet.v1.ListVipPackagesResponse.packages:type_name -> hyapp.wallet.v1.VipLevel - 88, // 39: hyapp.wallet.v1.GetMyVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip - 88, // 40: hyapp.wallet.v1.PurchaseVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip - 86, // 41: hyapp.wallet.v1.PurchaseVipResponse.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem - 88, // 42: hyapp.wallet.v1.GrantVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip - 86, // 43: hyapp.wallet.v1.GrantVipResponse.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem - 87, // 44: hyapp.wallet.v1.ListAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel - 97, // 45: hyapp.wallet.v1.UpdateAdminVipLevelsRequest.levels:type_name -> hyapp.wallet.v1.AdminVipLevelInput - 87, // 46: hyapp.wallet.v1.UpdateAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel - 2, // 47: hyapp.wallet.v1.CreditTaskRewardResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance - 107, // 48: hyapp.wallet.v1.RedPacket.claims:type_name -> hyapp.wallet.v1.RedPacketClaim - 106, // 49: hyapp.wallet.v1.GetRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig - 106, // 50: hyapp.wallet.v1.UpdateRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig - 108, // 51: hyapp.wallet.v1.CreateRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket - 107, // 52: hyapp.wallet.v1.ClaimRedPacketResponse.claim:type_name -> hyapp.wallet.v1.RedPacketClaim - 108, // 53: hyapp.wallet.v1.ListRedPacketsResponse.packets:type_name -> hyapp.wallet.v1.RedPacket - 108, // 54: hyapp.wallet.v1.GetRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket - 0, // 55: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest - 3, // 56: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest - 5, // 57: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest - 7, // 58: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest - 9, // 59: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest - 20, // 60: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest - 22, // 61: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest - 24, // 62: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest - 25, // 63: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest - 26, // 64: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest - 28, // 65: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest - 30, // 66: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest - 32, // 67: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest - 33, // 68: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest - 34, // 69: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest - 36, // 70: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest - 38, // 71: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest - 42, // 72: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest - 43, // 73: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest - 44, // 74: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest - 40, // 75: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest - 46, // 76: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest - 47, // 77: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest - 49, // 78: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest - 51, // 79: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest - 53, // 80: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest - 56, // 81: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest - 59, // 82: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest - 62, // 83: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest - 65, // 84: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest - 68, // 85: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest - 70, // 86: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest - 72, // 87: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest - 73, // 88: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest - 74, // 89: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest - 78, // 90: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest - 81, // 91: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest - 84, // 92: hyapp.wallet.v1.WalletService.ApplyWithdrawal:input_type -> hyapp.wallet.v1.ApplyWithdrawalRequest - 89, // 93: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest - 91, // 94: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest - 93, // 95: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest - 95, // 96: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest - 98, // 97: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest - 100, // 98: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest - 102, // 99: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest - 104, // 100: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest - 109, // 101: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest - 111, // 102: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest - 113, // 103: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest - 115, // 104: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest - 117, // 105: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest - 119, // 106: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest - 121, // 107: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest - 1, // 108: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse - 4, // 109: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse - 6, // 110: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse - 8, // 111: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse - 10, // 112: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse - 21, // 113: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse - 23, // 114: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse - 27, // 115: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse - 27, // 116: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse - 27, // 117: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse - 29, // 118: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse - 31, // 119: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse - 35, // 120: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 35, // 121: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 35, // 122: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse - 37, // 123: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse - 39, // 124: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse - 45, // 125: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse - 45, // 126: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse - 45, // 127: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse - 41, // 128: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse - 48, // 129: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse - 48, // 130: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse - 50, // 131: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse - 52, // 132: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse - 54, // 133: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse - 57, // 134: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse - 60, // 135: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse - 63, // 136: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse - 66, // 137: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse - 69, // 138: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse - 71, // 139: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse - 75, // 140: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse - 75, // 141: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse - 76, // 142: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse - 79, // 143: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse - 82, // 144: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse - 85, // 145: hyapp.wallet.v1.WalletService.ApplyWithdrawal:output_type -> hyapp.wallet.v1.ApplyWithdrawalResponse - 90, // 146: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse - 92, // 147: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse - 94, // 148: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse - 96, // 149: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse - 99, // 150: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse - 101, // 151: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse - 103, // 152: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse - 105, // 153: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse - 110, // 154: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse - 112, // 155: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse - 114, // 156: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse - 116, // 157: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse - 118, // 158: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse - 120, // 159: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse - 122, // 160: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse - 108, // [108:161] is the sub-list for method output_type - 55, // [55:108] is the sub-list for method input_type - 55, // [55:55] is the sub-list for extension type_name - 55, // [55:55] is the sub-list for extension extendee - 0, // [0:55] is the sub-list for field type_name + 2, // 30: hyapp.wallet.v1.ConfirmGooglePaymentResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance + 67, // 31: hyapp.wallet.v1.ListAdminRechargeProductsResponse.products:type_name -> hyapp.wallet.v1.RechargeProduct + 67, // 32: hyapp.wallet.v1.RechargeProductResponse.product:type_name -> hyapp.wallet.v1.RechargeProduct + 79, // 33: hyapp.wallet.v1.GetDiamondExchangeConfigResponse.rules:type_name -> hyapp.wallet.v1.DiamondExchangeRule + 82, // 34: hyapp.wallet.v1.ListWalletTransactionsResponse.transactions:type_name -> hyapp.wallet.v1.WalletTransaction + 85, // 35: hyapp.wallet.v1.ApplyWithdrawalResponse.withdrawal:type_name -> hyapp.wallet.v1.WithdrawalRequest + 2, // 36: hyapp.wallet.v1.ApplyWithdrawalResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance + 88, // 37: hyapp.wallet.v1.VipLevel.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem + 90, // 38: hyapp.wallet.v1.ListVipPackagesResponse.current_vip:type_name -> hyapp.wallet.v1.UserVip + 89, // 39: hyapp.wallet.v1.ListVipPackagesResponse.packages:type_name -> hyapp.wallet.v1.VipLevel + 90, // 40: hyapp.wallet.v1.GetMyVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip + 90, // 41: hyapp.wallet.v1.PurchaseVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip + 88, // 42: hyapp.wallet.v1.PurchaseVipResponse.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem + 90, // 43: hyapp.wallet.v1.GrantVipResponse.vip:type_name -> hyapp.wallet.v1.UserVip + 88, // 44: hyapp.wallet.v1.GrantVipResponse.reward_items:type_name -> hyapp.wallet.v1.VipRewardItem + 89, // 45: hyapp.wallet.v1.ListAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel + 99, // 46: hyapp.wallet.v1.UpdateAdminVipLevelsRequest.levels:type_name -> hyapp.wallet.v1.AdminVipLevelInput + 89, // 47: hyapp.wallet.v1.UpdateAdminVipLevelsResponse.levels:type_name -> hyapp.wallet.v1.VipLevel + 2, // 48: hyapp.wallet.v1.CreditTaskRewardResponse.balance:type_name -> hyapp.wallet.v1.AssetBalance + 109, // 49: hyapp.wallet.v1.RedPacket.claims:type_name -> hyapp.wallet.v1.RedPacketClaim + 108, // 50: hyapp.wallet.v1.GetRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig + 108, // 51: hyapp.wallet.v1.UpdateRedPacketConfigResponse.config:type_name -> hyapp.wallet.v1.RedPacketConfig + 110, // 52: hyapp.wallet.v1.CreateRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket + 109, // 53: hyapp.wallet.v1.ClaimRedPacketResponse.claim:type_name -> hyapp.wallet.v1.RedPacketClaim + 110, // 54: hyapp.wallet.v1.ListRedPacketsResponse.packets:type_name -> hyapp.wallet.v1.RedPacket + 110, // 55: hyapp.wallet.v1.GetRedPacketResponse.packet:type_name -> hyapp.wallet.v1.RedPacket + 0, // 56: hyapp.wallet.v1.WalletService.DebitGift:input_type -> hyapp.wallet.v1.DebitGiftRequest + 3, // 57: hyapp.wallet.v1.WalletService.GetBalances:input_type -> hyapp.wallet.v1.GetBalancesRequest + 5, // 58: hyapp.wallet.v1.WalletService.AdminCreditAsset:input_type -> hyapp.wallet.v1.AdminCreditAssetRequest + 7, // 59: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:input_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockRequest + 9, // 60: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:input_type -> hyapp.wallet.v1.TransferCoinFromSellerRequest + 20, // 61: hyapp.wallet.v1.WalletService.ListResources:input_type -> hyapp.wallet.v1.ListResourcesRequest + 22, // 62: hyapp.wallet.v1.WalletService.GetResource:input_type -> hyapp.wallet.v1.GetResourceRequest + 24, // 63: hyapp.wallet.v1.WalletService.CreateResource:input_type -> hyapp.wallet.v1.CreateResourceRequest + 25, // 64: hyapp.wallet.v1.WalletService.UpdateResource:input_type -> hyapp.wallet.v1.UpdateResourceRequest + 26, // 65: hyapp.wallet.v1.WalletService.SetResourceStatus:input_type -> hyapp.wallet.v1.SetResourceStatusRequest + 28, // 66: hyapp.wallet.v1.WalletService.ListResourceGroups:input_type -> hyapp.wallet.v1.ListResourceGroupsRequest + 30, // 67: hyapp.wallet.v1.WalletService.GetResourceGroup:input_type -> hyapp.wallet.v1.GetResourceGroupRequest + 32, // 68: hyapp.wallet.v1.WalletService.CreateResourceGroup:input_type -> hyapp.wallet.v1.CreateResourceGroupRequest + 33, // 69: hyapp.wallet.v1.WalletService.UpdateResourceGroup:input_type -> hyapp.wallet.v1.UpdateResourceGroupRequest + 34, // 70: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:input_type -> hyapp.wallet.v1.SetResourceGroupStatusRequest + 36, // 71: hyapp.wallet.v1.WalletService.ListGiftConfigs:input_type -> hyapp.wallet.v1.ListGiftConfigsRequest + 38, // 72: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:input_type -> hyapp.wallet.v1.ListGiftTypeConfigsRequest + 42, // 73: hyapp.wallet.v1.WalletService.CreateGiftConfig:input_type -> hyapp.wallet.v1.CreateGiftConfigRequest + 43, // 74: hyapp.wallet.v1.WalletService.UpdateGiftConfig:input_type -> hyapp.wallet.v1.UpdateGiftConfigRequest + 44, // 75: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:input_type -> hyapp.wallet.v1.SetGiftConfigStatusRequest + 40, // 76: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:input_type -> hyapp.wallet.v1.UpsertGiftTypeConfigRequest + 46, // 77: hyapp.wallet.v1.WalletService.GrantResource:input_type -> hyapp.wallet.v1.GrantResourceRequest + 47, // 78: hyapp.wallet.v1.WalletService.GrantResourceGroup:input_type -> hyapp.wallet.v1.GrantResourceGroupRequest + 49, // 79: hyapp.wallet.v1.WalletService.ListUserResources:input_type -> hyapp.wallet.v1.ListUserResourcesRequest + 51, // 80: hyapp.wallet.v1.WalletService.EquipUserResource:input_type -> hyapp.wallet.v1.EquipUserResourceRequest + 53, // 81: hyapp.wallet.v1.WalletService.ListResourceGrants:input_type -> hyapp.wallet.v1.ListResourceGrantsRequest + 56, // 82: hyapp.wallet.v1.WalletService.ListRechargeBills:input_type -> hyapp.wallet.v1.ListRechargeBillsRequest + 59, // 83: hyapp.wallet.v1.WalletService.GetWalletOverview:input_type -> hyapp.wallet.v1.GetWalletOverviewRequest + 62, // 84: hyapp.wallet.v1.WalletService.GetWalletValueSummary:input_type -> hyapp.wallet.v1.GetWalletValueSummaryRequest + 65, // 85: hyapp.wallet.v1.WalletService.GetUserGiftWall:input_type -> hyapp.wallet.v1.GetUserGiftWallRequest + 68, // 86: hyapp.wallet.v1.WalletService.ListRechargeProducts:input_type -> hyapp.wallet.v1.ListRechargeProductsRequest + 70, // 87: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:input_type -> hyapp.wallet.v1.ConfirmGooglePaymentRequest + 72, // 88: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:input_type -> hyapp.wallet.v1.ListAdminRechargeProductsRequest + 74, // 89: hyapp.wallet.v1.WalletService.CreateRechargeProduct:input_type -> hyapp.wallet.v1.CreateRechargeProductRequest + 75, // 90: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:input_type -> hyapp.wallet.v1.UpdateRechargeProductRequest + 76, // 91: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:input_type -> hyapp.wallet.v1.DeleteRechargeProductRequest + 80, // 92: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:input_type -> hyapp.wallet.v1.GetDiamondExchangeConfigRequest + 83, // 93: hyapp.wallet.v1.WalletService.ListWalletTransactions:input_type -> hyapp.wallet.v1.ListWalletTransactionsRequest + 86, // 94: hyapp.wallet.v1.WalletService.ApplyWithdrawal:input_type -> hyapp.wallet.v1.ApplyWithdrawalRequest + 91, // 95: hyapp.wallet.v1.WalletService.ListVipPackages:input_type -> hyapp.wallet.v1.ListVipPackagesRequest + 93, // 96: hyapp.wallet.v1.WalletService.GetMyVip:input_type -> hyapp.wallet.v1.GetMyVipRequest + 95, // 97: hyapp.wallet.v1.WalletService.PurchaseVip:input_type -> hyapp.wallet.v1.PurchaseVipRequest + 97, // 98: hyapp.wallet.v1.WalletService.GrantVip:input_type -> hyapp.wallet.v1.GrantVipRequest + 100, // 99: hyapp.wallet.v1.WalletService.ListAdminVipLevels:input_type -> hyapp.wallet.v1.ListAdminVipLevelsRequest + 102, // 100: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:input_type -> hyapp.wallet.v1.UpdateAdminVipLevelsRequest + 104, // 101: hyapp.wallet.v1.WalletService.CreditTaskReward:input_type -> hyapp.wallet.v1.CreditTaskRewardRequest + 106, // 102: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:input_type -> hyapp.wallet.v1.ApplyGameCoinChangeRequest + 111, // 103: hyapp.wallet.v1.WalletService.GetRedPacketConfig:input_type -> hyapp.wallet.v1.GetRedPacketConfigRequest + 113, // 104: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:input_type -> hyapp.wallet.v1.UpdateRedPacketConfigRequest + 115, // 105: hyapp.wallet.v1.WalletService.CreateRedPacket:input_type -> hyapp.wallet.v1.CreateRedPacketRequest + 117, // 106: hyapp.wallet.v1.WalletService.ClaimRedPacket:input_type -> hyapp.wallet.v1.ClaimRedPacketRequest + 119, // 107: hyapp.wallet.v1.WalletService.ListRedPackets:input_type -> hyapp.wallet.v1.ListRedPacketsRequest + 121, // 108: hyapp.wallet.v1.WalletService.GetRedPacket:input_type -> hyapp.wallet.v1.GetRedPacketRequest + 123, // 109: hyapp.wallet.v1.WalletService.ExpireRedPackets:input_type -> hyapp.wallet.v1.ExpireRedPacketsRequest + 1, // 110: hyapp.wallet.v1.WalletService.DebitGift:output_type -> hyapp.wallet.v1.DebitGiftResponse + 4, // 111: hyapp.wallet.v1.WalletService.GetBalances:output_type -> hyapp.wallet.v1.GetBalancesResponse + 6, // 112: hyapp.wallet.v1.WalletService.AdminCreditAsset:output_type -> hyapp.wallet.v1.AdminCreditAssetResponse + 8, // 113: hyapp.wallet.v1.WalletService.AdminCreditCoinSellerStock:output_type -> hyapp.wallet.v1.AdminCreditCoinSellerStockResponse + 10, // 114: hyapp.wallet.v1.WalletService.TransferCoinFromSeller:output_type -> hyapp.wallet.v1.TransferCoinFromSellerResponse + 21, // 115: hyapp.wallet.v1.WalletService.ListResources:output_type -> hyapp.wallet.v1.ListResourcesResponse + 23, // 116: hyapp.wallet.v1.WalletService.GetResource:output_type -> hyapp.wallet.v1.GetResourceResponse + 27, // 117: hyapp.wallet.v1.WalletService.CreateResource:output_type -> hyapp.wallet.v1.ResourceResponse + 27, // 118: hyapp.wallet.v1.WalletService.UpdateResource:output_type -> hyapp.wallet.v1.ResourceResponse + 27, // 119: hyapp.wallet.v1.WalletService.SetResourceStatus:output_type -> hyapp.wallet.v1.ResourceResponse + 29, // 120: hyapp.wallet.v1.WalletService.ListResourceGroups:output_type -> hyapp.wallet.v1.ListResourceGroupsResponse + 31, // 121: hyapp.wallet.v1.WalletService.GetResourceGroup:output_type -> hyapp.wallet.v1.GetResourceGroupResponse + 35, // 122: hyapp.wallet.v1.WalletService.CreateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 35, // 123: hyapp.wallet.v1.WalletService.UpdateResourceGroup:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 35, // 124: hyapp.wallet.v1.WalletService.SetResourceGroupStatus:output_type -> hyapp.wallet.v1.ResourceGroupResponse + 37, // 125: hyapp.wallet.v1.WalletService.ListGiftConfigs:output_type -> hyapp.wallet.v1.ListGiftConfigsResponse + 39, // 126: hyapp.wallet.v1.WalletService.ListGiftTypeConfigs:output_type -> hyapp.wallet.v1.ListGiftTypeConfigsResponse + 45, // 127: hyapp.wallet.v1.WalletService.CreateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse + 45, // 128: hyapp.wallet.v1.WalletService.UpdateGiftConfig:output_type -> hyapp.wallet.v1.GiftConfigResponse + 45, // 129: hyapp.wallet.v1.WalletService.SetGiftConfigStatus:output_type -> hyapp.wallet.v1.GiftConfigResponse + 41, // 130: hyapp.wallet.v1.WalletService.UpsertGiftTypeConfig:output_type -> hyapp.wallet.v1.GiftTypeConfigResponse + 48, // 131: hyapp.wallet.v1.WalletService.GrantResource:output_type -> hyapp.wallet.v1.ResourceGrantResponse + 48, // 132: hyapp.wallet.v1.WalletService.GrantResourceGroup:output_type -> hyapp.wallet.v1.ResourceGrantResponse + 50, // 133: hyapp.wallet.v1.WalletService.ListUserResources:output_type -> hyapp.wallet.v1.ListUserResourcesResponse + 52, // 134: hyapp.wallet.v1.WalletService.EquipUserResource:output_type -> hyapp.wallet.v1.EquipUserResourceResponse + 54, // 135: hyapp.wallet.v1.WalletService.ListResourceGrants:output_type -> hyapp.wallet.v1.ListResourceGrantsResponse + 57, // 136: hyapp.wallet.v1.WalletService.ListRechargeBills:output_type -> hyapp.wallet.v1.ListRechargeBillsResponse + 60, // 137: hyapp.wallet.v1.WalletService.GetWalletOverview:output_type -> hyapp.wallet.v1.GetWalletOverviewResponse + 63, // 138: hyapp.wallet.v1.WalletService.GetWalletValueSummary:output_type -> hyapp.wallet.v1.GetWalletValueSummaryResponse + 66, // 139: hyapp.wallet.v1.WalletService.GetUserGiftWall:output_type -> hyapp.wallet.v1.GetUserGiftWallResponse + 69, // 140: hyapp.wallet.v1.WalletService.ListRechargeProducts:output_type -> hyapp.wallet.v1.ListRechargeProductsResponse + 71, // 141: hyapp.wallet.v1.WalletService.ConfirmGooglePayment:output_type -> hyapp.wallet.v1.ConfirmGooglePaymentResponse + 73, // 142: hyapp.wallet.v1.WalletService.ListAdminRechargeProducts:output_type -> hyapp.wallet.v1.ListAdminRechargeProductsResponse + 77, // 143: hyapp.wallet.v1.WalletService.CreateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse + 77, // 144: hyapp.wallet.v1.WalletService.UpdateRechargeProduct:output_type -> hyapp.wallet.v1.RechargeProductResponse + 78, // 145: hyapp.wallet.v1.WalletService.DeleteRechargeProduct:output_type -> hyapp.wallet.v1.DeleteRechargeProductResponse + 81, // 146: hyapp.wallet.v1.WalletService.GetDiamondExchangeConfig:output_type -> hyapp.wallet.v1.GetDiamondExchangeConfigResponse + 84, // 147: hyapp.wallet.v1.WalletService.ListWalletTransactions:output_type -> hyapp.wallet.v1.ListWalletTransactionsResponse + 87, // 148: hyapp.wallet.v1.WalletService.ApplyWithdrawal:output_type -> hyapp.wallet.v1.ApplyWithdrawalResponse + 92, // 149: hyapp.wallet.v1.WalletService.ListVipPackages:output_type -> hyapp.wallet.v1.ListVipPackagesResponse + 94, // 150: hyapp.wallet.v1.WalletService.GetMyVip:output_type -> hyapp.wallet.v1.GetMyVipResponse + 96, // 151: hyapp.wallet.v1.WalletService.PurchaseVip:output_type -> hyapp.wallet.v1.PurchaseVipResponse + 98, // 152: hyapp.wallet.v1.WalletService.GrantVip:output_type -> hyapp.wallet.v1.GrantVipResponse + 101, // 153: hyapp.wallet.v1.WalletService.ListAdminVipLevels:output_type -> hyapp.wallet.v1.ListAdminVipLevelsResponse + 103, // 154: hyapp.wallet.v1.WalletService.UpdateAdminVipLevels:output_type -> hyapp.wallet.v1.UpdateAdminVipLevelsResponse + 105, // 155: hyapp.wallet.v1.WalletService.CreditTaskReward:output_type -> hyapp.wallet.v1.CreditTaskRewardResponse + 107, // 156: hyapp.wallet.v1.WalletService.ApplyGameCoinChange:output_type -> hyapp.wallet.v1.ApplyGameCoinChangeResponse + 112, // 157: hyapp.wallet.v1.WalletService.GetRedPacketConfig:output_type -> hyapp.wallet.v1.GetRedPacketConfigResponse + 114, // 158: hyapp.wallet.v1.WalletService.UpdateRedPacketConfig:output_type -> hyapp.wallet.v1.UpdateRedPacketConfigResponse + 116, // 159: hyapp.wallet.v1.WalletService.CreateRedPacket:output_type -> hyapp.wallet.v1.CreateRedPacketResponse + 118, // 160: hyapp.wallet.v1.WalletService.ClaimRedPacket:output_type -> hyapp.wallet.v1.ClaimRedPacketResponse + 120, // 161: hyapp.wallet.v1.WalletService.ListRedPackets:output_type -> hyapp.wallet.v1.ListRedPacketsResponse + 122, // 162: hyapp.wallet.v1.WalletService.GetRedPacket:output_type -> hyapp.wallet.v1.GetRedPacketResponse + 124, // 163: hyapp.wallet.v1.WalletService.ExpireRedPackets:output_type -> hyapp.wallet.v1.ExpireRedPacketsResponse + 110, // [110:164] is the sub-list for method output_type + 56, // [56:110] is the sub-list for method input_type + 56, // [56:56] is the sub-list for extension type_name + 56, // [56:56] is the sub-list for extension extendee + 0, // [0:56] is the sub-list for field type_name } func init() { file_proto_wallet_v1_wallet_proto_init() } @@ -12396,7 +12662,7 @@ func file_proto_wallet_v1_wallet_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wallet_v1_wallet_proto_rawDesc), len(file_proto_wallet_v1_wallet_proto_rawDesc)), NumEnums: 0, - NumMessages: 123, + NumMessages: 125, NumExtensions: 0, NumServices: 1, }, diff --git a/api/proto/wallet/v1/wallet.proto b/api/proto/wallet/v1/wallet.proto index f7d2d9f7..7fbe4862 100644 --- a/api/proto/wallet/v1/wallet.proto +++ b/api/proto/wallet/v1/wallet.proto @@ -745,6 +745,32 @@ message ListRechargeProductsResponse { repeated string channels = 2; } +message ConfirmGooglePaymentRequest { + string request_id = 1; + string app_code = 2; + string command_id = 3; + int64 user_id = 4; + int64 region_id = 5; + int64 product_id = 6; + string product_code = 7; + string package_name = 8; + string purchase_token = 9; + string order_id = 10; + int64 purchase_time_ms = 11; +} + +message ConfirmGooglePaymentResponse { + string payment_order_id = 1; + string transaction_id = 2; + string status = 3; + int64 product_id = 4; + string product_code = 5; + int64 coin_amount = 6; + AssetBalance balance = 7; + bool idempotent_replay = 8; + string consume_state = 9; +} + // ListAdminRechargeProductsRequest 是后台内购配置列表查询,不参与用户充值主链路。 message ListAdminRechargeProductsRequest { string request_id = 1; @@ -1233,6 +1259,7 @@ service WalletService { rpc GetWalletValueSummary(GetWalletValueSummaryRequest) returns (GetWalletValueSummaryResponse); rpc GetUserGiftWall(GetUserGiftWallRequest) returns (GetUserGiftWallResponse); rpc ListRechargeProducts(ListRechargeProductsRequest) returns (ListRechargeProductsResponse); + rpc ConfirmGooglePayment(ConfirmGooglePaymentRequest) returns (ConfirmGooglePaymentResponse); rpc ListAdminRechargeProducts(ListAdminRechargeProductsRequest) returns (ListAdminRechargeProductsResponse); rpc CreateRechargeProduct(CreateRechargeProductRequest) returns (RechargeProductResponse); rpc UpdateRechargeProduct(UpdateRechargeProductRequest) returns (RechargeProductResponse); diff --git a/api/proto/wallet/v1/wallet_grpc.pb.go b/api/proto/wallet/v1/wallet_grpc.pb.go index e77e6eb1..75372705 100644 --- a/api/proto/wallet/v1/wallet_grpc.pb.go +++ b/api/proto/wallet/v1/wallet_grpc.pb.go @@ -50,6 +50,7 @@ const ( WalletService_GetWalletValueSummary_FullMethodName = "/hyapp.wallet.v1.WalletService/GetWalletValueSummary" WalletService_GetUserGiftWall_FullMethodName = "/hyapp.wallet.v1.WalletService/GetUserGiftWall" WalletService_ListRechargeProducts_FullMethodName = "/hyapp.wallet.v1.WalletService/ListRechargeProducts" + WalletService_ConfirmGooglePayment_FullMethodName = "/hyapp.wallet.v1.WalletService/ConfirmGooglePayment" WalletService_ListAdminRechargeProducts_FullMethodName = "/hyapp.wallet.v1.WalletService/ListAdminRechargeProducts" WalletService_CreateRechargeProduct_FullMethodName = "/hyapp.wallet.v1.WalletService/CreateRechargeProduct" WalletService_UpdateRechargeProduct_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateRechargeProduct" @@ -111,6 +112,7 @@ type WalletServiceClient interface { GetWalletValueSummary(ctx context.Context, in *GetWalletValueSummaryRequest, opts ...grpc.CallOption) (*GetWalletValueSummaryResponse, error) GetUserGiftWall(ctx context.Context, in *GetUserGiftWallRequest, opts ...grpc.CallOption) (*GetUserGiftWallResponse, error) ListRechargeProducts(ctx context.Context, in *ListRechargeProductsRequest, opts ...grpc.CallOption) (*ListRechargeProductsResponse, error) + ConfirmGooglePayment(ctx context.Context, in *ConfirmGooglePaymentRequest, opts ...grpc.CallOption) (*ConfirmGooglePaymentResponse, error) ListAdminRechargeProducts(ctx context.Context, in *ListAdminRechargeProductsRequest, opts ...grpc.CallOption) (*ListAdminRechargeProductsResponse, error) CreateRechargeProduct(ctx context.Context, in *CreateRechargeProductRequest, opts ...grpc.CallOption) (*RechargeProductResponse, error) UpdateRechargeProduct(ctx context.Context, in *UpdateRechargeProductRequest, opts ...grpc.CallOption) (*RechargeProductResponse, error) @@ -453,6 +455,16 @@ func (c *walletServiceClient) ListRechargeProducts(ctx context.Context, in *List return out, nil } +func (c *walletServiceClient) ConfirmGooglePayment(ctx context.Context, in *ConfirmGooglePaymentRequest, opts ...grpc.CallOption) (*ConfirmGooglePaymentResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ConfirmGooglePaymentResponse) + err := c.cc.Invoke(ctx, WalletService_ConfirmGooglePayment_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *walletServiceClient) ListAdminRechargeProducts(ctx context.Context, in *ListAdminRechargeProductsRequest, opts ...grpc.CallOption) (*ListAdminRechargeProductsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListAdminRechargeProductsResponse) @@ -710,6 +722,7 @@ type WalletServiceServer interface { GetWalletValueSummary(context.Context, *GetWalletValueSummaryRequest) (*GetWalletValueSummaryResponse, error) GetUserGiftWall(context.Context, *GetUserGiftWallRequest) (*GetUserGiftWallResponse, error) ListRechargeProducts(context.Context, *ListRechargeProductsRequest) (*ListRechargeProductsResponse, error) + ConfirmGooglePayment(context.Context, *ConfirmGooglePaymentRequest) (*ConfirmGooglePaymentResponse, error) ListAdminRechargeProducts(context.Context, *ListAdminRechargeProductsRequest) (*ListAdminRechargeProductsResponse, error) CreateRechargeProduct(context.Context, *CreateRechargeProductRequest) (*RechargeProductResponse, error) UpdateRechargeProduct(context.Context, *UpdateRechargeProductRequest) (*RechargeProductResponse, error) @@ -835,6 +848,9 @@ func (UnimplementedWalletServiceServer) GetUserGiftWall(context.Context, *GetUse func (UnimplementedWalletServiceServer) ListRechargeProducts(context.Context, *ListRechargeProductsRequest) (*ListRechargeProductsResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListRechargeProducts not implemented") } +func (UnimplementedWalletServiceServer) ConfirmGooglePayment(context.Context, *ConfirmGooglePaymentRequest) (*ConfirmGooglePaymentResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ConfirmGooglePayment not implemented") +} func (UnimplementedWalletServiceServer) ListAdminRechargeProducts(context.Context, *ListAdminRechargeProductsRequest) (*ListAdminRechargeProductsResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListAdminRechargeProducts not implemented") } @@ -1480,6 +1496,24 @@ func _WalletService_ListRechargeProducts_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _WalletService_ConfirmGooglePayment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmGooglePaymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WalletServiceServer).ConfirmGooglePayment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WalletService_ConfirmGooglePayment_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WalletServiceServer).ConfirmGooglePayment(ctx, req.(*ConfirmGooglePaymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _WalletService_ListAdminRechargeProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListAdminRechargeProductsRequest) if err := dec(in); err != nil { @@ -2007,6 +2041,10 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListRechargeProducts", Handler: _WalletService_ListRechargeProducts_Handler, }, + { + MethodName: "ConfirmGooglePayment", + Handler: _WalletService_ConfirmGooglePayment_Handler, + }, { MethodName: "ListAdminRechargeProducts", Handler: _WalletService_ListAdminRechargeProducts_Handler, diff --git a/docs/ExploreTab-Flutter-App对接文档.md b/docs/ExploreTab-Flutter-App对接文档.md new file mode 100644 index 00000000..89248528 --- /dev/null +++ b/docs/ExploreTab-Flutter-App对接文档.md @@ -0,0 +1,268 @@ +# Explore tab Flutter App 对接文档 + +本文档定义 App 端 Explore 页 H5 tab 的读取接口。后台在 `HYApp 管理平台 / APP配置 / Explore配置` 维护 tab 名称和 H5 链接;App 只读取已启用配置并按服务端返回顺序展示。 + +## 基础约定 + +本地网关地址: + +```text +http://127.0.0.1:13000 +``` + +所有 `/api/v1` 业务接口使用统一响应外壳: + +```json +{ + "code": "OK", + "message": "ok", + "request_id": "req_xxx", + "data": {} +} +``` + +客户端成功判断: + +```text +HTTP 200 && code == "OK" +``` + +失败时保留 `request_id`,用于后端排查日志。 + +## App 标识 Header + +Explore tab 按 App 隔离,接口没有 query/body 形式的 `app_code` 参数。gateway 通过 Header 解析 App: + +| Header | 必填 | 说明 | +| --- | --- | --- | +| `X-App-Code` | 推荐 | 内部 App code,例如 `lalu`。 | +| `X-HY-App-Code` | 否 | `X-App-Code` 的兼容别名。 | +| `X-App-Package` | 推荐二选一 | App 包名,例如 `com.org.laluparty`。传包名时 gateway 可解析到内部 `app_code`。 | +| `X-App-Platform` | 包名解析时推荐 | 平台,例如 `android`、`ios`。 | + +当前开发默认 `app_code` 是 `lalu`。Flutter 仍建议显式传 `X-App-Code` 或 `X-App-Package`,避免多 App 环境串配置。 + +## 获取 Explore tab 列表 + +接口地址: + +```http +GET /api/v1/app/explore-tabs +``` + +完整本地地址: + +```text +http://127.0.0.1:13000/api/v1/app/explore-tabs +``` + +鉴权: + +```text +不需要 Bearer token +``` + +服务端行为: + +- 只返回当前 App 已启用的 Explore tabs。 +- 后台关闭的 tab 不下发给 App。 +- 返回顺序为后台 `sort_order` 升序,同排序时按较新的记录优先。 + +### 请求 Header + +```http +X-App-Code: lalu +``` + +或: + +```http +X-App-Package: com.org.laluparty +X-App-Platform: android +``` + +### Query 参数 + +无。 + +### Request Body + +无。 + +### curl 示例 + +```bash +curl -X GET 'http://127.0.0.1:13000/api/v1/app/explore-tabs' \ + -H 'X-App-Code: lalu' +``` + +包名解析方式: + +```bash +curl -X GET 'http://127.0.0.1:13000/api/v1/app/explore-tabs' \ + -H 'X-App-Package: com.org.laluparty' \ + -H 'X-App-Platform: android' +``` + +### 成功响应 + +```json +{ + "code": "OK", + "message": "ok", + "request_id": "req_xxx", + "data": { + "items": [ + { + "id": 7, + "app_code": "lalu", + "tab": "Farm", + "h5_url": "https://www.baidu.com", + "enabled": true, + "sort_order": 1, + "updated_at_ms": 1700000000000 + } + ], + "total": 1 + } +} +``` + +### `data` 字段 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `items` | array | Explore tab 列表。 | +| `total` | int | 本次返回数量。 | + +### `items[]` 字段 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | int | 后台配置记录 ID,只用于排查或本地缓存 key,不作为业务路由。 | +| `app_code` | string | tab 所属 App,例如 `lalu`。 | +| `tab` | string | App 展示的 tab 文案。 | +| `h5_url` | string | 点击 tab 后加载的 H5 地址。 | +| `enabled` | bool | 是否启用。App 接口只返回 `true` 的记录。 | +| `sort_order` | int | 展示排序,数值越小越靠前。 | +| `updated_at_ms` | int | 更新时间,Unix epoch milliseconds。 | + +### 空列表响应 + +当后台没有启用的 Explore tab 时,返回空数组,不是错误: + +```json +{ + "code": "OK", + "message": "ok", + "request_id": "req_xxx", + "data": { + "items": [], + "total": 0 + } +} +``` + +### 错误响应 + +配置读取异常时: + +```json +{ + "code": "UPSTREAM_ERROR", + "message": "upstream service error", + "request_id": "req_xxx" +} +``` + +客户端处理建议: + +- `UPSTREAM_ERROR`:展示空态或保留上一次本地缓存。 +- 非 `OK`:不要使用 `data`。 +- 记录 `request_id` 到客户端日志,便于问题排查。 + +## Flutter 数据模型 + +```dart +class ExploreTabList { + final List items; + final int total; + + ExploreTabList({ + required this.items, + required this.total, + }); + + factory ExploreTabList.fromJson(Map json) { + final rawItems = json['items'] as List? ?? const []; + return ExploreTabList( + items: rawItems + .map((e) => ExploreTabItem.fromJson(e as Map)) + .toList(), + total: json['total'] as int? ?? rawItems.length, + ); + } +} + +class ExploreTabItem { + final int id; + final String appCode; + final String tab; + final String h5Url; + final bool enabled; + final int sortOrder; + final int updatedAtMs; + + ExploreTabItem({ + required this.id, + required this.appCode, + required this.tab, + required this.h5Url, + required this.enabled, + required this.sortOrder, + required this.updatedAtMs, + }); + + factory ExploreTabItem.fromJson(Map json) { + return ExploreTabItem( + id: json['id'] as int? ?? 0, + appCode: json['app_code'] as String? ?? '', + tab: json['tab'] as String? ?? '', + h5Url: json['h5_url'] as String? ?? '', + enabled: json['enabled'] as bool? ?? false, + sortOrder: json['sort_order'] as int? ?? 0, + updatedAtMs: json['updated_at_ms'] as int? ?? 0, + ); + } +} +``` + +## Flutter Dio 示例 + +```dart +Future fetchExploreTabs(Dio dio) async { + final response = await dio.get( + '/api/v1/app/explore-tabs', + options: Options( + headers: { + 'X-App-Code': 'lalu', + }, + ), + ); + + final body = response.data as Map; + if (body['code'] != 'OK') { + throw Exception('${body['code']}: ${body['message']} request_id=${body['request_id']}'); + } + + return ExploreTabList.fromJson(body['data'] as Map); +} +``` + +## 展示和跳转规则 + +- App 按 `items` 返回顺序展示,不需要二次排序。 +- `tab` 为空或 `h5_url` 为空时,建议 App 跳过该项,避免展示不可点击入口。 +- 点击 tab 后打开 `h5_url`,由 H5 页面自身处理内部导航。 +- 如果接口失败,App 可以使用本地缓存的上一版 tabs;没有缓存时展示空态。 + diff --git a/docs/flutter对接/Google Play充值Flutter对接.md b/docs/flutter对接/Google Play充值Flutter对接.md index ca7c3c78..cae9dada 100644 --- a/docs/flutter对接/Google Play充值Flutter对接.md +++ b/docs/flutter对接/Google Play充值Flutter对接.md @@ -20,16 +20,16 @@ Flutter 只有在 `code == "OK"` 时读取 `data`。其他错误必须记录 `re 已实现: - `GET /api/v1/wallet/recharge/products`:App 端充值商品列表。 +- `POST /api/v1/wallet/payments/google/confirm`:提交 Google purchase token,后端调用 Google Play Developer API 校验、入账、写支付订单审计并 consume。 - `GET /api/v1/wallet/me/balances`:刷新金币余额。 - 钱包余额 IM 通知:`WalletBalanceChanged`。 +- `payment_orders`:保存 Google provider 订单审计,purchase token 只落 SHA256,不落明文。 后端待补齐: -- `POST /api/v1/wallet/payments/google/confirm`:提交 Google purchase token,后端校验并入账。 - Google Play RTDN / Pub/Sub 回调:只做补偿通知,不替代客户端确认接口。 -- `payment_orders` 和 Google provider 订单审计表。 -Flutter 可以先按本文契约接商品列表和本地 Google Billing 流程;确认支付接口需要等后端补齐后联调。 +Flutter 可以按本文契约联调商品列表、本地 Google Billing 流程和确认支付接口。 ## 2. Flutter 依赖 @@ -200,7 +200,7 @@ void startPurchaseListener() { ## 6. 确认 Google 支付 -后端待实现接口: +后端已实现接口: `POST /api/v1/wallet/payments/google/confirm` @@ -214,7 +214,7 @@ void startPurchaseListener() { | `X-App-Code` | 否 | App 编码,默认 `lalu`。 | | `X-App-Platform` | 是 | 固定传 `android`。 | -请求体建议契约: +请求体: ```json { @@ -232,7 +232,7 @@ void startPurchaseListener() { | 字段 | 必填 | 说明 | | --- | --- | --- | -| `command_id` | 是 | 客户端幂等 ID。同一个 purchase token 重试必须使用同一个值。 | +| `command_id` | 是 | 客户端幂等 ID。同一个 purchase token 重试建议使用同一个值。后端最终还会按 purchase token 去重。 | | `product_id` | 是 | 后端商品列表返回的本地商品 ID。 | | `product_code` | 是 | 后端商品列表返回的 Google productId。 | | `package_name` | 是 | 当前 Android 包名。 | @@ -246,7 +246,7 @@ void startPurchaseListener() { final String commandId = 'google-pay-${sha256Of(purchaseToken).substring(0, 24)}'; ``` -成功响应建议契约: +成功响应: ```json { @@ -254,7 +254,7 @@ final String commandId = 'google-pay-${sha256Of(purchaseToken).substring(0, 24)} "message": "ok", "request_id": "req_abc", "data": { - "payment_order_id": "pay_google_xxx", + "payment_order_id": "gpay_xxx", "transaction_id": "wtx_xxx", "status": "credited", "product_id": 11, @@ -276,16 +276,26 @@ Flutter 成功处理: - `status=credited`:展示充值成功,刷新 `/wallet/me/balances`。 - `idempotent_replay=true`:按成功处理,不重复提示异常。 -- `consume_state=consume_pending`:仍按到账成功处理;后端会补偿 consume。 +- `consume_state=consumed`:后端已完成 Google consume。 +- `consume_state=consume_pending`:仍按到账成功处理;说明入账已成功但后端 consume 调用短时失败,下一次提交同一 token 会继续尝试 consume。 - 后端成功后调用 `InAppPurchase.instance.completePurchase(purchaseDetails)`,结束客户端 pending 状态。 失败处理: - `UNAUTHORIZED`:登录失效,走登录态恢复。 -- `INVALID_ARGUMENT`:商品 ID、token、包名等参数错误,记录 `request_id`。 +- `INVALID_ARGUMENT`:商品 ID、token、包名等参数错误,或 Google 判定 token 无效,记录 `request_id`。 +- `CONFLICT`:商品未上架、商品区域不匹配、Google purchase state 不是 `PURCHASED`、Google productId/orderId 与后端商品不一致;不入账。 - `UPSTREAM_ERROR` / `INTERNAL_ERROR`:保留订单为待确认,稍后重试。 - provider 校验失败:不入账,不 complete purchase;记录 `request_id` 并触发补单或客服入口。 +后端校验和审计规则: + +- 后端使用 Google Play Developer API `purchases.productsv2.getproductpurchasev2` 查询 purchase token,只接受 `purchaseState=PURCHASED`。 +- Google 返回的 `productLineItem[0].productId` 必须等于后端商品 `product_code`。 +- 后端以 `payment_orders(app_code, provider, purchase_token_hash)` 做 provider 幂等,同一个 token 不会重复发币。 +- 后端入账成功后写 `wallet_transactions`、`wallet_entries`、`wallet_recharge_records`、`payment_orders` 和 `wallet_outbox`。 +- 后端不会记录明文 `purchase_token`,只保存 SHA256 hash 和 Google 返回快照。 + ## 7. 补单规则 Flutter 必须做补单,因为用户可能在支付成功后断网、杀进程或后端短时失败。 diff --git a/docs/openapi/gateway.swagger.yaml b/docs/openapi/gateway.swagger.yaml index 4c1cb207..f0739d6f 100644 --- a/docs/openapi/gateway.swagger.yaml +++ b/docs/openapi/gateway.swagger.yaml @@ -2156,6 +2156,38 @@ paths: $ref: "#/responses/Internal" "502": $ref: "#/responses/UpstreamError" + /api/v1/wallet/payments/google/confirm: + post: + tags: + - wallet + summary: 确认 Google Play 充值支付 + operationId: confirmGooglePayment + description: App 支付成功后提交 Google purchase token;后端调用 Google Play Developer API 校验,成功后写入钱包账本、充值记录、payment_orders 审计并尝试 consume。接口支持按 purchase token 幂等重试。 + security: + - BearerAuth: [] + parameters: + - name: body + in: body + required: true + schema: + $ref: "#/definitions/GooglePaymentConfirmRequest" + responses: + "200": + description: 校验成功并已入账;`consume_state=consume_pending` 也表示已入账成功,只是 Google consume 待后续重试。 + schema: + $ref: "#/definitions/GooglePaymentConfirmEnvelope" + "400": + $ref: "#/responses/BadRequest" + "401": + $ref: "#/responses/Unauthorized" + "403": + $ref: "#/responses/Forbidden" + "409": + $ref: "#/responses/Conflict" + "500": + $ref: "#/responses/Internal" + "502": + $ref: "#/responses/UpstreamError" /api/v1/wallet/coin-seller/transfer: post: tags: @@ -3800,6 +3832,75 @@ definitions: type: array items: $ref: "#/definitions/RechargeProductData" + GooglePaymentConfirmRequest: + type: object + required: + - command_id + - product_id + - package_name + - purchase_token + properties: + command_id: + type: string + description: 客户端确认支付幂等键;同一 purchase token 重试建议复用。 + product_id: + type: integer + format: int64 + description: 后端充值商品 ID。 + product_code: + type: string + description: 后端返回的 Google productId,必须与 Play Console 商品 ID 一致。 + package_name: + type: string + description: Android 包名。 + purchase_token: + type: string + description: Google Play Billing 返回的 serverVerificationData,服务端只保存 SHA256。 + order_id: + type: string + description: Google orderId;客户端拿不到时可不传。 + purchase_time_ms: + type: integer + format: int64 + description: 客户端购买时间,UTC epoch ms,仅用于排障。 + GooglePaymentConfirmData: + type: object + properties: + payment_order_id: + type: string + transaction_id: + type: string + status: + type: string + enum: [credited] + product_id: + type: integer + format: int64 + product_code: + type: string + coin_amount: + type: integer + format: int64 + balance: + type: object + properties: + asset_type: + type: string + example: COIN + available_amount: + type: integer + format: int64 + frozen_amount: + type: integer + format: int64 + version: + type: integer + format: int64 + idempotent_replay: + type: boolean + consume_state: + type: string + enum: [consume_pending, consumed] CoinSellerTransferRequest: type: object required: @@ -5095,6 +5196,13 @@ definitions: properties: data: $ref: "#/definitions/RechargeProductListData" + GooglePaymentConfirmEnvelope: + allOf: + - $ref: "#/definitions/GatewayOKEnvelopeBase" + - type: object + properties: + data: + $ref: "#/definitions/GooglePaymentConfirmData" CoinSellerTransferEnvelope: allOf: - $ref: "#/definitions/GatewayOKEnvelopeBase" diff --git a/server/admin/internal/modules/resource/handler.go b/server/admin/internal/modules/resource/handler.go index d7377153..f59fffb1 100644 --- a/server/admin/internal/modules/resource/handler.go +++ b/server/admin/internal/modules/resource/handler.go @@ -351,6 +351,37 @@ func (h *Handler) UpdateGiftType(c *gin.Context) { response.OK(c, item) } +func (h *Handler) UpdateGiftTypes(c *gin.Context) { + var req giftTypesRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.BadRequest(c, "礼物类型参数不正确") + return + } + if len(req.Items) == 0 { + response.BadRequest(c, "礼物类型不能为空") + return + } + items := make([]giftTypeDTO, 0, len(req.Items)) + tabKeys := make([]string, 0, len(req.Items)) + for _, requestItem := range req.Items { + tabKey := strings.TrimSpace(requestItem.TabKey) + if tabKey == "" { + response.BadRequest(c, "类型编码不正确") + return + } + resp, err := h.wallet.UpsertGiftTypeConfig(c.Request.Context(), requestItem.upsertProto(c)) + if err != nil { + response.BadRequest(c, err.Error()) + return + } + item := giftTypeFromProto(resp.GetGiftType()) + items = append(items, item) + tabKeys = append(tabKeys, item.TabKey) + } + h.auditLog(c, "update-gift-types", "gift_type_configs", "batch", "success", strings.Join(tabKeys, ",")) + response.OK(c, items) +} + func (h *Handler) CreateGift(c *gin.Context) { var req giftRequest if err := c.ShouldBindJSON(&req); err != nil { diff --git a/server/admin/internal/modules/resource/request.go b/server/admin/internal/modules/resource/request.go index 47ca33b2..b7575b4f 100644 --- a/server/admin/internal/modules/resource/request.go +++ b/server/admin/internal/modules/resource/request.go @@ -122,6 +122,18 @@ type giftTypeRequest struct { SortOrder int32 `json:"sortOrder"` } +type giftTypesRequest struct { + Items []giftTypeItemRequest `json:"items"` +} + +type giftTypeItemRequest struct { + TabKey string `json:"tabKey"` + DisplayName string `json:"displayName"` + TabName string `json:"tabName"` + Status string `json:"status"` + SortOrder int32 `json:"sortOrder"` +} + type grantResourceRequest struct { CommandID string `json:"commandId"` TargetUserID int64 `json:"targetUserId"` @@ -326,6 +338,15 @@ func (r giftTypeRequest) upsertProto(c *gin.Context, typeCode string) *walletv1. } } +func (r giftTypeItemRequest) upsertProto(c *gin.Context) *walletv1.UpsertGiftTypeConfigRequest { + return giftTypeRequest{ + DisplayName: r.DisplayName, + TabName: r.TabName, + Status: r.Status, + SortOrder: r.SortOrder, + }.upsertProto(c, r.TabKey) +} + func managerGrantEnabledOrDefault(value *bool) *bool { enabled := true if value != nil { diff --git a/server/admin/internal/modules/resource/routes.go b/server/admin/internal/modules/resource/routes.go index c5b8a555..002d77b5 100644 --- a/server/admin/internal/modules/resource/routes.go +++ b/server/admin/internal/modules/resource/routes.go @@ -32,6 +32,7 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) { protected.GET("/admin/gifts", middleware.RequirePermission("gift:view"), h.ListGifts) protected.GET("/admin/gift-types", middleware.RequirePermission("gift:view"), h.ListGiftTypes) + protected.PUT("/admin/gift-types", middleware.RequirePermission("gift:update"), h.UpdateGiftTypes) protected.PUT("/admin/gift-types/:type_code", middleware.RequirePermission("gift:update"), h.UpdateGiftType) protected.POST("/admin/gifts", middleware.RequirePermission("gift:create"), h.CreateGift) protected.PUT("/admin/gifts/:gift_id", middleware.RequirePermission("gift:update"), h.UpdateGift) diff --git a/services/gateway-service/internal/client/wallet_client.go b/services/gateway-service/internal/client/wallet_client.go index 30ea4628..9dde6e5d 100644 --- a/services/gateway-service/internal/client/wallet_client.go +++ b/services/gateway-service/internal/client/wallet_client.go @@ -15,6 +15,7 @@ type WalletClient interface { GetWalletValueSummary(ctx context.Context, req *walletv1.GetWalletValueSummaryRequest) (*walletv1.GetWalletValueSummaryResponse, error) GetUserGiftWall(ctx context.Context, req *walletv1.GetUserGiftWallRequest) (*walletv1.GetUserGiftWallResponse, error) ListRechargeProducts(ctx context.Context, req *walletv1.ListRechargeProductsRequest) (*walletv1.ListRechargeProductsResponse, error) + ConfirmGooglePayment(ctx context.Context, req *walletv1.ConfirmGooglePaymentRequest) (*walletv1.ConfirmGooglePaymentResponse, error) GetDiamondExchangeConfig(ctx context.Context, req *walletv1.GetDiamondExchangeConfigRequest) (*walletv1.GetDiamondExchangeConfigResponse, error) ListWalletTransactions(ctx context.Context, req *walletv1.ListWalletTransactionsRequest) (*walletv1.ListWalletTransactionsResponse, error) ApplyWithdrawal(ctx context.Context, req *walletv1.ApplyWithdrawalRequest) (*walletv1.ApplyWithdrawalResponse, error) @@ -66,6 +67,10 @@ func (c *grpcWalletClient) ListRechargeProducts(ctx context.Context, req *wallet return c.client.ListRechargeProducts(ctx, req) } +func (c *grpcWalletClient) ConfirmGooglePayment(ctx context.Context, req *walletv1.ConfirmGooglePaymentRequest) (*walletv1.ConfirmGooglePaymentResponse, error) { + return c.client.ConfirmGooglePayment(ctx, req) +} + func (c *grpcWalletClient) GetDiamondExchangeConfig(ctx context.Context, req *walletv1.GetDiamondExchangeConfigRequest) (*walletv1.GetDiamondExchangeConfigResponse, error) { return c.client.GetDiamondExchangeConfig(ctx, req) } diff --git a/services/gateway-service/internal/transport/http/httproutes/router.go b/services/gateway-service/internal/transport/http/httproutes/router.go index 23653ffe..9842d621 100644 --- a/services/gateway-service/internal/transport/http/httproutes/router.go +++ b/services/gateway-service/internal/transport/http/httproutes/router.go @@ -154,6 +154,7 @@ type WalletHandlers struct { GetWalletOverview http.HandlerFunc GetMyBalances http.HandlerFunc ListRechargeProducts http.HandlerFunc + ConfirmGooglePayment http.HandlerFunc GetDiamondExchangeConfig http.HandlerFunc ApplyWithdrawal http.HandlerFunc ListCoinTransactions http.HandlerFunc @@ -361,6 +362,7 @@ func (r routes) registerWalletRoutes() { r.profile("/wallet/me/overview", http.MethodGet, h.GetWalletOverview) r.profile("/wallet/me/balances", "", h.GetMyBalances) r.profile("/wallet/recharge/products", http.MethodGet, h.ListRechargeProducts) + r.profile("/wallet/payments/google/confirm", http.MethodPost, h.ConfirmGooglePayment) r.profile("/wallet/diamond-exchange/config", http.MethodGet, h.GetDiamondExchangeConfig) r.profile("/wallet/withdrawals/apply", http.MethodPost, h.ApplyWithdrawal) r.profile("/wallet/coin-transactions", http.MethodGet, h.ListCoinTransactions) diff --git a/services/gateway-service/internal/transport/http/response_test.go b/services/gateway-service/internal/transport/http/response_test.go index 0f6b3d28..2943ecab 100644 --- a/services/gateway-service/internal/transport/http/response_test.go +++ b/services/gateway-service/internal/transport/http/response_test.go @@ -346,6 +346,8 @@ type fakeWalletClient struct { giftWallResp *walletv1.GetUserGiftWallResponse lastRechargeProducts *walletv1.ListRechargeProductsRequest rechargeProductsResp *walletv1.ListRechargeProductsResponse + lastGoogleConfirm *walletv1.ConfirmGooglePaymentRequest + googleConfirmResp *walletv1.ConfirmGooglePaymentResponse lastDiamondExchange *walletv1.GetDiamondExchangeConfigRequest diamondExchangeResp *walletv1.GetDiamondExchangeConfigResponse lastTransactions *walletv1.ListWalletTransactionsRequest @@ -1041,6 +1043,17 @@ func (f *fakeWalletClient) ListRechargeProducts(_ context.Context, req *walletv1 return &walletv1.ListRechargeProductsResponse{}, nil } +func (f *fakeWalletClient) ConfirmGooglePayment(_ context.Context, req *walletv1.ConfirmGooglePaymentRequest) (*walletv1.ConfirmGooglePaymentResponse, error) { + f.lastGoogleConfirm = req + if f.err != nil { + return nil, f.err + } + if f.googleConfirmResp != nil { + return f.googleConfirmResp, nil + } + return &walletv1.ConfirmGooglePaymentResponse{}, nil +} + func (f *fakeWalletClient) GetDiamondExchangeConfig(_ context.Context, req *walletv1.GetDiamondExchangeConfigRequest) (*walletv1.GetDiamondExchangeConfigResponse, error) { f.lastDiamondExchange = req if f.err != nil { @@ -3624,6 +3637,60 @@ func TestListRechargeProductsUsesProfileRegionAndPlatform(t *testing.T) { } } +func TestConfirmGooglePaymentUsesAuthenticatedUserAndProfileRegion(t *testing.T) { + walletClient := &fakeWalletClient{googleConfirmResp: &walletv1.ConfirmGooglePaymentResponse{ + PaymentOrderId: "gpay_abc", + TransactionId: "wtx_abc", + Status: "credited", + ProductId: 11, + ProductCode: "iap_android_11", + CoinAmount: 1500, + Balance: &walletv1.AssetBalance{ + AssetType: "COIN", + AvailableAmount: 2500, + }, + ConsumeState: "consumed", + }} + profileClient := &fakeUserProfileClient{regionID: 2002} + handler := NewHandlerWithClients(&fakeRoomClient{}, nil, nil, profileClient) + handler.SetWalletClient(walletClient) + router := handler.Routes(auth.NewVerifier("secret")) + body := `{"command_id":"pay-cmd-1","product_id":11,"product_code":"iap_android_11","package_name":"com.hyapp.lalu","purchase_token":"purchase-token","order_id":"GPA.1","purchase_time_ms":1710000000000}` + request := httptest.NewRequest(http.MethodPost, "/api/v1/wallet/payments/google/confirm", bytes.NewBufferString(body)) + request.Header.Set("Authorization", "Bearer "+signGatewayToken(t, "secret", 42)) + request.Header.Set("Content-Type", "application/json") + request.Header.Set("X-Request-ID", "req-google-confirm") + recorder := httptest.NewRecorder() + + router.ServeHTTP(recorder, request) + + if recorder.Code != http.StatusOK { + t.Fatalf("status mismatch: got %d body=%s", recorder.Code, recorder.Body.String()) + } + if profileClient.lastGet == nil || profileClient.lastGet.GetUserId() != 42 { + t.Fatalf("profile lookup mismatch: %+v", profileClient.lastGet) + } + if walletClient.lastGoogleConfirm == nil || + walletClient.lastGoogleConfirm.GetUserId() != 42 || + walletClient.lastGoogleConfirm.GetRegionId() != 2002 || + walletClient.lastGoogleConfirm.GetProductId() != 11 || + walletClient.lastGoogleConfirm.GetProductCode() != "iap_android_11" || + walletClient.lastGoogleConfirm.GetPackageName() != "com.hyapp.lalu" || + walletClient.lastGoogleConfirm.GetPurchaseToken() != "purchase-token" || + walletClient.lastGoogleConfirm.GetCommandId() != "pay-cmd-1" || + walletClient.lastGoogleConfirm.GetRequestId() != assertGeneratedRequestID(t, recorder, "req-google-confirm") { + t.Fatalf("google confirm request mismatch: %+v", walletClient.lastGoogleConfirm) + } + var response httpkit.ResponseEnvelope + if err := json.NewDecoder(recorder.Body).Decode(&response); err != nil { + t.Fatalf("decode response failed: %v", err) + } + data, ok := response.Data.(map[string]any) + if response.Code != httpkit.CodeOK || !ok || data["payment_order_id"] != "gpay_abc" || data["consume_state"] != "consumed" || data["coin_amount"] != float64(1500) { + t.Fatalf("google confirm response mismatch: %+v", response) + } +} + func TestCoinSellerTransferChecksIdentityAndPropagatesWalletCommand(t *testing.T) { walletClient := &fakeWalletClient{transferResp: &walletv1.TransferCoinFromSellerResponse{ TransactionId: "wtx-coin-seller", diff --git a/services/gateway-service/internal/transport/http/walletapi/app_wallet_handler.go b/services/gateway-service/internal/transport/http/walletapi/app_wallet_handler.go index 35a260d4..a2667a13 100644 --- a/services/gateway-service/internal/transport/http/walletapi/app_wallet_handler.go +++ b/services/gateway-service/internal/transport/http/walletapi/app_wallet_handler.go @@ -105,6 +105,35 @@ type withdrawalApplyRequestBody struct { Reason string `json:"reason"` } +type googlePaymentConfirmRequestBody struct { + CommandID string `json:"command_id"` + CommandIDAlt string `json:"commandId"` + ProductID int64 `json:"product_id"` + ProductIDAlt int64 `json:"productId"` + ProductCode string `json:"product_code"` + ProductCodeAlt string `json:"productCode"` + PackageName string `json:"package_name"` + PackageNameAlt string `json:"packageName"` + PurchaseToken string `json:"purchase_token"` + PurchaseAlt string `json:"purchaseToken"` + OrderID string `json:"order_id"` + OrderIDAlt string `json:"orderId"` + PurchaseTimeMS int64 `json:"purchase_time_ms"` + PurchaseTimeAlt int64 `json:"purchaseTimeMs"` +} + +type googlePaymentConfirmData struct { + PaymentOrderID string `json:"payment_order_id"` + TransactionID string `json:"transaction_id"` + Status string `json:"status"` + ProductID int64 `json:"product_id"` + ProductCode string `json:"product_code"` + CoinAmount int64 `json:"coin_amount"` + Balance assetBalanceData `json:"balance"` + IdempotentReplay bool `json:"idempotent_replay"` + ConsumeState string `json:"consume_state"` +} + type withdrawalData struct { WithdrawalID string `json:"withdrawal_id"` UserID int64 `json:"user_id"` @@ -199,6 +228,77 @@ func (h *Handler) listRechargeProducts(writer http.ResponseWriter, request *http httpkit.WriteOK(writer, request, map[string]any{"channels": resp.GetChannels(), "products": products}) } +// confirmGooglePayment 接收 App 支付成功后的 Google purchase_token,转交 wallet-service 做服务端校验和入账。 +func (h *Handler) confirmGooglePayment(writer http.ResponseWriter, request *http.Request) { + if h.walletClient == nil || h.userProfileClient == nil { + httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error") + return + } + var body googlePaymentConfirmRequestBody + if !httpkit.Decode(writer, request, &body) { + return + } + commandID := strings.TrimSpace(body.CommandID) + if commandID == "" { + commandID = strings.TrimSpace(body.CommandIDAlt) + } + productID := body.ProductID + if productID <= 0 { + productID = body.ProductIDAlt + } + productCode := strings.TrimSpace(body.ProductCode) + if productCode == "" { + productCode = strings.TrimSpace(body.ProductCodeAlt) + } + packageName := strings.TrimSpace(body.PackageName) + if packageName == "" { + packageName = strings.TrimSpace(body.PackageNameAlt) + } + purchaseToken := strings.TrimSpace(body.PurchaseToken) + if purchaseToken == "" { + purchaseToken = strings.TrimSpace(body.PurchaseAlt) + } + orderID := strings.TrimSpace(body.OrderID) + if orderID == "" { + orderID = strings.TrimSpace(body.OrderIDAlt) + } + purchaseTimeMS := body.PurchaseTimeMS + if purchaseTimeMS <= 0 { + purchaseTimeMS = body.PurchaseTimeAlt + } + if commandID == "" || productID <= 0 || packageName == "" || purchaseToken == "" { + httpkit.WriteError(writer, request, http.StatusBadRequest, httpkit.CodeInvalidArgument, "invalid argument") + return + } + userID := auth.UserIDFromContext(request.Context()) + profileResp, err := h.userProfileClient.GetUser(request.Context(), &userv1.GetUserRequest{ + Meta: httpkit.UserMeta(request, ""), + UserId: userID, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + resp, err := h.walletClient.ConfirmGooglePayment(request.Context(), &walletv1.ConfirmGooglePaymentRequest{ + RequestId: httpkit.RequestIDFromContext(request.Context()), + AppCode: appcode.FromContext(request.Context()), + CommandId: commandID, + UserId: userID, + RegionId: profileResp.GetUser().GetRegionId(), + ProductId: productID, + ProductCode: productCode, + PackageName: packageName, + PurchaseToken: purchaseToken, + OrderId: orderID, + PurchaseTimeMs: purchaseTimeMS, + }) + if err != nil { + httpkit.WriteRPCError(writer, request, err) + return + } + httpkit.WriteOK(writer, request, googlePaymentConfirmFromProto(resp)) +} + // getDiamondExchangeConfig 返回钻石兑换配置。 func (h *Handler) getDiamondExchangeConfig(writer http.ResponseWriter, request *http.Request) { if h.walletClient == nil { @@ -347,6 +447,23 @@ func rechargeProductFromProto(product *walletv1.RechargeProduct) rechargeProduct } } +func googlePaymentConfirmFromProto(resp *walletv1.ConfirmGooglePaymentResponse) googlePaymentConfirmData { + if resp == nil { + return googlePaymentConfirmData{} + } + return googlePaymentConfirmData{ + PaymentOrderID: resp.GetPaymentOrderId(), + TransactionID: resp.GetTransactionId(), + Status: resp.GetStatus(), + ProductID: resp.GetProductId(), + ProductCode: resp.GetProductCode(), + CoinAmount: resp.GetCoinAmount(), + Balance: balanceFromProto(resp.GetBalance()), + IdempotentReplay: resp.GetIdempotentReplay(), + ConsumeState: resp.GetConsumeState(), + } +} + func diamondExchangeRuleFromProto(rule *walletv1.DiamondExchangeRule) diamondExchangeRuleData { if rule == nil { return diamondExchangeRuleData{} diff --git a/services/gateway-service/internal/transport/http/walletapi/handler.go b/services/gateway-service/internal/transport/http/walletapi/handler.go index 860b6428..3d9d87c2 100644 --- a/services/gateway-service/internal/transport/http/walletapi/handler.go +++ b/services/gateway-service/internal/transport/http/walletapi/handler.go @@ -40,6 +40,7 @@ func (h *Handler) WalletHandlers() httproutes.WalletHandlers { GetWalletOverview: h.getWalletOverview, GetMyBalances: h.getMyBalances, ListRechargeProducts: h.listRechargeProducts, + ConfirmGooglePayment: h.confirmGooglePayment, GetDiamondExchangeConfig: h.getDiamondExchangeConfig, ApplyWithdrawal: h.applyWithdrawal, ListCoinTransactions: h.listCoinTransactions, diff --git a/services/wallet-service/configs/config.docker.yaml b/services/wallet-service/configs/config.docker.yaml index a28f1945..ae296fd2 100644 --- a/services/wallet-service/configs/config.docker.yaml +++ b/services/wallet-service/configs/config.docker.yaml @@ -31,6 +31,15 @@ rocketmq: enabled: true topic: "hyapp_wallet_outbox" producer_group: "hyapp-wallet-outbox-producer" +google_play: + enabled: false + package_name: "" + service_account_file: "" + service_account_json: "" + api_base_url: "https://androidpublisher.googleapis.com" + token_url: "https://oauth2.googleapis.com/token" + http_timeout: "10s" + consume_enabled: true outbox_worker: enabled: true poll_interval: "1s" diff --git a/services/wallet-service/configs/config.tencent.example.yaml b/services/wallet-service/configs/config.tencent.example.yaml index 6b78ba40..967d7a30 100644 --- a/services/wallet-service/configs/config.tencent.example.yaml +++ b/services/wallet-service/configs/config.tencent.example.yaml @@ -31,6 +31,15 @@ rocketmq: enabled: true topic: "hyapp_wallet_outbox" producer_group: "hyapp-wallet-outbox-producer" +google_play: + enabled: false + package_name: "com.example.hyapp" + service_account_file: "/etc/hyapp/secrets/google-play-service-account.json" + service_account_json: "" + api_base_url: "https://androidpublisher.googleapis.com" + token_url: "https://oauth2.googleapis.com/token" + http_timeout: "10s" + consume_enabled: true outbox_worker: enabled: true poll_interval: "1s" diff --git a/services/wallet-service/configs/config.yaml b/services/wallet-service/configs/config.yaml index 748d8a0e..cc0cecb3 100644 --- a/services/wallet-service/configs/config.yaml +++ b/services/wallet-service/configs/config.yaml @@ -31,6 +31,15 @@ rocketmq: enabled: false topic: "hyapp_wallet_outbox" producer_group: "hyapp-wallet-outbox-producer" +google_play: + enabled: false + package_name: "" + service_account_file: "" + service_account_json: "" + api_base_url: "https://androidpublisher.googleapis.com" + token_url: "https://oauth2.googleapis.com/token" + http_timeout: "10s" + consume_enabled: true outbox_worker: enabled: false poll_interval: "1s" diff --git a/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql b/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql index 6ec12e53..3705b311 100644 --- a/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql +++ b/services/wallet-service/deploy/mysql/initdb/001_wallet_service.sql @@ -243,6 +243,35 @@ CREATE TABLE IF NOT EXISTS wallet_recharge_product_regions ( KEY idx_wallet_recharge_product_regions_region (app_code, region_id, product_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钱包充值商品区域表'; +CREATE TABLE IF NOT EXISTS payment_orders ( + app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', + payment_order_id VARCHAR(96) NOT NULL COMMENT '平台支付订单 ID', + provider VARCHAR(32) NOT NULL COMMENT '支付提供方', + channel VARCHAR(32) NOT NULL COMMENT '充值渠道', + status VARCHAR(32) NOT NULL COMMENT '订单状态', + command_id VARCHAR(128) NOT NULL COMMENT '客户端确认命令幂等 ID', + user_id BIGINT NOT NULL COMMENT '用户 ID', + product_id BIGINT NOT NULL COMMENT '后台充值商品 ID', + product_code VARCHAR(128) NOT NULL COMMENT 'Google Play 商品 ID', + package_name VARCHAR(256) NOT NULL DEFAULT '' COMMENT 'Google Play 包名', + provider_order_id VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'Google Play orderId', + purchase_token_hash VARCHAR(128) NOT NULL COMMENT 'Google purchase token SHA256,不落明文 token', + purchase_state VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'Google purchase state', + consume_state VARCHAR(32) NOT NULL DEFAULT '' COMMENT 'Google consume 状态', + wallet_transaction_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '钱包交易 ID', + coin_amount BIGINT NOT NULL COMMENT '到账金币数量', + currency_code VARCHAR(8) NOT NULL DEFAULT '' COMMENT '商品币种编码', + amount_micro BIGINT NOT NULL DEFAULT 0 COMMENT '商品金额微单位', + provider_payload JSON NULL COMMENT 'Google Play 校验返回快照', + created_at_ms BIGINT NOT NULL COMMENT '创建时间,UTC epoch ms', + updated_at_ms BIGINT NOT NULL COMMENT '更新时间,UTC epoch ms', + PRIMARY KEY (app_code, payment_order_id), + UNIQUE KEY uk_payment_orders_token (app_code, provider, purchase_token_hash), + UNIQUE KEY uk_payment_orders_command (app_code, command_id), + KEY idx_payment_orders_user_time (app_code, user_id, created_at_ms), + KEY idx_payment_orders_provider_order (app_code, provider, provider_order_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='支付订单与 provider 审计表'; + CREATE TABLE IF NOT EXISTS coin_seller_stock_records ( app_code VARCHAR(32) NOT NULL DEFAULT 'lalu' COMMENT '应用编码,用于多租户隔离', stock_id VARCHAR(96) NOT NULL COMMENT '库存 ID', diff --git a/services/wallet-service/internal/app/app.go b/services/wallet-service/internal/app/app.go index 0885bf7d..3b5a891a 100644 --- a/services/wallet-service/internal/app/app.go +++ b/services/wallet-service/internal/app/app.go @@ -22,6 +22,7 @@ import ( "hyapp/pkg/rocketmqx" "hyapp/pkg/walletmq" "hyapp/services/wallet-service/internal/client" + "hyapp/services/wallet-service/internal/client/googleplay" "hyapp/services/wallet-service/internal/config" walletservice "hyapp/services/wallet-service/internal/service/wallet" mysqlstorage "hyapp/services/wallet-service/internal/storage/mysql" @@ -82,6 +83,19 @@ func New(cfg config.Config) (*App, error) { server := grpc.NewServer(grpc.UnaryInterceptor(logx.UnaryServerInterceptor("wallet-service"))) svc := walletservice.New(repository, client.NewActivityAchievementClient(activityConn)) + if cfg.GooglePlay.Enabled { + googleClient, err := googleplay.New(cfg.GooglePlay) + if err != nil { + if outboxProducer != nil { + _ = outboxProducer.Shutdown() + } + _ = activityConn.Close() + _ = listener.Close() + _ = repository.Close() + return nil, err + } + svc.SetGooglePlayClient(googleClient) + } walletv1.RegisterWalletServiceServer(server, grpcserver.NewServer(svc)) health := grpchealth.NewServingChecker("wallet-service", grpchealth.Dependency{ Name: "mysql", diff --git a/services/wallet-service/internal/client/googleplay/client.go b/services/wallet-service/internal/client/googleplay/client.go new file mode 100644 index 00000000..eb74620c --- /dev/null +++ b/services/wallet-service/internal/client/googleplay/client.go @@ -0,0 +1,281 @@ +package googleplay + +import ( + "bytes" + "context" + "crypto/rsa" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "strings" + "sync" + "time" + + "github.com/golang-jwt/jwt/v5" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/config" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +const androidPublisherScope = "https://www.googleapis.com/auth/androidpublisher" + +// Client implements the minimal Google Play Developer API calls needed by wallet confirm. +type Client struct { + httpClient *http.Client + apiBaseURL string + tokenURL string + packageName string + consumeEnabled bool + email string + privateKey *rsa.PrivateKey + + mu sync.Mutex + accessToken string + expiresAt time.Time +} + +type serviceAccount struct { + ClientEmail string `json:"client_email"` + PrivateKey string `json:"private_key"` + TokenURI string `json:"token_uri"` +} + +// New creates a Google Play Developer API client from wallet-service config. +func New(cfg config.GooglePlayConfig) (*Client, error) { + body := strings.TrimSpace(cfg.ServiceAccountJSON) + if body == "" && strings.TrimSpace(cfg.ServiceAccountFile) != "" { + fileBody, err := os.ReadFile(strings.TrimSpace(cfg.ServiceAccountFile)) + if err != nil { + return nil, err + } + body = string(fileBody) + } + var account serviceAccount + if err := json.Unmarshal([]byte(body), &account); err != nil { + return nil, fmt.Errorf("parse google play service account: %w", err) + } + account.ClientEmail = strings.TrimSpace(account.ClientEmail) + account.PrivateKey = strings.TrimSpace(account.PrivateKey) + account.TokenURI = strings.TrimSpace(account.TokenURI) + if account.ClientEmail == "" || account.PrivateKey == "" { + return nil, errors.New("google play service account is incomplete") + } + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(account.PrivateKey)) + if err != nil { + return nil, fmt.Errorf("parse google play private key: %w", err) + } + tokenURL := strings.TrimSpace(cfg.TokenURL) + if tokenURL == "" { + tokenURL = account.TokenURI + } + if tokenURL == "" { + tokenURL = "https://oauth2.googleapis.com/token" + } + apiBaseURL := strings.TrimRight(strings.TrimSpace(cfg.APIBaseURL), "/") + if apiBaseURL == "" { + apiBaseURL = "https://androidpublisher.googleapis.com" + } + timeout := cfg.HTTPTimeout + if timeout <= 0 { + timeout = 10 * time.Second + } + return &Client{ + httpClient: &http.Client{Timeout: timeout}, + apiBaseURL: apiBaseURL, + tokenURL: tokenURL, + packageName: strings.TrimSpace(cfg.PackageName), + consumeEnabled: cfg.ConsumeEnabled, + email: account.ClientEmail, + privateKey: privateKey, + }, nil +} + +func (c *Client) GetProductPurchase(ctx context.Context, packageName string, purchaseToken string) (ledger.GooglePlayPurchase, error) { + if c == nil { + return ledger.GooglePlayPurchase{}, xerr.New(xerr.Unavailable, "google play client is not configured") + } + packageName = c.normalizePackageName(packageName) + purchaseToken = strings.TrimSpace(purchaseToken) + if packageName == "" || purchaseToken == "" { + return ledger.GooglePlayPurchase{}, xerr.New(xerr.InvalidArgument, "google play purchase request is incomplete") + } + endpoint := fmt.Sprintf("%s/androidpublisher/v3/applications/%s/purchases/productsv2/tokens/%s", + c.apiBaseURL, + url.PathEscape(packageName), + url.PathEscape(purchaseToken), + ) + body, err := c.doJSON(ctx, http.MethodGet, endpoint, nil) + if err != nil { + return ledger.GooglePlayPurchase{}, err + } + var parsed productPurchaseV2 + if err := json.Unmarshal(body, &parsed); err != nil { + return ledger.GooglePlayPurchase{}, err + } + purchase := ledger.GooglePlayPurchase{ + PackageName: packageName, + OrderID: parsed.OrderID, + PurchaseState: parsed.PurchaseStateContext.PurchaseState, + AcknowledgementState: parsed.AcknowledgementState, + PurchaseCompletionTime: parsed.PurchaseCompletionTime, + RawJSON: string(body), + } + if len(parsed.ProductLineItem) > 0 { + purchase.ProductID = parsed.ProductLineItem[0].ProductID + purchase.ConsumptionState = parsed.ProductLineItem[0].ProductOfferDetails.ConsumptionState + } + return purchase, nil +} + +func (c *Client) ConsumeProduct(ctx context.Context, packageName string, productID string, purchaseToken string) error { + if c == nil { + return xerr.New(xerr.Unavailable, "google play client is not configured") + } + if !c.consumeEnabled { + return xerr.New(xerr.Unavailable, "google play consume is disabled") + } + packageName = c.normalizePackageName(packageName) + productID = strings.TrimSpace(productID) + purchaseToken = strings.TrimSpace(purchaseToken) + if packageName == "" || productID == "" || purchaseToken == "" { + return xerr.New(xerr.InvalidArgument, "google play consume request is incomplete") + } + endpoint := fmt.Sprintf("%s/androidpublisher/v3/applications/%s/purchases/products/%s/tokens/%s:consume", + c.apiBaseURL, + url.PathEscape(packageName), + url.PathEscape(productID), + url.PathEscape(purchaseToken), + ) + _, err := c.doJSON(ctx, http.MethodPost, endpoint, bytes.NewReader(nil)) + return err +} + +func (c *Client) normalizePackageName(value string) string { + value = strings.TrimSpace(value) + if value != "" { + return value + } + return c.packageName +} + +func (c *Client) doJSON(ctx context.Context, method string, endpoint string, body io.Reader) ([]byte, error) { + token, err := c.token(ctx) + if err != nil { + return nil, err + } + req, err := http.NewRequestWithContext(ctx, method, endpoint, body) + if err != nil { + return nil, err + } + req.Header.Set("Authorization", "Bearer "+token) + if method != http.MethodGet { + req.Header.Set("Content-Type", "application/json") + } + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, xerr.New(xerr.Unavailable, "google play api request failed") + } + defer resp.Body.Close() + respBody, readErr := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if readErr != nil { + return nil, readErr + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusBadRequest { + return nil, xerr.New(xerr.InvalidArgument, "google play purchase token is invalid") + } + if resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden { + return nil, xerr.New(xerr.Unavailable, "google play api is not authorized") + } + return nil, xerr.New(xerr.Unavailable, "google play api returned non-success") + } + return respBody, nil +} + +func (c *Client) token(ctx context.Context) (string, error) { + c.mu.Lock() + if c.accessToken != "" && time.Now().Before(c.expiresAt.Add(-60*time.Second)) { + token := c.accessToken + c.mu.Unlock() + return token, nil + } + c.mu.Unlock() + + now := time.Now() + claims := jwt.MapClaims{ + "iss": c.email, + "scope": androidPublisherScope, + "aud": c.tokenURL, + "iat": now.Unix(), + "exp": now.Add(time.Hour).Unix(), + } + assertion, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(c.privateKey) + if err != nil { + return "", err + } + form := url.Values{} + form.Set("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer") + form.Set("assertion", assertion) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.tokenURL, strings.NewReader(form.Encode())) + if err != nil { + return "", err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + resp, err := c.httpClient.Do(req) + if err != nil { + return "", xerr.New(xerr.Unavailable, "google oauth token request failed") + } + defer resp.Body.Close() + respBody, readErr := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if readErr != nil { + return "", readErr + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return "", xerr.New(xerr.Unavailable, "google oauth token request failed") + } + var tokenResp struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + TokenType string `json:"token_type"` + } + if err := json.Unmarshal(respBody, &tokenResp); err != nil { + return "", err + } + if tokenResp.AccessToken == "" { + return "", xerr.New(xerr.Unavailable, "google oauth token response is incomplete") + } + expiresIn := time.Duration(tokenResp.ExpiresIn) * time.Second + if expiresIn <= 0 { + expiresIn = time.Hour + } + c.mu.Lock() + c.accessToken = tokenResp.AccessToken + c.expiresAt = now.Add(expiresIn) + c.mu.Unlock() + return tokenResp.AccessToken, nil +} + +type productPurchaseV2 struct { + ProductLineItem []productLineItem `json:"productLineItem"` + OrderID string `json:"orderId"` + PurchaseStateContext purchaseState `json:"purchaseStateContext"` + PurchaseCompletionTime string `json:"purchaseCompletionTime"` + AcknowledgementState string `json:"acknowledgementState"` +} + +type purchaseState struct { + PurchaseState string `json:"purchaseState"` +} + +type productLineItem struct { + ProductID string `json:"productId"` + ProductOfferDetails productOfferDetails `json:"productOfferDetails"` +} + +type productOfferDetails struct { + ConsumptionState string `json:"consumptionState"` +} diff --git a/services/wallet-service/internal/config/config.go b/services/wallet-service/internal/config/config.go index 29ae3214..eb6bb235 100644 --- a/services/wallet-service/internal/config/config.go +++ b/services/wallet-service/internal/config/config.go @@ -25,6 +25,8 @@ type Config struct { RedPacketExpiryWorker RedPacketExpiryWorkerConfig `yaml:"red_packet_expiry_worker"` // RocketMQ 控制 wallet_outbox 事实发布。 RocketMQ RocketMQConfig `yaml:"rocketmq"` + // GooglePlay 控制 Google Play Developer API 购买校验。 + GooglePlay GooglePlayConfig `yaml:"google_play"` // OutboxWorker 控制 wallet_outbox 到 MQ 的补偿投递。 OutboxWorker OutboxWorkerConfig `yaml:"outbox_worker"` // MySQLAutoMigrate 保留给显式本地迁移;线上 schema 由发布流程或 initdb 管理。 @@ -73,6 +75,18 @@ type OutboxWorkerConfig struct { MaxBackoff time.Duration `yaml:"max_backoff"` } +// GooglePlayConfig 保存 Google Play Developer API 服务账号和网络配置。 +type GooglePlayConfig struct { + Enabled bool `yaml:"enabled"` + PackageName string `yaml:"package_name"` + ServiceAccountFile string `yaml:"service_account_file"` + ServiceAccountJSON string `yaml:"service_account_json"` + APIBaseURL string `yaml:"api_base_url"` + TokenURL string `yaml:"token_url"` + HTTPTimeout time.Duration `yaml:"http_timeout"` + ConsumeEnabled bool `yaml:"consume_enabled"` +} + // Default 返回本地开发默认配置。 func Default() Config { return Config{ @@ -90,6 +104,13 @@ func Default() Config { BatchSize: 50, }, RocketMQ: defaultRocketMQConfig(), + GooglePlay: GooglePlayConfig{ + Enabled: false, + APIBaseURL: "https://androidpublisher.googleapis.com", + TokenURL: "https://oauth2.googleapis.com/token", + HTTPTimeout: 10 * time.Second, + ConsumeEnabled: true, + }, OutboxWorker: OutboxWorkerConfig{ Enabled: false, PollInterval: time.Second, @@ -167,6 +188,28 @@ func Load(path string) (Config, error) { return Config{}, err } cfg.RocketMQ = rocketMQ + cfg.GooglePlay.PackageName = strings.TrimSpace(cfg.GooglePlay.PackageName) + cfg.GooglePlay.ServiceAccountFile = strings.TrimSpace(cfg.GooglePlay.ServiceAccountFile) + cfg.GooglePlay.ServiceAccountJSON = strings.TrimSpace(cfg.GooglePlay.ServiceAccountJSON) + cfg.GooglePlay.APIBaseURL = strings.TrimRight(strings.TrimSpace(cfg.GooglePlay.APIBaseURL), "/") + if cfg.GooglePlay.APIBaseURL == "" { + cfg.GooglePlay.APIBaseURL = Default().GooglePlay.APIBaseURL + } + cfg.GooglePlay.TokenURL = strings.TrimSpace(cfg.GooglePlay.TokenURL) + if cfg.GooglePlay.TokenURL == "" { + cfg.GooglePlay.TokenURL = Default().GooglePlay.TokenURL + } + if cfg.GooglePlay.HTTPTimeout <= 0 { + cfg.GooglePlay.HTTPTimeout = Default().GooglePlay.HTTPTimeout + } + if cfg.GooglePlay.Enabled { + if cfg.GooglePlay.PackageName == "" { + return Config{}, errors.New("google_play package_name is required") + } + if cfg.GooglePlay.ServiceAccountFile == "" && cfg.GooglePlay.ServiceAccountJSON == "" { + return Config{}, errors.New("google_play service account is required") + } + } if cfg.OutboxWorker.PollInterval <= 0 { cfg.OutboxWorker.PollInterval = Default().OutboxWorker.PollInterval } diff --git a/services/wallet-service/internal/domain/ledger/ledger.go b/services/wallet-service/internal/domain/ledger/ledger.go index 6b16f7c2..33936cd6 100644 --- a/services/wallet-service/internal/domain/ledger/ledger.go +++ b/services/wallet-service/internal/domain/ledger/ledger.go @@ -32,6 +32,16 @@ const ( RechargeChannelGoogle = "google" // RechargeChannelApple 是 iOS 平台内购渠道标识。 RechargeChannelApple = "apple" + // PaymentProviderGooglePlay 是 Google Play 一次性内购支付渠道。 + PaymentProviderGooglePlay = "google_play" + // PaymentStatusCredited 表示支付已完成校验并入账。 + PaymentStatusCredited = "credited" + // PaymentConsumeStatePending 表示已入账但 Google consume 尚未确认完成。 + PaymentConsumeStatePending = "consume_pending" + // PaymentConsumeStateConsumed 表示 Google consume 已确认完成。 + PaymentConsumeStateConsumed = "consumed" + // GooglePurchaseStatePurchased 是 Google Play 已支付完成状态。 + GooglePurchaseStatePurchased = "PURCHASED" // WithdrawalStatusPending 表示主播美元余额提现已提交,等待后台人工审核和线下转账。 WithdrawalStatusPending = "pending" @@ -316,6 +326,45 @@ type RechargeProductCommand struct { OperatorUserID int64 } +// GooglePaymentCommand 是 App 完成 Google Play 支付后提交给后端确认和入账的命令。 +type GooglePaymentCommand struct { + AppCode string + CommandID string + UserID int64 + RegionID int64 + ProductID int64 + ProductCode string + PackageName string + PurchaseToken string + OrderID string + PurchaseTimeMS int64 +} + +// GooglePlayPurchase 是 Google Play Developer API 返回的一次性商品购买状态快照。 +type GooglePlayPurchase struct { + PackageName string + ProductID string + OrderID string + PurchaseState string + ConsumptionState string + AcknowledgementState string + PurchaseCompletionTime string + RawJSON string +} + +// GooglePaymentReceipt 是 Google 支付确认接口返回给 App 的稳定入账回执。 +type GooglePaymentReceipt struct { + PaymentOrderID string + TransactionID string + Status string + ProductID int64 + ProductCode string + CoinAmount int64 + Balance AssetBalance + IdempotentReplay bool + ConsumeState string +} + // DiamondExchangeRule 是钻石兑换金币或余额的固定规则投影。 type DiamondExchangeRule struct { ExchangeType string diff --git a/services/wallet-service/internal/service/wallet/service.go b/services/wallet-service/internal/service/wallet/service.go index 242b9503..ec755566 100644 --- a/services/wallet-service/internal/service/wallet/service.go +++ b/services/wallet-service/internal/service/wallet/service.go @@ -37,6 +37,9 @@ type Repository interface { GetUserGiftWall(ctx context.Context, userID int64) (ledger.UserGiftWall, error) ListRechargeProducts(ctx context.Context, userID int64, regionID int64, platform string) ([]ledger.RechargeProduct, []string, error) ListAdminRechargeProducts(ctx context.Context, query ledger.ListRechargeProductsQuery) ([]ledger.RechargeProduct, int64, error) + GetRechargeProduct(ctx context.Context, appCode string, productID int64) (ledger.RechargeProduct, error) + ConfirmGooglePayment(ctx context.Context, command ledger.GooglePaymentCommand, product ledger.RechargeProduct, purchase ledger.GooglePlayPurchase) (ledger.GooglePaymentReceipt, error) + MarkGooglePaymentConsumed(ctx context.Context, appCode string, paymentOrderID string) error CreateRechargeProduct(ctx context.Context, command ledger.RechargeProductCommand) (ledger.RechargeProduct, error) UpdateRechargeProduct(ctx context.Context, command ledger.RechargeProductCommand) (ledger.RechargeProduct, error) DeleteRechargeProduct(ctx context.Context, appCode string, productID int64) error @@ -81,10 +84,17 @@ type ActivityBadgeClient interface { ConsumeAchievementEvent(ctx context.Context, req *activityv1.ConsumeAchievementEventRequest, opts ...grpc.CallOption) (*activityv1.ConsumeAchievementEventResponse, error) } +// GooglePlayClient 隔离 Google Play Developer API,service 只依赖购买校验和消耗能力。 +type GooglePlayClient interface { + GetProductPurchase(ctx context.Context, packageName string, purchaseToken string) (ledger.GooglePlayPurchase, error) + ConsumeProduct(ctx context.Context, packageName string, productID string, purchaseToken string) error +} + // Service 承载钱包账务用例。 type Service struct { repository Repository activity ActivityBadgeClient + googlePlay GooglePlayClient now func() time.Time } @@ -97,6 +107,11 @@ func New(repository Repository, activity ...ActivityBadgeClient) *Service { return &Service{repository: repository, activity: activityClient, now: time.Now} } +// SetGooglePlayClient 注入 Google Play Developer API 客户端;未配置时 confirm 返回依赖不可用。 +func (s *Service) SetGooglePlayClient(client GooglePlayClient) { + s.googlePlay = client +} + // DebitGift 校验送礼扣费命令,并交给 repository 做原子落账和幂等。 func (s *Service) DebitGift(ctx context.Context, command ledger.DebitGiftCommand) (ledger.Receipt, error) { if command.CommandID == "" || command.RoomID == "" || command.SenderUserID <= 0 || command.TargetUserID <= 0 || command.GiftID == "" { @@ -491,6 +506,86 @@ func (s *Service) DeleteRechargeProduct(ctx context.Context, appCode string, pro return s.repository.DeleteRechargeProduct(ctx, appcode.FromContext(ctx), productID) } +// ConfirmGooglePayment 校验 Google Play purchase token,原子入账并记录支付审计。 +func (s *Service) ConfirmGooglePayment(ctx context.Context, command ledger.GooglePaymentCommand) (ledger.GooglePaymentReceipt, error) { + command.AppCode = appcode.Normalize(command.AppCode) + command.CommandID = strings.TrimSpace(command.CommandID) + command.ProductCode = strings.TrimSpace(command.ProductCode) + command.PackageName = strings.TrimSpace(command.PackageName) + command.PurchaseToken = strings.TrimSpace(command.PurchaseToken) + command.OrderID = strings.TrimSpace(command.OrderID) + if command.CommandID == "" || command.UserID <= 0 || command.RegionID <= 0 || command.ProductID <= 0 || command.PackageName == "" || command.PurchaseToken == "" { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.InvalidArgument, "google payment command is incomplete") + } + if len(command.CommandID) > 128 || len(command.PackageName) > 256 || len(command.PurchaseToken) > 4096 || len(command.OrderID) > 128 { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.InvalidArgument, "google payment command is too long") + } + if s.repository == nil { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Unavailable, "wallet repository is not configured") + } + if s.googlePlay == nil { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Unavailable, "google play client is not configured") + } + ctx = appcode.WithContext(ctx, command.AppCode) + + product, err := s.repository.GetRechargeProduct(ctx, command.AppCode, command.ProductID) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if product.Status != ledger.RechargeProductStatusActive || !product.Enabled { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "recharge product is not active") + } + if product.Platform != ledger.RechargeProductPlatformAndroid || product.Channel != ledger.RechargeChannelGoogle { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.InvalidArgument, "recharge product is not google play product") + } + if command.ProductCode != "" && command.ProductCode != product.ProductCode { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "product_code does not match") + } + if !rechargeProductSupportsRegion(product, command.RegionID) { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "recharge product is not available in user region") + } + + purchase, err := s.googlePlay.GetProductPurchase(ctx, command.PackageName, command.PurchaseToken) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if purchase.PackageName == "" { + purchase.PackageName = command.PackageName + } + if purchase.PackageName != command.PackageName { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "package_name does not match") + } + if purchase.PurchaseState != ledger.GooglePurchaseStatePurchased { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "google purchase is not purchased") + } + if purchase.ProductID != "" && purchase.ProductID != product.ProductCode { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "google product_id does not match recharge product") + } + if command.OrderID != "" && purchase.OrderID != "" && command.OrderID != purchase.OrderID { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "google order_id does not match") + } + + receipt, err := s.repository.ConfirmGooglePayment(ctx, command, product, purchase) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if receipt.ConsumeState == ledger.PaymentConsumeStateConsumed { + return receipt, nil + } + consumeProductID := product.ProductCode + if purchase.ProductID != "" { + consumeProductID = purchase.ProductID + } + if err := s.googlePlay.ConsumeProduct(ctx, command.PackageName, consumeProductID, command.PurchaseToken); err != nil { + return receipt, nil + } + if err := s.repository.MarkGooglePaymentConsumed(ctx, command.AppCode, receipt.PaymentOrderID); err != nil { + return receipt, nil + } + receipt.ConsumeState = ledger.PaymentConsumeStateConsumed + return receipt, nil +} + // GetDiamondExchangeConfig 返回当前 App 支持的钻石兑换规则。 func (s *Service) GetDiamondExchangeConfig(ctx context.Context, userID int64) ([]ledger.DiamondExchangeRule, error) { if userID <= 0 { @@ -669,3 +764,12 @@ func validateRechargeProductCommand(command ledger.RechargeProductCommand, requi } return nil } + +func rechargeProductSupportsRegion(product ledger.RechargeProduct, regionID int64) bool { + for _, productRegionID := range product.RegionIDs { + if productRegionID == regionID { + return true + } + } + return false +} diff --git a/services/wallet-service/internal/storage/mysql/google_payment_repository.go b/services/wallet-service/internal/storage/mysql/google_payment_repository.go new file mode 100644 index 00000000..3bbffa87 --- /dev/null +++ b/services/wallet-service/internal/storage/mysql/google_payment_repository.go @@ -0,0 +1,358 @@ +package mysql + +import ( + "context" + "database/sql" + "errors" + "fmt" + "strings" + "time" + + "hyapp/pkg/appcode" + "hyapp/pkg/xerr" + "hyapp/services/wallet-service/internal/domain/ledger" +) + +// ConfirmGooglePayment 将 Google Play 已购买 token 落为平台支付订单、钱包交易和充值审计记录。 +func (r *Repository) ConfirmGooglePayment(ctx context.Context, command ledger.GooglePaymentCommand, product ledger.RechargeProduct, purchase ledger.GooglePlayPurchase) (ledger.GooglePaymentReceipt, error) { + if r == nil || r.db == nil { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + ctx = contextWithCommandApp(ctx, command.AppCode) + command.AppCode = appcode.FromContext(ctx) + + tx, err := r.db.BeginTx(ctx, nil) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + defer func() { _ = tx.Rollback() }() + + tokenHash := googlePurchaseTokenHash(command.PurchaseToken) + if existing, exists, err := r.lookupGooglePaymentOrderByToken(ctx, tx, tokenHash); err != nil || exists { + if err != nil || !exists { + return ledger.GooglePaymentReceipt{}, err + } + if existing.UserID != command.UserID || existing.ProductID != product.ProductID { + return ledger.GooglePaymentReceipt{}, xerr.New(xerr.Conflict, "google purchase token belongs to another payment order") + } + return r.receiptForGooglePaymentOrder(ctx, tx, existing.PaymentOrderID, true) + } + + requestHash := googlePaymentRequestHash(command, product, purchase, tokenHash) + if txRow, exists, err := r.lookupTransaction(ctx, tx, command.CommandID, requestHash, bizTypeGooglePlayRecharge); err != nil || exists { + if err != nil || !exists { + return ledger.GooglePaymentReceipt{}, err + } + return r.receiptForGooglePaymentTransaction(ctx, tx, txRow.TransactionID, true) + } + + nowMs := time.Now().UnixMilli() + account, err := r.lockAccount(ctx, tx, command.UserID, ledger.AssetCoin, true, nowMs) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + transactionID := transactionID(command.AppCode, command.CommandID) + paymentOrderID := googlePaymentOrderID(command.AppCode, tokenHash) + balanceAfter := account.AvailableAmount + product.CoinAmount + rechargeSequence, err := r.reserveUserRechargeSequence(ctx, tx, command.AppCode, command.UserID, transactionID, product.CoinAmount, product.AmountMicro, nowMs) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + metadata := googlePaymentMetadata{ + AppCode: command.AppCode, + PaymentOrderID: paymentOrderID, + UserID: command.UserID, + RegionID: command.RegionID, + ProductID: product.ProductID, + ProductCode: product.ProductCode, + ProductName: product.ProductName, + PackageName: command.PackageName, + Provider: ledger.PaymentProviderGooglePlay, + Channel: ledger.RechargeChannelGoogle, + ProviderOrderID: purchase.OrderID, + ClientOrderID: command.OrderID, + PurchaseTokenHash: tokenHash, + PurchaseState: purchase.PurchaseState, + ConsumptionState: purchase.ConsumptionState, + AcknowledgementState: purchase.AcknowledgementState, + PurchaseCompletionTime: purchase.PurchaseCompletionTime, + CoinAmount: product.CoinAmount, + CurrencyCode: product.CurrencyCode, + AmountMicro: product.AmountMicro, + BalanceAfter: balanceAfter, + RechargeSequence: rechargeSequence, + CreatedAtMS: nowMs, + } + if err := r.insertTransaction(ctx, tx, transactionID, command.CommandID, bizTypeGooglePlayRecharge, requestHash, externalGooglePaymentRef(purchase, tokenHash), metadata, nowMs); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := r.applyAccountDelta(ctx, tx, account, product.CoinAmount, 0, nowMs); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := r.insertEntry(ctx, tx, walletEntry{ + TransactionID: transactionID, + UserID: command.UserID, + AssetType: ledger.AssetCoin, + AvailableDelta: product.CoinAmount, + FrozenDelta: 0, + AvailableAfter: balanceAfter, + FrozenAfter: account.FrozenAmount, + CreatedAtMS: nowMs, + }); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := r.insertRechargeRecord(ctx, tx, transactionID, coinSellerTransferMetadata{ + AppCode: command.AppCode, + TargetUserID: command.UserID, + TargetRegionID: command.RegionID, + Amount: product.CoinAmount, + TargetAssetType: ledger.AssetCoin, + TargetBalanceAfter: balanceAfter, + RechargeSequence: rechargeSequence, + RechargeUSDMinor: product.AmountMicro, + RechargeCurrencyCode: product.CurrencyCode, + RechargePolicyVersion: product.PolicyVersion, + RechargePolicyCoinAmount: product.CoinAmount, + RechargePolicyUSDMinorAmount: product.AmountMicro, + }, nowMs); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := r.insertGooglePaymentOrder(ctx, tx, paymentOrderID, command, product, purchase, tokenHash, transactionID, nowMs); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := r.insertWalletOutbox(ctx, tx, []walletOutboxEvent{ + balanceChangedEvent(transactionID, command.CommandID, command.UserID, ledger.AssetCoin, product.CoinAmount, 0, balanceAfter, account.FrozenAmount, account.Version+1, metadata, nowMs), + googlePaymentCreditedEvent(transactionID, command.CommandID, metadata, nowMs), + rechargeRecordedEvent(transactionID, command.CommandID, command.UserID, product.CoinAmount, metadata, nowMs), + }); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + if err := tx.Commit(); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + + return ledger.GooglePaymentReceipt{ + PaymentOrderID: paymentOrderID, + TransactionID: transactionID, + Status: ledger.PaymentStatusCredited, + ProductID: product.ProductID, + ProductCode: product.ProductCode, + CoinAmount: product.CoinAmount, + Balance: ledger.AssetBalance{ + AppCode: command.AppCode, + UserID: command.UserID, + AssetType: ledger.AssetCoin, + AvailableAmount: balanceAfter, + FrozenAmount: account.FrozenAmount, + }, + ConsumeState: ledger.PaymentConsumeStatePending, + }, nil +} + +func (r *Repository) MarkGooglePaymentConsumed(ctx context.Context, appCode string, paymentOrderID string) error { + if r == nil || r.db == nil { + return xerr.New(xerr.Unavailable, "mysql repository is not configured") + } + ctx = contextWithCommandApp(ctx, appCode) + paymentOrderID = strings.TrimSpace(paymentOrderID) + if paymentOrderID == "" { + return xerr.New(xerr.InvalidArgument, "payment_order_id is required") + } + _, err := r.db.ExecContext(ctx, ` + UPDATE payment_orders + SET consume_state = ?, updated_at_ms = ? + WHERE app_code = ? AND payment_order_id = ? AND provider = ?`, + ledger.PaymentConsumeStateConsumed, + time.Now().UnixMilli(), + appcode.FromContext(ctx), + paymentOrderID, + ledger.PaymentProviderGooglePlay, + ) + return err +} + +type googlePaymentOrderRow struct { + PaymentOrderID string + UserID int64 + ProductID int64 + TransactionID string +} + +func (r *Repository) lookupGooglePaymentOrderByToken(ctx context.Context, tx *sql.Tx, tokenHash string) (googlePaymentOrderRow, bool, error) { + row := tx.QueryRowContext(ctx, ` + SELECT payment_order_id, user_id, product_id, wallet_transaction_id + FROM payment_orders + WHERE app_code = ? AND provider = ? AND purchase_token_hash = ? + FOR UPDATE`, + appcode.FromContext(ctx), + ledger.PaymentProviderGooglePlay, + tokenHash, + ) + var payment googlePaymentOrderRow + if err := row.Scan(&payment.PaymentOrderID, &payment.UserID, &payment.ProductID, &payment.TransactionID); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return googlePaymentOrderRow{}, false, nil + } + return googlePaymentOrderRow{}, false, err + } + return payment, true, nil +} + +func (r *Repository) insertGooglePaymentOrder(ctx context.Context, tx *sql.Tx, paymentOrderID string, command ledger.GooglePaymentCommand, product ledger.RechargeProduct, purchase ledger.GooglePlayPurchase, tokenHash string, transactionID string, nowMs int64) error { + payloadJSON := purchase.RawJSON + if strings.TrimSpace(payloadJSON) == "" { + payloadJSON = mustJSON(purchase) + } + _, err := tx.ExecContext(ctx, ` + INSERT INTO payment_orders ( + app_code, payment_order_id, provider, channel, status, command_id, user_id, + product_id, product_code, package_name, provider_order_id, purchase_token_hash, + purchase_state, consume_state, wallet_transaction_id, coin_amount, currency_code, + amount_micro, provider_payload, created_at_ms, updated_at_ms + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + command.AppCode, + paymentOrderID, + ledger.PaymentProviderGooglePlay, + ledger.RechargeChannelGoogle, + ledger.PaymentStatusCredited, + command.CommandID, + command.UserID, + product.ProductID, + product.ProductCode, + command.PackageName, + purchase.OrderID, + tokenHash, + purchase.PurchaseState, + ledger.PaymentConsumeStatePending, + transactionID, + product.CoinAmount, + product.CurrencyCode, + product.AmountMicro, + payloadJSON, + nowMs, + nowMs, + ) + if err != nil && isMySQLDuplicateError(err) { + return xerr.New(xerr.Conflict, "google payment order already exists") + } + return err +} + +func (r *Repository) receiptForGooglePaymentTransaction(ctx context.Context, tx *sql.Tx, transactionID string, idempotentReplay bool) (ledger.GooglePaymentReceipt, error) { + var paymentOrderID string + if err := tx.QueryRowContext(ctx, ` + SELECT payment_order_id + FROM payment_orders + WHERE app_code = ? AND wallet_transaction_id = ? + LIMIT 1`, + appcode.FromContext(ctx), + transactionID, + ).Scan(&paymentOrderID); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + return r.receiptForGooglePaymentOrder(ctx, tx, paymentOrderID, idempotentReplay) +} + +func (r *Repository) receiptForGooglePaymentOrder(ctx context.Context, tx *sql.Tx, paymentOrderID string, idempotentReplay bool) (ledger.GooglePaymentReceipt, error) { + row := tx.QueryRowContext(ctx, ` + SELECT payment_order_id, wallet_transaction_id, status, user_id, product_id, product_code, + coin_amount, consume_state + FROM payment_orders + WHERE app_code = ? AND payment_order_id = ?`, + appcode.FromContext(ctx), + paymentOrderID, + ) + var receipt ledger.GooglePaymentReceipt + var userID int64 + if err := row.Scan( + &receipt.PaymentOrderID, + &receipt.TransactionID, + &receipt.Status, + &userID, + &receipt.ProductID, + &receipt.ProductCode, + &receipt.CoinAmount, + &receipt.ConsumeState, + ); err != nil { + return ledger.GooglePaymentReceipt{}, err + } + balance, err := r.balanceAfterTransaction(ctx, tx, receipt.TransactionID, userID, ledger.AssetCoin) + if err != nil { + return ledger.GooglePaymentReceipt{}, err + } + receipt.Balance = balance + receipt.IdempotentReplay = idempotentReplay + return receipt, nil +} + +type googlePaymentMetadata struct { + AppCode string `json:"app_code"` + PaymentOrderID string `json:"payment_order_id"` + UserID int64 `json:"user_id"` + RegionID int64 `json:"region_id"` + ProductID int64 `json:"product_id"` + ProductCode string `json:"product_code"` + ProductName string `json:"product_name"` + PackageName string `json:"package_name"` + Provider string `json:"provider"` + Channel string `json:"channel"` + ProviderOrderID string `json:"provider_order_id"` + ClientOrderID string `json:"client_order_id"` + PurchaseTokenHash string `json:"purchase_token_hash"` + PurchaseState string `json:"purchase_state"` + ConsumptionState string `json:"consumption_state"` + AcknowledgementState string `json:"acknowledgement_state"` + PurchaseCompletionTime string `json:"purchase_completion_time"` + CoinAmount int64 `json:"coin_amount"` + CurrencyCode string `json:"currency_code"` + AmountMicro int64 `json:"amount_micro"` + BalanceAfter int64 `json:"balance_after"` + RechargeSequence int64 `json:"recharge_sequence"` + CreatedAtMS int64 `json:"created_at_ms"` +} + +func googlePaymentCreditedEvent(transactionID string, commandID string, metadata googlePaymentMetadata, nowMs int64) walletOutboxEvent { + return walletOutboxEvent{ + EventID: eventID(transactionID, "WalletGooglePaymentCredited", metadata.UserID, ledger.AssetCoin), + EventType: "WalletGooglePaymentCredited", + TransactionID: transactionID, + CommandID: commandID, + UserID: metadata.UserID, + AssetType: ledger.AssetCoin, + AvailableDelta: metadata.CoinAmount, + FrozenDelta: 0, + Payload: metadata, + CreatedAtMS: nowMs, + } +} + +func googlePaymentRequestHash(command ledger.GooglePaymentCommand, product ledger.RechargeProduct, purchase ledger.GooglePlayPurchase, tokenHash string) string { + return stableHash(fmt.Sprintf("google_play|%s|%d|%d|%d|%s|%s|%s|%s|%s|%d|%d", + appcode.Normalize(command.AppCode), + command.UserID, + command.RegionID, + product.ProductID, + product.ProductCode, + command.PackageName, + tokenHash, + purchase.OrderID, + purchase.PurchaseState, + product.CoinAmount, + product.AmountMicro, + )) +} + +func googlePurchaseTokenHash(token string) string { + return stableHash(strings.TrimSpace(token)) +} + +func googlePaymentOrderID(appCode string, tokenHash string) string { + return "gpay_" + stableHash(appcode.Normalize(appCode) + "|" + tokenHash)[:48] +} + +func externalGooglePaymentRef(purchase ledger.GooglePlayPurchase, tokenHash string) string { + if strings.TrimSpace(purchase.OrderID) != "" { + return purchase.OrderID + } + return "token:" + tokenHash[:32] +} diff --git a/services/wallet-service/internal/storage/mysql/repository.go b/services/wallet-service/internal/storage/mysql/repository.go index cd1eeb39..9998ae59 100644 --- a/services/wallet-service/internal/storage/mysql/repository.go +++ b/services/wallet-service/internal/storage/mysql/repository.go @@ -28,6 +28,7 @@ const ( bizTypeCoinSellerTransfer = "coin_seller_transfer" bizTypeCoinSellerStockPurchase = "coin_seller_stock_purchase" bizTypeCoinSellerCoinCompensation = "coin_seller_coin_compensation" + bizTypeGooglePlayRecharge = "google_play_recharge" bizTypeGameDebit = "game_debit" bizTypeGameCredit = "game_credit" bizTypeGameRefund = "game_refund" diff --git a/services/wallet-service/internal/transport/grpc/server.go b/services/wallet-service/internal/transport/grpc/server.go index c2783d55..f015c1f0 100644 --- a/services/wallet-service/internal/transport/grpc/server.go +++ b/services/wallet-service/internal/transport/grpc/server.go @@ -140,6 +140,37 @@ func (s *Server) ListRechargeProducts(ctx context.Context, req *walletv1.ListRec return resp, nil } +// ConfirmGooglePayment 校验 Google Play purchase token 并完成钱包入账。 +func (s *Server) ConfirmGooglePayment(ctx context.Context, req *walletv1.ConfirmGooglePaymentRequest) (*walletv1.ConfirmGooglePaymentResponse, error) { + ctx = appcode.WithContext(ctx, req.GetAppCode()) + receipt, err := s.svc.ConfirmGooglePayment(ctx, ledger.GooglePaymentCommand{ + AppCode: req.GetAppCode(), + CommandID: req.GetCommandId(), + UserID: req.GetUserId(), + RegionID: req.GetRegionId(), + ProductID: req.GetProductId(), + ProductCode: req.GetProductCode(), + PackageName: req.GetPackageName(), + PurchaseToken: req.GetPurchaseToken(), + OrderID: req.GetOrderId(), + PurchaseTimeMS: req.GetPurchaseTimeMs(), + }) + if err != nil { + return nil, xerr.ToGRPCError(err) + } + return &walletv1.ConfirmGooglePaymentResponse{ + PaymentOrderId: receipt.PaymentOrderID, + TransactionId: receipt.TransactionID, + Status: receipt.Status, + ProductId: receipt.ProductID, + ProductCode: receipt.ProductCode, + CoinAmount: receipt.CoinAmount, + Balance: balanceToProto(receipt.Balance), + IdempotentReplay: receipt.IdempotentReplay, + ConsumeState: receipt.ConsumeState, + }, nil +} + // ListAdminRechargeProducts 返回后台内购配置列表。 func (s *Server) ListAdminRechargeProducts(ctx context.Context, req *walletv1.ListAdminRechargeProductsRequest) (*walletv1.ListAdminRechargeProductsResponse, error) { ctx = appcode.WithContext(ctx, req.GetAppCode())