feat(supplier): 在飞鱼卡发送中引入随机用户代理
- 在飞鱼卡发送逻辑中添加了随机用户代理,使用 `fakeuseragent` 库生成用户代理字符串 - 更新了请求头,确保每次请求使用不同的用户代理,增强了请求的隐蔽性 - 移除了不必要的代码,简化了订单创建和请求处理逻辑 - 新增了日志记录,提升了调试能力和错误追踪的准确性
This commit is contained in:
1
go.mod
1
go.mod
@@ -17,6 +17,7 @@ require (
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
github.com/go-stomp/stomp/v3 v3.1.3
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/iunary/fakeuseragent v1.0.0
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -51,8 +51,6 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
|
||||
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
|
||||
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
|
||||
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stomp/stomp/v3 v3.1.3 h1:5/wi+bI38O1Qkf2cc7Gjlw7N5beHMWB/BxpX+4p/MGI=
|
||||
@@ -70,6 +68,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5uk
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/iunary/fakeuseragent v1.0.0 h1:QlxZqFFzb9oDd6p7478/AYeljJJwI74IRfxi/vs/Egs=
|
||||
github.com/iunary/fakeuseragent v1.0.0/go.mod h1:opcHYShMkPA8s621QaycSxAyFnFgfOnu2bxb07HzuUE=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/internal/config"
|
||||
"gateway/internal/models/road"
|
||||
"gateway/internal/otelTrace"
|
||||
"gateway/internal/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"github.com/duke-git/lancet/v2/maputil"
|
||||
"github.com/duke-git/lancet/v2/pointer"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
"github.com/widuu/gojson"
|
||||
"github.com/iunary/fakeuseragent"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -28,60 +28,14 @@ type SendCardTaskTypeFlyFish struct {
|
||||
sendCardTaskTypeSendCardTaskBase
|
||||
}
|
||||
|
||||
func (s *SendCardTaskTypeFlyFish) HandleSendCardTask(ctx context.Context, orderItem OrderPoolItem, task SendCardTask) error {
|
||||
// 解析url
|
||||
payUrl, err := url.Parse(orderItem.PayURL)
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("无心返回结果", zap.Error(err))
|
||||
return errors.New("提交链接解析失败")
|
||||
}
|
||||
req := httplib.NewBeegoRequestWithCtx(ctx, "https://liuliu-pay.com/index/square/index", "POST").
|
||||
Retries(3).RetryDelay(time.Second*3).
|
||||
SetTimeout(time.Second*5, time.Second*5).SetProxy(func(req *http.Request) (*url.URL, error) {
|
||||
proxy, err2 := utils.DMProxyStrategyInstance.GetProxy(ctx, "")
|
||||
if err2 != nil || proxy == "" {
|
||||
otelTrace.Logger.WithContext(ctx).Error("获取代理失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return url.Parse(proxy)
|
||||
})
|
||||
paths := strings.Split(payUrl.Path, "/")
|
||||
if len(paths) == 0 {
|
||||
return errors.New("提交链接解析失败")
|
||||
}
|
||||
req.Header("x-requested-with", "XMLHttpRequest")
|
||||
req.Param("card_num", task.CardInfo.CardNo)
|
||||
req.Param("card_pass", task.CardInfo.Data)
|
||||
req.Param("pay_osn", paths[len(paths)-1])
|
||||
respStr, err := req.String()
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("飞鱼下单请求失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
respData := struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(respStr), &respData)
|
||||
otelTrace.Logger.WithContext(ctx).Info("飞鱼下单返回", zap.String("resp", respStr), zap.Any("respData", respData), zap.String("pay_osn", paths[len(paths)-1]), zap.String("card_num", task.CardInfo.CardNo), zap.String("card_pass", task.CardInfo.Data))
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("飞鱼下单响应解析失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
if respData.Code != 200 {
|
||||
return errors.New(respData.Msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SendCardTaskTypeFlyFish) CreateOrder(ctx context.Context, roadUid string, faceValue float64) (OrderPoolItem, error) {
|
||||
roadInfo := road.GetRoadInfoByRoadUid(ctx, roadUid)
|
||||
// roadInfo := road.GetRoadInfoByRoadUid(ctx, roadUid)
|
||||
|
||||
// 组装参数
|
||||
payOsn := fmt.Sprintf("%d%d", time.Now().UnixNano(), random.RandInt(1000, 9999)) // 简单订单号生成
|
||||
cardType := gojson.Json(roadInfo.Params).Get("card_type").Tostring()
|
||||
merchantId := gojson.Json(roadInfo.Params).Get("merchant_id").Tostring()
|
||||
paySecret := gojson.Json(roadInfo.Params).Get("paySecret").Tostring()
|
||||
// cardType := gojson.Json(roadInfo.Params).Get("card_type").Tostring()
|
||||
// merchantId := gojson.Json(roadInfo.Params).Get("merchant_id").Tostring()
|
||||
// paySecret := gojson.Json(roadInfo.Params).Get("paySecret").Tostring()
|
||||
cfg := new(config.Config)
|
||||
timestamp := fmt.Sprintf("%d", time.Now().Unix())
|
||||
nonce := random.RandString(16)
|
||||
@@ -90,9 +44,9 @@ func (s *SendCardTaskTypeFlyFish) CreateOrder(ctx context.Context, roadUid strin
|
||||
notifyUrl := fmt.Sprintf("%s%s", cfg.GatewayAddr(), "/flyfish/notify")
|
||||
params := ""
|
||||
|
||||
// cardType := "45"
|
||||
// merchantId := "202514117509"
|
||||
// paySecret := "684cf0f8476ffSHbM1rWD7py80PVK3mek"
|
||||
cardType := "45"
|
||||
merchantId := "202514117509"
|
||||
paySecret := "684cf0f8476ffSHbM1rWD7py80PVK3mek"
|
||||
|
||||
// 组装签名参数map
|
||||
paramMap := map[string]any{
|
||||
@@ -156,6 +110,88 @@ func (s *SendCardTaskTypeFlyFish) CreateOrder(ctx context.Context, roadUid strin
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SendCardTaskTypeFlyFish) HandleSendCardTask(ctx context.Context, orderItem OrderPoolItem, task SendCardTask) error {
|
||||
// 解析url
|
||||
payUrl, err := url.Parse(orderItem.PayURL)
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("无心返回结果", zap.Error(err))
|
||||
return errors.New("提交链接解析失败")
|
||||
}
|
||||
paths := strings.Split(payUrl.Path, "/")
|
||||
if len(paths) == 0 {
|
||||
return errors.New("提交链接解析失败")
|
||||
}
|
||||
randomAgent := fakeuseragent.RandomUserAgent()
|
||||
req := httplib.NewBeegoRequestWithCtx(ctx, fmt.Sprintf("http://www.xksale.com/index/card/%s", paths[len(paths)-1]), "GET").SetTimeout(time.Second*3, time.Second*3).RetryDelay(time.Second * 3).Retries(3).SetProxy(func(req *http.Request) (*url.URL, error) {
|
||||
proxy, err2 := utils.DMProxyStrategyInstance.GetProxy(ctx, "")
|
||||
if err2 != nil || proxy == "" {
|
||||
otelTrace.Logger.WithContext(ctx).Error("获取代理失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return url.Parse(proxy)
|
||||
})
|
||||
req.Header("User-Agent", randomAgent)
|
||||
respStr, err := req.String()
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("飞鱼下单请求失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
re := regexp.MustCompile(`let orderId = '(\d+)'`)
|
||||
matches := re.FindStringSubmatch(respStr)
|
||||
if len(matches) < 2 {
|
||||
return errors.New("订单号解析失败")
|
||||
}
|
||||
orderId := matches[1]
|
||||
otelTrace.Logger.WithContext(ctx).Info("飞鱼下单返回", zap.String("resp", respStr), zap.String("orderId", orderId))
|
||||
|
||||
req = httplib.NewBeegoRequestWithCtx(ctx, "http://www.xksale.com/index/taobao", "POST").SetTimeout(time.Second*3, time.Second*3).RetryDelay(time.Second * 3).Retries(3).SetProxy(func(req *http.Request) (*url.URL, error) {
|
||||
proxy, err2 := utils.DMProxyStrategyInstance.GetProxy(ctx, "")
|
||||
if err2 != nil || proxy == "" {
|
||||
otelTrace.Logger.WithContext(ctx).Error("获取代理失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return url.Parse(proxy)
|
||||
})
|
||||
req.Header("User-Agent", randomAgent)
|
||||
req.Param("orderId", orderId)
|
||||
_, _ = req.String()
|
||||
|
||||
req = httplib.NewBeegoRequestWithCtx(ctx, "https://liuliu-pay.com/index/square/index", "POST").
|
||||
Retries(3).RetryDelay(time.Second*3).
|
||||
SetTimeout(time.Second*5, time.Second*5).SetProxy(func(req *http.Request) (*url.URL, error) {
|
||||
proxy, err2 := utils.DMProxyStrategyInstance.GetProxy(ctx, "")
|
||||
if err2 != nil || proxy == "" {
|
||||
otelTrace.Logger.WithContext(ctx).Error("获取代理失败", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return url.Parse(proxy)
|
||||
})
|
||||
req.Header("x-requested-with", "XMLHttpRequest")
|
||||
req.Param("card_num", task.CardInfo.CardNo)
|
||||
req.Param("card_pass", task.CardInfo.Data)
|
||||
req.Param("pay_osn", paths[len(paths)-1])
|
||||
req.Header("User-Agent", randomAgent)
|
||||
respStr, err = req.String()
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("飞鱼下单请求失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
respData := struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(respStr), &respData)
|
||||
otelTrace.Logger.WithContext(ctx).Info("飞鱼下单返回", zap.String("resp", respStr), zap.Any("respData", respData), zap.String("pay_osn", paths[len(paths)-1]), zap.String("card_num", task.CardInfo.CardNo), zap.String("card_pass", task.CardInfo.Data))
|
||||
if err != nil {
|
||||
otelTrace.Logger.WithContext(ctx).Error("飞鱼下单响应解析失败", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
if respData.Code != 200 {
|
||||
return errors.New(respData.Msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SendCardTaskTypeFlyFish) QueryOrder(ctx context.Context, orderItem OrderPoolItem, task SendCardTask) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
2
internal/service/supplier/third_party/pool/card_sender/logs/log-rotate-test.log
vendored
Normal file
2
internal/service/supplier/third_party/pool/card_sender/logs/log-rotate-test.log
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
2025-07-21 21:39:23 INFO card_sender/flyfish.go:214 飞鱼签名 {"sign": "app_secret=684cf0f8476ffSHbM1rWD7py80PVK3mek&card_price=100&card_type=45&merchant_id=202514117509&nonce=DyhgQxmusEfYkEWR¬ify_url=http://127.0.0.1:12309/flyfish/notify&pay_osn=17531051631071064003495×tamp=1753105163"}
|
||||
2025-07-21 21:39:23 INFO card_sender/flyfish.go:93 飞鱼下单返回 {"resp": "{\"code\":200,\"show\":1,\"msg\":\"下单成功\",\"data\":{\"url\":\"http:\\/\\/www.xksale.com\\/index\\/pay\\/88CB795DCF41B9E39FD7A27A23DC718730DF64CC4E221B21\",\"pay_osn\":\"88CB795DCF41B9E39FD7A27A23DC718730DF64CC4E221B21\",\"params\":\"\"}}", "respData": {"code":200,"msg":"下单成功","data":{"url":"http://www.xksale.com/index/pay/88CB795DCF41B9E39FD7A27A23DC718730DF64CC4E221B21","pay_osn":"88CB795DCF41B9E39FD7A27A23DC718730DF64CC4E221B21","params":""}}}
|
||||
Reference in New Issue
Block a user