|
|
@ -4,111 +4,13 @@ import ( |
|
|
|
"fmt" |
|
|
|
"github.com/chanxuehong/wechat/mch/mmpaymkttransfers" |
|
|
|
"github.com/chanxuehong/wechat/mch/mmpaymkttransfers/promotion" |
|
|
|
"go.uber.org/zap" |
|
|
|
"hudongzhuanjia/logger" |
|
|
|
"hudongzhuanjia/models" |
|
|
|
"hudongzhuanjia/utils" |
|
|
|
"hudongzhuanjia/utils/define" |
|
|
|
"math" |
|
|
|
"strconv" |
|
|
|
"time" |
|
|
|
) |
|
|
|
|
|
|
|
func init() { |
|
|
|
//go loopTransfer()
|
|
|
|
} |
|
|
|
|
|
|
|
var transferDelayQueue = make(chan *transferDelayQueueParam, math.MaxInt8) |
|
|
|
|
|
|
|
type transferDelayQueueParam struct { |
|
|
|
first bool // 首次跳过
|
|
|
|
Retries int `json:"retries"` // 尝试次数
|
|
|
|
Delay int `json:"delay"` // 延迟时间, 单位second
|
|
|
|
Amount int `json:"amount"` // 转账金额
|
|
|
|
Desc string `json:"desc"` // 转账描述
|
|
|
|
OpenId string `json:"open_id"` // 被转账人
|
|
|
|
PartnerTradeNo string `json:"partner_trade_no"` // 转账账单单号
|
|
|
|
} |
|
|
|
|
|
|
|
func loopTransfer() { |
|
|
|
//初始化
|
|
|
|
transfers, err := models.GetUserTransferByStatus(0, 1, 3) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
|
|
|
|
transferDelayQueue = make(chan *transferDelayQueueParam, math.MaxInt8) |
|
|
|
for _, transfer := range transfers { |
|
|
|
transferDelayQueue <- &transferDelayQueueParam{ |
|
|
|
first: true, |
|
|
|
Retries: 5, |
|
|
|
Delay: 2 * 60, |
|
|
|
Amount: transfer.PaymentAmount, |
|
|
|
Desc: transfer.Desc, |
|
|
|
OpenId: transfer.OpenId, |
|
|
|
PartnerTradeNo: transfer.PartnerTradeNo, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
defer func() { |
|
|
|
if errRec := recover(); errRec != nil { |
|
|
|
logger.Error("转账轮询 loop transfer panic", zap.Any("错误原因", errRec)) |
|
|
|
} |
|
|
|
loopTransfer() |
|
|
|
}() |
|
|
|
for { |
|
|
|
select { |
|
|
|
case param, ok := <-transferDelayQueue: |
|
|
|
if !ok { |
|
|
|
panic("转账延迟通道异常关闭") |
|
|
|
} |
|
|
|
|
|
|
|
// 尝试次数
|
|
|
|
if param.Retries <= 0 { |
|
|
|
logger.Info("微信转账尝试3次失败", zap.String("转账账单单号", param.PartnerTradeNo)) |
|
|
|
userTransfer := new(models.UserTransfer) |
|
|
|
userTransfer.Status = 4 |
|
|
|
_, err = userTransfer.UpdateByPartnerTradeNo(param.PartnerTradeNo) |
|
|
|
if err != nil { |
|
|
|
logger.Info("微信转账更新状态失败", zap.String("失败原因", err.Error()), |
|
|
|
zap.String("转账账单单号", param.PartnerTradeNo)) |
|
|
|
} |
|
|
|
continue |
|
|
|
} else { |
|
|
|
param.Retries-- |
|
|
|
} |
|
|
|
|
|
|
|
if !param.first { |
|
|
|
time.Sleep(time.Duration(param.Delay) * time.Second) |
|
|
|
} |
|
|
|
param.first = false |
|
|
|
res, err := TransferInfo(param.PartnerTradeNo) |
|
|
|
if err != nil { |
|
|
|
logger.Error("微信转账查询出现的错误", zap.String("错误原因", err.Error()), |
|
|
|
zap.String("转账账单", param.PartnerTradeNo)) |
|
|
|
transferDelayQueue <- param |
|
|
|
continue |
|
|
|
} |
|
|
|
|
|
|
|
if res.Status == define.CODE_SUCCESS { |
|
|
|
continue |
|
|
|
} else if res.Status == define.CODE_TRANSFER_PROCESSING { |
|
|
|
transferDelayQueue <- param |
|
|
|
continue |
|
|
|
} else { |
|
|
|
//失败 --> 重新转账
|
|
|
|
_, err = Transfer(param.Desc, param.OpenId, param.PartnerTradeNo, param.Amount) |
|
|
|
if err != nil { |
|
|
|
logger.Error("微信转账出现的错误", zap.String("错误原因", err.Error()), |
|
|
|
zap.String("转账账单", param.PartnerTradeNo)) |
|
|
|
} |
|
|
|
transferDelayQueue <- param // 重新确认
|
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 企业向微信用户个人付款(不支持沙箱环境)
|
|
|
|
type TransferResponse struct { |
|
|
|
DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"` |
|
|
@ -118,24 +20,6 @@ type TransferResponse struct { |
|
|
|
PaymentTime string `xml:"payment_time,omitempty" json:"payment_time,omitempty"` |
|
|
|
} |
|
|
|
|
|
|
|
func PutTransferDelayQueue(desc, openId, partnerTradeNo string, amount, retries, delay int) { |
|
|
|
if retries <= 0 { |
|
|
|
retries = 3 |
|
|
|
} |
|
|
|
if delay == 0 { |
|
|
|
delay = 30 |
|
|
|
} |
|
|
|
transferDelayQueue <- &transferDelayQueueParam{ |
|
|
|
first: true, |
|
|
|
Retries: retries, |
|
|
|
Delay: delay, |
|
|
|
Amount: amount, |
|
|
|
Desc: desc, |
|
|
|
OpenId: openId, |
|
|
|
PartnerTradeNo: partnerTradeNo, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func Transfer(desc, openId, partnerTradeNo string, amount int) (*TransferResponse, error) { |
|
|
|
client, err := Client() |
|
|
|
if err != nil { |
|
|
@ -280,9 +164,9 @@ func SendRedPack(sendName, openId, wishing, actName, remark string, totalAmount, |
|
|
|
|
|
|
|
body := make(map[string]string, 0) |
|
|
|
body["mch_id"] = client.MchId() |
|
|
|
body["sub_mch_id"] = client.SubMchId() |
|
|
|
//body["sub_mch_id"] = client.SubMchId()
|
|
|
|
body["wxappid"] = client.AppId() |
|
|
|
body["msgappid"] = define.WxAppId |
|
|
|
//body["msgappid"] = define.WxAppId
|
|
|
|
body["nonce_str"] = nonceStr |
|
|
|
body["mch_billno"] = mchBillNo |
|
|
|
body["send_name"] = sendName |
|
|
@ -293,7 +177,7 @@ func SendRedPack(sendName, openId, wishing, actName, remark string, totalAmount, |
|
|
|
body["client_ip"] = define.ClientIp |
|
|
|
body["act_name"] = actName |
|
|
|
body["remark"] = remark |
|
|
|
//body["scene_id"] = fmt.Sprintf("PRODUCT_%d", scene)
|
|
|
|
body["scene_id"] = fmt.Sprintf("PRODUCT_%d", scene) |
|
|
|
|
|
|
|
m, err := mmpaymkttransfers.SendRedPack(client, body) |
|
|
|
if err != nil { |
|
|
|