更新依赖和优化代码结构

- 在 go.mod 中添加了 go-resty/resty/v2 依赖,并移除不再使用的 gopkg.in/yaml.v2 依赖。
- 在 main.go 中优化了请求日志记录,使用 zap 进行结构化日志记录。
- 在 payfor_controller.go 中注释掉了多个未使用的函数,提升代码整洁性。
- 在 scan_controller.go 中增加了订单提交的限流机制,防止重复提交。
- 在 pay_solve.go 中优化了错误处理逻辑,使用 fmt.Errorf 替代 errors.New。
- 在多个第三方支付实现中,统一了 MD5 加密函数的调用方式,提升代码一致性。
This commit is contained in:
danial
2025-05-05 12:45:52 +08:00
parent 1168059e69
commit 2f9da02943
27 changed files with 470 additions and 478 deletions

3
go.mod
View File

@@ -13,6 +13,7 @@ require (
github.com/carlmjohnson/requests v0.24.3
github.com/duke-git/lancet/v2 v2.3.5
github.com/forgoer/openssl v1.6.0
github.com/go-resty/resty/v2 v2.16.5
github.com/go-sql-driver/mysql v1.9.1
github.com/go-stomp/stomp/v3 v3.1.3
github.com/google/uuid v1.6.0
@@ -34,7 +35,6 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.35.0
go.opentelemetry.io/otel/trace v1.35.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
)
require (
@@ -48,7 +48,6 @@ require (
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/klauspost/compress v1.17.11 // indirect

3
go.sum
View File

@@ -182,6 +182,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@@ -200,7 +202,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,20 +1,6 @@
package gateway
import (
"context"
"fmt"
"gateway/internal/config"
"gateway/internal/models/order"
"gateway/internal/models/payfor"
"gateway/internal/models/road"
"gateway/internal/schema/response"
"gateway/internal/service/pay_for"
"gateway/internal/service/supplier/third_party"
"strings"
"github.com/beego/beego/v2/core/logs"
"github.com/duke-git/lancet/v2/convertor"
"github.com/beego/beego/v2/server/web"
)
@@ -22,114 +8,114 @@ type PayForGateway struct {
web.Controller
}
// PayFor 接受下游商户的代付请求
func (c *PayForGateway) PayFor() {
ctx := context.Background()
params := map[string]any{
"merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
"realname": strings.TrimSpace(c.GetString("realname")),
"cardNo": strings.TrimSpace(c.GetString("cardNo")),
"accType": strings.TrimSpace(c.GetString("accType")),
"amount": strings.TrimSpace(c.GetString("amount")),
"merchantOrderId": strings.TrimSpace(c.GetString("merchantOrderId")),
"sign": strings.TrimSpace(c.GetString("sign")),
}
payForResponse := new(response.PayForResponse)
res, msg := checkParams(params)
if !res {
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = msg
} else {
payForResponse = pay_for.AutoPayFor(ctx, params, config.SELF_API)
}
c.Data["json"] = payForResponse
_ = c.ServeJSON()
}
// // PayFor 接受下游商户的代付请求
// func (c *PayForGateway) PayFor() {
// ctx := context.Background()
// params := map[string]any{
// "merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
// "realname": strings.TrimSpace(c.GetString("realname")),
// "cardNo": strings.TrimSpace(c.GetString("cardNo")),
// "accType": strings.TrimSpace(c.GetString("accType")),
// "amount": strings.TrimSpace(c.GetString("amount")),
// "merchantOrderId": strings.TrimSpace(c.GetString("merchantOrderId")),
// "sign": strings.TrimSpace(c.GetString("sign")),
// }
// payForResponse := new(response.PayForResponse)
// res, msg := checkParams(params)
// if !res {
// payForResponse.ResultCode = "01"
// payForResponse.ResultMsg = msg
// } else {
// payForResponse = pay_for.AutoPayFor(ctx, params, config.SELF_API)
// }
// c.Data["json"] = payForResponse
// _ = c.ServeJSON()
// }
// PayForQuery 代付结果查询,
func (c *PayForGateway) PayForQuery() {
ctx := context.Background()
params := map[string]any{
"merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
"timestamp": strings.TrimSpace(c.GetString("timestamp")),
"merchantOrderId": strings.TrimSpace(c.GetString("merchantOrderId")),
"sign": strings.TrimSpace(c.GetString("sign")),
}
c.Data["json"] = pay_for.PayForResultQuery(ctx, params)
_ = c.ServeJSON()
}
// // PayForQuery 代付结果查询,
// func (c *PayForGateway) PayForQuery() {
// ctx := context.Background()
// params := map[string]any{
// "merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
// "timestamp": strings.TrimSpace(c.GetString("timestamp")),
// "merchantOrderId": strings.TrimSpace(c.GetString("merchantOrderId")),
// "sign": strings.TrimSpace(c.GetString("sign")),
// }
// c.Data["json"] = pay_for.PayForResultQuery(ctx, params)
// _ = c.ServeJSON()
// }
// QuerySupplierPayForResult 查询上游的代付结果
func (c *PayForGateway) QuerySupplierPayForResult() {
ctx := context.Background()
bankOrderId := strings.TrimSpace(c.GetString("bankOrderId"))
p := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
if p.RoadUid == "" {
// 向上游查询订单结果
orderInfo := order.GetOrderByBankOrderId(ctx, bankOrderId)
// // QuerySupplierPayForResult 查询上游的代付结果
// func (c *PayForGateway) QuerySupplierPayForResult() {
// ctx := context.Background()
// bankOrderId := strings.TrimSpace(c.GetString("bankOrderId"))
// p := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
// if p.RoadUid == "" {
// // 向上游查询订单结果
// orderInfo := order.GetOrderByBankOrderId(ctx, bankOrderId)
if orderInfo.BankOrderId == "" {
c.Ctx.WriteString("fail")
return
}
// if orderInfo.BankOrderId == "" {
// c.Ctx.WriteString("fail")
// return
// }
roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
supplier.PayQuery(orderInfo, roadInfo)
} else {
roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
res := supplier.PayFor(p)
logs.Debug("代付查询结果:", res)
c.Ctx.WriteString("success")
}
}
// roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
// supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
// supplier.PayQuery(orderInfo, roadInfo)
// } else {
// roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
// supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
// res := supplier.PayFor(p)
// logs.Debug("代付查询结果:", res)
// c.Ctx.WriteString("success")
// }
// }
// SolvePayForResult 接收boss发送过来的代付手动处理结果
func (c *PayForGateway) SolvePayForResult() {
ctx := context.Background()
resultType := strings.TrimSpace(c.GetString("resultType"))
bankOrderId := strings.TrimSpace(c.GetString("bankOrderId"))
// // SolvePayForResult 接收boss发送过来的代付手动处理结果
// func (c *PayForGateway) SolvePayForResult() {
// ctx := context.Background()
// resultType := strings.TrimSpace(c.GetString("resultType"))
// bankOrderId := strings.TrimSpace(c.GetString("bankOrderId"))
p := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
if p.BankOrderId == "" {
c.Ctx.WriteString(config.FAIL)
}
// p := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
// if p.BankOrderId == "" {
// c.Ctx.WriteString(config.FAIL)
// }
if resultType == config.PAYFOR_FAIL {
pay_for.PayForFail(ctx, p)
} else if resultType == config.PAYFOR_SUCCESS {
pay_for.PayForSuccess(ctx, p)
}
// if resultType == config.PAYFOR_FAIL {
// pay_for.PayForFail(ctx, p)
// } else if resultType == config.PAYFOR_SUCCESS {
// pay_for.PayForSuccess(ctx, p)
// }
c.Ctx.WriteString(config.SUCCESS)
}
// c.Ctx.WriteString(config.SUCCESS)
// }
// Balance 商户查找余额
func (c *PayForGateway) Balance() {
ctx := context.Background()
params := map[string]any{
"merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
"timestamp": strings.TrimSpace(c.GetString("timestamp")),
"sign": strings.TrimSpace(c.GetString("sign")),
}
balanceResponse := new(response.BalanceResponse)
res, msg := checkParams(params)
if !res {
balanceResponse.ResultCode = "-1"
balanceResponse.ResultMsg = msg
c.Data["json"] = balanceResponse
} else {
c.Data["json"] = pay_for.BalanceQuery(ctx, params)
}
_ = c.ServeJSON()
}
// // Balance 商户查找余额
// func (c *PayForGateway) Balance() {
// ctx := context.Background()
// params := map[string]any{
// "merchantKey": strings.TrimSpace(c.GetString("merchantKey")),
// "timestamp": strings.TrimSpace(c.GetString("timestamp")),
// "sign": strings.TrimSpace(c.GetString("sign")),
// }
// balanceResponse := new(response.BalanceResponse)
// res, msg := checkParams(params)
// if !res {
// balanceResponse.ResultCode = "-1"
// balanceResponse.ResultMsg = msg
// c.Data["json"] = balanceResponse
// } else {
// c.Data["json"] = pay_for.BalanceQuery(ctx, params)
// }
// _ = c.ServeJSON()
// }
func checkParams(params map[string]any) (bool, string) {
for k, v := range params {
if v == "" || len(convertor.ToString(v)) == 0 {
return false, fmt.Sprintf("字段: %s 为必填!", k)
}
}
return true, ""
}
// func checkParams(params map[string]any) (bool, string) {
// for k, v := range params {
// if v == "" || len(convertor.ToString(v)) == 0 {
// return false, fmt.Sprintf("字段: %s 为必填!", k)
// }
// }
// return true, ""
// }

View File

@@ -28,7 +28,6 @@ import (
"github.com/duke-git/lancet/v2/random"
"github.com/allegro/bigcache/v3"
"github.com/beego/beego/v2/core/validation"
"github.com/bytedance/gopkg/util/gopool"
"github.com/duke-git/lancet/v2/convertor"
@@ -39,12 +38,29 @@ import (
)
var (
delayPool = gopool.NewPool("delayHandler", 20, gopool.NewConfig())
idCache, _ = bigcache.New(otelTrace.InitCtx, bigcache.DefaultConfig(30*time.Second))
merchantOrderLock = sync.Mutex{}
orderGeneratorLock = sync.Mutex{}
delayPool = gopool.NewPool("delayHandler", 20, gopool.NewConfig())
SubmitLimiterPool = gopool.NewPool("SubmitLimiterPool", 20, gopool.NewConfig())
)
var orderSubmitLimiter sync.Map
func isAllowed(orderNo string, intervalSec int64) bool {
now := time.Now().Unix()
last, ok := orderSubmitLimiter.Load(orderNo)
if ok {
lastTime := last.(int64)
if now-lastTime < intervalSec {
return false // 限流,拒绝
}
}
orderSubmitLimiter.Store(orderNo, now)
SubmitLimiterPool.Go(func() {
time.Sleep(time.Duration(intervalSec) * time.Second)
orderSubmitLimiter.Delete(orderNo)
})
return true // 允许
}
type ScanController struct {
BaseGateway
}
@@ -81,25 +97,14 @@ func (c *ScanController) Scan() {
return
}
c.Ctx.Request = c.Ctx.Request.WithContext(ctx)
p.ClientIP = strings.TrimSpace(c.GetString("ip"))
merchantOrderLock.Lock()
cacheId, _ := idCache.Get(strings.TrimSpace(c.GetString("orderNo")))
_ = idCache.Set(strings.TrimSpace(c.GetString("orderNo")), []byte("1"))
merchantOrderLock.Unlock()
if len(cacheId) != 0 {
otelTrace.Logger.WithContext(ctx).Info(
fmt.Sprintf("订单已经提交订单信息id=%s", p.Params["orderNo"]), zap.Any("orderInfo", p.Params),
)
p.Msg = "订单已经提交!"
p.Code = -1
c.SolveFailJSON(p)
if !isAllowed(strings.TrimSpace(c.GetString("orderNo")), 5) { // 5秒内同订单号只能提交一次
c.Data["json"] = response.CommonErr(-1, "请勿频繁提交")
_ = c.ServeJSON()
return
}
defer func() {
_ = idCache.Delete(strings.TrimSpace(c.GetString("orderNo")))
}()
c.Ctx.Request = c.Ctx.Request.WithContext(ctx)
p.ClientIP = strings.TrimSpace(c.GetString("ip"))
p = service.JudgeParams(ctx, p)
p = service.OrderIsValid(ctx, p)
@@ -198,7 +203,6 @@ func (c *ScanController) Scan() {
return
}
otelTrace.Logger.WithContext(ctx).Info("【BaseGateway】生成订单记录", zap.Any("orderInfo", orderInfo))
if mt.AutoSettle == config.NO {
params := map[string]any{
"orderNo": orderInfo.BankOrderId,
@@ -232,7 +236,7 @@ func (c *ScanController) Scan() {
return
}
otelTrace.Logger.WithContext(ctx).Info("【BaseGateway】获取到对应的上游", zap.Any("supplierByCode", supplierByCode), zap.String("supplierCode", supplierCode))
otelTrace.Logger.WithContext(ctx).Info("【BaseGateway】获取到对应的上游", zap.Any("supplierByCode", supplierByCode), zap.String("supplierCode", supplierCode), zap.Any("orderInfo", orderInfo))
hiddenCfg := service.GetOrderHidden(ctx, &orderInfo)
if hiddenCfg != nil {
@@ -294,7 +298,7 @@ func (c *ScanController) Scan() {
}
// 插入处理失败的动账通知
service.SolvePayFail(ctx, orderInfo.BankOrderId, "", scanData.ReturnData)
service.SolvePayFail(ctx, orderInfo.BankOrderId, orderInfo.BankTransId, scanData.ReturnData)
p.Msg = scanData.Msg
p.Code = -1
c.SolveFailJSON(p)

View File

@@ -7,16 +7,11 @@ import (
"gateway/internal/models/payfor"
"gateway/internal/models/road"
"gateway/internal/otelTrace"
"gateway/internal/service/message"
"gateway/internal/service/pay_for"
"gateway/internal/service/supplier/third_party"
"gateway/internal/utils"
"os"
"time"
"github.com/bytedance/gopkg/util/gopool"
"github.com/go-stomp/stomp/v3"
)
type PayForQueryTask struct {
@@ -87,66 +82,66 @@ func PayForSupplier(ctx context.Context, task PayForQueryTask) {
}
}
func payForQueryConsumer(ctx context.Context, bankOrderId string) {
exist := payfor.IsExistPayForByBankOrderId(bankOrderId)
if !exist {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("代付记录不存在bankOrderId = %s", bankOrderId))
return
}
// func payForQueryConsumer(ctx context.Context, bankOrderId string) {
// exist := payfor.IsExistPayForByBankOrderId(bankOrderId)
// if !exist {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("代付记录不存在bankOrderId = %s", bankOrderId))
// return
// }
payFor := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
// payFor := payfor.GetPayForByBankOrderId(ctx, bankOrderId)
if payFor.Status != config.PAYFOR_BANKING {
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("代付状态不是银行处理中不需要去查询bankOrderId = %s", bankOrderId))
return
}
// if payFor.Status != config.PAYFOR_BANKING {
// otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("代付状态不是银行处理中不需要去查询bankOrderId = %s", bankOrderId))
// return
// }
payForQueryTask := PayForQueryTask{
Delay: time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute),
MerchantOrderId: payFor.MerchantOrderId,
BankOrderId: payFor.BankOrderId,
FirstNotifyTime: utils.GetBasicDateTime(),
QueryTimes: 1,
LimitTimes: PayForLimitTimes,
Status: payFor.Status,
}
PayForQueryPool.Go(func() {
PayForQueryTimer(ctx, payForQueryTask)
})
}
// payForQueryTask := PayForQueryTask{
// Delay: time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute),
// MerchantOrderId: payFor.MerchantOrderId,
// BankOrderId: payFor.BankOrderId,
// FirstNotifyTime: utils.GetBasicDateTime(),
// QueryTimes: 1,
// LimitTimes: PayForLimitTimes,
// Status: payFor.Status,
// }
// PayForQueryPool.Go(func() {
// PayForQueryTimer(ctx, payForQueryTask)
// })
// }
// CreatePayForQueryConsumer 创建代付查询的消费者
func CreatePayForQueryConsumer(ctx context.Context) {
ctx, cancel := otelTrace.Span(ctx, "CreatePayForQueryConsumer", "CreatePayForQueryConsumer")
defer cancel()
// 启动定时任务
conn := message.GetActiveMQConn()
if conn == nil {
otelTrace.Logger.WithContext(ctx).Error("启动消息队列消费者失败....")
os.Exit(1)
}
payForQuery, err := conn.Subscribe(config.MqPayForQuery, stomp.AckClient)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("订阅代付查询失败......")
}
// // CreatePayForQueryConsumer 创建代付查询的消费者
// func CreatePayForQueryConsumer(ctx context.Context) {
// ctx, cancel := otelTrace.Span(ctx, "CreatePayForQueryConsumer", "CreatePayForQueryConsumer")
// defer cancel()
// // 启动定时任务
// conn := message.GetActiveMQConn()
// if conn == nil {
// otelTrace.Logger.WithContext(ctx).Error("启动消息队列消费者失败....")
// os.Exit(1)
// }
// payForQuery, err := conn.Subscribe(config.MqPayForQuery, stomp.AckClient)
// if err != nil {
// otelTrace.Logger.WithContext(ctx).Error("订阅代付查询失败......")
// }
for {
select {
case v := <-payForQuery.C:
if v != nil {
bankOrderId := string(v.Body)
payForQueryConsumerPool.CtxGo(ctx, func() {
// 创建一个5分钟超时的上下文
ctx2, span := otelTrace.NewSchedulerTrace().Start(ctx, "CreatePayForQueryConsumer")
defer span.End()
payForQueryConsumer(ctx2, bankOrderId)
})
// 应答,重要
err := conn.Ack(v)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("消息应答失败!")
}
}
}
}
}
// for {
// select {
// case v := <-payForQuery.C:
// if v != nil {
// bankOrderId := string(v.Body)
// payForQueryConsumerPool.CtxGo(ctx, func() {
// // 创建一个5分钟超时的上下文
// ctx2, span := otelTrace.NewSchedulerTrace().Start(ctx, "CreatePayForQueryConsumer")
// defer span.End()
// payForQueryConsumer(ctx2, bankOrderId)
// })
// // 应答,重要
// err := conn.Ack(v)
// if err != nil {
// otelTrace.Logger.WithContext(ctx).Error("消息应答失败!")
// }
// }
// }
// }
// }

View File

@@ -2,7 +2,6 @@ package message
import (
"context"
"fmt"
"gateway/internal/otelTrace"
"os"
@@ -17,10 +16,10 @@ func SendMessage(ctx context.Context, topic, message string) {
os.Exit(1)
}
err := conn.Send(topic, "text/plain", []byte(message))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("发送消息给activeMQ失败, message=", zap.String("message", message))
} else {
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("发送消息给activeMQ成功message="), zap.String("message", message))
return
}
otelTrace.Logger.WithContext(ctx).Info("发送消息给activeMQ成功message=", zap.String("message", message))
}

View File

@@ -7,265 +7,241 @@ import (
"gateway/internal/config"
"gateway/internal/models/accounts"
"gateway/internal/models/merchant"
"gateway/internal/models/merchant_deploy"
"gateway/internal/models/payfor"
"gateway/internal/models/road"
"gateway/internal/otelTrace"
"gateway/internal/schema/response"
"gateway/internal/service/message"
"gateway/internal/service/supplier/third_party"
"gateway/internal/utils"
"strconv"
"strings"
"time"
"github.com/duke-git/lancet/v2/convertor"
"go.uber.org/zap"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/rs/xid"
)
// AutoPayFor 程序自动代付
func AutoPayFor(ctx context.Context, params map[string]any, giveType string) *response.PayForResponse {
payForResponse := new(response.PayForResponse)
// // AutoPayFor 程序自动代付
// func AutoPayFor(ctx context.Context, params map[string]any, giveType string) *response.PayForResponse {
// payForResponse := new(response.PayForResponse)
merchantInfo := merchant.GetMerchantByPasskey(ctx, convertor.ToString(params["merchantKey"]))
if !utils.Md5Verify(ctx, params, merchantInfo.MerchantSecret) {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("下游商户代付请求,签名失败,商户信息: %+v", merchantInfo))
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = "下游商户代付请求,签名失败。"
return payForResponse
} else {
res, msg := checkSettAmount(ctx, convertor.ToString(params["amount"]))
if !res {
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = msg
// merchantInfo := merchant.GetMerchantByPasskey(ctx, convertor.ToString(params["merchantKey"]))
// if !utils.Md5Verify(ctx, params, merchantInfo.MerchantSecret) {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("下游商户代付请求,签名失败,商户信息: %+v", merchantInfo))
// payForResponse.ResultCode = "01"
// payForResponse.ResultMsg = "下游商户代付请求,签名失败。"
// return payForResponse
// } else {
// res, msg := checkSettAmount(ctx, convertor.ToString(params["amount"]))
// if !res {
// payForResponse.ResultCode = "01"
// payForResponse.ResultMsg = msg
return payForResponse
}
// return payForResponse
// }
exist := payfor.IsExistPayForByMerchantOrderId(convertor.ToString(params["merchantOrderId"]))
if exist {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("代付订单号重复merchantOrderId = %s", params["merchantOrderId"]))
payForResponse.ResultMsg = "商户订单号重复"
payForResponse.ResultCode = "01"
// exist := payfor.IsExistPayForByMerchantOrderId(convertor.ToString(params["merchantOrderId"]))
// if exist {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("代付订单号重复merchantOrderId = %s", params["merchantOrderId"]))
// payForResponse.ResultMsg = "商户订单号重复"
// payForResponse.ResultCode = "01"
return payForResponse
}
// return payForResponse
// }
settAmount, err := strconv.ParseFloat(convertor.ToString(params["amount"]), 64)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("代付的金额错误:", zap.Error(err))
payForResponse.ResultMsg = "代付金额错误"
payForResponse.ResultCode = "01"
return payForResponse
}
// settAmount, err := strconv.ParseFloat(convertor.ToString(params["amount"]), 64)
// if err != nil {
// otelTrace.Logger.WithContext(ctx).Error("代付的金额错误:", zap.Error(err))
// payForResponse.ResultMsg = "代付金额错误"
// payForResponse.ResultCode = "01"
// return payForResponse
// }
p := payfor.PayforInfo{
PayforUid: "pppp" + xid.New().String(),
MerchantUid: merchantInfo.MerchantUid,
MerchantName: merchantInfo.MerchantName,
MerchantOrderId: convertor.ToString(params["merchantOrderId"]),
BankOrderId: "4444" + xid.New().String(),
PayforAmount: settAmount,
Status: config.PAYFOR_COMFRIM,
BankAccountName: convertor.ToString(params["realname"]),
BankAccountNo: convertor.ToString(params["cardNo"]),
BankAccountType: convertor.ToString(params["accType"]),
City: convertor.ToString(params["city"]),
Ares: convertor.ToString(params["province"]) + convertor.ToString(params["city"]),
PhoneNo: convertor.ToString(params["mobileNo"]),
GiveType: giveType,
CreateTime: time.Now(),
UpdateTime: time.Now(),
RequestTime: time.Now(),
}
// p := payfor.PayforInfo{
// PayforUid: "pppp" + xid.New().String(),
// MerchantUid: merchantInfo.MerchantUid,
// MerchantName: merchantInfo.MerchantName,
// MerchantOrderId: convertor.ToString(params["merchantOrderId"]),
// BankOrderId: "4444" + xid.New().String(),
// PayforAmount: settAmount,
// Status: config.PAYFOR_COMFRIM,
// BankAccountName: convertor.ToString(params["realname"]),
// BankAccountNo: convertor.ToString(params["cardNo"]),
// BankAccountType: convertor.ToString(params["accType"]),
// City: convertor.ToString(params["city"]),
// Ares: convertor.ToString(params["province"]) + convertor.ToString(params["city"]),
// PhoneNo: convertor.ToString(params["mobileNo"]),
// GiveType: giveType,
// CreateTime: time.Now(),
// UpdateTime: time.Now(),
// RequestTime: time.Now(),
// }
// 获取银行编码和银行名称
p.BankCode = utils.GetBankCodeByBankCardNo(ctx, p.BankAccountNo)
p.BankName = utils.GetBankNameByCode(p.BankCode)
// // 获取银行编码和银行名称
// p.BankCode = utils.GetBankCodeByBankCardNo(ctx, p.BankAccountNo)
// p.BankName = utils.GetBankNameByCode(p.BankCode)
if !payfor.InsertPayFor(ctx, p) {
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = "代付记录插入失败"
} else {
payForResponse.ResultMsg = "代付订单已生成"
payForResponse.ResultCode = "00"
payForResponse.SettAmount = convertor.ToString(params["amount"])
payForResponse.MerchantOrderId = convertor.ToString(params["MerchantOrderId"])
// if !payfor.InsertPayFor(ctx, p) {
// payForResponse.ResultCode = "01"
// payForResponse.ResultMsg = "代付记录插入失败"
// } else {
// payForResponse.ResultMsg = "代付订单已生成"
// payForResponse.ResultCode = "00"
// payForResponse.SettAmount = convertor.ToString(params["amount"])
// payForResponse.MerchantOrderId = convertor.ToString(params["MerchantOrderId"])
p = payfor.GetPayForByBankOrderId(ctx, p.BankOrderId)
// p = payfor.GetPayForByBankOrderId(ctx, p.BankOrderId)
if findPayForRoad(ctx, p) {
payForResponse.ResultCode = "00"
payForResponse.ResultMsg = "银行处理中"
} else {
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = "系统处理失败"
}
// if findPayForRoad(ctx, p) {
// payForResponse.ResultCode = "00"
// payForResponse.ResultMsg = "银行处理中"
// } else {
// payForResponse.ResultCode = "01"
// payForResponse.ResultMsg = "系统处理失败"
// }
}
// }
return payForResponse
}
}
// return payForResponse
// }
// }
/**
* 返回1表示需要手动打款返回0表示银行已经受理-1表示系统处理失败
*/
func findPayForRoad(ctx context.Context, p payfor.PayforInfo) bool {
m := merchant.GetMerchantByUid(ctx, p.MerchantUid)
// /**
// * 返回1表示需要手动打款返回0表示银行已经受理-1表示系统处理失败
// */
// func findPayForRoad(ctx context.Context, p payfor.PayforInfo) bool {
// m := merchant.GetMerchantByUid(ctx, p.MerchantUid)
md := merchant_deploy.GetMerchantDeployByUidAndRoadUid(ctx, m.MerchantUid, p.RoadUid)
// md := merchant_deploy.GetMerchantDeployByUidAndRoadUid(ctx, m.MerchantUid, p.RoadUid)
// 检查商户是否设置了自动代付
if md.AutoPayfor == config.NO || md.AutoPayfor == "" {
logs.Notice(fmt.Sprintf("该商户uid=%s 没有开通自动代付功能", p.MerchantUid))
p.Type = config.PAYFOR_HAND
payfor.UpdatePayFor(ctx, p)
} else {
if m.SinglePayForRoadUid != "" {
p.RoadUid = m.SinglePayForRoadUid
p.RoadName = m.SinglePayForRoadName
} else {
roadPoolInfo := road.GetRoadPoolByRoadPoolCode(ctx, m.RollPayForRoadCode)
roadUids := strings.Split(roadPoolInfo.RoadUidPool, "||")
roadInfoList := road.GetRoadInfosByRoadUids(ctx, roadUids)
if len(roadUids) == 0 || len(roadInfoList) == 0 {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("通道轮询池=%s, 没有配置通道", m.RollPayForRoadCode))
} else {
p.RoadUid = roadInfoList[0].RoadUid
p.RoadName = roadInfoList[0].RoadName
}
}
// // 检查商户是否设置了自动代付
// if md.AutoPayfor == config.NO || md.AutoPayfor == "" {
// logs.Notice(fmt.Sprintf("该商户uid=%s 没有开通自动代付功能", p.MerchantUid))
// p.Type = config.PAYFOR_HAND
// payfor.UpdatePayFor(ctx, p)
// } else {
// if m.SinglePayForRoadUid != "" {
// p.RoadUid = m.SinglePayForRoadUid
// p.RoadName = m.SinglePayForRoadName
// } else {
// roadPoolInfo := road.GetRoadPoolByRoadPoolCode(ctx, m.RollPayForRoadCode)
// roadUids := strings.Split(roadPoolInfo.RoadUidPool, "||")
// roadInfoList := road.GetRoadInfosByRoadUids(ctx, roadUids)
// if len(roadUids) == 0 || len(roadInfoList) == 0 {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("通道轮询池=%s, 没有配置通道", m.RollPayForRoadCode))
// } else {
// p.RoadUid = roadInfoList[0].RoadUid
// p.RoadName = roadInfoList[0].RoadName
// }
// }
if !payfor.UpdatePayFor(ctx, p) {
return false
}
// if !payfor.UpdatePayFor(ctx, p) {
// return false
// }
if len(p.RoadUid) > 0 {
roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
p.PayforFee = roadInfo.SettleFee
p.PayforTotalAmount = p.PayforFee + p.PayforAmount
// if len(p.RoadUid) > 0 {
// roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
// p.PayforFee = roadInfo.SettleFee
// p.PayforTotalAmount = p.PayforFee + p.PayforAmount
if m.PayforFee > config.ZERO {
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("商户uid=%s有单独的代付手续费。", m.MerchantUid))
p.PayforFee = m.PayforFee
p.PayforTotalAmount = p.PayforFee + p.PayforAmount
}
// if m.PayforFee > config.ZERO {
// otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("商户uid=%s有单独的代付手续费。", m.MerchantUid))
// p.PayforFee = m.PayforFee
// p.PayforTotalAmount = p.PayforFee + p.PayforAmount
// }
if !payfor.UpdatePayFor(ctx, p) {
return false
}
// if !payfor.UpdatePayFor(ctx, p) {
// return false
// }
if p.GiveType == config.SELF_HELP {
if !MerchantSelf(ctx, p) {
return false
}
} else {
if !SendPayFor(ctx, p) {
return false
}
}
} else {
p.Status = config.PAYFOR_FAIL
if !payfor.UpdatePayFor(ctx, p) {
return false
}
p.ResponseContent = "没有设置代付通道"
}
}
// if p.GiveType == config.SELF_HELP {
// if !MerchantSelf(ctx, p) {
// return false
// }
// } else {
// if !SendPayFor(ctx, p) {
// return false
// }
// }
// } else {
// p.Status = config.PAYFOR_FAIL
// if !payfor.UpdatePayFor(ctx, p) {
// return false
// }
// p.ResponseContent = "没有设置代付通道"
// }
// }
return true
}
// return true
// }
// MerchantSelf 商户自己体现
func MerchantSelf(ctx context.Context, p payfor.PayforInfo) bool {
o := orm.NewOrm()
// // MerchantSelf 商户自己体现
// func MerchantSelf(ctx context.Context, p payfor.PayforInfo) bool {
// o := orm.NewOrm()
if err := o.DoTxWithCtx(ctx, func(ctx context.Context, txOrm orm.TxOrmer) error {
p.UpdateTime = time.Now()
p.Status = config.PAYFOR_BANKING
p.RequestTime = time.Now()
p.IsSend = config.YES
if _, err := txOrm.Update(&p); err != nil {
return err
}
// if err := o.DoTxWithCtx(ctx, func(ctx context.Context, txOrm orm.TxOrmer) error {
// p.UpdateTime = time.Now()
// p.Status = config.PAYFOR_BANKING
// p.RequestTime = time.Now()
// p.IsSend = config.YES
// if _, err := txOrm.Update(&p); err != nil {
// return err
// }
RequestPayFor(ctx, p)
// RequestPayFor(ctx, p)
return nil
}); err != nil {
return false
}
return true
}
// return nil
// }); err != nil {
// return false
// }
// return true
// }
func SendPayFor(ctx context.Context, p payfor.PayforInfo) bool {
o := orm.NewOrm()
// func SendPayFor(ctx context.Context, p payfor.PayforInfo) bool {
// o := orm.NewOrm()
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
var account accounts.AccountInfo
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", p.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
otelTrace.Logger.WithContext(ctx).Error("send payfor select account fail", zap.Error(err))
return err
}
// if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
// var account accounts.AccountInfo
// if err := txOrm.Raw("select * from account_info where account_uid = ? for update", p.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
// otelTrace.Logger.WithContext(ctx).Error("send payfor select account fail", zap.Error(err))
// return err
// }
// 支付金额不足,将直接判定为失败,不往下面邹逻辑了
if account.SettleAmount-account.PayforAmount < p.PayforAmount+p.PayforFee {
p.Status = config.PAYFOR_FAIL
p.UpdateTime = time.Now()
// // 支付金额不足,将直接判定为失败,不往下面邹逻辑了
// if account.SettleAmount-account.PayforAmount < p.PayforAmount+p.PayforFee {
// p.Status = config.PAYFOR_FAIL
// p.UpdateTime = time.Now()
if _, err := txOrm.Update(&p); err != nil {
return err
} else {
return nil
}
}
// if _, err := txOrm.Update(&p); err != nil {
// return err
// } else {
// return nil
// }
// }
account.UpdateTime = time.Now()
account.PayforAmount = account.PayforAmount + p.PayforAmount + p.PayforFee
// account.UpdateTime = time.Now()
// account.PayforAmount = account.PayforAmount + p.PayforAmount + p.PayforFee
if _, err := txOrm.Update(&account); err != nil {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("商户uid=%s在发送代付给上游的处理中更新账户表出错, err: %s", p.MerchantUid, err))
return err
}
// if _, err := txOrm.Update(&account); err != nil {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("商户uid=%s在发送代付给上游的处理中更新账户表出错, err: %s", p.MerchantUid, err))
// return err
// }
p.IsSend = config.YES
p.Status = config.PAYFOR_BANKING // 变为银行处理中
p.GiveType = config.PAYFOR_ROAD
p.RequestTime = time.Now()
p.UpdateTime = time.Now()
// p.IsSend = config.YES
// p.Status = config.PAYFOR_BANKING // 变为银行处理中
// p.GiveType = config.PAYFOR_ROAD
// p.RequestTime = time.Now()
// p.UpdateTime = time.Now()
if _, err := txOrm.Update(&p); err != nil {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("商户uid=%s在发送代付给上游的处理中更代付列表出错 err%s", p.MerchantUid, err))
return err
}
// if _, err := txOrm.Update(&p); err != nil {
// otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("商户uid=%s在发送代付给上游的处理中更代付列表出错 err%s", p.MerchantUid, err))
// return err
// }
RequestPayFor(ctx, p)
// RequestPayFor(ctx, p)
return nil
}); err != nil {
return false
}
return true
}
func RequestPayFor(ctx context.Context, p payfor.PayforInfo) {
if p.RoadUid == "" {
return
}
p.Type = config.PAYFOR_ROAD
roadInfo := road.GetRoadInfoByRoadUid(ctx, p.RoadUid)
supplierCode := roadInfo.ProductUid
supplier := third_party.GetPaySupplierByCode(supplierCode)
res := supplier.PayFor(p)
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("代付uid=%s上游处理结果为%s", p.PayforUid, res))
// 将代付订单号发送到消息队列
message.SendMessage(ctx, config.MqPayForQuery, p.BankOrderId)
}
// return nil
// }); err != nil {
// return false
// }
// return true
// }
// PayForResultQuery 代付结果查询
func PayForResultQuery(ctx context.Context, params map[string]any) string {

View File

@@ -51,7 +51,7 @@ func SolvePaySuccess(ctx context.Context, bankOrderId string, factAmount float64
}
if orderInfo.Status == config.SUCCESS {
otelTrace.Logger.WithContext(ctx).Error("该订单已经处理,订单号=", zap.String("bankOrderId", bankOrderId))
return errors.New(fmt.Sprintf("该订单已经处理,订单号= %s", bankOrderId))
return fmt.Errorf("该订单已经处理,订单号= %s", bankOrderId)
}
orderInfo.CardReturnData = cardReturnData
@@ -91,7 +91,7 @@ func SolvePaySuccess(ctx context.Context, bankOrderId string, factAmount float64
}
if orderProfitInfo.BankOrderId == "" {
otelTrace.Logger.WithContext(ctx).Error("solve pay success, get orderProfit fail, bankOrderId = ", zap.String("bankOrderId", bankOrderId))
return errors.New(fmt.Sprintf("solve pay success, get orderProfit fail, bankOrderId = %s", bankOrderId))
return fmt.Errorf("solve pay success, get orderProfit fail, bankOrderId = %s", bankOrderId)
}
if isStealCard {
return nil
@@ -176,13 +176,14 @@ func SolvePaySuccess(ctx context.Context, bankOrderId string, factAmount float64
// 创建一个5分钟超时的上下文
ctx2, span := otelTrace.NewSchedulerTrace().Start(context.Background(), "SolvePaySuccess", trace.WithNewRoot())
defer span.End()
CreateOrderNotifyInfo(ctx2, bankOrderId, config.SUCCESS)
otelTrace.Logger.WithContext(ctx2).Info("SolvePaySuccess", zap.String("bankOrderId", bankOrderId), zap.String("factAmount", strconv.FormatFloat(factAmount, 'f', 2, 64)))
CreateOrderNotifyInfo(ctx2, bankOrderId)
})
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("SolvePaySuccess失败", zap.Error(err))
return true
}
otelTrace.Logger.WithContext(ctx).Info("SolvePaySuccess处理成功")
otelTrace.Logger.WithContext(ctx).Info("SolvePaySuccess成功", zap.String("bankOrderId", bankOrderId))
return true
}
@@ -190,6 +191,7 @@ func SolvePaySuccess(ctx context.Context, bankOrderId string, factAmount float64
func SolvePayFail(ctx context.Context, bankOrderId, transId string, cardReturnData string) bool {
ctx, cancel := otelTrace.Span(ctx, "订单处理", "SolvePayFail", trace.WithAttributes(
attribute.String("bankOrderId", bankOrderId),
attribute.String("transId", transId),
attribute.String("cardReturnData", cardReturnData),
))
defer cancel()
@@ -201,7 +203,6 @@ func SolvePayFail(ctx context.Context, bankOrderId, transId string, cardReturnDa
}
if orderTmp.Status != config.WAIT {
return nil
// return errors.New("订单已经处理,不要重复加款")
}
if _, err := txOrm.QueryTable(order.ORDER_INFO).Filter("bank_order_id", bankOrderId).UpdateWithCtx(ctx, orm.Params{
"status": config.FAIL,
@@ -229,12 +230,13 @@ func SolvePayFail(ctx context.Context, bankOrderId, transId string, cardReturnDa
// 创建一个5分钟超时的上下文
ctx2, span := otelTrace.NewSchedulerTrace().Start(context.Background(), "SolvePayFail", trace.WithNewRoot())
defer span.End()
CreateOrderNotifyInfo(ctx2, bankOrderId, config.FAIL)
otelTrace.Logger.WithContext(ctx2).Info("SolvePayFail", zap.String("bankOrderId", bankOrderId), zap.String("transId", transId), zap.String("cardReturnData", cardReturnData))
CreateOrderNotifyInfo(ctx2, bankOrderId)
})
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("SolvePayFail", zap.Error(err))
}
otelTrace.Logger.WithContext(ctx).Info("SolvePayFail成功")
otelTrace.Logger.WithContext(ctx).Info("SolvePayFail成功", zap.String("bankOrderId", bankOrderId))
return true
}
@@ -513,14 +515,14 @@ func CompareOrderAndFactAmount(factAmount float64, orderInfo order.OrderInfo) in
}
// CreateOrderNotifyInfo 支付完成后,处理给商户的回调信息
func CreateOrderNotifyInfo(ctx context.Context, bankOrderId string, tradeStatus string) {
func CreateOrderNotifyInfo(ctx context.Context, bankOrderId string) {
orderInfo := order.GetOneOrder(ctx, bankOrderId)
if orderInfo.Status != config.SUCCESS && orderInfo.Status != config.FAIL {
return
}
merchantInfo := merchant.GetMerchantByUid(ctx, orderInfo.MerchantUid)
statusCode := 0
if tradeStatus == "success" {
if orderInfo.Status == config.SUCCESS {
statusCode = 1
}
params := map[string]any{
@@ -548,9 +550,9 @@ func CreateOrderNotifyInfo(ctx context.Context, bankOrderId string, tradeStatus
UpdateTime: time.Now(),
Url: orderInfo.NotifyUrl + "?" + u.Encode(),
}) {
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("订单bankOrderId=%s已经将回调地址插入数据库", orderInfo.BankOrderId))
otelTrace.Logger.WithContext(ctx).Info(fmt.Sprintf("订单bankOrderId=%s回调地址插入数据库", orderInfo.BankOrderId), zap.Any("params", params))
} else {
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("订单bankOrderId=%s插入回调数据库失败", orderInfo.BankOrderId))
otelTrace.Logger.WithContext(ctx).Error(fmt.Sprintf("订单bankOrderId=%s插入回调数据库失败", orderInfo.BankOrderId), zap.Any("params", params))
}
// 将订单发送到消息队列,给下面的商户进行回调
sendMessageNotify.Go(func() {

View File

@@ -136,7 +136,7 @@ func (c *AiboCardImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, road
// KMEncrypt 加密卡密
func (c *AiboCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -186,7 +186,7 @@ func (c *AppleCardImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roa
// KMEncrypt 加密卡密
func (c *AppleCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -151,7 +151,7 @@ func (c *AppleCardSharkImpl) Scan(ctx context.Context, orderInfo order.OrderInfo
// KMEncrypt 加密卡密
func (c *AppleCardSharkImpl) kMEncrypt(ctx context.Context, kf, appSecret string) (string, error) {
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -143,7 +143,7 @@ func (c *CTripSelfImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roa
func (c *CTripSelfImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -104,7 +104,7 @@ func (c *CarelessImpl) SendCard(ctx context.Context, jsonStr string, cardInfo su
request := httplib.NewBeegoRequest("https://api.wuxinpay.xyz/api/v1/payment/init", "POST").
SetTransport(otelhttp.NewTransport(http.DefaultTransport)).
SetTimeout(time.Second*3, time.Second*3).Retries(3)
SetTimeout(time.Second*30, time.Second*30).Retries(3).RetryDelay(time.Second)
request, err = request.JSONBody(reqStruct)
if err != nil {
@@ -112,6 +112,9 @@ func (c *CarelessImpl) SendCard(ctx context.Context, jsonStr string, cardInfo su
return false, "请求格式错误"
}
otelTrace.Logger.WithContext(ctx).Info("请求响应", zap.Any("reqStruct", reqStruct))
return true, ""
response, err := request.Response()
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("请求失败", zap.Error(err))
@@ -146,6 +149,12 @@ func (c *CarelessImpl) SendCard(ctx context.Context, jsonStr string, cardInfo su
}
otelTrace.Logger.WithContext(ctx).Info("请求响应", zap.Any("reqStruct", reqStruct), zap.String("body", string(body)))
err = json.Unmarshal(body, &resp)
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("解析失败", zap.Error(err))
return false, "登录返回数据错误:" + string(body)
}
if resp.Code != "200" {
otelTrace.Logger.WithContext(ctx).Error("请求失败", zap.String("msg", resp.Msg))
return false, resp.Msg

View File

@@ -0,0 +1,22 @@
package third_party
import (
"context"
"gateway/internal/service/supplier"
"gateway/internal/utils"
"testing"
)
func TestCarelessImpl_SendCard(t *testing.T) {
eggplant := &CarelessImpl{}
//{
// "mchKey": "1103",
// "product": "813",
// "paySecret":"kysV3ApKDrp5u4YQN8xGgLC"
//}
eggplant.SendCard(context.Background(), "{\"mchKey\":\"1103\",\"product\":\"813\",\"paySecret\":\"kysV3ApKDrp5u4YQN8xGgLC\",\"url\":\"https://admin.djfkm.xyz\"}", supplier.RedeemCardInfo{
FaceType: "10",
CardNo: "888888100018931806",
Data: "JR2NKN37WNYZ2AG",
}, utils.GenerateId())
}

View File

@@ -65,7 +65,7 @@ func (c *DaiLiImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadInf
waitStr := utils.MapToString(utils.SortMapByKeys(params))
waitStr = waitStr + "&signkey=" + signKey
sign := utils.GetMD5LOWER(waitStr)
sign := utils.GetMd5Lower(waitStr)
params["sign"] = sign
request := URL + "?" + utils.MapToString(params)

View File

@@ -54,7 +54,6 @@ type eggplantProductCode struct {
}
func (c *eggplantProductCode) SendData(ctx context.Context, orderId string, forwardUrl *url.URL) (bool, string, string) {
otelTrace.Logger.WithContext(ctx).Info("发送数据", zap.Any("forwardUrl", forwardUrl), zap.Any("productCode", c.ProductCode), zap.Any("cardNo", c.CardNo), zap.Any("cardPassword", c.CardPassword))
// 通道1
chnnalOneCodeArray := []string{"8055", "8076", "8055"}
if slices.Contains(chnnalOneCodeArray, strutil.Trim(c.ProductCode)) {
@@ -209,7 +208,7 @@ func (c *EggplantImpl) generateSign(ctx context.Context, params map[string]any,
signStr += fmt.Sprintf("%s=%s&", k, convertor.ToString(params[k]))
}
signStr += fmt.Sprintf("Key=%s", key)
return utils.GetMD5LOWER(signStr)
return utils.GetMd5Lower(signStr)
}
func (c *EggplantImpl) SendCard(ctx context.Context, jsonStr string, cardInfo supplier.RedeemCardInfo, attach string) (bool, string, string) {
@@ -321,7 +320,7 @@ func (c *EggplantImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, road
// KMEncrypt 加密卡密
func (c *EggplantImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("茄子: AesDecrypt failed to NewCipher")
@@ -336,7 +335,7 @@ func (c *EggplantImpl) kMEncrypt(kf, appSecret string) (string, error) {
}
func (c *EggplantImpl) PayNotify() {
ctx := context.Background()
ctx := c.Ctx.Request.Context()
var params struct {
OrderId string `json:"order_no" form:"order_no"`
@@ -365,7 +364,6 @@ func (c *EggplantImpl) PayNotify() {
)
defer cancel()
otelTrace.Logger.WithContext(ctx).Info("【茄子】回调数据", zap.Any("params", params))
orderInfo := order.GetOrderByBankOrderId(ctx, params.OrderId)
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
@@ -400,13 +398,13 @@ func (c *EggplantImpl) PayNotify() {
} else {
c.Ctx.WriteString("fail")
}
return
}
isOk := service.SolvePayFail(ctx, orderInfo.BankOrderId, orderInfo.BankOrderId, "支付失败")
if isOk {
c.Ctx.WriteString("success")
} else {
isOk := service.SolvePayFail(ctx, orderInfo.BankOrderId, orderInfo.BankOrderId, "支付失败")
if isOk {
c.Ctx.WriteString("success")
} else {
c.Ctx.WriteString("fail")
}
c.Ctx.WriteString("fail")
}
return
}

View File

@@ -316,7 +316,7 @@ func (c *FavorableCloudsCardImpl) delayQuery(ctx context.Context, orderId string
// KMEncrypt 加密卡密
func (c *FavorableCloudsCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("祥云: AesDecrypt failed to NewCipher")

View File

@@ -150,12 +150,12 @@ func (c *HeepayImpl) SendCard(ctx context.Context, jsonStr string, cardInfo supp
}
params := map[string]any{
"agent_id": agentID,
"card_type": int64(10),
"bill_id": attach,
"bill_time": time.Now().Format("20060102150405"),
"card_data": TripleDesEncrypt(fmt.Sprintf("%s,%s,%s", cardInfo.CardNo, cardInfo.Data, cardInfo.FaceType), gojson.Json(jsonStr).Get("3ds_key").Tostring()),
"pay_amt": int64(payAmt),
"agent_id": agentID,
"card_type": int64(10),
"bill_id": attach,
"bill_time": time.Now().Format("20060102150405"),
"card_data": TripleDesEncrypt(fmt.Sprintf("%s,%s,%s", cardInfo.CardNo, cardInfo.Data, cardInfo.FaceType), gojson.Json(jsonStr).Get("3ds_key").Tostring()),
"pay_amt": int64(payAmt),
"client_ip": strings.ReplaceAll("127.0.0.1", ".", "_"),
"goods_detail": convertor.ToString(product),
"time_stamp": timeStampInt,
@@ -257,7 +257,7 @@ func (c *HeepayImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadIn
func (c *HeepayImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -149,7 +149,7 @@ func (c *JDCardImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roadIn
func (c *JDCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -174,7 +174,7 @@ func (c *MFCardV2Impl) Scan(ctx context.Context, orderInfo order.OrderInfo, road
// KMEncrypt 加密卡密
func (c *MFCardV2Impl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -152,7 +152,7 @@ func (c *NinjaCardImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roa
// KMEncrypt 加密卡密
func (c *NinjaCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("忍者: AesDecrypt failed to NewCipher")

View File

@@ -162,7 +162,7 @@ func (c *QiXiCardImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, road
// KMEncrypt 加密卡密
func (c *QiXiCardImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("七喜: AesDecrypt failed to NewCipher")

View File

@@ -130,7 +130,7 @@ func (c *SelfThirdImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, roa
func (c *SelfThirdImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")

View File

@@ -153,7 +153,7 @@ func (c *WalmartSelfImpl) Scan(ctx context.Context, orderInfo order.OrderInfo, r
func (c *WalmartSelfImpl) kMEncrypt(kf, appSecret string) (string, error) {
ctx := context.Background()
secret := utils.GetMD5LOWER(appSecret)[:16] // 加密秘钥
secret := utils.GetMd5Lower(appSecret)[:16] // 加密秘钥
block, err := aes.NewCipher([]byte(secret))
if err != nil {
otelTrace.Logger.WithContext(ctx).Error("Joker: AesDecrypt failed to NewCipher")
@@ -189,8 +189,8 @@ func (c *WalmartSelfImpl) PayNotify() {
params := map[string]string{
"merchantId": strings.TrimSpace(c.GetString("merchantId")),
"amount": strings.TrimSpace(c.GetString("amount")), // 时间戳
"status": strings.TrimSpace(c.GetString("status")),
"remark": strings.TrimSpace(c.GetString("remark")),
"status": strings.TrimSpace(c.GetString("status")),
"remark": strings.TrimSpace(c.GetString("remark")),
}
otelTrace.Logger.WithContext(ctx).Info("【沃尔玛】回调参数:", zap.Any("params", params))

View File

@@ -13,12 +13,13 @@ package utils
import (
"crypto/md5"
"encoding/hex"
"github.com/duke-git/lancet/v2/convertor"
"strings"
"github.com/duke-git/lancet/v2/convertor"
)
// GetMD5LOWER 获取小写的MD5
func GetMD5LOWER(s string) string {
// GetMd5Lower 获取小写的MD5
func GetMd5Lower(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
@@ -26,7 +27,7 @@ func GetMD5LOWER(s string) string {
// GetMD5Upper 获取大写的MD5
func GetMD5Upper(s string) string {
return strings.ToUpper(GetMD5LOWER(s))
return strings.ToUpper(GetMd5Lower(s))
}
// MapToString 将map数据变成key=value形式的字符串

View File

@@ -103,6 +103,5 @@ func GetMD5SignMF(params map[string]any, paySecret string) string {
}
}
signStr += paySecret
otelTrace.Logger.WithContext(context.Background()).Info("signStr=%s", zap.String("signStr", signStr))
return GetMD5LOWER(signStr)
return GetMd5Lower(signStr)
}

View File

@@ -11,17 +11,19 @@ import (
_ "gateway/internal/service/message"
"gateway/internal/service/notify"
_ "gateway/internal/service/supplier/third_party"
"github.com/beego/beego/v2/server/web"
"log"
_ "net/http/pprof"
"github.com/beego/beego/v2/server/web"
"go.uber.org/zap"
"github.com/beego/beego/v2/server/web/context"
_ "github.com/go-sql-driver/mysql"
)
func logRequest(ctx *context.Context) {
log.Printf("Request: %s %s", ctx.Input.Method(), ctx.Input.URI())
otelTrace.Logger.WithContext(otelTrace.InitCtx).Info("Request", zap.String("method", ctx.Input.Method()), zap.String("uri", ctx.Input.URI()), zap.String("ip", ctx.Input.IP()), zap.Any("params", ctx.Input.Params()), zap.Any("body", ctx.Input.RequestBody))
}
func main() {
@@ -31,7 +33,6 @@ func main() {
log.Printf("初始化代理池失败: %v", err)
return
}
// cleanup1, cleanup2, cleanup3 := otelTrace.InitTracer()
// defer func() {
// if cleanup1 != nil {
@@ -45,7 +46,7 @@ func main() {
// }
// }()
go notify.CreateOrderNotifyConsumer(otelTrace.InitCtx)
go query.CreatePayForQueryConsumer(otelTrace.InitCtx)
// go query.CreatePayForQueryConsumer(otelTrace.InitCtx)
go service.OrderSettleInit(otelTrace.InitCtx)
go query.CreateSupplierOrderQueryCuConsumer(otelTrace.InitCtx)
web.InsertFilter("*", web.BeforeRouter, logRequest)