Browse Source

pay loop

master
黄梓健 5 years ago
parent
commit
e2bb0e7e36
  1. 2
      controllers/client/activity.go
  2. 14
      controllers/client/bully_screen.go
  3. 102
      controllers/client/live.go
  4. 22
      controllers/client/reward.go
  5. 38
      controllers/pc/bully_screen.go
  6. 21
      controllers/pc/reward.go
  7. 27
      models/bully_screen_history.go
  8. 13
      models/live_red_pack.go
  9. 21
      models/live_red_pack_info.go
  10. 13
      models/reward_history.go
  11. 62
      models/user_order.go
  12. 7
      models/user_refund.go
  13. 4
      services/bully_reward/current.go
  14. 36
      services/bully_reward/dao.go
  15. 21
      services/bully_screen/dao.go
  16. 287
      services/pay/order.go
  17. 150
      services/pay/refund.go

2
controllers/client/activity.go

@ -6,7 +6,7 @@ import (
activity_service "hudongzhuanjia/services/activity"
auction_service "hudongzhuanjia/services/auction"
bahe_service "hudongzhuanjia/services/bahe"
bully_screen_service "hudongzhuanjia/services/bully_screen"
bully_screen_service "hudongzhuanjia/services/bully_reward"
calorie_service "hudongzhuanjia/services/calorie"
red_envelope_service "hudongzhuanjia/services/red_envelope"
vote_service "hudongzhuanjia/services/vote"

14
controllers/client/bully_screen.go

@ -4,7 +4,7 @@ import (
"hudongzhuanjia/controllers"
"hudongzhuanjia/libs/filter"
"hudongzhuanjia/models"
bully_screen_service "hudongzhuanjia/services/bully_screen"
bully_screen_service "hudongzhuanjia/services/bully_reward"
"hudongzhuanjia/services/pay"
"hudongzhuanjia/utils/code"
"strings"
@ -54,11 +54,11 @@ func (t *BullyScreenCtl) PaScreen() {
// 调用微信统一下单接口
amount := bullyScreenServer.Price * second
ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":")
res, err := pay_service.Order("欧轩互动-霸屏支付", ip[0], user.Openid, int(amount*100), 1, user.Id, activityId)
res, err := pay_service.Order("欧轩互动-霸屏支付", ip[0], user.Openid, int64(amount*100), 1, user.Id, activityId)
t.CheckErr(err)
history := &models.BullyScreenHistory{
UserOrderId: res["user_order_id"].(int64),
OutTradeNo: res["out_trade_no"].(string),
BullyScreenServerId: bullyScreenServer.Id,
ActivityId: activityId,
UserId: user.Id,
@ -77,8 +77,6 @@ func (t *BullyScreenCtl) PaScreen() {
}
_, err = core.GetXormAuto().InsertOne(history)
t.CheckErr(err)
delete(res, "out_trade_no")
delete(res, "user_order_id")
t.JSON(res)
}
@ -92,11 +90,7 @@ func (t *BullyScreenCtl) List() {
t.CheckErr(err)
t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在")
// 查询是否已经付款
t.CheckErr(pay_service.BatchQueryByUserId(uid))
t.CheckErr(pay_service.BatchQueryRefundByUserId(uid))
list, err := bully_screen_service.GetReviewList(uid, bss.Id)
list, err := bully_screen_service.GetBullyList(uid, bss.Id)
t.CheckErr(err)
t.JSON(map[string]interface{}{
"total": len(list),

102
controllers/client/live.go

@ -16,7 +16,7 @@ import (
var MaxQueueSize = 10000
var RequestLimit = 60 * time.Second
var GetRedPackQueue = make(chan int64, MaxQueueSize)
var GetRedPackQueue = make(chan string, MaxQueueSize)
func loopGetRedPack() {
redPacks, err := models.GetRedPacksByStatus(1)
@ -25,11 +25,11 @@ func loopGetRedPack() {
}
// 保证容量足够
GetRedPackQueue = make(chan int64, MaxQueueSize+len(redPacks))
GetRedPackQueue = make(chan string, MaxQueueSize+len(redPacks))
// 初始化
for _, redPack := range redPacks {
GetRedPackQueue <- redPack.Id
GetRedPackQueue <- redPack.TransferNo
}
defer func() {
@ -42,22 +42,17 @@ func loopGetRedPack() {
}()
for {
select {
case redPackId, ok := <-GetRedPackQueue:
case transferNo, ok := <-GetRedPackQueue:
if !ok {
panic("GetRedPackQueue通道关闭")
}
time.Sleep(RequestLimit) // 请求频率
redPack := new(models.LiveRedPack)
exist, err := models.GetById(redPack, redPackId)
if err != nil {
GetRedPackQueue <- redPackId
logger.Error("获取LiveRedPack表数据出现错误",
zap.Any("错误原因", err), zap.Int64("LiveRedPack表的id", redPack.Id))
continue
}
if !exist {
logger.Error("不存在LiveRedPack表数据", zap.Int64("LiveRedPack表的id", redPack.Id))
exist, err := redPack.GetByTransferNo(transferNo)
if err != nil || !exist {
logger.Error("获取LiveRedPack表数据出现错误", zap.String("错误原因", err.Error()),
zap.Bool("是否存在", exist), zap.Int64("LiveRedPack表的id", redPack.Id))
continue
}
@ -65,7 +60,7 @@ func loopGetRedPack() {
// todo: 是否需要发放系统通知
resp, err := pay_service.TransferInfo(redPack.TransferNo)
if err != nil {
GetRedPackQueue <- redPackId
GetRedPackQueue <- transferNo
logger.Error("微信企业转账查询API",
zap.Any("错误原因", err), zap.Int64("LiveRedPack表的id", redPack.Id))
continue
@ -73,23 +68,23 @@ func loopGetRedPack() {
if resp.Status == pay_service.CODE_FAIL { // 转账失败
_, err = pay_service.Transfer("欧轩互动-红包活动", redPack.OpenId, redPack.TransferNo, redPack.Amount)
if err != nil {
GetRedPackQueue <- redPackId
GetRedPackQueue <- transferNo
logger.Error("微信企业转账API",
zap.Any("错误原因", err), zap.Int64("LiveRedPack表的id", redPack.Id))
zap.String("错误原因", err.Error()), zap.String("转账单号", transferNo))
continue
}
_, err = redPack.UpdateStatusById(redPack.Id, 2)
if err != nil {
GetRedPackQueue <- redPackId
logger.Error("微信企业转账,LiveRedPack表更新错误",
zap.Any("错误原因", err), zap.Int64("LiveRedPack表id", redPack.Id))
GetRedPackQueue <- transferNo
logger.Error("微信企业转账API,LiveRedPack表更新错误",
zap.String("错误原因", err.Error()), zap.String("转账单号", transferNo))
continue
}
} else if resp.Status == pay_service.CODE_SUCCESS {
_, err = redPack.UpdateStatusById(redPack.Id, 2)
if err != nil {
logger.Error("微信企业查询,转账成功",
zap.Any("错误原因", err), zap.Int64("LiveRedPack表id", redPack.Id))
zap.String("错误原因", err.Error()), zap.String("转账单号", transferNo))
continue
}
}
@ -97,10 +92,18 @@ func loopGetRedPack() {
}
}
var SendRedPackQueue = make(chan int64, MaxQueueSize)
var SendRedPackQueue = make(chan string)
func loopSendRedPack() {
redPackInfo :=
redPackInfos, err := models.GetLiveRedPackInfos(0)
if err != nil {
panic(err)
}
SendRedPackQueue = make(chan string, MaxQueueSize+len(redPackInfos))
for _, redPackInfo := range redPackInfos {
SendRedPackQueue <- redPackInfo.OutTradeNo
}
defer func() {
if err := recover(); err != nil {
logger.Error("用户发送红包轮询出现错误",
@ -111,15 +114,48 @@ func loopSendRedPack() {
}()
for {
select {
case redPackInfoId, ok := <-SendRedPackQueue:
case outTradeNo, ok := <-SendRedPackQueue:
if !ok {
panic("SendRedPackQueue通道异常关闭")
}
redPackInfo := new(models.LiveRedPackInfo)
exist, err := redPackInfo.GetByOutTradeNo(outTradeNo)
if err != nil || !exist {
logger.Error("通过out_trade_no获取red_pack_info", zap.String("错误原因", err.Error()),
zap.Bool("是否存在", exist), zap.String("交易单号", outTradeNo))
continue
}
res, err := pay_service.OrderQuery(outTradeNo)
if err != nil {
SendRedPackQueue <- outTradeNo
logger.Error("微信查询订单API", zap.String("错误原因", err.Error()),
zap.String("交易单号", outTradeNo))
}
if res.TradeState == pay_service.CODE_TRADE_SUCCESS { // 交易成功
redPackInfo.Status = 1
} else if res.TradeState == pay_service.CODE_TRADE_CLOSED {
redPackInfo.Status = 3
} else if res.TradeState == pay_service.CODE_TRADE_PAYERROR { // 支付失败
redPackInfo.Status = 4
} else if res.TradeState == pay_service.CODE_TRADE_NOTPAY {
time.Sleep(5 * time.Second)
SendRedPackQueue <- outTradeNo
continue
}
_, err = redPackInfo.UpdateStatusById(redPackInfo.Id, redPackInfo.Status)
if err != nil {
logger.Error("red_pack_info状态更新出现错误", zap.String("错误原因", err.Error()),
zap.String("交易单号", outTradeNo))
}
}
}
}
func init() {
go loopGetRedPack()
go loopSendRedPack()
}
type LiveCtl struct {
controllers.AuthorCtl
//controllers.BaseCtl
@ -185,7 +221,7 @@ func (t *LiveCtl) SendLiveRedPack() {
userId := t.MustGetUID() // 用户 uid
activityId := t.MustGetInt64("activity_id") // activity_id
num := t.MustGetInt("num") // 红包数量
amount := t.MustGetInt64("amount") // 金额
amount := t.MustGetInt64("amount") // 金额
prompt := t.MustGet("prompt") // 提示
user := models.User{}
@ -194,21 +230,22 @@ func (t *LiveCtl) SendLiveRedPack() {
t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在")
ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":")
res, err := pay_service.UnifiedOrder("欧轩互动-直播红包", ip[0], user.Openid, amount)
res, err := pay_service.Order("欧轩互动-直播红包", ip[0], user.Openid, amount, 3, activityId, userId)
t.CheckErr(err)
info := models.LiveRedPackInfo{}
info.OutTradeNo = res["out_trade_no"].(string)
info.Amount = amount
info.UserId = userId
info.ActivityId = activityId
info.Prompt = prompt
info.Prompt = filter.Replace(prompt)
info.IsDelete = false
info.UpdatedAt = time.Now()
info.CreatedAt = time.Now()
_, err = info.Add()
t.CheckErr(err)
redPacks := red_envelope_service.GenRedPack(int(amount*100), num)
redPacks := red_envelope_service.GenRedPack(int(amount), num)
for _, v := range redPacks {
redPack := new(models.LiveRedPack)
redPack.LiveRedPackInfoId = info.Id
@ -220,8 +257,11 @@ func (t *LiveCtl) SendLiveRedPack() {
_, err = redPack.Add()
t.CheckErr(err)
}
info.Prompt = filter.Replace(info.Prompt)
t.JSON(info)
res["red_pack_info_id"] = info.Id
pay_service.PutOrderChan(info.OutTradeNo) // 加入查询队列
t.JSON(res)
}
// 领取红包
@ -254,7 +294,7 @@ func (t *LiveCtl) GetRedPack() {
t.ERROR("红包被领完了", code.MSG_LIVE_RED_PACK_NOT_EXIST)
return
}
GetRedPackQueue <- redPack.Id // 进入队列
GetRedPackQueue <- redPack.TransferNo // 进入队列
t.JSON(redPack)
}

22
controllers/client/reward.go

@ -4,6 +4,7 @@ import (
"hudongzhuanjia/controllers"
"hudongzhuanjia/libs/filter"
"hudongzhuanjia/models"
bully_reward_service "hudongzhuanjia/services/bully_reward"
pay_service "hudongzhuanjia/services/pay"
"hudongzhuanjia/utils"
"hudongzhuanjia/utils/code"
@ -51,11 +52,11 @@ func (t *RewardCtl) Reward() {
t.Assert(exist, code.MSG_USER_NOT_EXIST, "用户不存在")
ip := strings.Split(t.Request.OriginRequest.RemoteAddr, ":")
res, err := pay_service.Order("欧轩互动-打赏支付", ip[0], user.Openid, int(amount*100), 2, user.Id, activityId)
res, err := pay_service.Order("欧轩互动-打赏支付", ip[0], user.Openid, int64(amount*100), 2, user.Id, activityId)
t.CheckErr(err)
_, err = core.GetXormAuto().InsertOne(&models.RewardHistory{
UserOrderId: res["user_order_id"].(int64),
OutTradeNo: res["out_trade_no"].(string),
RewardServerId: rewardServer.Id,
CustomerId: t.MustGetCustomerId(),
UserId: user.Id,
@ -69,18 +70,9 @@ func (t *RewardCtl) Reward() {
UpdatedAt: time.Now(),
})
t.CheckErr(err)
delete(res, "user_order_id")
delete(res, "out_trade_no")
t.JSON(res)
}
type RWListResult struct {
Id int64 `json:"id"`
Content string `json:"content"`
Amount float64 `json:"amount"`
Status int `json:"status"`
}
func (t *RewardCtl) List() {
uid := t.MustGetUID()
activityId := t.MustGetInt64("activity_id")
@ -90,13 +82,7 @@ func (t *RewardCtl) List() {
t.CheckErr(err)
t.Assert(exist, code.MSG_REWARD_NOT_EXIST, "打赏不存在")
t.CheckErr(pay_service.BatchQueryByUserId(uid))
t.CheckErr(pay_service.BatchQueryRefundByUserId(uid))
list := make([]*RWListResult, 0)
err = core.GetXormAuto().Table(new(models.RewardHistory)).Select("id, content, amount, status").
Where("is_delete=0 and user_id=? and reward_server_id=? and status <> -1", uid, rs.Id).
Desc("created_at").Find(&list)
list, err := bully_reward_service.GetRewardList(uid, rs.Id)
t.CheckErr(err)
t.JSON(map[string]interface{}{
"total": len(list),

38
controllers/pc/bully_screen.go

@ -37,9 +37,6 @@ func (t *BullyScreenCtl) WaitReview() {
t.CheckErr(err)
t.Assert(exist, code.MSG_BULLY_SCREEN_SERVER_NOT_EXIST, "霸屏不存在")
t.CheckErr(pay_service.BatchQueryByActivityId(activityId))
t.CheckErr(pay_service.BatchQueryRefundByActivityId(activityId))
//根据霸屏服务得id获取待审核得霸屏列表
result := make([]*BullyScreenBaseResult, 0)
err = core.GetXormAuto().Table(new(models.BullyScreenHistory)).Alias("h").
@ -56,10 +53,11 @@ func (t *BullyScreenCtl) WaitReview() {
//审核操作
func (t *BullyScreenCtl) Review() {
customerId := t.MustGetUID()
idList := t.MustGet("ids")
status := t.MustGetBool("status")
ids := strings.Split(idList, "|")
//rehearsalId := t.MustGetInt64("rehearsal_id")
rehearsalId := t.MustGetInt64("rehearsal_id")
//将金额退回给用户
result := make([]*models.BullyScreenHistory, 0)
@ -71,49 +69,39 @@ func (t *BullyScreenCtl) Review() {
t.ERROR("该霸屏已处理", code.MSG_USER_DATA_ERROR)
}
if status { // true 失败 、、 false 成功
_, err := v.UpdateStatus(v.Id, 1)
_, err = v.UpdateStatus(v.Id, 1)
t.CheckErr(err)
//if rehearsalId != 0 { // 彩排
// continue
//}
if rehearsalId != 0 { // 彩排
continue
}
//todo: 回退金额给用户 ==> 直接微信退款
// 1. 提请微信退款
// 2. 查询退款是否成功
// 3. 退款成功设置状态
// 4. 写入金额流水记录
order := new(models.UserOrder)
exist, err := models.GetById(order, v.UserOrderId)
t.CheckErr(err)
t.Assert(exist, code.MSG_USER_ORDER_NOT_EXIST, "用户支付订单不存在")
_, err = pay_service.Refund("欧轩互动-霸屏拉黑", order.OutTradeNo, order.OpenId, order.GoodType, order.TotalFee, order.TotalFee, order.UserId, order.ActivityId)
_, err = pay_service.Refund("欧轩互动-霸屏拉黑", v.OutTradeNo)
t.CheckErr(err)
} else {
_, err := v.UpdateStatus(v.Id, 2)
_, err = v.UpdateStatus(v.Id, 2)
t.CheckErr(err)
// todo: 审核成功
// 1. 金额打入主账号的打赏钱包里面
// 2. 记录金额流水
//if rehearsalId != 0 {
// continue
//}
uid := t.MustGetUID()
customer := new(models.Customer)
exist, err := models.GetById(customer, uid)
t.CheckErr(err)
t.Assert(exist, code.MSG_CUSTOMER_NOT_EXIST, "客户不存在")
if rehearsalId != 0 {
continue
}
wallet := new(models.BullyScreenWallet)
_, err = wallet.IncrBalance(customer.Id, v.Amount)
_, err = wallet.IncrBalance(customerId, v.Amount)
t.CheckErr(err)
_, err = core.GetXormAuto().InsertOne(&models.BullyScreenWalletHistory{
CustomerId: customer.Id,
CustomerId: customerId,
UserId: v.UserId,
Money: v.Amount,
Type: "霸屏",

21
controllers/pc/reward.go

@ -88,7 +88,7 @@ func (t *RewardCtl) Review() {
idList := t.MustGet("ids")
status := t.MustGetBool("status")
ids := strings.Split(idList, "|")
//rehearsalId := t.MustGetInt64("rehearsal_id")
rehearsalId := t.MustGetInt64("rehearsal_id")
result := make([]*models.RewardHistory, 0)
err := core.GetXormAuto().Where("is_delete=0").In("id", ids).Find(&result)
@ -111,16 +111,11 @@ func (t *RewardCtl) Review() {
_, err := v.UpdateStatus(v.Id, 1)
t.CheckErr(err)
//if rehearsalId != 0 { // 彩排不需要金额
// continue
//}
order := new(models.UserOrder)
exist, err := models.GetById(order, v.UserOrderId)
t.CheckErr(err)
t.Assert(exist, code.MSG_USER_ORDER_NOT_EXIST, "用户支付订单不存在")
if rehearsalId != 0 { // 彩排不需要金额
continue
}
_, err = pay_service.Refund("欧轩互动-打赏拉黑", order.OutTradeNo, order.OpenId, order.GoodType, order.TotalFee, order.TotalFee, order.UserId, order.ActivityId)
_, err = pay_service.Refund("欧轩互动-打赏拉黑", v.OutTradeNo)
t.CheckErr(err)
} else {
@ -128,9 +123,9 @@ func (t *RewardCtl) Review() {
_, err := v.UpdateStatus(v.Id, 2)
t.CheckErr(err)
//if rehearsalId != 0 { // 彩排不需要金额
// continue
//}
if rehearsalId != 0 { // 彩排不需要金额
continue
}
uid := t.MustGetUID()
customer := new(models.Customer)

27
models/bully_screen_history.go

@ -11,7 +11,7 @@ const BullyScreenHistoryTableName = TableNamePrefix + "bully_screen_history"
type BullyScreenHistory struct {
Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"`
BullyScreenServerId int64 `json:"bully_screen_server_id" xorm:"not null comment('霸屏服务得id') INT(11)"`
UserOrderId int64 `json:"user_order_id" xorm:"not null default 0 comment('微信统一下订单id') INT(11)"`
OutTradeNo string `json:"out_trade_no" xorm:"not null default '' comment('微信订单号') VARCHAR(128)"`
CustomerId int64 `json:"customer_id" xorm:"not null comment('客户id') INT(11)"`
ActivityId int64 `json:"activity_id" xorm:"not null comment('互动id') INT(11)"`
UserId int64 `json:"user_id" xorm:"not null comment('用户得id') INT(11)"`
@ -20,7 +20,7 @@ type BullyScreenHistory struct {
Style int `json:"style" xorm:"not null comment('服务样式') INT(11)"`
Second int `json:"second" xorm:"not null comment('霸屏时间(秒)') INT(11)"`
Content string `json:"content" xorm:"not null comment('内容') TEXT"`
Status int `json:"status" xorm:"not null default(0) comment('[-1未支付,0未审核,1未通过,2已通过, 3已推送]') INT(11)"`
Status int `json:"status" xorm:"not null default(0) comment('[-1未支付,0未审核,1未通过,2已通过,3已推送,4已退款,5被取消]') INT(11)"`
Amount float64 `json:"amount" xorm:"not null default 0.00 comment('霸屏金额') DECIMAL(10)"`
ReviewTime int64 `json:"review_time" xorm:"not null comment('审核的时间') INT(11)"`
Version int64 `json:"version" xorm:"not null version comment('乐观锁') INT(11)"`
@ -33,16 +33,27 @@ func (t *BullyScreenHistory) TableName() string {
return BullyScreenHistoryTableName
}
func (t *BullyScreenHistory) GetByUserOrderId(userOrderId int64) (bool, error) {
return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Get(t)
}
func (t *BullyScreenHistory) UpdateStatus(id int64, status int) (int64, error) {
t.Status = status
return core.GetXormAuto().ID(id).Cols("status").Update(t)
}
func (t *BullyScreenHistory) UpdateStatusByUserOrderId(userOrderId interface{}, status int) (int64, error) {
//
//func (t *BullyScreenHistory) UpdateStatusByUserOrderId(userOrderId interface{}, status int) (int64, error) {
// t.Status = status
// return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).
// Cols("status").Update(t)
//}
func GetBullyScreenHistoriesByStatus(status int) ([]*BullyScreenHistory, error) {
histories := make([]*BullyScreenHistory, 0)
err := core.GetXormAuto().Where("is_delete and status=?", status).Find(&histories)
return histories, err
}
// 更改未支付状态
func (t *BullyScreenHistory) UpdateStatusByOutTradeNo(outTradeNo string, status int) (int64, error) {
t.Status = status
return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Cols("status").Update(t)
return core.GetXormAuto().Where("is_delete=0 and status=-1 and out_trade_no=?", outTradeNo).
Cols("status").Update(t)
}

13
models/live_red_pack.go

@ -20,7 +20,7 @@ type LiveRedPack struct {
Amount int `json:"amount" xorm:"not null default 0 comment('红包金额, 分') INT(18)"`
TransferType int `json:"transfer_type" xorm:"not null default 0 comment('转账方式[0微信红包1微信零钱]') TINYINT(1)"`
TransferNo string `json:"transfer_no" xorm:"not null default '' comment('转账账号') VARCHAR(128) "`
Status int `json:"status" xorm:"not null default 0 comment('0 未被领取 1 已被领取 2 已发送') TINYINT(1)"`
Status int `json:"status" xorm:"not null default 0 comment('0 未被领取 1 已被领取 2 已发送 3 出现错误') TINYINT(1)"`
Version int `json:"version" xorm:"not null version comment('乐观锁') INT(11)"`
}
@ -36,14 +36,9 @@ func (t *LiveRedPack) GetByInfoId(infoId int64) (bool, error) {
return core.GetXormAuto().Where("live_red_package_info_id=? and is_delete=0", infoId).Get(t)
}
func (t *LiveRedPack) Receive(userId int64) (int64, error) {
t.Status = 1
return core.GetXormAuto().Where("id=?", t.Id).Cols("user_id, status").Update(t)
}
func (t *LiveRedPack) UpdateStatusById(id interface{}, status int) (int64, error) {
t.Status = status
return core.GetXormAuto().Where("id=?", t.Id).
return core.GetXormAuto().Where("id=?", id).
Cols("receiver, open_id, transfer_type, transfer_no, status").Update(t)
}
@ -52,3 +47,7 @@ func GetRedPacksByStatus(status interface{}) ([]*LiveRedPack, error) {
err := core.GetXormAuto().Where("is_delete=0 and status=?", status).Find(&redPacks)
return redPacks, err
}
func (t *LiveRedPack) GetByTransferNo(transferNo string) (bool, error) {
return core.GetXormAuto().Where("is_delete=0 and transfer_no=?", transferNo).Get(t)
}

21
models/live_red_pack_info.go

@ -18,7 +18,8 @@ type LiveRedPackInfo struct {
Prompt string `json:"prompt" xorm:"not null default 0 comment('祝福语') VARCHAR(255)"`
Amount int64 `json:"amount" xorm:"not null default 0 comment('红包金额, 分') INT(18)"`
OutTradeNo string `json:"out_trade_no" xorm:"not null default '' comment('订单号') VARCHAR(128)"`
Status int `json:"status" xorm:"not null default 0 comment('0尚未支付1取消支付2支付成功3订单关闭')"`
Error string `json:"error" xorm:"not null default '' comment('出现错误') VARCHAR(255)"`
Status int `json:"status" xorm:"not null default 0 comment('-1尚未支付0支付成功1已推送')"`
}
func (t *LiveRedPackInfo) TableName() string {
@ -29,7 +30,21 @@ func (t *LiveRedPackInfo) Add() (int64, error) {
return core.GetXormAuto().InsertOne(t)
}
func GetLiveRedPackInfos() {
func GetLiveRedPackInfos(status int) ([]*LiveRedPackInfo, error) {
infos := make([]*LiveRedPackInfo, 0)
core.GetXormAuto().Where("is_delete=0 and ")
err := core.GetXormAuto().Where("is_delete=0 and status=?", status).Find(&infos)
return infos, err
}
func (t *LiveRedPackInfo) GetByOutTradeNo(outTradeNo string) (bool, error) {
return core.GetXormAuto().Where("is_delete=0 and out_trade_no=?", outTradeNo).Get(t)
}
func (t *LiveRedPackInfo) UpdateStatusById(id interface{}, status int) (int64, error) {
return core.GetXormAuto().Where("id=?", id).Cols("status").Update(&LiveRedPack{Status: status})
}
func (t *LiveRedPackInfo) UpdateStatusByOutTradeNo(outTradeNo string, status int) (int64, error) {
t.Status = status
return core.GetXormAuto().Where("is_delete=0 and status=0 and out_trade_no=?", outTradeNo).Update(t)
}

13
models/reward_history.go

@ -10,7 +10,7 @@ const ReWardHistoryTableName = TableNamePrefix + "reward_history"
//打赏历史
type RewardHistory struct {
Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"`
UserOrderId int64 `json:"user_order_id" xorm:"not null default(0) comment('用户订单id') INT(11)"`
OutTradeNo string `json:"out_trade_no" xorm:"not null default '' comment('微信订单号') VARCHAR(128)"`
CustomerId int64 `json:"customer_id" xorm:"not null comment('客户id') INT(11)"`
RewardServerId int64 `json:"reward_server_id" xorm:"not null comment('打赏服务id') INT(11)"`
RehearsalId int64 `json:"rehearsal_id" xorm:"not null default(0) comment('彩排id/0正式') INT(11)"`
@ -19,7 +19,7 @@ type RewardHistory struct {
Content string `json:"content" xorm:"not null comment('内容') text"`
Amount float64 `json:"amount" xorm:"not null default(0.0) comment('金额') DECIMAL"`
RewardAmount string `json:"reward_amount" xorm:"-" description:"同上, 字符串"`
Status int `json:"status" xorm:"not null default(0) comment('-1未支付 0未审核,1未通过,2已通过,3已推送') INT(11)"`
Status int `json:"status" xorm:"not null default(0) comment('-1未支付,0未审核,1未通过,2已通过,3已推送,4已退款,5被取消') INT(11)"`
ReviewTime int64 `json:"review_time" xorm:"not null default(0) comment('审核时间') INT(11)"`
Version int64 `json:"version" xorm:"not null version comment('乐观锁') INT(11)"`
IsDelete bool `json:"is_delete" xorm:"not null default(0)"`
@ -40,7 +40,12 @@ func (t *RewardHistory) UpdateStatus(id int64, status int) (int64, error) {
return core.GetXormAuto().Where("id=?", id).Cols("status").Update(t)
}
func (t *RewardHistory) UpdateStatusByUserOrderId(userOrderId interface{}, status int) (int64, error) {
//func (t *RewardHistory) UpdateStatusByUserOrderId(userOrderId interface{}, status int) (int64, error) {
// t.Status = status
// return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Cols("status").Update(t)
//}
func (t *RewardHistory) UpdateStatusByOutTradeNo(outTradeNo string, status int) (int64, error) {
t.Status = status
return core.GetXormAuto().Where("is_delete=0 and user_order_id=?", userOrderId).Cols("status").Update(t)
return core.GetXormAuto().Where("is_delete=0 and status=-1 and out_trade_no=?", outTradeNo).Update(status)
}

62
models/user_order.go

@ -8,26 +8,34 @@ import (
const UserOrderTableName = TableNamePrefix + "user_order"
type UserOrder struct {
Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"`
DeviceInfo string `json:"device_info" xorm:"not null default('') comment('设备号') VARCHAR(32)"`
GoodType int `json:"good_type" xorm:"not null default(0) comment('1霸屏2打赏3直播红包')"`
Desc string `json:"desc" xorm:"not null default('') comment('') VARCHAR(128)"`
OutTradeNo string `json:"out_trade_no" xorm:"not null default('') comment('商户订单号') VARCHAR(32)"`
FeeType string `json:"fee_type" xorm:"not null default('CNY') comment('货币种类') VARCHAR(16)"`
TotalFee int `json:"total_fee" xorm:"not null default(0) comment('订单总金额,单位是分') INT(88)"`
TradeType string `json:"trade_type" xorm:"not null default('JSAPI') comment('交易类型') VARCHAR(16)"`
OpenId string `json:"open_id" xorm:"not null default('') comment('用户标识') VARCHAR(128)"`
UserId int64 `json:"user_id" xorm:"not null default(0) comment('用户id') INT(11)"`
ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('活动id') INT(11)"`
TransactionId string `json:"transaction_id" xorm:"not null default('') comment('微信支付订单号') VARCHAR(32)"`
TimeStart string `json:"time_start" xorm:"not null default('') comment('交易起始时间') VARCHAR(14)"`
TimeExpire string `json:"time_expire" xorm:"not null default('') comment('交易结束时间') VARCHAR(14)"`
TimeEnd string `json:"time_end" xorm:"not null default('') comment('交易结算时间') VARCHAR(14)"`
PrepayId string `json:"prepay_id" xorm:"not null default('') comment('预支付交易会话标识') VARCHAR(64)"`
Status int `json:"status" xorm:"not null default(0) comment('-1订单关闭0尚未支付/支付中1支付成功2已撤销3转入退款4支付失败') TINYINT(1)"`
IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"`
CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"`
Id int64 `json:"id" xorm:"not null pk autoincr INT(11)"`
IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"`
CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"`
// 订单信息
DeviceInfo string `json:"device_info" xorm:"not null default('') comment('设备号') VARCHAR(32)"`
GoodType int64 `json:"good_type" xorm:"not null default(0) comment('1霸屏2打赏3直播红包')"`
Desc string `json:"desc" xorm:"not null default('') comment('') VARCHAR(128)"`
OutTradeNo string `json:"out_trade_no" xorm:"not null default('') comment('商户订单号') VARCHAR(32)"`
FeeType string `json:"fee_type" xorm:"not null default('CNY') comment('货币种类') VARCHAR(16)"`
TotalFee int64 `json:"total_fee" xorm:"not null default(0) comment('订单总金额,单位是分') INT(88)"`
TradeType string `json:"trade_type" xorm:"not null default('JSAPI') comment('交易类型') VARCHAR(16)"`
OpenId string `json:"open_id" xorm:"not null default('') comment('用户标识') VARCHAR(128)"`
UserId int64 `json:"user_id" xorm:"not null default(0) comment('用户id') INT(11)"`
ActivityId int64 `json:"activity_id" xorm:"not null default(0) comment('活动id') INT(11)"`
TransactionId string `json:"transaction_id" xorm:"not null default('') comment('微信支付订单号') VARCHAR(32)"`
TimeStart string `json:"time_start" xorm:"not null default('') comment('交易起始时间') VARCHAR(14)"`
TimeExpire string `json:"time_expire" xorm:"not null default('') comment('交易结束时间') VARCHAR(14)"`
TimeEnd string `json:"time_end" xorm:"not null default('') comment('交易结算时间') VARCHAR(14)"`
PrepayId string `json:"prepay_id" xorm:"not null default('') comment('预支付交易会话标识') VARCHAR(64)"`
Status int `json:"status" xorm:"not null default(0) comment('0尚未支付/支付中1支付成功2已撤销3转入退款4退款成功5支付失败6订单关闭') TINYINT(1)"`
ErrMsg string `json:"err_msg" xorm:"not null default 0 comment('出现错误') VARCHAR(255)"`
// 退款
SuccessTime time.Time `json:"success_time" xorm:"not null default '' comment('退款成功时间') VARCHAR(20)"`
RefundRecvAccount string `json:"refund_recv_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"`
RefundAccount string `json:"refund_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"`
}
func (t *UserOrder) TableName() string {
@ -53,6 +61,14 @@ func (t *UserOrder) UpdateStatusByOutTradeNo(outTradeNo interface{}, status int)
Cols("time_end, transaction_id, status").Update(t)
}
func (t *UserOrder) UpdateErrByOutTradeNo(outTradeNo interface{}) (int64, error) {
return core.GetXormAuto().Where("out_trade_no=? and is_delete=0", outTradeNo).Cols("err_msg").Update(t)
}
func (t *UserOrder) UpdateRefundByOutTradeNo(outTradeNo interface{}) (int64, error) {
return core.GetXormAuto().Where("out_trade_no=?", outTradeNo).Cols("success_time", "refund_recv_account", "refund_account").Update(t)
}
func GetUserOrdersByStatusAndUserId(userId interface{}, status int) ([]*UserOrder, error) {
orders := make([]*UserOrder, 0)
err := core.GetXormAuto().Where("is_delete = 0 and status = ? and user_id = ?", status, userId).Find(&orders)
@ -64,3 +80,9 @@ func GetUserOrdersByStatusAndActivityId(activityId interface{}, status int) ([]*
err := core.GetXormAuto().Where("is_delete = 0 and status = ? and activity_id = ?", status, activityId).Find(&orders)
return orders, err
}
func GetValidUserOrders() ([]*UserOrder, error) {
orders := make([]*UserOrder, 0)
err := core.GetXormAuto().Where("is_delete=0 and (status=? or status=?)", 0, 3).Find(&orders)
return orders, err
}

7
models/user_refund.go

@ -24,9 +24,10 @@ type UserRefund struct {
SuccessTime time.Time `json:"success_time" xorm:"not null default '' comment('退款成功时间') VARCHAR(20)"`
RefundRecvAccount string `json:"refund_recv_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"`
RefundAccount string `json:"refund_account" xorm:"not null default '' comment('入账账号') VARCHAR(64)"`
IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"`
CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"`
IsDelete bool `json:"is_delete" xorm:"not null default(0) comment('是否删除') TINYINT(1)" description:"是否删除"`
CreatedAt time.Time `json:"created_at" xorm:"not null created comment('创建时间') DATETIME" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" xorm:"not null updated comment('更新时间') DATETIME" description:"更新时间"`
}
func (t *UserRefund) TableName() string {

4
services/bully_screen/current.go → services/bully_reward/current.go

@ -1,4 +1,4 @@
package bully_screen_service
package bully_reward_service
import (
"errors"
@ -15,6 +15,6 @@ func GetCurrentBullyScreen(activityId int64) (map[string]interface{}, error) {
return nil, errors.New("霸屏不存在")
}
return map[string]interface{}{
"bully_screen": server,
"bully_reward": server,
}, nil
}

36
services/bully_reward/dao.go

@ -0,0 +1,36 @@
package bully_reward_service
import (
"github.com/ouxuanserver/osmanthuswine/src/core"
"hudongzhuanjia/models"
)
type BullyListResult struct {
Id int `json:"id"`
Content string `json:"content"`
Status int `json:"status"`
Second int `json:"second"`
}
func GetBullyList(userId, bullyId int64) ([]*BullyListResult, error) {
list := make([]*BullyListResult, 0)
err := core.GetXormAuto().Table(new(models.BullyScreenHistory)).Select("id, content, status, second").
Where("is_delete=0 and user_id=? and bully_screen_server_id=? and status<> -1", userId, bullyId).
OrderBy("created_at desc").Find(&list)
return list, err
}
type RewardListResult struct {
Id int64 `json:"id"`
Content string `json:"content"`
Amount float64 `json:"amount"`
Status int `json:"status"`
}
func GetRewardList(userId, rewardId int64) ([]*RewardListResult, error) {
list := make([]*RewardListResult, 0)
err := core.GetXormAuto().Table(new(models.RewardHistory)).Select("id, content, amount, status").
Where("is_delete=0 and user_id=? and reward_server_id=? and status <> -1", userId, rewardId).
Desc("created_at").Find(&list)
return list, err
}

21
services/bully_screen/dao.go

@ -1,21 +0,0 @@
package bully_screen_service
import (
"github.com/ouxuanserver/osmanthuswine/src/core"
"hudongzhuanjia/models"
)
type ReviewListResult struct {
Id int `json:"id"`
Content string `json:"content"`
Status int `json:"status"`
Second int `json:"second"`
}
func GetReviewList(uid, bssid int64) ([]*ReviewListResult, error) {
list := make([]*ReviewListResult, 0)
err := core.GetXormAuto().Table(new(models.BullyScreenHistory)).Select("id, content, status, second").
Where("is_delete=0 and user_id=? and bully_screen_server_id=? and status<> -1", uid, bssid).
OrderBy("created_at desc").Find(&list)
return list, err
}

287
services/pay/order.go

@ -5,6 +5,8 @@ import (
"fmt"
core2 "github.com/chanxuehong/wechat/mch/core"
"github.com/chanxuehong/wechat/mch/pay"
"github.com/pkg/errors"
"go.uber.org/zap"
"hudongzhuanjia/logger"
"hudongzhuanjia/models"
"hudongzhuanjia/utils"
@ -13,9 +15,82 @@ import (
"time"
)
func init() {
go loop()
}
var orderChanSize = 10000
var orderChanDelay = 1
var orderChan chan string
func PutOrderChan(value string) {
time.Sleep(time.Duration(orderChanDelay) * time.Second)
orderChan <- value
}
func loop() {
orders, err := models.GetValidUserOrders()
if err != nil {
panic(err)
}
orderChan = make(chan string, orderChanSize+len(orders))
for _, order := range orders {
orderChan <- order.OutTradeNo
}
defer func() {
if err := recover(); err != nil {
logger.Error("订单轮询查询", zap.Any("panic 恢复错误", err))
}
// 重启
time.Sleep(5 * time.Second)
loop()
}()
for {
select {
case outTradeNo, ok := <-orderChan:
if !ok {
panic("通道异常关闭")
}
userOrder := new(models.UserOrder)
if userOrder.Status == 0 {
res, err := OrderQuery(outTradeNo)
// 出现错误
if err != nil {
logger.Error("查询订单出现错误", zap.String("错误原因", err.Error()),
zap.String("交易订单号", outTradeNo))
PutOrderChan(outTradeNo)
continue
}
if res.TradeState == CODE_TRADE_SUCCESS {
continue
} else if res.TradeState == CODE_TRADE_REFUND {
PutOrderChan(outTradeNo)
continue
}
} else if userOrder.Status == 3 {
_, err = QueryRefund(outTradeNo)
if err != nil {
logger.Error("退款订单查询错误", zap.String("错误原因", err.Error()),
zap.String("交易订单号", outTradeNo))
}
} else {
continue
}
}
}
}
func init() {
go loop()
}
const CallbackOrderUrl = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder"
func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) {
func Order(content, ip, openid string, fee, goodType, userId, activityId int64) (map[string]interface{}, error) {
client, err := Client()
if err != nil {
return nil, err
@ -43,6 +118,7 @@ func Order(content, ip, openid string, fee, goodType int, userId, activityId int
return nil, err
}
// 记录这次订单
userOrder := new(models.UserOrder)
userOrder.DeviceInfo = "WEB"
userOrder.Desc = content
@ -69,6 +145,8 @@ func Order(content, ip, openid string, fee, goodType int, userId, activityId int
//获取H5支付需要的paySign
pac := "prepay_id=" + resp.PrepayId
paySign := core2.JsapiSign(client.AppId(), nonceStr, pac, core2.SignType_MD5, timestamp, ApiKey)
PutOrderChan(outTradeNo)
return map[string]interface{}{
"appid": Appid,
"timestamp": timestamp,
@ -81,47 +159,6 @@ func Order(content, ip, openid string, fee, goodType int, userId, activityId int
}, nil
}
func UnifiedOrder(content, ip, openid string, fee int64) (map[string]interface{}, error) {
client, err := Client()
if err != nil {
return nil, err
}
now := time.Now()
outTradeNo := utils.RandomStr(32)
nonceStr := utils.RandomStr(32)
resp, err := pay.UnifiedOrder2(client, &pay.UnifiedOrderRequest{
Body: content,
OutTradeNo: outTradeNo,
TotalFee: int64(fee),
SpbillCreateIP: ip,
NotifyURL: CallbackOrderUrl,
TradeType: "JSAPI",
DeviceInfo: "WEB",
NonceStr: nonceStr,
SignType: core2.SignType_MD5,
TimeStart: now,
OpenId: openid,
})
if err != nil {
return nil, err
}
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
//获取H5支付需要的paySign
pac := "prepay_id=" + resp.PrepayId
paySign := core2.JsapiSign(client.AppId(), nonceStr, pac, core2.SignType_MD5, timestamp, ApiKey)
return map[string]interface{}{
"appid": Appid,
"timestamp": timestamp,
"nonce_str": nonceStr,
"package": pac,
"sign_type": core2.SignType_MD5,
"pay_sign": paySign,
"out_trade_no": outTradeNo,
}, nil
}
// Notify
type NotifyRequest struct {
ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"`
@ -186,42 +223,43 @@ func NotifyOrder(req *http.Request) error {
if _, err = userOrder.UpdateStatusById(userOrder.Id); err != nil {
return err
}
// 设置一下
if userOrder.GoodType == 1 { // 霸屏
_, err = new(models.BullyScreenHistory).UpdateStatusByUserOrderId(userOrder.Id, 0)
if err != nil {
return err
}
} else if userOrder.GoodType == 2 {
_, err = new(models.RewardHistory).UpdateStatusByUserOrderId(userOrder.Id, 0)
if err != nil {
return err
}
}
//// 设置一下
//if userOrder.GoodType == 1 { // 霸屏
// _, err = new(models.BullyScreenHistory).UpdateStatusByUserOrderId(userOrder.Id, 0)
// if err != nil {
// return err
// }
//} else if userOrder.GoodType == 2 {
// _, err = new(models.RewardHistory).UpdateStatusByUserOrderId(userOrder.Id, 0)
// if err != nil {
// return err
// }
//}
return nil
}
func Query(outTradeNo string) (*models.UserOrder, error) {
func OrderQuery(outTradeNo string) (*pay.OrderQueryResponse, error) {
client, err := Client()
if err != nil {
return nil, err
}
// 请求订单查询,成功后得到结果
userOrder := new(models.UserOrder)
res, err := pay.OrderQuery2(client, &pay.OrderQueryRequest{
OutTradeNo: outTradeNo,
NonceStr: utils.RandomStr(32),
SignType: core2.SignType_MD5,
})
if err != nil {
userOrder.ErrMsg = err.Error()
userOrder.UpdateErrByOutTradeNo(outTradeNo)
return nil, err
}
userOrder := new(models.UserOrder)
userOrder.TransactionId = res.TransactionId
userOrder.TimeEnd = core2.FormatTime(res.TimeEnd)
switch res.TradeState {
case CODE_TRADE_CLOSED:
userOrder.Status = -1
case CODE_TRADE_SUCCESS:
userOrder.Status = 1
case CODE_TRADE_REVOKED:
@ -229,89 +267,108 @@ func Query(outTradeNo string) (*models.UserOrder, error) {
case CODE_TRADE_REFUND:
userOrder.Status = 3
case CODE_TRADE_PAYERROR:
userOrder.Status = 4
userOrder.Status = 5
case CODE_TRADE_CLOSED:
userOrder.Status = 6
default:
userOrder.Status = 0
}
if _, err = userOrder.UpdateStatusByOutTradeNo(outTradeNo, userOrder.Status); err != nil {
return nil, err
}
return userOrder, nil
return res, nil
}
func BatchQueryByUserId(userId int64) error {
orders, err := models.GetUserOrdersByStatusAndUserId(userId, 0)
func Close(outTradeNo string) error {
//client := wechat.NewClient(Appid, Mchid, ApiKey, true)
client, err := Client()
if err != nil {
return err
}
return batchQuery(orders)
}
func BatchQueryByActivityId(activityId int64) error {
orders, err := models.GetUserOrdersByStatusAndActivityId(activityId, 0)
err = pay.CloseOrder2(client, &pay.CloseOrderRequest{
OutTradeNo: outTradeNo,
NonceStr: utils.RandomStr(32),
SignType: core2.SignType_MD5,
})
// 请求关闭订单,成功后得到结果
if err != nil {
return nil
return err
}
return batchQuery(orders)
return nil
}
func batchQuery(orders []*models.UserOrder) error {
for _, order := range orders {
userOrder, err := Query(order.OutTradeNo)
if err != nil {
return err
}
order.Status = userOrder.Status
order.TransactionId = userOrder.TransactionId
order.TimeEnd = userOrder.TimeEnd
if order.Status == 1 { // 付款成功
if order.GoodType == 1 {
_, err = new(models.BullyScreenHistory).UpdateStatusByUserOrderId(order.Id, 0)
if err != nil {
return err
}
} else if order.GoodType == 2 {
_, err = new(models.RewardHistory).UpdateStatusByUserOrderId(order.Id, 0)
if err != nil {
return err
}
//const CALLBACK_REFUND_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackRefund"
} else {
logger.Sugar.Info("支付测试")
}
} else if order.TimeExpire <= time.Now().Format("20060101150405") {
err = Close(order.OutTradeNo)
if err != nil {
return err
}
order.Status = -1 // 关闭支付
_, err = order.UpdateStatusById(order.Id)
if err != nil {
return err
}
func Refund(reason, outTradeNo string) (*pay.RefundResponse, error) {
userOrder := new(models.UserOrder)
exist, err := userOrder.GetByOutTradeNo(outTradeNo)
if err != nil {
return nil, err
}
if !exist {
return nil, errors.New("订单不存在")
}
client, err := Client()
}
outRefundNo := utils.RandomStr(64)
nonceStr := utils.RandomStr(32)
res, err := pay.Refund2(client, &pay.RefundRequest{
TransactionId: "",
OutTradeNo: outTradeNo,
OutRefundNo: outRefundNo,
TotalFee: userOrder.TotalFee,
RefundFee: userOrder.TotalFee,
NonceStr: nonceStr,
SignType: core2.SignType_MD5,
RefundFeeType: "CNY",
RefundDesc: reason,
})
//
if err != nil {
userOrder.ErrMsg = err.Error()
userOrder.UpdateErrByOutTradeNo(outTradeNo)
return nil, err
}
return nil
userOrder.Status = 3
_, err = userOrder.UpdateStatusByOutTradeNo(outTradeNo, userOrder.Status)
if err != nil {
return nil, err
}
PutOrderChan(outTradeNo) // 退款查询
return res, nil
}
func Close(outTradeNo string) error {
//client := wechat.NewClient(Appid, Mchid, ApiKey, true)
client, err := Client()
func QueryRefund(outTradeNo string) (*pay.RefundQueryResponse, error) {
userOrder := new(models.UserOrder)
exist, err := userOrder.GetByOutTradeNo(outTradeNo)
if err != nil {
return err
return nil, err
}
err = pay.CloseOrder2(client, &pay.CloseOrderRequest{
if !exist {
return nil, errors.New("不存在改笔退款")
}
client, err := Client()
res, err := pay.RefundQuery2(client, &pay.RefundQueryRequest{
OutTradeNo: outTradeNo,
NonceStr: utils.RandomStr(32),
SignType: core2.SignType_MD5,
})
// 请求关闭订单,成功后得到结果
//请求申请退款
if err != nil {
return err
return nil, err
}
return nil
userOrder.RefundAccount = res.RefundList[0].RefundAccount
userOrder.RefundRecvAccount = res.RefundList[0].RefundRecvAccout
userOrder.SuccessTime = res.RefundList[0].RefundSuccessTime
userOrder.Status = 4
_, err = userOrder.UpdateRefundByOutTradeNo(outTradeNo)
if err != nil {
return nil, err
}
return res, nil
}

150
services/pay/refund.go

@ -1,122 +1,32 @@
package pay_service
import (
"errors"
core2 "github.com/chanxuehong/wechat/mch/core"
"github.com/chanxuehong/wechat/mch/pay"
"github.com/ouxuanserver/osmanthuswine/src/core"
"hudongzhuanjia/models"
"hudongzhuanjia/utils"
"time"
)
const CALLBACK_REFUND_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackRefund"
func Refund(reason, outTradeNo, openId string, goodType, totalFee, refundFee int, userId, activityId int64) (*pay.RefundResponse, error) {
client, err := Client()
outRefundNo := utils.RandomStr(64)
nonceStr := utils.RandomStr(32)
res, err := pay.Refund2(client, &pay.RefundRequest{
TransactionId: "",
OutTradeNo: outTradeNo,
OutRefundNo: outRefundNo,
TotalFee: int64(totalFee),
RefundFee: int64(refundFee),
NonceStr: nonceStr,
SignType: core2.SignType_MD5,
RefundFeeType: "CNY",
RefundDesc: reason,
})
//
if err != nil {
return nil, err
}
refund := new(models.UserRefund)
refund.OutTradeNo = outTradeNo
refund.Status = 0
refund.TotalFee = totalFee
refund.GoodType = goodType
refund.RefundDesc = reason
refund.FeeType = "CNY"
refund.OpenId = openId
refund.UserId = userId
refund.ActivityId = activityId
refund.IsDelete = false
refund.CreatedAt = time.Now()
refund.UpdatedAt = time.Now()
_, err = refund.AddUserRefund()
if err != nil {
return nil, err
}
return res, err
}
func QueryRefund(outTradeNo string) (*pay.RefundQueryResponse, error) {
refund := new(models.UserRefund)
exist, err := refund.GetByOutTradeNo(outTradeNo)
if err != nil {
return nil, err
}
if !exist {
return nil, errors.New("不存在改笔退款")
}
client, err := Client()
res, err := pay.RefundQuery2(client, &pay.RefundQueryRequest{
OutTradeNo: outTradeNo,
NonceStr: utils.RandomStr(32),
SignType: core2.SignType_MD5,
})
//请求申请退款
if err != nil {
return nil, err
}
refund.RefundAccount = res.RefundList[0].RefundAccount
refund.RefundRecvAccount = res.RefundList[0].RefundRecvAccout
refund.RefundStatus = res.RefundList[0].RefundStatus
refund.Status = 1
refund.SuccessTime = res.RefundList[0].RefundSuccessTime
refund.WxRefundId = res.RefundList[0].RefundId
refund.TransactionId = res.TransactionId
_, err = refund.QueryUpdate()
if err != nil {
return nil, err
}
return res, nil
}
func BatchQueryRefundByUserId(userId int64) error {
refunds := make([]*models.UserRefund, 0)
if err := core.GetXormAuto().Where("status = 0 and user_id=?", userId).Find(&refunds); err != nil {
return err
}
if err := batchQueryRefund(refunds); err != nil {
return err
}
return nil
}
func BatchQueryRefundByActivityId(activityId int64) error {
refunds := make([]*models.UserRefund, 0)
if err := core.GetXormAuto().Where("status = 0 and user_id=?", activityId).Find(&refunds); err != nil {
return err
}
if err := batchQueryRefund(refunds); err != nil {
return err
}
return nil
}
func batchQueryRefund(refunds []*models.UserRefund) error {
for _, refund := range refunds {
_, err := QueryRefund(refund.OutTradeNo)
if err != nil {
return err
}
}
return nil
}
//func BatchQueryRefundByUserId(userId int64) error {
// refunds := make([]*models.UserRefund, 0)
// if err := core.GetXormAuto().Where("status = 0 and user_id=?", userId).Find(&refunds); err != nil {
// return err
// }
// if err := batchQueryRefund(refunds); err != nil {
// return err
// }
// return nil
//}
//func BatchQueryRefundByActivityId(activityId int64) error {
// refunds := make([]*models.UserRefund, 0)
// if err := core.GetXormAuto().Where("status = 0 and user_id=?", activityId).Find(&refunds); err != nil {
// return err
// }
// if err := batchQueryRefund(refunds); err != nil {
// return err
// }
// return nil
//}
//
//func batchQueryRefund(refunds []*models.UserRefund) error {
// for _, refund := range refunds {
// _, err := QueryRefund(refund.OutTradeNo)
// if err != nil {
// return err
// }
// }
// return nil
//}
Loading…
Cancel
Save