add 查询回调地址接口,设置回调通知i接口

This commit is contained in:
李子铭 2025-03-13 16:42:20 +08:00
parent 8d294ef297
commit 0597083258
8 changed files with 110 additions and 7 deletions

View File

@ -159,7 +159,19 @@ message DecryptBody {
message QueryWechatVoucherNotifyUrlRequest { message QueryWechatVoucherNotifyUrlRequest {
string mch_id = 1 [json_name = "mch_id"]; string mch_id = 1 [json_name = "mch_id"];
string mch_cert_no = 2 [json_name = "mch_cert_no"];
} }
message QueryWechatVoucherNotifyUrlReply { message QueryWechatVoucherNotifyUrlReply {
string url = 1 [json_name = "url"]; 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"];
}

View File

@ -52,7 +52,7 @@ wechatNotifyMQ:
wechat: wechat:
mchID: "1605446142" # 证书所属商户 蓝色兄弟服务商立减金配置 mchID: "1605446142" # 证书所属商户 蓝色兄弟服务商立减金配置
mchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76" mchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76" #商户证书序列号
cmb: cmb:
sm2Prk: "8d39ff3d2559258c163f4510f082727f51531e1953ab203d5ab1ea4a6d94fd73" sm2Prk: "8d39ff3d2559258c163f4510f082727f51531e1953ab203d5ab1ea4a6d94fd73"

View File

@ -11,6 +11,7 @@ type WechatCpnRepo interface {
Order(ctx context.Context, order *bo.OrderBo) (couponId string, err error) Order(ctx context.Context, order *bo.OrderBo) (couponId string, err error)
Query(ctx context.Context, order *bo.OrderBo) (vo.OrderStatus, error) Query(ctx context.Context, order *bo.OrderBo) (vo.OrderStatus, error)
QueryProduct(ctx context.Context, stockCreatorMchId, stockId string) (*cashcoupons.Stock, 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 RegisterNotifyTag(ctx context.Context, stockID string) error
} }

View File

@ -33,6 +33,10 @@ func (s *CmbMixRepoImpl) OrderVerify(ctx context.Context, req *v1.CmbRequest) (*
return nil, err return nil, err
} }
if len(bizStr) == 0 {
return nil, errors.New("业务参数获取异常,请检查参数是否正确传递")
}
var resp *v1.CmbOrderRequest var resp *v1.CmbOrderRequest
if err = json.Unmarshal([]byte(bizStr), &resp); err != nil { if err = json.Unmarshal([]byte(bizStr), &resp); err != nil {
return nil, err return nil, err
@ -81,6 +85,10 @@ func (s *CmbMixRepoImpl) Verify(_ context.Context, req *v1.CmbRequest) (string,
return "", errors.New("签名验证失败") return "", errors.New("签名验证失败")
} }
if len(req.EncryptBody) == 0 {
return "", errors.New("encryptBody is empty")
}
bizStr, err := cmb.Decrypt(s.bc.Cmb.Sm2Prk, req.EncryptBody) bizStr, err := cmb.Decrypt(s.bc.Cmb.Sm2Prk, req.EncryptBody)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -20,15 +20,18 @@ type Server struct {
} }
func (c *Server) Validate() error { func (c *Server) Validate() error {
if err := validator.New().Struct(c); err != nil { if err := validator.New().Struct(c); err != nil {
for _, err = range err.(validator.ValidationErrors) { for _, err = range err.(validator.ValidationErrors) {
return err return err
} }
} }
return nil return nil
} }
func newClient(ctx context.Context, c *Server) (*core.Client, error) { func newClient(ctx context.Context, c *Server) (*core.Client, error) {
dir, err := os.Getwd() dir, err := os.Getwd()
if err != nil { if err != nil {
return nil, err return nil, err
@ -84,6 +87,7 @@ func init() {
} }
func GetClient(ctx context.Context, c *Server) (*core.Client, error) { func GetClient(ctx context.Context, c *Server) (*core.Client, error) {
instance.mutex.Lock() instance.mutex.Lock()
defer instance.mutex.Unlock() defer instance.mutex.Unlock()
@ -94,12 +98,14 @@ func GetClient(ctx context.Context, c *Server) (*core.Client, error) {
var err error var err error
instance.once.Do(func() { instance.once.Do(func() {
i, err2 := newClient(ctx, c) i, err2 := newClient(ctx, c)
if err2 != nil { if err2 != nil {
err = err2 err = err2
return return
} }
instance.clients[c.MchID] = i instance.clients[c.MchID] = i
}) })
if err != nil { if err != nil {

View File

@ -154,9 +154,18 @@ func (c *CpnRepoImpl) QueryProduct(ctx context.Context, stockCreatorMchId, stock
return response, nil 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 { if err != nil {
return nil, err return nil, err
} }
@ -188,8 +197,51 @@ func (c *CpnRepoImpl) QueryCallback(ctx context.Context, mchId string) (*cashcou
return response, nil return response, nil
} }
func (c *CpnRepoImpl) Notify(ctx context.Context) error { func (c *CpnRepoImpl) SetCallback(ctx context.Context, mchId, mchCertNo, url string) (*cashcoupons.SetCallbackResponse, error) {
return nil
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 { func (c *CpnRepoImpl) RegisterNotifyTag(ctx context.Context, stockID string) error {

View File

@ -49,6 +49,7 @@ func NewHTTPServer(
v1.POST("/decryptBody", voucherService.DecryptBody) v1.POST("/decryptBody", voucherService.DecryptBody)
v1.POST("/queryWechatVoucherNotifyUrl", voucherService.QueryWechatVoucherNotifyUrl) v1.POST("/queryWechatVoucherNotifyUrl", voucherService.QueryWechatVoucherNotifyUrl)
v1.POST("/setWechatVoucherNotifyUrl", voucherService.SetWechatVoucherNotifyUrl)
return srv return srv
} }

View File

@ -117,7 +117,7 @@ func (s *VoucherService) QueryWechatVoucherNotifyUrl(ctx http.Context) error {
return err 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 { if err != nil {
return err return err
} }
@ -126,3 +126,26 @@ func (s *VoucherService) QueryWechatVoucherNotifyUrl(ctx http.Context) error {
Url: *rep.NotifyUrl, 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,
})
}