From 05970832583d7150f0f50b82786081ececd7b9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AD=90=E9=93=AD?= Date: Thu, 13 Mar 2025 16:42:20 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=9F=A5=E8=AF=A2=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E6=8E=A5=E5=8F=A3,=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E9=80=9A=E7=9F=A5i=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/cmb_cpn.proto | 12 ++++++ configs/config.yaml | 2 +- internal/biz/wechatrepo/cpn.go | 3 +- internal/data/mixrepoimpl/cmb.go | 8 ++++ internal/data/wechat.go | 6 +++ internal/data/wechatrepoimpl/cpn.go | 60 +++++++++++++++++++++++++++-- internal/server/http.go | 1 + internal/service/cmb_mock.go | 25 +++++++++++- 8 files changed, 110 insertions(+), 7 deletions(-) diff --git a/api/v1/cmb_cpn.proto b/api/v1/cmb_cpn.proto index d03e5de..da4c8f3 100644 --- a/api/v1/cmb_cpn.proto +++ b/api/v1/cmb_cpn.proto @@ -159,7 +159,19 @@ message DecryptBody { message QueryWechatVoucherNotifyUrlRequest { string mch_id = 1 [json_name = "mch_id"]; + string mch_cert_no = 2 [json_name = "mch_cert_no"]; } message QueryWechatVoucherNotifyUrlReply { string url = 1 [json_name = "url"]; +} + +message SetWechatVoucherNotifyUrlRequest { + string mch_id = 1 [json_name = "mch_id"]; + string mch_cert_no = 2 [json_name = "mch_cert_no"]; + string url = 3 [json_name = "url"]; +} +message SetWechatVoucherNotifyUrlReply { + string mch_id = 1 [json_name = "mch_id"]; + string url = 2 [json_name = "url"]; + string mch_cert_no = 3 [json_name = "mch_cert_no"]; } \ No newline at end of file diff --git a/configs/config.yaml b/configs/config.yaml index ea60075..6941fc3 100644 --- a/configs/config.yaml +++ b/configs/config.yaml @@ -52,7 +52,7 @@ wechatNotifyMQ: wechat: mchID: "1605446142" # 证书所属商户 蓝色兄弟服务商立减金配置 - mchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76" + mchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76" #商户证书序列号 cmb: sm2Prk: "8d39ff3d2559258c163f4510f082727f51531e1953ab203d5ab1ea4a6d94fd73" diff --git a/internal/biz/wechatrepo/cpn.go b/internal/biz/wechatrepo/cpn.go index 8f2dee9..2495228 100644 --- a/internal/biz/wechatrepo/cpn.go +++ b/internal/biz/wechatrepo/cpn.go @@ -11,6 +11,7 @@ type WechatCpnRepo interface { Order(ctx context.Context, order *bo.OrderBo) (couponId string, err error) Query(ctx context.Context, order *bo.OrderBo) (vo.OrderStatus, error) QueryProduct(ctx context.Context, stockCreatorMchId, stockId string) (*cashcoupons.Stock, error) - QueryCallback(ctx context.Context, mchId string) (*cashcoupons.Callback, error) + QueryCallback(ctx context.Context, mchId, mchCertNo string) (*cashcoupons.Callback, error) + SetCallback(ctx context.Context, mchId, mchCertNo, url string) (*cashcoupons.SetCallbackResponse, error) RegisterNotifyTag(ctx context.Context, stockID string) error } diff --git a/internal/data/mixrepoimpl/cmb.go b/internal/data/mixrepoimpl/cmb.go index 2c91877..f4143fd 100644 --- a/internal/data/mixrepoimpl/cmb.go +++ b/internal/data/mixrepoimpl/cmb.go @@ -33,6 +33,10 @@ func (s *CmbMixRepoImpl) OrderVerify(ctx context.Context, req *v1.CmbRequest) (* return nil, err } + if len(bizStr) == 0 { + return nil, errors.New("业务参数获取异常,请检查参数是否正确传递") + } + var resp *v1.CmbOrderRequest if err = json.Unmarshal([]byte(bizStr), &resp); err != nil { return nil, err @@ -81,6 +85,10 @@ func (s *CmbMixRepoImpl) Verify(_ context.Context, req *v1.CmbRequest) (string, return "", errors.New("签名验证失败") } + if len(req.EncryptBody) == 0 { + return "", errors.New("encryptBody is empty") + } + bizStr, err := cmb.Decrypt(s.bc.Cmb.Sm2Prk, req.EncryptBody) if err != nil { return "", err diff --git a/internal/data/wechat.go b/internal/data/wechat.go index 44c5171..ca67489 100644 --- a/internal/data/wechat.go +++ b/internal/data/wechat.go @@ -20,15 +20,18 @@ type Server struct { } func (c *Server) Validate() error { + if err := validator.New().Struct(c); err != nil { for _, err = range err.(validator.ValidationErrors) { return err } } + return nil } func newClient(ctx context.Context, c *Server) (*core.Client, error) { + dir, err := os.Getwd() if err != nil { return nil, err @@ -84,6 +87,7 @@ func init() { } func GetClient(ctx context.Context, c *Server) (*core.Client, error) { + instance.mutex.Lock() defer instance.mutex.Unlock() @@ -94,12 +98,14 @@ func GetClient(ctx context.Context, c *Server) (*core.Client, error) { var err error instance.once.Do(func() { + i, err2 := newClient(ctx, c) if err2 != nil { err = err2 return } instance.clients[c.MchID] = i + }) if err != nil { diff --git a/internal/data/wechatrepoimpl/cpn.go b/internal/data/wechatrepoimpl/cpn.go index 183ca6c..a34b930 100644 --- a/internal/data/wechatrepoimpl/cpn.go +++ b/internal/data/wechatrepoimpl/cpn.go @@ -154,9 +154,18 @@ func (c *CpnRepoImpl) QueryProduct(ctx context.Context, stockCreatorMchId, stock return response, nil } -func (c *CpnRepoImpl) QueryCallback(ctx context.Context, mchId string) (*cashcoupons.Callback, error) { +func (c *CpnRepoImpl) QueryCallback(ctx context.Context, mchId, mchCertNo string) (*cashcoupons.Callback, error) { - client, err := data.GetClient(ctx, c.Server) + server := &data.Server{ + MchID: mchId, + MchCertificateSerialNumber: mchCertNo, + } + + if err := server.Validate(); err != nil { + return nil, err + } + + client, err := data.GetClient(ctx, server) if err != nil { return nil, err } @@ -188,8 +197,51 @@ func (c *CpnRepoImpl) QueryCallback(ctx context.Context, mchId string) (*cashcou return response, nil } -func (c *CpnRepoImpl) Notify(ctx context.Context) error { - return nil +func (c *CpnRepoImpl) SetCallback(ctx context.Context, mchId, mchCertNo, url string) (*cashcoupons.SetCallbackResponse, error) { + + server := &data.Server{ + MchID: mchId, + MchCertificateSerialNumber: mchCertNo, + } + + if err := server.Validate(); err != nil { + return nil, err + } + + client, err := data.GetClient(ctx, server) + if err != nil { + return nil, err + } + + svc := cashcoupons.CallBackUrlApiService{Client: client} + + response, result, err := svc.SetCallback(ctx, cashcoupons.SetCallbackRequest{ + Mchid: core.String(mchId), + NotifyUrl: core.String(url), + Switch: core.Bool(true), + }) + + if err != nil { + + log.Errorf("请求微信返回错误:%s", err.Error()) + + bodyBytes, err := io.ReadAll(result.Response.Body) + if err != nil { + return nil, err + } + + if err = json.Unmarshal(bodyBytes, &ErrBody); err != nil { + return nil, err + } + + return nil, fmt.Errorf("微信返回错误:%s", ErrBody.Message) + } + + if result.Response.StatusCode != CodeSuccess { + return nil, fmt.Errorf("微信返回错误tatus[%s]", result.Response.Status) + } + + return response, nil } func (c *CpnRepoImpl) RegisterNotifyTag(ctx context.Context, stockID string) error { diff --git a/internal/server/http.go b/internal/server/http.go index 6e6073e..5da4471 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -49,6 +49,7 @@ func NewHTTPServer( v1.POST("/decryptBody", voucherService.DecryptBody) v1.POST("/queryWechatVoucherNotifyUrl", voucherService.QueryWechatVoucherNotifyUrl) + v1.POST("/setWechatVoucherNotifyUrl", voucherService.SetWechatVoucherNotifyUrl) return srv } diff --git a/internal/service/cmb_mock.go b/internal/service/cmb_mock.go index 83e333e..cdcadf0 100644 --- a/internal/service/cmb_mock.go +++ b/internal/service/cmb_mock.go @@ -117,7 +117,7 @@ func (s *VoucherService) QueryWechatVoucherNotifyUrl(ctx http.Context) error { return err } - rep, err := s.VoucherBiz.WechatCpnRepo.QueryCallback(ctx, req.MchId) + rep, err := s.VoucherBiz.WechatCpnRepo.QueryCallback(ctx, req.MchId, req.MchCertNo) if err != nil { return err } @@ -126,3 +126,26 @@ func (s *VoucherService) QueryWechatVoucherNotifyUrl(ctx http.Context) error { Url: *rep.NotifyUrl, }) } + +func (s *VoucherService) SetWechatVoucherNotifyUrl(ctx http.Context) error { + + bodyBytes, err := io.ReadAll(ctx.Request().Body) + if err != nil { + return err + } + + var req *v1.SetWechatVoucherNotifyUrlRequest + if err = json.Unmarshal(bodyBytes, &req); err != nil { + return err + } + + rep, err := s.VoucherBiz.WechatCpnRepo.SetCallback(ctx, req.MchId, req.MchCertNo, req.Url) + if err != nil { + return err + } + + return ctx.JSON(200, &v1.SetWechatVoucherNotifyUrlReply{ + MchId: req.MchId, + Url: *rep.NotifyUrl, + }) +}