mirror of
https://github.com/kongyuebin1/dongfeng-pay.git
synced 2025-08-18 11:41:59 +08:00
修改网关代码的结构,调整了逻辑,删除了许多无用的代码
This commit is contained in:
83
gateway/query/merchant_query.go
Normal file
83
gateway/query/merchant_query.go
Normal file
@@ -0,0 +1,83 @@
|
||||
/***************************************************
|
||||
** @Desc : 供下游订单状态查询和代付结果查询
|
||||
** @Time : 2019/11/6 13:59
|
||||
** @Author : yuebin
|
||||
** @File : order_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/6 13:59
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package query
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MerchantQueryController struct {
|
||||
web.Controller
|
||||
}
|
||||
|
||||
type OrderQueryFailData struct {
|
||||
PayKey string `json:"payKey"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
/*
|
||||
** 改接口是为下游商户提供订单查询
|
||||
*/
|
||||
func (c *MerchantQueryController) OrderQuery() {
|
||||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||||
payKey := strings.TrimSpace(c.GetString("payKey"))
|
||||
sign := strings.TrimSpace(c.GetString("sign"))
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderNo
|
||||
params["payKey"] = payKey
|
||||
|
||||
failData := new(OrderQueryFailData)
|
||||
failData.StatusCode = "01"
|
||||
failData.PayKey = payKey
|
||||
|
||||
merchantInfo := merchant.GetMerchantByPaykey(payKey)
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
failData.Msg = "商户不存在,请核对payKey字段"
|
||||
}
|
||||
orderInfo := order.GetOrderByMerchantOrderId(orderNo)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
failData.Msg = "不存在这样的订单,请核对orderNo字段"
|
||||
}
|
||||
keys := utils.SortMap(params)
|
||||
paySercet := merchantInfo.MerchantSecret
|
||||
tmpSign := utils.GetMD5Sign(params, keys, paySercet)
|
||||
if tmpSign != sign {
|
||||
failData.Msg = "签名错误"
|
||||
}
|
||||
if failData.Msg != "" {
|
||||
c.Data["json"] = failData
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
p := make(map[string]string)
|
||||
p["orderNo"] = orderNo
|
||||
p["orderTime"] = strings.TrimSpace(strings.Replace("-", "", orderInfo.UpdateTime, -1))
|
||||
p["trxNo"] = orderInfo.BankOrderId
|
||||
p["tradeStatus"] = orderInfo.Status
|
||||
p["payKey"] = payKey
|
||||
p["orderPrice"] = fmt.Sprintf("%.2f", orderInfo.OrderAmount)
|
||||
p["factPrice"] = fmt.Sprintf("%.2f", orderInfo.FactAmount)
|
||||
p["statusCode"] = "00"
|
||||
keys = utils.SortMap(p)
|
||||
p["sign"] = utils.GetMD5Sign(p, keys, paySercet)
|
||||
s, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
logs.Error("json marshal fail: ", err)
|
||||
}
|
||||
c.Data["json"] = s
|
||||
}
|
137
gateway/query/payfor_query.go
Normal file
137
gateway/query/payfor_query.go
Normal file
@@ -0,0 +1,137 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理代付查询功能
|
||||
** @Time : 2019/12/3 15:07
|
||||
** @Author : yuebin
|
||||
** @File : pay_for_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/3 15:07
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/payfor"
|
||||
"gateway/models/road"
|
||||
"gateway/pay_for"
|
||||
"gateway/supplier/third_party"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PayForQueryTask struct {
|
||||
Delay *time.Timer
|
||||
MerchantOrderId string
|
||||
BankOrderId string
|
||||
FirstNotifyTime string
|
||||
QueryTimes int
|
||||
LimitTimes int
|
||||
Status string
|
||||
}
|
||||
|
||||
const (
|
||||
PayForLimitTimes = 12 //最多查询次数
|
||||
PayForQueryInterval = 5 //时间间隔为5分钟
|
||||
)
|
||||
|
||||
func PayForQueryTimer(task PayForQueryTask) {
|
||||
for {
|
||||
select {
|
||||
case <-task.Delay.C:
|
||||
PayForSupplier(task)
|
||||
task.Delay.Stop()
|
||||
return
|
||||
//70分钟没有执行该协程,那么退出协程
|
||||
case <-time.After(time.Minute * 70):
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PayForSupplier(task PayForQueryTask) {
|
||||
logs.Info(fmt.Sprintf("执行代付查询任务:%+v", task))
|
||||
payFor := payfor.GetPayForByBankOrderId(task.BankOrderId)
|
||||
roadInfo := road.GetRoadInfoByRoadUid(payFor.RoadUid)
|
||||
supplier := third_party.GetPaySupplierByCode(roadInfo.ProductUid)
|
||||
if supplier == nil {
|
||||
logs.Error("代付查询返回supplier为空")
|
||||
return
|
||||
}
|
||||
res, _ := supplier.PayForQuery(payFor)
|
||||
if res == conf.PAYFOR_SUCCESS {
|
||||
//代付成功了
|
||||
pay_for.PayForSuccess(payFor)
|
||||
} else if res == conf.PAYFOR_FAIL {
|
||||
//代付失败
|
||||
pay_for.PayForFail(payFor)
|
||||
} else if res == conf.PAYFOR_BANKING {
|
||||
//银行处理中,那么就继续执行查询,直到次数超过最大次数
|
||||
if task.QueryTimes <= task.LimitTimes {
|
||||
task.QueryTimes += 1
|
||||
task.Delay = time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute)
|
||||
go PayForQueryTimer(task)
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("该代付订单已经超过最大查询次数,bankOrderId = %s", task.BankOrderId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func payForQueryConsumer(bankOrderId string) {
|
||||
exist := payfor.IsExistPayForByBankOrderId(bankOrderId)
|
||||
if !exist {
|
||||
logs.Error(fmt.Sprintf("代付记录不存在,bankOrderId = %s", bankOrderId))
|
||||
return
|
||||
}
|
||||
|
||||
payFor := payfor.GetPayForByBankOrderId(bankOrderId)
|
||||
|
||||
if payFor.Status != conf.PAYFOR_BANKING {
|
||||
logs.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}
|
||||
|
||||
go PayForQueryTimer(payForQueryTask)
|
||||
}
|
||||
|
||||
/*
|
||||
* 创建代付查询的消费者
|
||||
*/
|
||||
func CreatePayForQueryConsumer() {
|
||||
//启动定时任务
|
||||
conn := message.GetActiveMQConn()
|
||||
if conn == nil {
|
||||
logs.Error("启动消息队列消费者失败....")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logs.Notice("代付查询消费启动成功......")
|
||||
|
||||
payForQuery, err := conn.Subscribe(conf.MQ_PAYFOR_QUERY, stomp.AckClient)
|
||||
if err != nil {
|
||||
logs.Error("订阅代付查询失败......")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case v := <-payForQuery.C:
|
||||
if v != nil {
|
||||
bankOrderId := string(v.Body)
|
||||
go payForQueryConsumer(bankOrderId)
|
||||
//应答,重要
|
||||
err := conn.Ack(v)
|
||||
if err != nil {
|
||||
logs.Error("消息应答失败!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
109
gateway/query/supplier_query.go
Normal file
109
gateway/query/supplier_query.go
Normal file
@@ -0,0 +1,109 @@
|
||||
/***************************************************
|
||||
** @Desc : 自动查询上游的支付结果
|
||||
** @Time : 2019/11/22 23:02
|
||||
** @Author : yuebin
|
||||
** @File : order_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 23:02
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/order"
|
||||
"gateway/supplier/third_party"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/go-stomp/stomp"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OrderQueryTask struct {
|
||||
BankOrderId string
|
||||
OrderQueryTimer *time.Timer
|
||||
Times int
|
||||
}
|
||||
|
||||
const (
|
||||
DelayTime = 5 //延时时间为5分钟查询一次
|
||||
LimitTimes = 5 //最多查询5次
|
||||
)
|
||||
|
||||
/*
|
||||
** 该接口是查询上游的订单
|
||||
*/
|
||||
func solveSupplierOrderQuery(task OrderQueryTask) {
|
||||
bankOrderId := task.BankOrderId
|
||||
orderInfo := order.GetOrderByBankOrderId(bankOrderId)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
logs.Error("不存在这样的订单,订单查询结束")
|
||||
return
|
||||
}
|
||||
if orderInfo.Status != "" && orderInfo.Status != "wait" {
|
||||
logs.Error(fmt.Sprintf("该订单=%s,已经处理完毕,", bankOrderId))
|
||||
return
|
||||
}
|
||||
supplierCode := orderInfo.PayProductCode
|
||||
supplier := third_party.GetPaySupplierByCode(supplierCode)
|
||||
flag := supplier.PayQuery(orderInfo)
|
||||
if flag {
|
||||
logs.Info("订单查询成功, bankOrderId:", bankOrderId)
|
||||
} else {
|
||||
if task.Times <= LimitTimes {
|
||||
task.Times += 1
|
||||
task.OrderQueryTimer = time.NewTimer(time.Duration(5) * time.Minute)
|
||||
DelayOrderQueryQueue(task)
|
||||
} else {
|
||||
logs.Notice(fmt.Sprintf("订单id=%s, 已经查询超过次数"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 延时队列
|
||||
*/
|
||||
func DelayOrderQueryQueue(task OrderQueryTask) {
|
||||
for {
|
||||
select {
|
||||
case <-task.OrderQueryTimer.C:
|
||||
logs.Info(fmt.Sprintf("订单id=%s,执行第:%d 次查询", task.BankOrderId, task.Times))
|
||||
solveSupplierOrderQuery(task)
|
||||
return
|
||||
case <-time.After(time.Duration(2*DelayTime) * time.Minute):
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** 启动消息订单查询的消息队列消费者
|
||||
*/
|
||||
func CreateSupplierOrderQueryCuConsumer() {
|
||||
conn := message.GetActiveMQConn()
|
||||
if conn == nil {
|
||||
logs.Error("supplier order query consumer fail")
|
||||
os.Exit(1)
|
||||
}
|
||||
logs.Notice("启动订单查询的消费者成功.....")
|
||||
orderQuerySub, _ := conn.Subscribe(conf.MqOrderQuery, stomp.AckClient)
|
||||
|
||||
for {
|
||||
select {
|
||||
case v := <-orderQuerySub.C:
|
||||
if v != nil {
|
||||
bankOrderId := string(v.Body)
|
||||
logs.Info("消费者正在处理订单查询: " + bankOrderId)
|
||||
task := OrderQueryTask{BankOrderId: bankOrderId, OrderQueryTimer: time.NewTimer(time.Second * 1), Times: 1}
|
||||
DelayOrderQueryQueue(task)
|
||||
//应答,重要
|
||||
err := conn.Ack(v)
|
||||
if err != nil {
|
||||
logs.Error("消息应答失败!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user