ysf red
This commit is contained in:
parent
2a4c5b9373
commit
eded0a5a1f
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||||
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
"net/http"
|
"net/http"
|
||||||
"plugins/union_pay_cpn/internal/po"
|
"plugins/union_pay_cpn/internal/po"
|
||||||
"plugins/union_pay_cpn/internal/vo"
|
"plugins/union_pay_cpn/internal/vo"
|
||||||
|
@ -16,12 +17,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AppId string `json:"app_id"`
|
AppId string `validate:"required" json:"app_id"`
|
||||||
ChNlId string `json:"chnlId"` // 渠道方代码
|
ChNlId string `validate:"required" json:"chnlId"` // 渠道方代码
|
||||||
IV string `json:"iv"` // 加密密钥
|
IV string `validate:"required" json:"iv"` // 加密密钥
|
||||||
KEY string `json:"key"` // 加密密钥
|
KEY string `validate:"required" json:"key"` // 加密密钥
|
||||||
Prk string `json:"prk"` // 私钥
|
Prk string `validate:"required" json:"prk"` // 私钥
|
||||||
Npk string `json:"npk"` // 回调公钥
|
Npk string `validate:"required" json:"npk"` // 回调公钥
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) validate() error {
|
||||||
|
err := validator.New().Struct(c)
|
||||||
|
if err != nil {
|
||||||
|
for _, err = range err.(validator.ValidationErrors) {
|
||||||
|
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transConfig(config []byte) (*Config, error) {
|
func transConfig(config []byte) (*Config, error) {
|
||||||
|
@ -29,6 +40,9 @@ func transConfig(config []byte) (*Config, error) {
|
||||||
if err := json.Unmarshal(config, &c); err != nil {
|
if err := json.Unmarshal(config, &c); err != nil {
|
||||||
return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||||||
}
|
}
|
||||||
|
if err := c.validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,8 @@ type QueryResp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *QueryResp) GetMsg() string {
|
func (o *QueryResp) GetMsg() string {
|
||||||
|
if o.Code.IsSuccess() {
|
||||||
|
return o.Msg
|
||||||
|
}
|
||||||
return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg())
|
return fmt.Sprintf("Msg:[%s],SubMsg:[%s],自定处理msg:[%s]", o.Msg, o.SubMsg, o.SubCode.GetMsg())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,95 @@
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||||
|
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"net/http"
|
||||||
"plugins/union_pay_redpack/internal/po"
|
"plugins/union_pay_redpack/internal/po"
|
||||||
"plugins/union_pay_redpack/internal/vo"
|
"plugins/union_pay_redpack/internal/vo"
|
||||||
|
request "plugins/utils/request/v2"
|
||||||
"plugins/utils/union_pay"
|
"plugins/utils/union_pay"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AppId string `json:"app_id"`
|
AppId string `validate:"required" json:"app_id"`
|
||||||
ChNlId string `json:"chnlId"` // 渠道方代码
|
ChNlId string `validate:"required" json:"chnlId"` // 渠道方代码
|
||||||
IV string `json:"iv"` // 加密密钥
|
IV string `validate:"required" json:"iv"` // 加密密钥
|
||||||
KEY string `json:"key"` // 加密密钥
|
KEY string `validate:"required" json:"key"` // 加密密钥
|
||||||
Prk string `json:"prk"` // 私钥
|
Prk string `validate:"required" json:"prk"` // 私钥
|
||||||
Npk string `json:"npk"` // 回调公钥
|
Npk string `validate:"required" json:"npk"` // 回调公钥
|
||||||
|
|
||||||
PointId string `json:"point_id"` // 积分ID-积分类别代码,41开头的16位数字
|
PointId string `validate:"required" json:"point_id"` // 积分ID-积分类别代码,41开头的16位数字
|
||||||
InsAcctId string `json:"ins_acct_id"` // 机构账户代码
|
InsAcctId string `validate:"required" json:"ins_acct_id"` // 机构账户代码
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) validate() error {
|
||||||
|
err := validator.New().Struct(c)
|
||||||
|
if err != nil {
|
||||||
|
for _, err = range err.(validator.ValidationErrors) {
|
||||||
|
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transConfig(config []byte) (*Config, error) {
|
func transConfig(config []byte) (*Config, error) {
|
||||||
var c Config
|
var c Config
|
||||||
err := json.Unmarshal(config, &c)
|
if err := json.Unmarshal(config, &c); err != nil {
|
||||||
if err != nil {
|
return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||||||
|
}
|
||||||
|
if err := c.validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
|
||||||
type OrderExtra struct {
|
type OrderExtra struct {
|
||||||
TransDtTm string `json:"transDtTm"` // 交易日期时间
|
TransDtTm string `json:"transDtTm"` // 交易日期时间
|
||||||
|
@ -37,8 +97,7 @@ func (c *Config) orderReq(in *proto.OrderRequest) (*po.OrderReq, error) {
|
||||||
TransDigest string `json:"transDigest"` // 交易摘要
|
TransDigest string `json:"transDigest"` // 交易摘要
|
||||||
}
|
}
|
||||||
var e OrderExtra
|
var e OrderExtra
|
||||||
err := json.Unmarshal(in.Order.Extra, &e)
|
if err := json.Unmarshal(in.Order.Extra, &e); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("order extra json unmarshal error: %v", err)
|
return nil, fmt.Errorf("order extra json unmarshal error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,9 @@ package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||||||
"github.com/carlmjohnson/requests"
|
|
||||||
"net/http"
|
|
||||||
"plugins/union_pay_redpack/internal/po"
|
"plugins/union_pay_redpack/internal/po"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 插件通信信息,若不对应则会报错panic
|
// 插件通信信息,若不对应则会报错panic
|
||||||
|
@ -37,17 +34,22 @@ func (p *UnionPayCpnService) Order(ctx context.Context, request *proto.OrderRequ
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uv, err := c.orderReq(request)
|
req, err := c.orderReq(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = uv.Validate(); err != nil {
|
if err = req.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, bodyBytes, err := c.Request(ctx, req, orderMethod, orderBizMethod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var response po.OrderResp
|
var response po.OrderResp
|
||||||
err = requests.URL(baseUri + orderMethod).Headers(headers(c, uv, orderBizMethod)).Post().BodyJSON(uv).ToJSON(&response).Fetch(ctx)
|
if err = json.Unmarshal(bodyBytes, &response); err != nil {
|
||||||
if err != nil {
|
return nil, proto.ErrorResponseFail(err.Error())
|
||||||
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return orderResp(request, response), nil
|
return orderResp(request, response), nil
|
||||||
|
@ -58,20 +60,22 @@ func (p *UnionPayCpnService) Query(ctx context.Context, request *proto.QueryRequ
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uv, err := c.queryReq(request, c.ChNlId)
|
req, err := c.queryReq(request, c.ChNlId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = uv.Validate(); err != nil {
|
if err = req.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response po.QueryResp
|
|
||||||
|
|
||||||
h := new(http.Client)
|
_, bodyBytes, err := c.Request(ctx, req, queryMethod, queryBizMethod)
|
||||||
h.Timeout = 20 * time.Second
|
|
||||||
err = requests.URL(baseUri + queryMethod).Client(h).Headers(headers(c, uv, queryBizMethod)).BodyJSON(uv).ToJSON(&response).Fetch(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response po.QueryResp
|
||||||
|
if err = json.Unmarshal(bodyBytes, &response); err != nil {
|
||||||
|
return nil, proto.ErrorResponseFail(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryResp(request, response), nil
|
return queryResp(request, response), nil
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
sdkutils "gitea.cdlsxd.cn/sdk/plugin/utils"
|
|
||||||
"net/http"
|
|
||||||
"plugins/union_pay_redpack/internal/po"
|
|
||||||
"plugins/union_pay_redpack/internal/vo"
|
|
||||||
"plugins/utils/union_pay"
|
|
||||||
"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
|
|
||||||
}
|
|
Loading…
Reference in New Issue