182 lines
4.3 KiB
Go
182 lines
4.3 KiB
Go
package internal
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"gitea.cdlsxd.cn/sdk/plugin/dctw/v1/api/direct"
|
||
"gitea.cdlsxd.cn/sdk/plugin/dctw/v1/core"
|
||
"gitea.cdlsxd.cn/sdk/plugin/proto"
|
||
"gitea.cdlsxd.cn/sdk/plugin/utils"
|
||
"github.com/go-playground/validator/v10"
|
||
"net/http"
|
||
"regexp"
|
||
)
|
||
|
||
type Config struct {
|
||
AppId string `json:"app_id" validate:"required"`
|
||
AppKey string `json:"app_key" validate:"required"`
|
||
BaseUri string `json:"base_uri" validate:"required"`
|
||
NotifyUrl string `json:"notify_url" validate:"required"`
|
||
MerchantId int64 `json:"merchant_id" validate:"required"`
|
||
}
|
||
|
||
func (c *Config) validate() error {
|
||
if err := validator.New().Struct(c); err != nil {
|
||
for _, err = range err.(validator.ValidationErrors) {
|
||
return proto.ErrorConfigFail(fmt.Sprintf("配置参数有误:%s", err.Error()))
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func transConfig(config []byte) (*Config, error) {
|
||
var c Config
|
||
|
||
if err := json.Unmarshal(config, &c); err != nil {
|
||
return nil, proto.ErrorConfigFail(fmt.Sprintf("配置参数解析失败: %v,参数:%s", err, string(config)))
|
||
}
|
||
|
||
if err := c.validate(); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &c, nil
|
||
}
|
||
|
||
func (c *Config) server() (*core.DctWServer, error) {
|
||
return core.NewDctWServer(
|
||
&core.DctWConfig{
|
||
AppId: c.AppId,
|
||
AppKey: c.AppKey,
|
||
BaseUri: c.BaseUri,
|
||
},
|
||
core.WithDebug(false),
|
||
)
|
||
}
|
||
|
||
func (c *Config) orderReq(in *proto.OrderRequest) (*direct.Order, error) {
|
||
// 账号类型(1:手机号 2:QQ号 其他:0)
|
||
accountType := int8(0)
|
||
if utils.IsPhoneNumber(in.Order.Account) {
|
||
accountType = 1
|
||
} else {
|
||
qqPattern := `^[1-9][0-9]{4,11}$`
|
||
qqRegex, err := regexp.Compile(qqPattern)
|
||
if err != nil {
|
||
return nil, proto.ErrorParamFail(fmt.Sprintf("正则表达式编译失败: %v", err))
|
||
}
|
||
if qqRegex.MatchString(in.Order.Account) {
|
||
accountType = 2
|
||
}
|
||
}
|
||
|
||
d := &direct.Order{
|
||
Number: in.Order.Quantity,
|
||
MerchantId: c.MerchantId,
|
||
OutTradeNo: in.Order.OrderNo,
|
||
ProductId: in.Product.ProductNo,
|
||
AccountType: accountType,
|
||
RechargeAccount: in.Order.Account,
|
||
NotifyUrl: c.NotifyUrl + "_" + fmt.Sprintf("%d", c.MerchantId),
|
||
Version: "1.0",
|
||
}
|
||
if in.Order.Extra != nil {
|
||
d.ExtendParameter = string(in.Order.Extra)
|
||
}
|
||
|
||
return d, nil
|
||
}
|
||
|
||
var speErrCodeMap = map[string]proto.Status{
|
||
//"1012": proto.Status_INVALID,
|
||
"1999": proto.Status_INVALID,
|
||
}
|
||
|
||
func orderResp(request *proto.OrderRequest, req *direct.Order, resp *direct.OrderResp) *proto.OrderResponse {
|
||
|
||
thirdResponse, _ := json.Marshal(resp)
|
||
thirdRequest, _ := req.Json()
|
||
|
||
response := &proto.OrderResponse{
|
||
Result: &proto.Result{
|
||
Status: proto.Status_ING,
|
||
OrderNo: request.Order.OrderNo,
|
||
TradeNo: resp.TradeNo,
|
||
Message: resp.Message,
|
||
Data: nil,
|
||
Extra: nil,
|
||
},
|
||
Idempotent: false,
|
||
ThirdRequest: string(thirdRequest),
|
||
ThirdResponse: string(thirdResponse),
|
||
}
|
||
|
||
if ec, ok := speErrCodeMap[string(resp.GetCode())]; ok {
|
||
response.Result.Status = ec
|
||
} else {
|
||
if !resp.GetCode().IsSuccess() {
|
||
response.Result.Status = proto.Status_FAIL
|
||
} else {
|
||
response.Result.Status = proto.Status_ING
|
||
}
|
||
}
|
||
|
||
return response
|
||
}
|
||
|
||
func (c *Config) queryReq(in *proto.QueryRequest) *direct.Query {
|
||
return &direct.Query{
|
||
MerchantId: c.MerchantId,
|
||
OutTradeNo: in.Order.OrderNo,
|
||
Version: "1.0",
|
||
}
|
||
}
|
||
|
||
func queryResp(request *proto.QueryRequest, req *direct.Query, resp *direct.QueryResp) (*proto.QueryResponse, error) {
|
||
|
||
thirdRequest, _ := req.Json()
|
||
thirdResponse, _ := json.Marshal(resp)
|
||
|
||
response := &proto.QueryResponse{
|
||
Result: &proto.Result{
|
||
Status: resp.Status.GetOrderStatus(),
|
||
OrderNo: request.Order.OrderNo,
|
||
TradeNo: request.Order.TradeNo,
|
||
Message: resp.Message,
|
||
Data: nil,
|
||
Extra: nil,
|
||
},
|
||
ThirdRequest: string(thirdRequest),
|
||
ThirdResponse: string(thirdResponse),
|
||
}
|
||
|
||
return response, nil
|
||
}
|
||
|
||
func notifyResp(resp *direct.Notify) (*proto.NotifyResponse, error) {
|
||
|
||
pb := &proto.NotifyResponse{
|
||
Result: &proto.Result{
|
||
Status: resp.Status.GetOrderStatus(),
|
||
OrderNo: resp.OutTradeNo,
|
||
TradeNo: resp.TradeNo,
|
||
Message: resp.Status.GetOrderStatusText(),
|
||
Data: nil,
|
||
Extra: nil,
|
||
},
|
||
Return: "success",
|
||
}
|
||
|
||
responseHeaders := make(http.Header)
|
||
responseHeaders.Set("Content-Type", "text/plain")
|
||
|
||
responseHeadersBytes, err := json.Marshal(responseHeaders)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
pb.Headers = string(responseHeadersBytes)
|
||
|
||
return pb, nil
|
||
}
|