mirror of
https://github.com/kongyuebin1/dongfeng-pay.git
synced 2025-10-16 10:08:00 +08:00
修改网关代码的结构,调整了逻辑,删除了许多无用的代码
This commit is contained in:
193
gateway/service/base_service.go
Normal file
193
gateway/service/base_service.go
Normal file
@@ -0,0 +1,193 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gateway/conf"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/response"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//获取商户信息
|
||||
func GetMerchantInfo(params map[string]string) *response.PayBaseResp {
|
||||
|
||||
c := new(response.PayBaseResp)
|
||||
c.Params = make(map[string]string)
|
||||
c.Params = params
|
||||
|
||||
merchantInfo := merchant.GetMerchantByPaykey(params["payKey"])
|
||||
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户不存在,或者paykey有误,请联系管理员"
|
||||
} else if merchantInfo.Status != conf.ACTIVE {
|
||||
c.Code = -1
|
||||
c.Msg = "商户状态已经被冻结或者被删除,请联系管理员!"
|
||||
} else {
|
||||
c.MerchantInfo = merchantInfo
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func JudgeParams(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
//c.ReturnUrlIsValid()
|
||||
c = OrderIsValid(c)
|
||||
c = NotifyUrlIsValid(c)
|
||||
c = OsTypeIsValid(c)
|
||||
c = PayWayCodeIsValid(c)
|
||||
c = ProductIsValid(c)
|
||||
c = OrderPeriodIsValid(c)
|
||||
//c = IpIsWhite()
|
||||
c = OrderPriceIsValid(c)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/*
|
||||
* 插入支付订单记录和订单利润记录,保证一致性
|
||||
*/
|
||||
func InsertOrderAndOrderProfit(orderInfo order.OrderInfo, orderProfitInfo order.OrderProfitInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
if _, err := txOrm.Insert(&orderInfo); err != nil {
|
||||
logs.Error("insert orderInfo fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Insert(&orderProfitInfo); err != nil {
|
||||
logs.Error("insert orderProfit fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断跳转地址是否符合规则
|
||||
*/
|
||||
func ReturnUrlIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["returnUrl"] == "" || len(c.Params["returnUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功后跳转地址不能为空"
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断回调地址是否符合规则
|
||||
*/
|
||||
func NotifyUrlIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["notifyUrl"] == "" || len(c.Params["notifyUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功订单回调地址不能空位"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断设备类型是否符合规则
|
||||
*/
|
||||
func OsTypeIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["osType"] == "" || len(c.Params["osType"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付设备系统类型不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
/**
|
||||
** 判断支付类型字段是否符合规则
|
||||
*/
|
||||
func PayWayCodeIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["payWayCode"] == "" || len(c.Params["payWayCode"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付类型字段不能为空"
|
||||
return c
|
||||
}
|
||||
|
||||
if !strings.Contains(c.Params["payWayCode"], "SCAN") {
|
||||
c.Code = -1
|
||||
c.Msg = "扫码支付不支持这种支付类型"
|
||||
} else {
|
||||
scanPayWayCodes := conf.GetScanPayWayCodes()
|
||||
for _, v := range scanPayWayCodes {
|
||||
if c.Params["payWayCode"] == v {
|
||||
c.PayWayCode = strings.Replace(c.Params["payWayCode"], "-", "_", -1)
|
||||
return c
|
||||
}
|
||||
}
|
||||
c.Code = -1
|
||||
c.Msg = "不存在这种支付类型,请仔细阅读对接文档"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func ProductIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["productName"] == "" || len(c.Params["productName"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商品描述信息字段不能为空"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func OrderPeriodIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderPeriod"] == "" || len(c.Params["orderPeriod"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单过期时间不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断订单金额
|
||||
func OrderPriceIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderPrice"] == "" || len(c.Params["orderPrice"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额不能为空"
|
||||
return c
|
||||
}
|
||||
|
||||
a, err := strconv.ParseFloat(c.Params["orderPrice"], 64)
|
||||
if err != nil {
|
||||
logs.Error("order price is invalid: ", c.Params["orderPrice"])
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额非法"
|
||||
}
|
||||
c.OrderAmount = a
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断金额订单号是否为空或者有重复
|
||||
func OrderIsValid(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
if c.Params["orderNo"] == "" || len(c.Params["orderNo"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号不能为空"
|
||||
return c
|
||||
}
|
||||
if order.OrderNoIsEixst(c.Params["orderNo"]) {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号重复"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断ip是否在白名单中
|
||||
func IpIsWhite() bool {
|
||||
//TODO
|
||||
return true
|
||||
}
|
249
gateway/service/pay_service.go
Normal file
249
gateway/service/pay_service.go
Normal file
@@ -0,0 +1,249 @@
|
||||
/***************************************************
|
||||
** @Desc : 处理网关模块的一些需要操作数据库的功能
|
||||
** @Time : 2019/12/7 16:40
|
||||
** @Author : yuebin
|
||||
** @File : gateway_solve
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/7 16:40
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/models/road"
|
||||
"gateway/response"
|
||||
"gateway/supplier"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/rs/xid"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
//选择通道
|
||||
func ChooseRoad(c *response.PayBaseResp) *response.PayBaseResp {
|
||||
payWayCode := c.Params["payWayCode"]
|
||||
merchantUid := c.MerchantInfo.MerchantUid
|
||||
//通道配置信息
|
||||
deployInfo := merchant.GetMerchantDeployByUidAndPayType(merchantUid, payWayCode)
|
||||
if deployInfo.MerchantUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道信息"
|
||||
return c
|
||||
}
|
||||
|
||||
singleRoad := road.GetRoadInfoByRoadUid(deployInfo.SingleRoadUid)
|
||||
c.RoadPoolInfo = road.GetRoadPoolByRoadPoolCode(deployInfo.RollRoadCode)
|
||||
if RoadIsValid(singleRoad, c) {
|
||||
c.RoadInfo = singleRoad
|
||||
c.PlatformRate = deployInfo.SingleRoadPlatformRate
|
||||
c.AgentRate = deployInfo.SingleRoadAgentRate
|
||||
return c
|
||||
}
|
||||
//如果单通道没有有效的,那么寻找通道池里面的通道
|
||||
if c.RoadPoolInfo.RoadPoolCode == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道"
|
||||
return c
|
||||
}
|
||||
roadUids := strings.Split(c.RoadPoolInfo.RoadUidPool, "||")
|
||||
roadInfos := road.GetRoadInfosByRoadUids(roadUids)
|
||||
for _, roadInfo := range roadInfos {
|
||||
if RoadIsValid(roadInfo, c) {
|
||||
c.RoadInfo = roadInfo
|
||||
c.PlatformRate = deployInfo.RollRoadPlatformRate
|
||||
c.AgentRate = deployInfo.RollRoadAgentRate
|
||||
return c
|
||||
}
|
||||
}
|
||||
if c.RoadInfo.RoadUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道或者通道不可用"
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
//判断通道是否是合法的
|
||||
func RoadIsValid(roadInfo road.RoadInfo, c *response.PayBaseResp) bool {
|
||||
if roadInfo.RoadUid == "" || len(roadInfo.RoadUid) == 0 {
|
||||
return false
|
||||
}
|
||||
FORMAT := fmt.Sprintf("该通道:%s;", roadInfo.RoadName)
|
||||
if roadInfo.Status != "active" {
|
||||
logs.Notice(FORMAT + "不是激活状态")
|
||||
return false
|
||||
}
|
||||
hour := time.Now().Hour()
|
||||
s := roadInfo.StarHour
|
||||
e := roadInfo.EndHour
|
||||
if hour < s || hour > e {
|
||||
logs.Notice(FORMAT)
|
||||
return false
|
||||
}
|
||||
minAmount := roadInfo.SingleMinLimit
|
||||
maxAmount := roadInfo.SingleMaxLimit
|
||||
if minAmount > c.OrderAmount || maxAmount < c.OrderAmount {
|
||||
logs.Error(FORMAT + "订单金额超限制")
|
||||
return false
|
||||
}
|
||||
todayLimit := roadInfo.TodayLimit
|
||||
totalLimit := roadInfo.TotalLimit
|
||||
todayIncome := roadInfo.TodayIncome
|
||||
totalIncome := roadInfo.TotalIncome
|
||||
if (todayIncome + c.OrderAmount) > todayLimit {
|
||||
logs.Error(FORMAT + "达到了每天金额上限")
|
||||
return false
|
||||
}
|
||||
if (totalIncome + c.OrderAmount) > totalLimit {
|
||||
logs.Error(FORMAT + "达到了总量限制")
|
||||
return false
|
||||
}
|
||||
//如果通道被选中,那么总请求数+1
|
||||
roadInfo.RequestAll = roadInfo.RequestAll + 1
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
road.UpdateRoadInfo(roadInfo)
|
||||
return true
|
||||
}
|
||||
|
||||
//获取基本订单记录
|
||||
func GenerateOrderInfo(c *response.PayBaseResp) order.OrderInfo {
|
||||
//6666是自己系统订单号
|
||||
bankOrderNo := "6666" + xid.New().String()
|
||||
//获取支付类型的名称,例如支付宝扫码等
|
||||
payTypeName := conf.GetNameByPayWayCode(c.Params["payWayCode"])
|
||||
orderInfo := order.OrderInfo{
|
||||
MerchantUid: c.MerchantInfo.MerchantUid,
|
||||
MerchantName: c.MerchantInfo.MerchantName,
|
||||
MerchantOrderId: c.Params["orderNo"],
|
||||
BankOrderId: bankOrderNo,
|
||||
OrderAmount: c.OrderAmount,
|
||||
FactAmount: c.OrderAmount,
|
||||
ShowAmount: c.OrderAmount,
|
||||
RollPoolCode: c.RoadPoolInfo.RoadPoolCode,
|
||||
RollPoolName: c.RoadPoolInfo.RoadPoolName,
|
||||
RoadUid: c.RoadInfo.RoadUid,
|
||||
RoadName: c.RoadInfo.RoadName,
|
||||
PayProductName: c.RoadInfo.ProductName,
|
||||
ShopName: c.Params["productName"],
|
||||
Freeze: conf.NO,
|
||||
Refund: conf.NO,
|
||||
Unfreeze: conf.NO,
|
||||
PayProductCode: c.RoadInfo.ProductUid,
|
||||
PayTypeCode: c.PayWayCode,
|
||||
PayTypeName: payTypeName,
|
||||
OsType: c.Params["osType"],
|
||||
Status: conf.WAIT,
|
||||
NotifyUrl: c.Params["notifyUrl"],
|
||||
ReturnUrl: c.Params["returnUrl"],
|
||||
OrderPeriod: c.Params["orderPeriod"],
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > conf.ZERO {
|
||||
orderInfo.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderInfo.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
//计算收益,平台利润,代理利润
|
||||
func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) order.OrderProfitInfo {
|
||||
//因为所有的手续费率都是百分率,所以需要除以100
|
||||
payTypeName := conf.GetNameByPayWayCode(c.PayWayCode)
|
||||
supplierProfit := c.OrderAmount / 100 * c.RoadInfo.BasicFee
|
||||
platformProfit := c.OrderAmount / 100 * c.PlatformRate
|
||||
agentProfit := c.OrderAmount / 100 * c.AgentRate
|
||||
//如果用户没有设置代理,那么代理利润为0.000
|
||||
if c.MerchantInfo.BelongAgentUid == "" || len(c.MerchantInfo.BelongAgentUid) == 0 {
|
||||
agentProfit = conf.ZERO
|
||||
}
|
||||
allProfit := supplierProfit + platformProfit + agentProfit
|
||||
|
||||
if allProfit >= c.OrderAmount {
|
||||
logs.Error("手续费已经超过订单金额,bankOrderId = %s", orderInfo.BankOrderId)
|
||||
c.Msg = "手续费已经超过了订单金额"
|
||||
c.Code = -1
|
||||
}
|
||||
|
||||
orderProfit := order.OrderProfitInfo{
|
||||
PayProductCode: c.RoadInfo.ProductUid,
|
||||
PayProductName: c.RoadInfo.ProductName,
|
||||
PayTypeCode: c.PayWayCode,
|
||||
PayTypeName: payTypeName,
|
||||
Status: conf.WAIT,
|
||||
MerchantOrderId: c.Params["orderNo"],
|
||||
BankOrderId: orderInfo.BankOrderId,
|
||||
OrderAmount: c.OrderAmount,
|
||||
FactAmount: c.OrderAmount,
|
||||
ShowAmount: c.OrderAmount,
|
||||
AllProfit: allProfit,
|
||||
UserInAmount: c.OrderAmount - allProfit,
|
||||
SupplierProfit: supplierProfit,
|
||||
PlatformProfit: platformProfit,
|
||||
AgentProfit: agentProfit,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
MerchantUid: c.MerchantInfo.MerchantUid,
|
||||
MerchantName: orderInfo.MerchantName,
|
||||
SupplierRate: c.RoadInfo.BasicFee,
|
||||
PlatformRate: c.PlatformRate,
|
||||
AgentRate: c.AgentRate,
|
||||
AgentName: orderInfo.AgentName,
|
||||
AgentUid: orderInfo.AgentUid,
|
||||
}
|
||||
|
||||
//如果该条订单设置了代理利率,并且设置了代理
|
||||
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > conf.ZERO {
|
||||
orderProfit.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderProfit.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderProfit
|
||||
}
|
||||
|
||||
/*
|
||||
* 生成订单一系列的记录
|
||||
*/
|
||||
func GenerateRecord(c *response.PayBaseResp) (order.OrderInfo, order.OrderProfitInfo) {
|
||||
//生成订单记录,订单利润利润
|
||||
orderInfo := GenerateOrderInfo(c)
|
||||
orderProfit := GenerateOrderProfit(orderInfo, c)
|
||||
if c.Code == -1 {
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
if !InsertOrderAndOrderProfit(orderInfo, orderProfit) {
|
||||
c.Code = -1
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
logs.Info("插入支付订单记录和支付利润记录成功")
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
|
||||
func GenerateSuccessData(scanData supplier.ScanData, c *response.PayBaseResp) *response.ScanSuccessData {
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = scanData.OrderNo
|
||||
params["orderPrice"] = scanData.OrderPrice
|
||||
params["payKey"] = c.MerchantInfo.MerchantKey
|
||||
params["payURL"] = scanData.PayUrl
|
||||
params["statusCode"] = "00"
|
||||
|
||||
keys := utils.SortMap(params)
|
||||
sign := utils.GetMD5Sign(params, keys, c.MerchantInfo.MerchantSecret)
|
||||
scanSuccessData := new(response.ScanSuccessData)
|
||||
|
||||
scanSuccessData.StatusCode = "00"
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.OrderNo = scanData.OrderNo
|
||||
scanSuccessData.OrderPrice = scanData.OrderPrice
|
||||
scanSuccessData.PayUrl = scanData.PayUrl
|
||||
scanSuccessData.PayKey = c.MerchantInfo.MerchantKey
|
||||
scanSuccessData.Msg = "请求成功"
|
||||
scanSuccessData.Sign = sign
|
||||
|
||||
return scanSuccessData
|
||||
}
|
503
gateway/service/pay_solve.go
Normal file
503
gateway/service/pay_solve.go
Normal file
@@ -0,0 +1,503 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/message"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/notify"
|
||||
"gateway/models/order"
|
||||
"gateway/models/road"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//处理支付成功的加款等各项操作
|
||||
func SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool {
|
||||
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderInfo order.OrderInfo
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("不存在该订单,或者select for update出错")
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != "wait" {
|
||||
logs.Error("该订单已经处理,订单号=", bankOrderId)
|
||||
return errors.New(fmt.Sprintf("该订单已经处理,订单号= %s", bankOrderId))
|
||||
}
|
||||
|
||||
if factAmount <= conf.ZERO {
|
||||
factAmount = orderInfo.OrderAmount
|
||||
}
|
||||
|
||||
var orderProfitInfo order.OrderProfitInfo
|
||||
if err := txOrm.Raw("select * from order_profit_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderProfitInfo); err != nil || orderProfitInfo.BankOrderId == "" {
|
||||
logs.Error("select order_profit_info for update fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderProfitInfo.BankOrderId == "" {
|
||||
logs.Error("solve pay success, get orderProfit fail, bankOrderId = ", bankOrderId)
|
||||
return errors.New(fmt.Sprintf("solve pay success, get orderProfit fail, bankOrderId = %s", bankOrderId))
|
||||
}
|
||||
|
||||
orderInfo.Status = conf.SUCCESS
|
||||
orderInfo.BankTransId = trxNo
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update order info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
orderSettleInfo := order.OrderSettleInfo{
|
||||
PayTypeCode: orderInfo.PayTypeCode,
|
||||
PayProductCode: orderInfo.PayProductCode,
|
||||
RoadUid: orderInfo.RoadUid,
|
||||
PayProductName: orderInfo.PayProductName,
|
||||
PayTypeName: orderInfo.PayTypeName,
|
||||
MerchantUid: orderInfo.MerchantUid,
|
||||
MerchantOrderId: orderInfo.MerchantOrderId,
|
||||
MerchantName: orderInfo.MerchantName,
|
||||
BankOrderId: bankOrderId,
|
||||
SettleAmount: orderProfitInfo.UserInAmount,
|
||||
IsAllowSettle: conf.YES,
|
||||
IsCompleteSettle: conf.NO,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&orderSettleInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success,insert order settle info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//做账户的加款操作,最重要的一部
|
||||
var accountInfo accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(&accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay success, raw account info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.QueryTable(accounts.ACCOUNT_INFO).Filter("account_uid", orderInfo.MerchantUid).
|
||||
Update((orm.Params{"balance": accountInfo.Balance + orderProfitInfo.UserInAmount, "wait_amount": accountInfo.WaitAmount + orderProfitInfo.UserInAmount})); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update account info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//添加一条动账记录
|
||||
accountHistory := accounts.AccountHistoryInfo{
|
||||
AccountUid: orderInfo.MerchantUid,
|
||||
AccountName: orderInfo.MerchantName,
|
||||
Type: conf.PLUS_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance + orderProfitInfo.UserInAmount,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistory); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success,insert account history fail:%s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//更新通道信息
|
||||
roadInfo := road.GetRoadInfoByRoadUid(orderInfo.RoadUid)
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
roadInfo.RequestSuccess += 1
|
||||
roadInfo.TotalIncome += orderInfo.FactAmount
|
||||
roadInfo.TodayIncome += orderInfo.FactAmount
|
||||
roadInfo.TodayProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
|
||||
roadInfo.TotalProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
|
||||
roadInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&roadInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update road info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
//更新订单利润表
|
||||
orderProfitInfo.Status = conf.SUCCESS
|
||||
orderProfitInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderProfitInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("solve pay success, update order profit info fail: %s, bankOrderId = %s", err, bankOrderId))
|
||||
return err
|
||||
}
|
||||
|
||||
// 给下游发送回调通知
|
||||
go CreateOrderNotifyInfo(orderInfo, conf.SUCCESS)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolvePaySuccess失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolvePaySuccess处理成功")
|
||||
return true
|
||||
}
|
||||
|
||||
//处理支付失败
|
||||
func SolvePayFail(bankOrderId, transId string) bool {
|
||||
o := orm.NewOrm()
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderTmp order.OrderInfo
|
||||
//bankOrderId := orderInfo.BankOrderId
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ?", bankOrderId).QueryRow(&orderTmp); err != nil || orderTmp.BankOrderId == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
if orderTmp.Status != "wait" {
|
||||
return errors.New("订单已经处理,不要重复加款")
|
||||
}
|
||||
if _, err := txOrm.QueryTable(order.ORDER_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": conf.FAIL, "bank_trans_id": transId}); err != nil {
|
||||
logs.Error("更改订单状态失败:", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.QueryTable(order.ORDER_PROFIT_INFO).Filter("bank_order_id", bankOrderId).Update(orm.Params{"status": conf.FAIL, "bank_trans_id": transId}); err != nil {
|
||||
logs.Error("更改订单状态失败:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
go CreateOrderNotifyInfo(orderTmp, conf.FAIL)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolvePayFail:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolvePayFail成功")
|
||||
return true
|
||||
}
|
||||
|
||||
//处理订单冻结
|
||||
func SolveOrderFreeze(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
var orderInfo order.OrderInfo
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(&orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve order freeze 不存在这样的订单记录,bankOrderId = ", bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != conf.SUCCESS {
|
||||
logs.Error("非成功订单不能进行冻结")
|
||||
return errors.New("非成功订单不能进行冻结")
|
||||
}
|
||||
|
||||
orderInfo.Freeze = conf.YES
|
||||
orderInfo.FreezeTime = utils.GetBasicDateTime()
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(&orderInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
//账户的冻结金额里面加入相应的金额
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
var accountInfo accounts.AccountInfo
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(&accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("solve pay fail select acount fail:%s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
accountInfo.FreezeAmount = accountInfo.FreezeAmount + orderProfitInfo.UserInAmount
|
||||
if _, err := txOrm.Update(&accountInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
//插入一条动账记录
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountName: accountInfo.AccountName,
|
||||
AccountUid: accountInfo.AccountUid,
|
||||
Type: conf.FREEZE_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order freeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logs.Error("SolveOrderFreeze:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
logs.Info("SolveOrderFreeze")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//订单解冻
|
||||
func SolveOrderUnfreeze(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve order unfreeze 不存在这样的订单记录,bankOrderId = ", bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
orderInfo.Freeze = ""
|
||||
orderInfo.Unfreeze = conf.YES
|
||||
orderInfo.UnfreezeTime = utils.GetBasicDateTime()
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order unfreeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error(fmt.Sprintf("unfreeze select account fail: %s", err))
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
accountInfo.FreezeAmount = accountInfo.FreezeAmount - orderProfitInfo.UserInAmount
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error("solve order unfreeze fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountUid: accountInfo.AccountUid,
|
||||
AccountName: accountInfo.AccountName,
|
||||
Type: conf.UNFREEZE_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: accountInfo.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
logs.Error("SolveOrderUnfreeze失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func SolveRefund(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil || orderInfo.BankOrderId == "" {
|
||||
logs.Error("solve refund 不存在这样的订单,bankOrderId = " + bankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
orderInfo.Refund = conf.YES
|
||||
orderInfo.RefundTime = utils.GetBasicDateTime()
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
account := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(account); err != nil || account.AccountUid == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
account.SettleAmount = account.SettleAmount - orderProfitInfo.UserInAmount
|
||||
account.Balance = account.Balance - orderProfitInfo.UserInAmount
|
||||
|
||||
if orderInfo.Freeze == conf.YES {
|
||||
account.FreezeAmount = account.FreezeAmount - orderProfitInfo.UserInAmount
|
||||
if account.FreezeAmount < 0 {
|
||||
account.FreezeAmount = conf.ZERO
|
||||
}
|
||||
orderInfo.Freeze = ""
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order refund update order info fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Update(account); err != nil {
|
||||
logs.Error("solve order refund update account fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountName: account.AccountName,
|
||||
AccountUid: account.AccountUid,
|
||||
Type: conf.REFUND,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: account.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order refund insert account history fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
logs.Error("SolveRefund 成功:", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func SolveOrderRoll(bankOrderId string) bool {
|
||||
o := orm.NewOrm()
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
|
||||
orderInfo := new(order.OrderInfo)
|
||||
|
||||
if err := txOrm.Raw("select * from order_info where bank_order_id = ? for update", bankOrderId).QueryRow(orderInfo); err != nil {
|
||||
logs.Error("solve order roll fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if orderInfo.Status != conf.SUCCESS {
|
||||
logs.Error("solve order roll 订单不存在或者订单状态不是success, bankOrderId=", bankOrderId)
|
||||
return errors.New("solve order roll failed")
|
||||
}
|
||||
orderInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(bankOrderId)
|
||||
|
||||
account := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", orderInfo.MerchantUid).QueryRow(account); err != nil || account.AccountUid == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
account.UpdateTime = utils.GetBasicDateTime()
|
||||
if orderInfo.Refund == conf.YES {
|
||||
account.Balance = account.Balance + orderProfitInfo.UserInAmount
|
||||
account.SettleAmount = account.SettleAmount + orderProfitInfo.UserInAmount
|
||||
orderInfo.Refund = conf.NO
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(orderInfo); err != nil {
|
||||
logs.Error("solve order roll fail update order info fail: ", err)
|
||||
return err
|
||||
}
|
||||
if _, err := txOrm.Update(account); err != nil {
|
||||
logs.Error("solve order roll update account fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountHistoryInfo := accounts.AccountHistoryInfo{
|
||||
AccountUid: account.AccountUid,
|
||||
AccountName: account.AccountName,
|
||||
Type: conf.PLUS_AMOUNT,
|
||||
Amount: orderProfitInfo.UserInAmount,
|
||||
Balance: account.Balance,
|
||||
UpdateTime: utils.GetBasicDateTime(),
|
||||
CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if _, err := txOrm.Insert(&accountHistoryInfo); err != nil {
|
||||
logs.Error("solve order roll insert account history fail: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
logs.Error("SolveOrderRoll处理失败:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//比较订单金额和实际支付金额的大小
|
||||
func CompareOrderAndFactAmount(factAmount float64, orderInfo order.OrderInfo) int {
|
||||
orderAmount := orderInfo.OrderAmount
|
||||
//将金额放大1000倍
|
||||
oa := int64(orderAmount * 1000)
|
||||
fa := int64(factAmount * 1000)
|
||||
if oa > fa {
|
||||
//如果实际金额大,返回1
|
||||
return 1
|
||||
} else if oa == fa {
|
||||
return 0
|
||||
} else {
|
||||
return 2
|
||||
}
|
||||
}
|
||||
|
||||
//支付完成后,处理给商户的回调信息
|
||||
func CreateOrderNotifyInfo(orderInfo order.OrderInfo, tradeStatus string) {
|
||||
|
||||
notifyInfo := new(notify.NotifyInfo)
|
||||
notifyInfo.Type = "order"
|
||||
notifyInfo.BankOrderId = orderInfo.BankOrderId
|
||||
notifyInfo.MerchantOrderId = orderInfo.MerchantOrderId
|
||||
notifyInfo.Status = "wait"
|
||||
notifyInfo.Times = 0
|
||||
notifyInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
notifyInfo.CreateTime = utils.GetBasicDateTime()
|
||||
|
||||
merchantInfo := merchant.GetMerchantByUid(orderInfo.MerchantUid)
|
||||
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderInfo.MerchantOrderId
|
||||
params["orderPrice"] = strconv.FormatFloat(orderInfo.OrderAmount, 'f', 2, 64)
|
||||
params["factPrice"] = strconv.FormatFloat(orderInfo.FactAmount, 'f', 2, 64)
|
||||
params["orderTime"] = utils.GetDateTimeNot()
|
||||
|
||||
if orderInfo.BankTransId != "" {
|
||||
params["trxNo"] = orderInfo.BankTransId
|
||||
} else {
|
||||
params["trxNo"] = orderInfo.BankOrderId
|
||||
}
|
||||
params["statusCode"] = "00"
|
||||
params["tradeStatus"] = tradeStatus
|
||||
params["payKey"] = merchantInfo.MerchantKey
|
||||
|
||||
params["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
|
||||
u := url.Values{}
|
||||
for k, v := range params {
|
||||
u.Add(k, v)
|
||||
}
|
||||
|
||||
notifyInfo.Url = orderInfo.NotifyUrl + "?" + u.Encode()
|
||||
|
||||
if notify.InsertNotifyInfo(*notifyInfo) {
|
||||
logs.Info(fmt.Sprintf("订单bankOrderId=%s,已经将回调地址插入数据库", orderInfo.BankOrderId))
|
||||
} else {
|
||||
logs.Error(fmt.Sprintf("订单bankOrderId=%s,插入回调数据库失败", orderInfo.BankOrderId))
|
||||
}
|
||||
//将订单发送到消息队列,给下面的商户进行回调
|
||||
go message.SendMessage(conf.MqOrderNotify, orderInfo.BankOrderId)
|
||||
}
|
234
gateway/service/settle_service.go
Normal file
234
gateway/service/settle_service.go
Normal file
@@ -0,0 +1,234 @@
|
||||
/***************************************************
|
||||
** @Desc : 订单结算,将订单上面的钱加入到账户余额中
|
||||
** @Time : 2019/11/22 11:34
|
||||
** @Author : yuebin
|
||||
** @File : order_settle
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 11:34
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gateway/conf"
|
||||
"gateway/models/accounts"
|
||||
"gateway/models/merchant"
|
||||
"gateway/models/order"
|
||||
"gateway/utils"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
Interval = 2 //隔多少分钟进行结算
|
||||
Minutes = 1 //每隔15分钟,进行扫码,看有没有隔天押款金额
|
||||
)
|
||||
|
||||
/**
|
||||
* 订单结算,将那些支付成功的订单金额加入到商户账户的结算金额中
|
||||
*/
|
||||
func OrderSettle() {
|
||||
|
||||
params := make(map[string]string)
|
||||
params["is_allow_settle"] = conf.YES
|
||||
params["is_complete_settle"] = conf.NO
|
||||
orderSettleList := order.GetOrderSettleListByParams(params)
|
||||
for _, orderSettle := range orderSettleList {
|
||||
orderProfitInfo := order.GetOrderProfitByBankOrderId(orderSettle.BankOrderId)
|
||||
if !settle(orderSettle, orderProfitInfo) {
|
||||
logs.Error(fmt.Sprintf("结算订单bankOrderId = #{orderSettle.BankOrderId}, 执行失败"))
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("结算订单bankOrderId= #{orderSettle.BankOrderId},执行成功"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func settle(orderSettle order.OrderSettleInfo, orderProfit order.OrderProfitInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
tmpSettle := new(order.OrderSettleInfo)
|
||||
if err := txOrm.Raw("select * from order_settle_info where bank_order_id=? for update", orderSettle.BankOrderId).QueryRow(tmpSettle); err != nil || tmpSettle.BankOrderId == "" {
|
||||
logs.Error("获取tmpSettle失败,bankOrderId=%s", orderSettle.BankOrderId)
|
||||
return err
|
||||
}
|
||||
|
||||
tmpSettle.UpdateTime = utils.GetBasicDateTime()
|
||||
tmpSettle.IsCompleteSettle = conf.YES
|
||||
if _, err := txOrm.Update(tmpSettle); err != nil {
|
||||
logs.Error("更新tmpSettle失败,错误:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid=? for update", orderSettle.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.UpdateTime == "" {
|
||||
logs.Error("结算select account info失败,错误信息:", err)
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
|
||||
// 商户有押款操作
|
||||
loadAmount := 0.0
|
||||
merchantDeployInfo := merchant.GetMerchantDeployByUidAndPayType(accountInfo.AccountUid, orderSettle.PayTypeCode)
|
||||
if merchantDeployInfo.IsLoan == conf.YES {
|
||||
loadAmount = merchantDeployInfo.LoanRate * 0.01 * orderProfit.FactAmount
|
||||
date := utils.GetDate()
|
||||
params := make(map[string]string)
|
||||
params["merchant_uid"] = tmpSettle.MerchantUid
|
||||
params["road_uid"] = tmpSettle.RoadUid
|
||||
params["load_date"] = date
|
||||
if !merchant.IsExistMerchantLoadByParams(params) {
|
||||
|
||||
tmp := merchant.MerchantLoadInfo{Status: conf.NO, MerchantUid: orderSettle.MerchantUid, RoadUid: orderSettle.RoadUid,
|
||||
LoadDate: utils.GetDateAfterDays(merchantDeployInfo.LoanDays), LoadAmount: loadAmount,
|
||||
UpdateTime: utils.GetBasicDateTime(), CreateTime: utils.GetBasicDateTime()}
|
||||
|
||||
if _, err := txOrm.Insert(&tmp); err != nil {
|
||||
logs.Error("結算插入merchantLoad失敗,失败信息:", err)
|
||||
return err
|
||||
} else {
|
||||
logs.Info("结算插入新的merchantLoad信息成功")
|
||||
}
|
||||
} else {
|
||||
merchantLoad := new(merchant.MerchantLoadInfo)
|
||||
if err := txOrm.Raw("select * from merchant_load_info where merchant_uid=? and road_uid=? and load_date=? for update").
|
||||
QueryRow(merchantLoad); err != nil || merchantLoad.UpdateTime == "" {
|
||||
logs.Error(fmt.Sprintf("结算过程,select merchant load info失败,错误信息:#{err}"))
|
||||
return err
|
||||
} else {
|
||||
merchantLoad.UpdateTime = utils.GetBasicDateTime()
|
||||
merchantLoad.LoadAmount += loadAmount
|
||||
if _, err := txOrm.Update(merchantLoad); err != nil {
|
||||
logs.Error(fmt.Sprintf("结算过程,update merchant load info失败,失败信息:#{err}"))
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("结算过程中,该商户不需要押款,全款结算"))
|
||||
}
|
||||
|
||||
if accountInfo.WaitAmount < orderProfit.UserInAmount {
|
||||
logs.Error("系统出现严重故障,账户的带结算金额小于订单结算金额")
|
||||
return errors.New("系统出现严重故障,账户的带结算金额小于订单结算金额, 账户 = " + accountInfo.AccountName + "订单id = " + orderProfit.BankOrderId)
|
||||
}
|
||||
|
||||
needAmount := orderProfit.UserInAmount - loadAmount
|
||||
|
||||
accountInfo.SettleAmount = accountInfo.SettleAmount + needAmount
|
||||
accountInfo.WaitAmount = accountInfo.WaitAmount - orderProfit.UserInAmount
|
||||
accountInfo.LoanAmount = accountInfo.LoanAmount + loadAmount
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error("结算update account 失败,错误信息:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
* 商户的押款释放处理,根据商户的押款时间进行处理
|
||||
*/
|
||||
func MerchantLoadSolve() {
|
||||
hour := time.Now().Hour()
|
||||
merchantDeployList := merchant.GetMerchantDeployByHour(hour)
|
||||
for _, merchantDeploy := range merchantDeployList {
|
||||
logs.Info(fmt.Sprintf("开始执行商户uid= #{merchantDeploy.MerchantUid},进行解款操作"))
|
||||
|
||||
loadDate := utils.GetDateBeforeDays(merchantDeploy.LoanDays)
|
||||
params := make(map[string]string)
|
||||
params["status"] = conf.NO
|
||||
params["merchant_uid"] = merchantDeploy.MerchantUid
|
||||
params["load_date"] = loadDate
|
||||
|
||||
merchantLoadList := merchant.GetMerchantLoadInfoByMap(params)
|
||||
for _, merchantLoad := range merchantLoadList {
|
||||
if MerchantAbleAmount(merchantLoad) {
|
||||
logs.Info(fmt.Sprintf("商户uid= %s,押款金额=%f,押款通道= %s, 解款成功", merchantLoad.MerchantUid, merchantLoad.LoadAmount, merchantLoad.RoadUid))
|
||||
} else {
|
||||
logs.Error(fmt.Sprintf("商户uid=%s,押款金额=%f,押款通道=%s, 解款失败", merchantLoad.MerchantUid, merchantLoad.LoadAmount, merchantLoad.RoadUid))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 对应的商户的账户可用金额进行调整操作
|
||||
*/
|
||||
func MerchantAbleAmount(merchantLoad merchant.MerchantLoadInfo) bool {
|
||||
o := orm.NewOrm()
|
||||
|
||||
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
|
||||
tmpLoad := new(merchant.MerchantLoadInfo)
|
||||
if err := txOrm.Raw("select * from merchant_load_info where merchant_uid=? and road_uid=? and load_date=? for update",
|
||||
merchantLoad.MerchantUid, merchantLoad.RoadUid, merchantLoad.LoadDate).QueryRow(tmpLoad); err != nil || tmpLoad.MerchantUid == "" {
|
||||
logs.Error(fmt.Sprintf("解款操作获取商户押款信息失败,fail: %s", err))
|
||||
return err
|
||||
|
||||
}
|
||||
if tmpLoad.Status != conf.NO {
|
||||
logs.Error(fmt.Sprintf("押款信息merchantuid=%s,通道uid=%s, 押款日期=%s,已经解款过,不需要再进行处理了", tmpLoad.MerchantUid, tmpLoad.RoadUid, tmpLoad.LoadDate))
|
||||
return errors.New("已经解款过,不需要再进行处理了")
|
||||
}
|
||||
|
||||
tmpLoad.UpdateTime = utils.GetBasicDateTime()
|
||||
tmpLoad.Status = conf.YES
|
||||
if _, err := txOrm.Update(tmpLoad); err != nil {
|
||||
logs.Error(fmt.Sprintf("解款操作更新merchant load info 失败:%s", err))
|
||||
return err
|
||||
}
|
||||
|
||||
accountInfo := new(accounts.AccountInfo)
|
||||
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", merchantLoad.MerchantUid).QueryRow(accountInfo); err != nil || accountInfo.AccountUid == "" {
|
||||
logs.Error("结款操作获取账户信息失败:", err)
|
||||
return err
|
||||
}
|
||||
accountInfo.UpdateTime = utils.GetBasicDateTime()
|
||||
if accountInfo.LoanAmount >= tmpLoad.LoadAmount {
|
||||
accountInfo.LoanAmount = accountInfo.LoanAmount - tmpLoad.LoadAmount
|
||||
accountInfo.SettleAmount = accountInfo.SettleAmount + tmpLoad.LoadAmount
|
||||
} else {
|
||||
accountInfo.LoanAmount = conf.ZERO
|
||||
}
|
||||
|
||||
if _, err := txOrm.Update(accountInfo); err != nil {
|
||||
logs.Error(fmt.Sprintf("解款操作更新account info 失败:%s,账户uid=%s", err, accountInfo.AccountUid))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func OrderSettleInit() {
|
||||
//每隔5分钟,巡查有没有可以进行结算的订单
|
||||
go func() {
|
||||
settleTimer := time.NewTimer(time.Duration(Interval) * time.Minute)
|
||||
oneMinuteTimer := time.NewTimer(time.Duration(Minutes) * time.Minute)
|
||||
for {
|
||||
select {
|
||||
case <-settleTimer.C:
|
||||
settleTimer = time.NewTimer(time.Duration(Interval) * time.Minute)
|
||||
logs.Info("开始对商户进行支付订单结算>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
||||
OrderSettle()
|
||||
case <-oneMinuteTimer.C:
|
||||
oneMinuteTimer = time.NewTimer(time.Duration(Minutes) * time.Minute)
|
||||
logs.Info("开始执行商户的解款操作>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
||||
MerchantLoadSolve()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
Reference in New Issue
Block a user