ysf cpn
This commit is contained in:
parent
2016395646
commit
c5c809a019
|
@ -5,7 +5,7 @@ go 1.22.2
|
|||
replace plugins/utils => ../../utils
|
||||
|
||||
require (
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/hashicorp/go-plugin v1.6.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
|
@ -99,5 +99,5 @@ func (s *AlipayCpnService) Notify(_ context.Context, request *proto.NotifyReques
|
|||
if !b {
|
||||
return nil, proto.ErrorSignFail("验签失败")
|
||||
}
|
||||
return notifyResp(n), nil
|
||||
return notifyResp(n)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"html"
|
||||
"net/http"
|
||||
"plugins/alipay_cpn/internal/po"
|
||||
"plugins/alipay_cpn/internal/vo"
|
||||
"time"
|
||||
|
@ -134,10 +135,11 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
|
|||
return n
|
||||
}
|
||||
|
||||
func notifyResp(n *po.Notify) *proto.NotifyResponse {
|
||||
func notifyResp(n *po.Notify) (*proto.NotifyResponse, error) {
|
||||
var b po.NotifyBizContent
|
||||
_ = json.Unmarshal([]byte(n.BizContent), &b)
|
||||
return &proto.NotifyResponse{
|
||||
|
||||
pb := &proto.NotifyResponse{
|
||||
Result: &proto.Result{
|
||||
Status: b.BizType.GetOrderStatus(),
|
||||
OrderNo: b.OrderID,
|
||||
|
@ -146,4 +148,15 @@ func notifyResp(n *po.Notify) *proto.NotifyResponse {
|
|||
},
|
||||
Return: "success",
|
||||
}
|
||||
|
||||
headers := make(http.Header)
|
||||
headers.Set("Content-Type", "text/plain")
|
||||
|
||||
headersBytes, err := json.Marshal(headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pb.Headers = string(headersBytes)
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ go 1.22.2
|
|||
replace plugins/utils => ../../utils
|
||||
|
||||
require (
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/hashicorp/go-plugin v1.6.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
|
@ -103,5 +103,5 @@ func (s *AlipayRedPackService) Notify(_ context.Context, request *proto.NotifyRe
|
|||
if !b {
|
||||
return nil, proto.ErrorSignFail("验签失败")
|
||||
}
|
||||
return notifyResp(n), nil
|
||||
return notifyResp(n)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"html"
|
||||
"net/http"
|
||||
"plugins/alipay_redpack/internal/po"
|
||||
"plugins/alipay_redpack/internal/vo"
|
||||
"plugins/utils/alipay"
|
||||
|
@ -151,10 +152,11 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
|
|||
return n
|
||||
}
|
||||
|
||||
func notifyResp(n *po.Notify) *proto.NotifyResponse {
|
||||
func notifyResp(n *po.Notify) (*proto.NotifyResponse, error) {
|
||||
var b po.NotifyBizContent
|
||||
_ = json.Unmarshal([]byte(n.BizContent), &b)
|
||||
return &proto.NotifyResponse{
|
||||
|
||||
pb := &proto.NotifyResponse{
|
||||
Result: &proto.Result{
|
||||
Status: b.Status.GetOrderStatus(),
|
||||
OrderNo: b.OutBizNo,
|
||||
|
@ -163,4 +165,15 @@ func notifyResp(n *po.Notify) *proto.NotifyResponse {
|
|||
},
|
||||
Return: "success",
|
||||
}
|
||||
|
||||
headers := make(http.Header)
|
||||
headers.Set("Content-Type", "text/plain")
|
||||
|
||||
headersBytes, err := json.Marshal(headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pb.Headers = string(headersBytes)
|
||||
|
||||
return pb, nil
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ go 1.22.2
|
|||
replace plugins/utils => ../../utils
|
||||
|
||||
require (
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19
|
||||
github.com/carlmjohnson/requests v0.24.2
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/hashicorp/go-plugin v1.6.1
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
|
|
|
@ -3,6 +3,7 @@ package po
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
|
@ -20,7 +21,7 @@ func (req *OrderReq) Validate() error {
|
|||
err := validator.New().Struct(req)
|
||||
if err != nil {
|
||||
for _, err = range err.(validator.ValidationErrors) {
|
||||
return fmt.Errorf("参数有误:" + err.Error())
|
||||
return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -39,7 +40,7 @@ func (req *QueryReq) Validate() error {
|
|||
err := validator.New().Struct(req)
|
||||
if err != nil {
|
||||
for _, err = range err.(validator.ValidationErrors) {
|
||||
return fmt.Errorf("参数有误:" + err.Error())
|
||||
return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -58,7 +59,7 @@ func (req *Notify) Validate() error {
|
|||
err := validator.New().Struct(req)
|
||||
if err != nil {
|
||||
for _, err = range err.(validator.ValidationErrors) {
|
||||
return fmt.Errorf("参数有误:" + err.Error())
|
||||
return proto.ErrorParamFail(fmt.Sprintf("参数有误: %v", err))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
||||
"net/http"
|
||||
"plugins/union_pay_cpn/internal/po"
|
||||
"plugins/union_pay_cpn/internal/vo"
|
||||
request "plugins/utils/request/v2"
|
||||
"plugins/utils/union_pay"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
@ -23,19 +28,78 @@ func transConfig(config []byte) (*Config, error) {
|
|||
var c Config
|
||||
err := json.Unmarshal(config, &c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (c *Config) verify(req *po.Notify, notifyBizMethod string) error {
|
||||
if req.Headers.SignMethod != vo.SignMethod {
|
||||
return fmt.Errorf("签名方式不匹配")
|
||||
}
|
||||
if req.Headers.AppId != c.AppId {
|
||||
return fmt.Errorf("appId不匹配")
|
||||
}
|
||||
if req.Headers.BizMethod != notifyBizMethod {
|
||||
return fmt.Errorf("业务方法不匹配")
|
||||
}
|
||||
rehash := union_pay.Sha(req.Headers.Version, c.AppId, req.Headers.BizMethod, req.GetReId(), string(req.ToJson()))
|
||||
lowerStr := strings.ToLower(rehash)
|
||||
if union_pay.Verify(lowerStr, req.Headers.Sign, []byte(sdkutils.NewPublic().Build(c.Npk))) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("验签失败")
|
||||
}
|
||||
|
||||
func (c *Config) headers(bizMethod string, req po.Req) http.Header {
|
||||
h := make(http.Header)
|
||||
h.Add("Content-type", vo.ContentType)
|
||||
h.Add("version", vo.Version)
|
||||
h.Add("appType", vo.AppType)
|
||||
h.Add("signMethod", vo.SignMethod)
|
||||
|
||||
h.Add("appId", c.AppId)
|
||||
h.Add("bizMethod", bizMethod)
|
||||
|
||||
h.Add("reqId", req.GetReId())
|
||||
|
||||
now := time.Now()
|
||||
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
|
||||
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
|
||||
|
||||
rehash := union_pay.Sha(vo.Version, c.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
|
||||
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(c.Prk)))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
h.Add("sign", signValue)
|
||||
return h
|
||||
}
|
||||
|
||||
func (c *Config) Request(ctx context.Context, req po.Req, method, bizMethod string) (http.Header, []byte, error) {
|
||||
respHeader, respBody, err := request.Post(
|
||||
ctx,
|
||||
fmt.Sprintf("%s%s", baseUri, method),
|
||||
req.ToJson(),
|
||||
request.WithHeaders(c.headers(bizMethod, req)),
|
||||
request.WithTimeout(15*time.Second),
|
||||
request.WithStatusCodeFunc(func(code int) bool {
|
||||
return code == http.StatusOK
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, proto.ErrorRequestFail(err.Error())
|
||||
}
|
||||
return respHeader, respBody, nil
|
||||
}
|
||||
|
||||
func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
|
||||
type OrderExtra struct {
|
||||
OrderDt string `json:"orderDt"`
|
||||
}
|
||||
var e OrderExtra
|
||||
err := json.Unmarshal(in.Order.Extra, &e)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("订单拓展参数 json unmarshal error: %v", err)
|
||||
if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
|
||||
return nil, fmt.Errorf("订单拓展参数fail: %w", err)
|
||||
}
|
||||
|
||||
mobile, err := union_pay.Encrypt([]byte(in.Order.Account), []byte(c.KEY), []byte(c.IV))
|
||||
|
@ -119,8 +183,8 @@ func notifyReq(in *proto.NotifyRequest) *po.Notify {
|
|||
}
|
||||
}
|
||||
|
||||
func notifyResp(request *proto.NotifyRequest, n *po.Notify) *proto.NotifyResponse {
|
||||
return &proto.NotifyResponse{
|
||||
func notifyResp(request *proto.NotifyRequest, n *po.Notify) (*proto.NotifyResponse, error) {
|
||||
pb := &proto.NotifyResponse{
|
||||
Result: &proto.Result{
|
||||
OrderNo: n.Body.TransSeq,
|
||||
TradeNo: n.Body.CouponCd,
|
||||
|
@ -130,4 +194,15 @@ func notifyResp(request *proto.NotifyRequest, n *po.Notify) *proto.NotifyRespons
|
|||
},
|
||||
Return: "success",
|
||||
}
|
||||
|
||||
headers := make(http.Header)
|
||||
headers.Set("Content-Type", "text/plain")
|
||||
|
||||
headersBytes, err := json.Marshal(headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pb.Headers = string(headersBytes)
|
||||
|
||||
return pb, err
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@ package internal
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
"github.com/carlmjohnson/requests"
|
||||
"plugins/union_pay_cpn/internal/po"
|
||||
)
|
||||
|
||||
|
@ -37,56 +36,64 @@ func (p *UnionPayCpnService) Order(ctx context.Context, request *proto.OrderRequ
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uv, err := c.orderReq(request)
|
||||
req, err := c.orderReq(request)
|
||||
if err != nil {
|
||||
return nil, proto.ErrorParamFail(err.Error())
|
||||
}
|
||||
if err = req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, bodyBytes, err := c.Request(ctx, req, orderMethod, orderBizMethod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = uv.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response po.OrderResp
|
||||
url := fmt.Sprintf("%s%s", baseUri, orderMethod)
|
||||
err = requests.URL(url).Headers(headers(c, uv, orderBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
||||
if err = json.Unmarshal(bodyBytes, &response); err != nil {
|
||||
return nil, proto.ErrorResponseFail(err.Error())
|
||||
}
|
||||
|
||||
return orderResp(request, response), nil
|
||||
}
|
||||
|
||||
func (p *UnionPayCpnService) Query(ctx context.Context, request *proto.QueryRequest) (*proto.QueryResponse, error) {
|
||||
conf, err := transConfig(request.Config)
|
||||
c, err := transConfig(request.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uv := queryReq(request, conf.ChNlId)
|
||||
if err = uv.Validate(); err != nil {
|
||||
req := queryReq(request, c.ChNlId)
|
||||
if err = req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, bodyBytes, err := c.Request(ctx, req, queryMethod, queryBizMethod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response po.QueryResp
|
||||
url := fmt.Sprintf("%s%s", baseUri, queryMethod)
|
||||
err = requests.URL(url).Headers(headers(conf, uv, queryBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
||||
if err = json.Unmarshal(bodyBytes, &response); err != nil {
|
||||
return nil, proto.ErrorResponseFail(err.Error())
|
||||
}
|
||||
|
||||
return queryResp(request, response), nil
|
||||
}
|
||||
|
||||
func (p *UnionPayCpnService) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
|
||||
uv := notifyReq(request)
|
||||
if err := uv.Validate(); err != nil {
|
||||
req := notifyReq(request)
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conf, err := transConfig(request.Config)
|
||||
c, err := transConfig(request.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = verify(conf, uv, notifyBizMethod); err != nil {
|
||||
if err = c.verify(req, notifyBizMethod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return notifyResp(request, uv), nil
|
||||
return notifyResp(request, req)
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
||||
"net/http"
|
||||
"plugins/union_pay_cpn/internal/po"
|
||||
"plugins/union_pay_cpn/internal/vo"
|
||||
"plugins/utils/union_pay"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func headers(config *Config, req po.Req, bizMethod string) map[string][]string {
|
||||
h := make(http.Header)
|
||||
h.Add("Content-type", vo.ContentType)
|
||||
h.Add("version", vo.Version)
|
||||
h.Add("appType", vo.AppType)
|
||||
h.Add("signMethod", vo.SignMethod)
|
||||
|
||||
h.Add("appId", config.AppId)
|
||||
h.Add("bizMethod", bizMethod)
|
||||
|
||||
h.Add("reqId", req.GetReId())
|
||||
|
||||
now := time.Now()
|
||||
milliseconds := now.Unix()*1000 + int64(now.Nanosecond())/1e6
|
||||
h.Add("reqTs", fmt.Sprintf("%d", milliseconds))
|
||||
|
||||
rehash := union_pay.Sha(vo.Version, config.AppId, bizMethod, req.GetReId(), string(req.ToJson()))
|
||||
signValue, err := union_pay.Sign(rehash, []byte(sdkutils.NewPrivate().Build(config.Prk)))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
h.Add("sign", signValue)
|
||||
return h
|
||||
}
|
||||
|
||||
func verify(config *Config, req *po.Notify, notifyBizMethod string) error {
|
||||
if req.Headers.SignMethod != vo.SignMethod {
|
||||
return fmt.Errorf("签名方式不匹配")
|
||||
}
|
||||
if req.Headers.AppId != config.AppId {
|
||||
return fmt.Errorf("appId不匹配")
|
||||
}
|
||||
if req.Headers.BizMethod != notifyBizMethod {
|
||||
return fmt.Errorf("业务方法不匹配")
|
||||
}
|
||||
rehash := union_pay.Sha(req.Headers.Version, config.AppId, req.Headers.BizMethod, req.GetReId(), string(req.ToJson()))
|
||||
lowerStr := strings.ToLower(rehash)
|
||||
if union_pay.Verify(lowerStr, req.Headers.Sign, []byte(sdkutils.NewPublic().Build(config.Npk))) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("验签失败")
|
||||
}
|
|
@ -5,7 +5,7 @@ go 1.22.2
|
|||
replace plugins/utils => ../../utils
|
||||
|
||||
require (
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19
|
||||
github.com/carlmjohnson/requests v0.24.2
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/hashicorp/go-plugin v1.6.1
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17 h1:agk+9iA1ZI6fLVLtxEnuOWxcDzSq9QH7VBFvhlZZsbw=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.17/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19 h1:j0Ifn3q+C7ibxSTfL1KbmnX1k/VO9e0XMDJSuPutixU=
|
||||
gitea.cdlsxd.cn/sdk/plugin v1.0.19/go.mod h1:O/bYQWg1o9g/cBq9qNA3kLIpuPt7VDZqj1bPE6s04NM=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
|
||||
"go/types"
|
||||
"plugins/utils/wechat"
|
||||
"plugins/wechat_cpn/internal/vo"
|
||||
)
|
||||
|
@ -89,10 +88,6 @@ func queryResp(request *proto.QueryRequest, resp *cashcoupons.Coupon) *proto.Que
|
|||
}
|
||||
}
|
||||
|
||||
func notifyReq(in *proto.NotifyRequest) *types.Nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
func notifyResp() *proto.NotifyResponse {
|
||||
return &proto.NotifyResponse{
|
||||
Result: &proto.Result{
|
||||
|
|
|
@ -25,7 +25,7 @@ func config() []byte {
|
|||
// AppKey: "95E7EC7D4A394FF8D11788E5E436DE99",
|
||||
// BaseUri: "https://openapi.1688sup.com",
|
||||
// NotifyUrl: "https://gateway.dev.cdlsxd.cn/yxh5api/v1/order/direct/notify",
|
||||
// MerchantId: 25537,
|
||||
// MerchantId: 25715,
|
||||
//}
|
||||
marshal, _ := json.Marshal(c)
|
||||
return marshal
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RequestOptions 用于配置请求的各种选项
|
||||
type RequestOptions struct {
|
||||
Headers http.Header
|
||||
|
||||
Timeout time.Duration
|
||||
StatusCodeFunc func(int) bool
|
||||
}
|
||||
|
||||
// RequestOption 是一个函数类型,用于设置RequestOptions的各个字段
|
||||
type RequestOption func(*RequestOptions)
|
||||
|
||||
// WithTimeout 设置请求超时时间的选项函数
|
||||
func WithTimeout(timeout time.Duration) RequestOption {
|
||||
return func(options *RequestOptions) {
|
||||
options.Timeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// WithHeaders 设置请求头的选项函数
|
||||
func WithHeaders(headers http.Header) RequestOption {
|
||||
return func(options *RequestOptions) {
|
||||
options.Headers = headers
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCodeFunc 设置自定义状态码处理函数的选项函数
|
||||
func WithStatusCodeFunc(statusCodeFunc func(int) bool) RequestOption {
|
||||
return func(options *RequestOptions) {
|
||||
options.StatusCodeFunc = statusCodeFunc
|
||||
}
|
||||
}
|
||||
|
||||
func Post(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) {
|
||||
return Request(ctx, http.MethodPost, url, body, options...)
|
||||
}
|
||||
|
||||
func Get(ctx context.Context, url string, options ...RequestOption) (http.Header, []byte, error) {
|
||||
return Request(ctx, http.MethodGet, url, nil, options...)
|
||||
}
|
||||
|
||||
func Put(ctx context.Context, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) {
|
||||
return Request(ctx, http.MethodPut, url, body, options...)
|
||||
}
|
||||
|
||||
// Request 封装的HTTP请求函数,使用选项模式进行配置
|
||||
func Request(_ context.Context, method, url string, body []byte, options ...RequestOption) (http.Header, []byte, error) {
|
||||
// 设置默认选项
|
||||
defaultOptions := &RequestOptions{
|
||||
Headers: http.Header{
|
||||
"Content-Type": []string{"application/json"},
|
||||
},
|
||||
Timeout: 15 * time.Second,
|
||||
|
||||
StatusCodeFunc: func(code int) bool {
|
||||
return code == http.StatusOK
|
||||
},
|
||||
}
|
||||
|
||||
// 根据传入的选项更新默认选项
|
||||
for _, option := range options {
|
||||
option(defaultOptions)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, url, bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("创建HTTP请求失败: %w", err)
|
||||
}
|
||||
|
||||
httpClient := &http.Client{
|
||||
Timeout: defaultOptions.Timeout,
|
||||
}
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("发送HTTP请求失败: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("读取响应体失败: %w", err)
|
||||
}
|
||||
|
||||
if !defaultOptions.StatusCodeFunc(resp.StatusCode) {
|
||||
return nil, nil, fmt.Errorf("请求异常:%s", resp.Status)
|
||||
}
|
||||
|
||||
return resp.Header, bodyBytes, nil
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test_Get(t *testing.T) {
|
||||
uri := "https://gateway.dev.cdlsxd.cn/adminyx/admin/v1/key_batch/list"
|
||||
|
||||
uv := url.Values{}
|
||||
uv.Set("page", "1")
|
||||
uv.Set("limit", "2")
|
||||
|
||||
h := http.Header{
|
||||
"Content-Type": []string{"application/x-www-form-urlencoded"},
|
||||
}
|
||||
respHeader, respBody, err := Get(context.Background(), uri+"?"+uv.Encode(), WithHeaders(h))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Logf("响应体:", string(respBody))
|
||||
t.Logf("响应头:", respHeader)
|
||||
}
|
||||
|
||||
func Test_RequestHeaders(t *testing.T) {
|
||||
uri := "http://example.com/api"
|
||||
body := []byte("request body")
|
||||
|
||||
h := http.Header{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"Authorization": []string{"Bearer token"},
|
||||
}
|
||||
|
||||
respHeader, respBody, err := Post(context.Background(), uri, body, WithTimeout(10*time.Second), WithHeaders(h))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Logf("响应体:", string(respBody))
|
||||
t.Logf("响应头:", respHeader)
|
||||
}
|
||||
|
||||
func Test_RequestStatusCode(t *testing.T) {
|
||||
uri := "http://example.com/api/update"
|
||||
body := []byte("update data")
|
||||
|
||||
isSuccess := func(code int) bool {
|
||||
return code == http.StatusOK || code == http.StatusCreated
|
||||
}
|
||||
|
||||
respHeader, respBody, err := Put(context.Background(), uri, body, WithStatusCodeFunc(isSuccess))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Logf("响应体:", string(respBody))
|
||||
t.Logf("响应头:", respHeader)
|
||||
}
|
Loading…
Reference in New Issue