将订单转移到前面

This commit is contained in:
sunxiaolong
2024-01-13 13:35:45 +08:00
parent 037b3a79c8
commit be71cd98a4
68 changed files with 679 additions and 533 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,3 @@
./idea
./vscode
/.idea/
/.vscode/
/main.exe

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

9
.idea/gateway.iml generated
View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/gateway.iml" filepath="$PROJECT_DIR$/.idea/gateway.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -2,11 +2,11 @@ package config
import (
"fmt"
"github.com/beego/beego/v2/server/web"
)
type Config struct {
}
type Config struct{}
func (c *Config) GetMFCardSubmitUrl() (string, error) {
return web.AppConfig.String("mf::submit_card_url")

View File

@@ -19,36 +19,37 @@ const (
ORDERROLL = "order_roll"
WAIT = "wait"
SUCCESS = "success"
Created = "created" // 创建订单
FAIL = "fail"
YES = "yes"
NO = "no"
ZERO = 0.0 //0元手续费
VERIFY_CODE_LEN = 4 //验证码的长度
PAYFOR_FEE = 2.00 //代付手续费
PAYFOR_INTERVAL = 5 //每过5分钟执行一次代付
ZERO = 0.0 // 0元手续费
VERIFY_CODE_LEN = 4 // 验证码的长度
PAYFOR_FEE = 2.00 // 代付手续费
PAYFOR_INTERVAL = 5 // 每过5分钟执行一次代付
PLUS_AMOUNT = "plus_amount" //加款操作
SUB_AMOUNT = "sub_amount" //减款操作
FREEZE_AMOUNT = "freeze_amount" //冻结操作
UNFREEZE_AMOUNT = "unfreeze_amount" //解冻操作
PLUS_AMOUNT = "plus_amount" // 加款操作
SUB_AMOUNT = "sub_amount" // 减款操作
FREEZE_AMOUNT = "freeze_amount" // 冻结操作
UNFREEZE_AMOUNT = "unfreeze_amount" // 解冻操作
PAYFOR_COMFRIM = "payfor_confirm" //下发带审核
PAYFOR_SOLVING = "payfor_solving" //发下处理中
PAYFOR_HANDING = "payfor_handing" //手动打款中
PAYFOR_BANKING = "payfor_banking" //银行处理中
PAYFOR_FAIL = "payfor_fail" //代付失败
PAYFOR_SUCCESS = "payfor_success" //代付成功
PAYFOR_COMFRIM = "payfor_confirm" // 下发带审核
PAYFOR_SOLVING = "payfor_solving" // 发下处理中
PAYFOR_HANDING = "payfor_handing" // 手动打款中
PAYFOR_BANKING = "payfor_banking" // 银行处理中
PAYFOR_FAIL = "payfor_fail" // 代付失败
PAYFOR_SUCCESS = "payfor_success" // 代付成功
PAYFOR_ROAD = "payfor_road" //通道打款
PAYFOR_HAND = "payfor_hand" //手动打款
PAYFOR_ROAD = "payfor_road" // 通道打款
PAYFOR_HAND = "payfor_hand" // 手动打款
PAYFOR_REFUSE = "payfor_refuse" // 拒绝打款
SELF_API = "self_api" //自助api系统下发
SELF_MERCHANT = "self_merchant" //管理手动处理商户下发
SELF_HELP = "self_help" //管理自己提现
SELF_API = "self_api" // 自助api系统下发
SELF_MERCHANT = "self_merchant" // 管理手动处理商户下发
SELF_HELP = "self_help" // 管理自己提现
PUBLIC = "public" //对公卡
PRIVATE = "private" //对私卡
PUBLIC = "public" // 对公卡
PRIVATE = "private" // 对私卡
)
const (

View File

@@ -1,8 +1,9 @@
package config
import (
"github.com/beego/beego/v2/server/web"
"net"
"github.com/beego/beego/v2/server/web"
)
var (
@@ -10,8 +11,8 @@ var (
mqPort = "61613"
MqOrderQuery = "order_query"
MQ_PAYFOR_QUERY = "payfor_query" //代付
MqOrderNotify = "order_notify" //订单通知
MQ_PAYFOR_QUERY = "payfor_query" // 代付
MqOrderNotify = "order_notify" // 订单通知
)
func GetMQAddress() string {

View File

@@ -1,19 +1,11 @@
package gateway
/***************************************************
** @Desc : 处理下游请求的一些公用的逻辑
** @Time : 2019/10/28 18:09
** @Author : yuebin
** @File : base_gateway
** @Last Modified by : yuebin
** @Last Modified time: 2019/10/28 18:09
** @Software: GoLand
****************************************************/
import (
"strings"
"gateway/response"
"gateway/service"
"github.com/beego/beego/v2/server/web"
"strings"
)
type BaseGateway struct {
@@ -23,7 +15,7 @@ type BaseGateway struct {
// PayPrepare 获取商户请求过来的基本参数参数
func (c *BaseGateway) PayPrepare() *response.PayBaseResp {
params := make(map[string]string)
//获取客户端的ip
// 获取客户端的ip
clientIP := c.Ctx.Input.IP()
params["exValue"] = strings.TrimSpace(c.GetString("exValue"))
params["orderNo"] = strings.TrimSpace(c.GetString("orderNo"))

View File

@@ -5,6 +5,9 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"gateway/config"
"gateway/models/merchant"
"gateway/models/order"
@@ -13,12 +16,11 @@ import (
"gateway/service"
"gateway/supplier/third_party"
"gateway/utils"
"github.com/astaxie/beego/logs"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/server/web"
"github.com/bytedance/sonic"
"strconv"
"strings"
)
type OrderController struct {
@@ -102,7 +104,7 @@ func (c *OrderController) CardSuit() {
return
}
p.OrderAmount = orderInfo.OrderAmount
//选择通道
// 选择通道
p = service.ChooseRoad(p)
if p.Code == -1 {
jsonResponse := response.Resp{
@@ -145,20 +147,20 @@ func (c *OrderController) CardSuit() {
// OrderCreate 订单创建
func (c *OrderController) OrderCreate() {
//客户传递过来对参数 订单ID 支付类型 卡类型 卡面值
//判断订单是否存在 是否关闭 是否支付成功
//c.Data["flash"] = map[string]string{"error": string2}
// 客户传递过来对参数 订单ID 支付类型 卡类型 卡面值
// 判断订单是否存在 是否关闭 是否支付成功
// c.Data["flash"] = map[string]string{"error": string2}
params := make(map[string]string)
//获取客户端的ip
//clientIp := c.Ctx.Input.IP()
// 获取客户端的ip
// clientIp := c.Ctx.Input.IP()
params["payWayCode"] = strings.TrimSpace(c.GetString("paycode"))
params["orderPrice"] = strings.TrimSpace(c.GetString("price"))
params["orderNo"] = strings.TrimSpace(c.GetString("orderid"))
params["notifyUrl"] = strings.TrimSpace(c.GetString("notifyurl"))
params["orderPeriod"] = "24" //订单有效时间
params["PayTypeCode"] = "CARD_DH" //类型
//商户ID
params["orderPeriod"] = "24" // 订单有效时间
params["PayTypeCode"] = "CARD_DH" // 类型
// 商户ID
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
if params["payWayCode"] == "" || params["orderPrice"] == "" || params["orderNo"] == "" {
c.ShowErr("参数有误,请检查再试试。")
@@ -186,8 +188,8 @@ func (c *OrderController) OrderCreate() {
}
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
//生成订单记录
orderInfo, _ = service.GenerateRecord(p)
// 生成订单记录
orderInfo, _, _ = service.GenerateRecord(p)
if p.Code == -1 {
c.ShowErr(p.Msg)
return
@@ -234,10 +236,10 @@ func (c *OrderController) OrderUpdate() {
case config.FAIL:
flag = service.SolvePayFail(bankOrderId, orderInfo.BankTransId)
case config.FREEZE_AMOUNT:
//将这笔订单进行冻结
// 将这笔订单进行冻结
flag = service.SolveOrderFreeze(bankOrderId)
case config.UNFREEZE_AMOUNT:
//将这笔订单金额解冻
// 将这笔订单金额解冻
flag = service.SolveOrderUnfreeze(bankOrderId)
case config.REFUND:
if orderInfo.Status == config.SUCCESS {

View File

@@ -11,6 +11,8 @@ package gateway
****************************************************/
import (
"fmt"
"strings"
"gateway/config"
"gateway/models/order"
"gateway/models/payfor"
@@ -20,7 +22,6 @@ import (
"gateway/supplier/third_party"
"github.com/astaxie/beego/logs"
"github.com/beego/beego/v2/server/web"
"strings"
)
type PayForGateway struct {
@@ -33,13 +34,13 @@ func (c *PayForGateway) PayFor() {
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
params["realname"] = strings.TrimSpace(c.GetString("realname"))
params["cardNo"] = strings.TrimSpace(c.GetString("cardNo"))
//params["bankCode"] = strings.TrimSpace(c.GetString("bankCode"))
// params["bankCode"] = strings.TrimSpace(c.GetString("bankCode"))
params["accType"] = strings.TrimSpace(c.GetString("accType"))
//params["province"] = strings.TrimSpace(c.GetString("province"))
//params["city"] = strings.TrimSpace(c.GetString("city"))
//params["bankAccountAddress"] = strings.TrimSpace(c.GetString("bankAccountAddress"))
// params["province"] = strings.TrimSpace(c.GetString("province"))
// params["city"] = strings.TrimSpace(c.GetString("city"))
// params["bankAccountAddress"] = strings.TrimSpace(c.GetString("bankAccountAddress"))
params["amount"] = strings.TrimSpace(c.GetString("amount"))
//params["mobileNo"] = strings.TrimSpace(c.GetString("mobileNo"))
// params["mobileNo"] = strings.TrimSpace(c.GetString("mobileNo"))
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
params["sign"] = strings.TrimSpace(c.GetString("sign"))
@@ -49,13 +50,11 @@ func (c *PayForGateway) PayFor() {
payForResponse.ResultCode = "01"
payForResponse.ResultMsg = msg
} else {
payForResponse = pay_for.AutoPayFor(params, config.SELF_API)
}
c.Data["json"] = payForResponse
_ = c.ServeJSON()
}
// PayForQuery 代付结果查询,

View File

@@ -3,13 +3,14 @@ package gateway
import (
"encoding/json"
"fmt"
"gateway/utils"
"io/ioutil"
"log"
"math/rand"
"net/http"
"testing"
"time"
"gateway/utils"
)
func TestPayFor(t *testing.T) {
@@ -69,6 +70,7 @@ func GenerateOrderNo() string {
code := fmt.Sprintf("%s%d%03d", date, GetTimeTick64(), r)
return code
}
func TestGenerateCode(t *testing.T) {
GenerateOrderNo()
}

View File

@@ -3,14 +3,17 @@ package gateway
import (
"errors"
"strconv"
"strings"
"gateway/config"
"gateway/models/merchant"
"gateway/models/order"
"gateway/request"
"gateway/response"
"gateway/service"
"gateway/supplier/third_party"
"gateway/utils"
"strconv"
"strings"
)
type ScanController struct {
@@ -43,14 +46,20 @@ func (c *ScanController) Scan() {
p.Msg = "签名异常"
c.SolveFailJSON(p)
}
//选择通道
// 选择通道
p = service.ChooseRoad(p)
if p.Code == -1 {
c.SolveFailJSON(p)
}
//生成订单记录
orderInfo, _ := service.GenerateRecord(p)
// 生成订单记录
orderInfo, _, err := service.GenerateRecord(p)
if err != nil {
p.Code = -1
p.Msg = "生成订单失败"
c.SolveFailJSON(p)
}
if p.Code == -1 {
c.SolveFailJSON(p)
}
@@ -73,7 +82,7 @@ func (c *ScanController) Scan() {
}
_ = c.ServeJSON()
}
//获取到对应的上游
// 获取到对应的上游
supplierCode := p.RoadInfo.ProductUid
supplier := third_party.GetPaySupplierByCode(supplierCode)
scanData := supplier.Scan(orderInfo, p.RoadInfo, p.MerchantInfo)
@@ -130,3 +139,37 @@ func (c *ScanController) GetAllowedMM() {
c.Data["json"] = response.Ok(factValue)
_ = c.ServeJSON()
}
// CreateOrder 创建订单
func (c *ScanController) CreateOrder() {
createdOrder := request.CreatedOrder{}
err := c.BindJSON(&createdOrder)
if err != nil {
res := response.CommonErr(-1, "创建订单错误")
c.Data["json"] = res
_ = c.ServeJSON()
}
merchantInfo := merchant.GetMerchantByPasskey(createdOrder.PayKey)
if merchantInfo.Id == 0 {
res := response.CommonErr(-1, "创建订单错误")
c.Data["json"] = res
_ = c.ServeJSON()
}
if !utils.Md5MFVerify(createdOrder.ToMap(), merchantInfo.MerchantSecret) {
res := response.CommonErr(-1, "创建订单错误")
c.Data["json"] = res
_ = c.ServeJSON()
}
err = service.CreateOrderInfoAndOrderProfitInfo(createdOrder, merchantInfo)
if err != nil {
res := response.CommonErr(-1, err.Error())
c.Data["json"] = res
_ = c.ServeJSON()
}
res := response.Ok("创建成功")
c.Data["json"] = res
_ = c.ServeJSON()
}

1
go.mod
View File

@@ -10,5 +10,6 @@ require (
github.com/go-sql-driver/mysql v1.6.0
github.com/go-stomp/stomp/v3 v3.0.5
github.com/rs/xid v1.5.0
github.com/shopspring/decimal v1.3.1 // indirect
github.com/widuu/gojson v0.0.0-20170212122013-7da9d2cd949b
)

2
go.sum
View File

@@ -419,6 +419,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=

View File

@@ -18,7 +18,7 @@ func main() {
RegisterLogs()
web.BConfig.WebConfig.Session.SessionOn = true
go notify.CreateOrderNotifyConsumer()
//go pay_for.PayForInit()
// go pay_for.PayForInit()
go query.CreatePayForQueryConsumer()
go service.OrderSettleInit()
go query.CreateSupplierOrderQueryCuConsumer()

View File

@@ -11,17 +11,18 @@ package message
****************************************************/
import (
"time"
"gateway/config"
"github.com/beego/beego/v2/core/logs"
"github.com/go-stomp/stomp/v3"
"time"
)
// 解决第一个问题的代码
var activeConn *stomp.Conn
var options = []func(*stomp.Conn) error{
//设置读写超时超时时间为1个小时
// 设置读写超时超时时间为1个小时
stomp.ConnOpt.HeartBeat(7200*time.Second, 7200*time.Second),
stomp.ConnOpt.HeartBeatError(360 * time.Second),
stomp.ConnOpt.Login("guest", "guest"),
@@ -31,10 +32,9 @@ var options = []func(*stomp.Conn) error{
func init() {
address := config.GetMQAddress()
conn, err := stomp.Dial("tcp", address, options...)
if err != nil {
logs.Error("链接MQ失败", err.Error())
//os.Exit(1)
// os.Exit(1)
}
activeConn = conn

View File

@@ -11,8 +11,9 @@ package message
****************************************************/
import (
"github.com/beego/beego/v2/core/logs"
"os"
"github.com/beego/beego/v2/core/logs"
)
func SendMessage(topic, message string) {

View File

@@ -20,13 +20,13 @@ type AccountInfo struct {
Status string
AccountUid string
AccountName string
Balance float64 //账户总余额
SettleAmount float64 //已经结算的金额
LoanAmount float64 //账户押款金额
FreezeAmount float64 //账户冻结金额
WaitAmount float64 //待结算资金
PayforAmount float64 //代付在途金额
//AbleBalance float64 //账户可用金额
Balance float64 // 账户总余额
SettleAmount float64 // 已经结算的金额
LoanAmount float64 // 账户押款金额
FreezeAmount float64 // 账户冻结金额
WaitAmount float64 // 待结算资金
PayforAmount float64 // 代付在途金额
// AbleBalance float64 //账户可用金额
UpdateTime string
CreateTime string
}
@@ -91,7 +91,6 @@ func GetAllAccount() []AccountInfo {
var accountList []AccountInfo
_, err := o.QueryTable(ACCOUNT_INFO).Limit(-1).All(&accountList)
if err != nil {
logs.Error("get all account fail: ", err)
}

View File

@@ -1,12 +1,3 @@
/***************************************************
** @Desc : This file for ...
** @Time : 2019/9/19 14:41
** @Author : yuebin
** @File : agent_info
** @Last Modified by : yuebin
** @Last Modified time: 2019/9/19 14:41
** @Software: GoLand
****************************************************/
package agent
import (
@@ -64,7 +55,6 @@ func GetAgentInfoByAgentUid(agentUid string) AgentInfo {
o := orm.NewOrm()
var agentInfo AgentInfo
_, err := o.QueryTable(AGENT_INFO).Filter("agent_uid", agentUid).Limit(1).All(&agentInfo)
if err != nil {
logs.Error("get agent info by agentUid fail: ", err)
}
@@ -76,7 +66,6 @@ func GetAgentInfoByPhone(phone string) AgentInfo {
o := orm.NewOrm()
var agentInfo AgentInfo
_, err := o.QueryTable(AGENT_INFO).Filter("agent_phone", phone).Limit(1).All(&agentInfo)
if err != nil {
logs.Error("get agent info by phone fail: ", err)
}
@@ -112,7 +101,6 @@ func GetAgentInfoByMap(params map[string]string, displayCount, offset int) []Age
}
_, err := qs.Limit(displayCount, offset).OrderBy("-update_time").All(&agentInfoList)
if err != nil {
logs.Error("get agentInfo by map fail: ", err)
}
@@ -142,7 +130,6 @@ func GetAllAgentByMap(parmas map[string]string) []AgentInfo {
func UpdateAgentInfo(agentInfo AgentInfo) bool {
o := orm.NewOrm()
_, err := o.Update(&agentInfo)
if err != nil {
logs.Error("update agentinfo fail: ", err)
return false

View File

@@ -10,5 +10,4 @@ package agent
** @Software: GoLand
****************************************************/
type AgentProfit struct {
}
type AgentProfit struct{}

View File

@@ -12,6 +12,7 @@ package models
import (
"fmt"
"gateway/models/accounts"
"gateway/models/agent"
"gateway/models/merchant"

View File

@@ -156,7 +156,6 @@ func GetMerchantLenByParams(params map[string]string) int {
}
cnt, err := qs.Limit(-1).Count()
if err != nil {
logs.Error("get merchant len by params fail: ", err)
}
@@ -186,7 +185,6 @@ func GetMerchantByPasskey(payKey string) MerchantInfo {
func UpdateMerchant(merchantInfo MerchantInfo) bool {
o := orm.NewOrm()
_, err := o.Update(&merchantInfo)
if err != nil {
logs.Error("update merchant fail: ", err)
return false

View File

@@ -14,6 +14,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
)
@@ -82,7 +83,6 @@ func (m *MerchantDeployInfo) GetFactMMValue(showMMValue float64) (float64, error
func (m *MerchantDeployInfo) GetSingleRoadPlatformRateByPrice(price float64) (float64, error) {
mapping, err := m.GetSingleRoadPlatformRateMapping()
if err != nil {
return 0.0, err
}
@@ -101,7 +101,7 @@ func (m *MerchantDeployInfo) CheckSingleRoadPlatformRate(price float64) bool {
return false
}
for k, _ := range mapping {
for k := range mapping {
if k == price {
return true
}
@@ -119,7 +119,6 @@ func GetMerchantDeployByUidAndPayType(uid, payType string) MerchantDeployInfo {
Filter("merchant_uid", uid).Filter("pay_type", payType).
Limit(1).
All(&merchantDeployInfo)
if err != nil {
logs.Error("get merchant deploy by uid and paytype fail:", err)
}
@@ -134,7 +133,6 @@ func GetMerchantDeployByUidAndRoadUid(uid, roadUid string) *MerchantDeployInfo {
Filter("merchant_uid", uid).Filter("single_road_uid", roadUid).
Limit(1).
All(merchantDeployInfo)
if err != nil {
logs.Error("get merchant deploy by uid and paytype fail:", err)
}

View File

@@ -16,7 +16,7 @@ import (
type NotifyInfo struct {
Id int
Type string //订单-order代付-payfor
Type string // 订单-order代付-payfor
BankOrderId string
MerchantOrderId string
Status string
@@ -65,7 +65,6 @@ func GetNotifyInfosNotSuccess(params map[string]interface{}) []NotifyInfo {
}
qs = qs.Exclude("status", "success")
_, err := qs.Limit(-1).All(&notifyInfoList)
if err != nil {
logs.Error("get notifyinfos fail: ", err)
}

View File

@@ -2,46 +2,48 @@ package order
import (
"fmt"
"strconv"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"strconv"
)
type OrderInfo struct {
Id int
ShopName string //商品名称
OrderPeriod string //订单有效时间
MerchantOrderId string //商户订单id
BankOrderId string //本系统订单id
BankTransId string //上游流水id
OrderAmount float64 //订单提交的金额
ShowAmount float64 //待支付的金额
FactAmount float64 //用户实际支付金额
RollPoolCode string //轮询池编码
RollPoolName string //轮询池名称
RoadUid string //通道标识
RoadName string //通道名称
PayProductName string //上游支付公司的名称
PayProductCode string //上游支付公司的编码代号
PayTypeCode string //支付产品编码
PayTypeName string //支付产品名称
OsType string //操作系统类型
Status string //订单支付状态
Refund string //退款状态
RefundTime string //退款操作时间
Freeze string //冻结状态
FreezeTime string //冻结时间
Unfreeze string //是否已经解冻
UnfreezeTime string //解冻时间
NotifyUrl string //下游回调地址
MerchantUid string //商户id
MerchantName string //商户名称
AgentUid string //该商户所属代理
AgentName string //该商户所属代理名称
ExValue string //扩展属性
ShopName string // 商品名称
OrderPeriod string // 订单有效时间
MerchantOrderId string // 商户订单id
BankOrderId string // 本系统订单id
BankTransId string // 上游流水id
OrderAmount float64 // 订单提交的金额
ShowAmount float64 // 待支付的金额
FactAmount float64 // 用户实际支付金额
RollPoolCode string // 轮询池编码
RollPoolName string // 轮询池名称
RoadUid string // 通道标识
RoadName string // 通道名称
PayProductName string // 上游支付公司的名称
PayProductCode string // 上游支付公司的编码代号
PayTypeCode string // 支付产品编码
PayTypeName string // 支付产品名称
OsType string // 操作系统类型
Status string // 订单支付状态
Refund string // 退款状态
RefundTime string // 退款操作时间
Freeze string // 冻结状态
FreezeTime string // 冻结时间
Unfreeze string // 是否已经解冻
UnfreezeTime string // 解冻时间
NotifyUrl string // 下游回调地址
MerchantUid string // 商户id
MerchantName string // 商户名称
AgentUid string // 该商户所属代理
AgentName string // 该商户所属代理名称
ExValue string // 扩展属性
CardData string
UpdateTime string
CreateTime string
PayTime string // 用户支付时间
Operator string // 操作人
CardReturnData string // 卡片返回数据
}
@@ -231,3 +233,11 @@ func InsertCardReturnData(merchantOrderId, cardReturnData string) bool {
})
return err == nil
}
func InsertOrderExValue(merchantOrderId, exValue string) bool {
o := orm.NewOrm()
_, err := o.QueryTable(ORDER_INFO).Filter("merchant_order_id", merchantOrderId).Update(orm.Params{
"ex_value": exValue,
})
return err == nil
}

View File

@@ -11,8 +11,11 @@ package order
****************************************************/
import (
"context"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/shopspring/decimal"
)
type OrderProfitInfo struct {
@@ -29,17 +32,17 @@ type OrderProfitInfo struct {
MerchantOrderId string
BankOrderId string
BankTransId string
OrderAmount float64
ShowAmount float64
FactAmount float64
UserInAmount float64
SupplierRate float64
PlatformRate float64
AgentRate float64
AllProfit float64
SupplierProfit float64
PlatformProfit float64
AgentProfit float64
OrderAmount decimal.Decimal
ShowAmount decimal.Decimal
FactAmount decimal.Decimal
UserInAmount decimal.Decimal
SupplierRate decimal.Decimal
PlatformRate decimal.Decimal
AgentRate decimal.Decimal
AllProfit decimal.Decimal
SupplierProfit decimal.Decimal
PlatformProfit decimal.Decimal
AgentProfit decimal.Decimal
UpdateTime string
CreateTime string
}
@@ -56,6 +59,16 @@ func GetOrderProfitByBankOrderId(bankOrderId string) OrderProfitInfo {
return orderProfit
}
func GetOrderProfitByMerchantOrderId(merchantOrderId string) OrderProfitInfo {
o := orm.NewOrm()
var orderProfit OrderProfitInfo
_, err := o.QueryTable(ORDER_PROFIT_INFO).Filter("merchant_order_id", merchantOrderId).Limit(1).All(&orderProfit)
if err != nil {
logs.Error("GetOrderProfitByBankOrderId fail", err)
}
return orderProfit
}
func GetOrderProfitLenByMap(params map[string]string) int {
o := orm.NewOrm()
qs := o.QueryTable(ORDER_PROFIT_INFO)
@@ -119,3 +132,46 @@ func GetPlatformProfitByMap(params map[string]string) []models.PlatformProfit {
return platformProfitList
}
*/
// InsertOrderAndOrderProfit 插入支付订单记录和订单利润记录,保证一致性
func InsertOrderAndOrderProfit(orderInfo OrderInfo, orderProfitInfo OrderProfitInfo) bool {
o := orm.NewOrm()
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
})
if err != nil {
return false
}
return true
}
func SwitchOrderAndOrderProfitStatus(merchantOrderId, status string) bool {
o := orm.NewOrm()
err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
if _, err := txOrm.QueryTable(ORDER_INFO).Filter("merchant_order_id", merchantOrderId).Update(orm.Params{
"status": status,
}); err != nil {
logs.Error("insert orderInfo fail: ", err)
return err
}
if _, err := txOrm.QueryTable(ORDER_PROFIT_INFO).Filter("merchant_order_id", merchantOrderId).Update(orm.Params{
"status": status,
}); err != nil {
logs.Error("insert orderInfo fail: ", err)
return err
}
return nil
})
if err != nil {
return false
}
return true
}

View File

@@ -13,6 +13,7 @@ package order
import (
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/shopspring/decimal"
)
type OrderSettleInfo struct {
@@ -26,7 +27,7 @@ type OrderSettleInfo struct {
MerchantName string
MerchantOrderId string
BankOrderId string
SettleAmount float64
SettleAmount decimal.Decimal
IsAllowSettle string
IsCompleteSettle string
UpdateTime string

View File

@@ -1,15 +1,5 @@
package order
/***************************************************
** @Desc : This file for ...
** @Time : 2019/12/17 17:50
** @Author : yuebin
** @File : platform_profit
** @Last Modified by : yuebin
** @Last Modified time: 2019/12/17 17:50
** @Software: GoLand
****************************************************/
type PlatformProfit struct {
MerchantName string
AgentName string

View File

@@ -73,7 +73,6 @@ func GetPayForByBankOrderId(bankOrderId string) PayforInfo {
o := orm.NewOrm()
var payFor PayforInfo
_, err := o.QueryTable(PAYFORINFO).Filter("bank_order_id", bankOrderId).Limit(1).All(&payFor)
if err != nil {
logs.Error("get pay for by bank_order_id fail: ", err)
}
@@ -86,7 +85,6 @@ func GetPayForByMerchantOrderId(merchantOrderId string) PayforInfo {
var payFor PayforInfo
_, err := o.QueryTable(PAYFORINFO).Filter("merchant_order_id", merchantOrderId).Limit(1).All(&payFor)
if err != nil {
logs.Error("fail: ", err)
}
@@ -97,7 +95,6 @@ func GetPayForByMerchantOrderId(merchantOrderId string) PayforInfo {
func UpdatePayFor(payFor PayforInfo) bool {
o := orm.NewOrm()
_, err := o.Update(&payFor)
if err != nil {
logs.Error("update pay for fail", err)
return false

View File

@@ -121,7 +121,6 @@ func GetAllRoad(params map[string]string) []RoadInfo {
func InsertRoadInfo(roadInfo RoadInfo) bool {
o := orm.NewOrm()
_, err := o.Insert(&roadInfo)
if err != nil {
logs.Error("insert road info fail: ", err)
return false

View File

@@ -1,12 +1,3 @@
/***************************************************
** @Desc : This file for ...
** @Time : 2019/9/9 16:35
** @Author : yuebin
** @File : road_pool_info
** @Last Modified by : yuebin
** @Last Modified time: 2019/9/9 16:35
** @Software: GoLand
****************************************************/
package road
import (
@@ -71,7 +62,6 @@ func GetRoadPoolByRoadPoolCode(roadPoolCode string) RoadPoolInfo {
o := orm.NewOrm()
var roadPoolInfo RoadPoolInfo
_, err := o.QueryTable(ROAD_POOL_INFO).Filter("road_pool_code", roadPoolCode).Limit(1).All(&roadPoolInfo)
if err != nil {
logs.Error("get road pool info by road pool code fail: ", err)
}
@@ -118,7 +108,6 @@ func DeleteRoadPoolByCode(roadPoolCode string) bool {
func UpdateRoadPool(roadPool RoadPoolInfo) bool {
o := orm.NewOrm()
_, err := o.Update(&roadPool)
if err != nil {
logs.Error("update road pool fail: ", err)
return false

View File

@@ -26,11 +26,11 @@ const (
func GetMsgCodeMapping(msg MsgModel) (code OrderMsgCode) {
mapping := map[OrderMsgCode][]MsgModel{
OrderNotExistCode: []MsgModel{OrderNotExist},
OrderSuccessCode: []MsgModel{RemoteSuccess, OrderFinished},
OrderHandleErrorCode: []MsgModel{DataErr, RemoteDataErr, RemoteDataHandErr, RemoteDataHealingErr},
OrderHandlingCode: []MsgModel{RemoteDataDealing},
OrderCardMsgErrorCode: []MsgModel{CardMsgErr},
OrderNotExistCode: {OrderNotExist},
OrderSuccessCode: {RemoteSuccess, OrderFinished},
OrderHandleErrorCode: {DataErr, RemoteDataErr, RemoteDataHandErr, RemoteDataHealingErr},
OrderHandlingCode: {RemoteDataDealing},
OrderCardMsgErrorCode: {CardMsgErr},
}
for msgCode, models := range mapping {

View File

@@ -36,7 +36,6 @@ const BANK_CARD_INFO = "bank_card_info"
func InsertBankCardInfo(bankCardInfo BankCardInfo) bool {
o := orm.NewOrm()
_, err := o.Insert(&bankCardInfo)
if err != nil {
logs.Error("insert bank card info fail: ", err)
return false
@@ -87,7 +86,6 @@ func GetBankCardByUid(uid string) BankCardInfo {
func DeleteBankCardByUid(uid string) bool {
o := orm.NewOrm()
_, err := o.QueryTable(BANK_CARD_INFO).Filter("uid", uid).Delete()
if err != nil {
logs.Error("delete bank card by uid fail: ", err)
return false

View File

@@ -38,7 +38,7 @@ func (m MenuInfoSlice) Swap(i, j int) {
}
func (m MenuInfoSlice) Less(i, j int) bool {
return m[i].MenuOrder < m[j].MenuOrder //从小到大排序
return m[i].MenuOrder < m[j].MenuOrder // 从小到大排序
}
const MENUINFO = "menu_info"

View File

@@ -63,7 +63,6 @@ func GetPower() []PowerInfo {
o := orm.NewOrm()
var powerInfo []PowerInfo
_, err := o.QueryTable(POWER_INFO).Limit(-1).All(&powerInfo)
if err != nil {
logs.Error("get power fail: ", err)
}
@@ -134,7 +133,6 @@ func DeletePowerItemByPowerID(powerID string) bool {
func DeletePowerBySecondUid(secondUid string) bool {
o := orm.NewOrm()
_, err := o.QueryTable(POWER_INFO).Filter("second_menu_uid", secondUid).Delete()
if err != nil {
logs.Error("delete power by second menu uid fail: ", err)
return false

View File

@@ -78,7 +78,6 @@ func GetRoleByRoleUid(roleUid string) RoleInfo {
o := orm.NewOrm()
var roleInfo RoleInfo
_, err := o.QueryTable(ROLE_INFO).Filter("role_uid", roleUid).Limit(1).All(&roleInfo)
if err != nil {
logs.Error("get role by role uid fail: ", err)
}
@@ -114,7 +113,6 @@ func DeleteRoleByRoleUid(roleUid string) bool {
func UpdateRoleInfo(roleInfo RoleInfo) bool {
o := orm.NewOrm()
_, err := o.Update(&roleInfo)
if err != nil {
logs.Error("update role info fail: ", err)
return false

View File

@@ -143,6 +143,7 @@ func GetSecondMenuByMap(params map[string]string, displayCount, offset int) []Se
}
return secondMenuList
}
func InsertSecondMenu(secondMenuInfo SecondMenuInfo) bool {
o := orm.NewOrm()
_, err := o.Insert(&secondMenuInfo)

View File

@@ -52,7 +52,6 @@ func GetOperatorByMap(params map[string]string, displayCount, offset int) []User
}
}
_, err := qs.Exclude("status", "delete").Limit(displayCount, offset).OrderBy("-update_time").All(&userInfo)
if err != nil {
logs.Error("get operator by map fail: ", err)
}
@@ -104,7 +103,6 @@ func UpdateUserInfo(userInfo UserInfo) {
func UpdateStauts(status, userId string) bool {
o := orm.NewOrm()
_, err := o.QueryTable(USERINFO).Filter("user_id", userId).Update(orm.Params{"status": status})
if err != nil {
logs.Error("update status fail: ", err)
return false
@@ -137,7 +135,6 @@ func InsertUser(userInfo UserInfo) bool {
func DeleteUserByUserId(userId string) bool {
o := orm.NewOrm()
_, err := o.QueryTable(USERINFO).Exclude("status", "delete").Filter("user_id", userId).Update(orm.Params{"status": "delete"})
if err != nil {
logs.Error("delete user by userId fail: ", err)
return false

View File

@@ -2,6 +2,10 @@ package notify
import (
"fmt"
"os"
"strings"
"time"
"gateway/config"
"gateway/message"
"gateway/models/notify"
@@ -9,9 +13,6 @@ import (
"github.com/beego/beego/v2/client/httplib"
"github.com/beego/beego/v2/core/logs"
"github.com/go-stomp/stomp/v3"
"os"
"strings"
"time"
)
type OrderNotifyTask struct {
@@ -21,11 +22,11 @@ type OrderNotifyTask struct {
FirstNotifyTime string
NotifyTimes int
LimitTimes int
Status string //success-通知成功,其余的为待通知或者通知未完成
Status string // success-通知成功,其余的为待通知或者通知未完成
}
const (
LimitTimes = 5 //最多通知5次
LimitTimes = 5 // 最多通知5次
)
// SendOrderNotify 给商户发送订单结果
@@ -64,9 +65,11 @@ func SendOrderNotify(bankOrderId string) {
} else {
minute := GetOrderNotifyMinute(notifyInfo.Times)
logs.Info(fmt.Sprintf("bankOrderId = %s, 进行第 %d 次回调,本次延时时间为:%d", notifyInfo.BankOrderId, notifyInfo.Times, minute))
task := OrderNotifyTask{Delay: time.NewTimer(time.Duration(minute) * time.Minute),
task := OrderNotifyTask{
Delay: time.NewTimer(time.Duration(minute) * time.Minute),
MerchantOrderId: notifyInfo.MerchantOrderId, BankOrderId: notifyInfo.BankOrderId, FirstNotifyTime: notifyInfo.CreateTime,
NotifyTimes: notifyInfo.Times, LimitTimes: LimitTimes, Status: notifyInfo.Status}
NotifyTimes: notifyInfo.Times, LimitTimes: LimitTimes, Status: notifyInfo.Status,
}
go OrderNotifyTimer(task)
if !notify.UpdateNotifyInfo(notifyInfo) {
logs.Error("订单回调失败,数据库更新失败:" + bankOrderId)
@@ -140,7 +143,7 @@ func CreateOrderDelayQueue() {
// CreateOrderNotifyConsumer 创建订单回调消费者
func CreateOrderNotifyConsumer() {
CreateOrderDelayQueue()
//启动定时任务
// 启动定时任务
conn := message.GetActiveMQConn()
if conn == nil {
logs.Error("启动消息队列消费者失败....")
@@ -159,7 +162,7 @@ func CreateOrderNotifyConsumer() {
if v != nil {
bankOrderId := string(v.Body)
go SendOrderNotify(bankOrderId)
//应答,重要
// 应答,重要
err := conn.Ack(v)
if err != nil {
logs.Error("消息应答失败!")

View File

@@ -4,6 +4,9 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"gateway/config"
"gateway/message"
"gateway/models/accounts"
@@ -16,13 +19,10 @@ import (
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"github.com/rs/xid"
"strconv"
"strings"
)
// AutoPayFor 程序自动代付
func AutoPayFor(params map[string]string, giveType string) *response.PayForResponse {
payForResponse := new(response.PayForResponse)
merchantInfo := merchant.GetMerchantByPasskey(params["merchantKey"])
@@ -104,14 +104,12 @@ func AutoPayFor(params map[string]string, giveType string) *response.PayForRespo
return payForResponse
}
}
/**
* 返回1表示需要手动打款返回0表示银行已经受理-1表示系统处理失败
*/
func findPayForRoad(p payfor.PayforInfo) bool {
m := merchant.GetMerchantByUid(p.MerchantUid)
// 检查商户是否设置了自动代付
if m.AutoPayFor == config.NO || m.AutoPayFor == "" {
@@ -180,7 +178,6 @@ func MerchantSelf(p payfor.PayforInfo) bool {
o := orm.NewOrm()
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
p.UpdateTime = utils.GetBasicDateTime()
p.Status = config.PAYFOR_BANKING
p.RequestTime = utils.GetBasicDateTime()
@@ -192,7 +189,6 @@ func MerchantSelf(p payfor.PayforInfo) bool {
RequestPayFor(p)
return nil
}); err != nil {
return false
}
@@ -203,14 +199,13 @@ func SendPayFor(p payfor.PayforInfo) bool {
o := orm.NewOrm()
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
var account accounts.AccountInfo
if err := txOrm.Raw("select * from account_info where account_uid = ? for update", p.MerchantUid).QueryRow(&account); err != nil || account.AccountUid == "" {
logs.Error("send payfor select account fail", err)
return err
}
//支付金额不足,将直接判定为失败,不往下面邹逻辑了
// 支付金额不足,将直接判定为失败,不往下面邹逻辑了
if account.SettleAmount-account.PayforAmount < p.PayforAmount+p.PayforFee {
p.Status = config.PAYFOR_FAIL
p.UpdateTime = utils.GetBasicDateTime()
@@ -231,7 +226,7 @@ func SendPayFor(p payfor.PayforInfo) bool {
}
p.IsSend = config.YES
p.Status = config.PAYFOR_BANKING //变为银行处理中
p.Status = config.PAYFOR_BANKING // 变为银行处理中
p.GiveType = config.PAYFOR_ROAD
p.RequestTime = utils.GetBasicDateTime()
p.UpdateTime = utils.GetBasicDateTime()
@@ -260,7 +255,7 @@ func RequestPayFor(p payfor.PayforInfo) {
supplier := third_party.GetPaySupplierByCode(supplierCode)
res := supplier.PayFor(p)
logs.Info(fmt.Sprintf("代付uid=%s上游处理结果为%s", p.PayforUid, res))
//将代付订单号发送到消息队列
// 将代付订单号发送到消息队列
message.SendMessage(config.MQ_PAYFOR_QUERY, p.BankOrderId)
}
@@ -314,7 +309,6 @@ func PayForResultQuery(params map[string]string) string {
// BalanceQuery 商户查询余额
func BalanceQuery(params map[string]string) string {
balanceResponse := new(response.BalanceResponse)
str := ""
merchantInfo := merchant.GetMerchantByPasskey(params["merchantKey"])

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"gateway/config"
"gateway/models/accounts"
"gateway/models/payfor"
@@ -13,10 +14,8 @@ import (
)
func PayForFail(p payfor.PayforInfo) bool {
o := orm.NewOrm()
if err := o.DoTx(func(ctx context.Context, txOrm orm.TxOrmer) error {
var tmpForPay payfor.PayforInfo
if err := txOrm.Raw(
"select * from payfor_info where bank_order_id = ? for update", p.BankOrderId).
@@ -30,7 +29,7 @@ func PayForFail(p payfor.PayforInfo) bool {
logs.Error(fmt.Sprintf("该代付订单uid=%s状态已经是最终结果", tmpForPay.PayforUid))
return errors.New("状态已经是最终结果")
}
//更新payfor记录的状态
// 更新payfor记录的状态
tmpForPay.Status = config.PAYFOR_FAIL
tmpForPay.UpdateTime = utils.GetBasicDateTime()
if _, err := txOrm.Update(&tmpForPay); err != nil {
@@ -53,7 +52,7 @@ func PayForFail(p payfor.PayforInfo) bool {
logs.Error(fmt.Sprintf("商户uid=%s账户中待代付金额小于代付记录的金额", tmpForPay.MerchantUid))
return errors.New("账户中待代付金额小于代付记录的金额")
}
//将正在打款中的金额减去
// 将正在打款中的金额减去
account.PayforAmount = account.PayforAmount - tmpForPay.PayforTotalAmount
if _, err := txOrm.Update(&account); err != nil {
@@ -62,7 +61,6 @@ func PayForFail(p payfor.PayforInfo) bool {
}
return nil
}); err != nil {
return false
}
@@ -108,11 +106,11 @@ func PayForSuccess(p payfor.PayforInfo) bool {
return errors.New("账户中待代付金额小于代付记录的金额")
}
//代付打款中的金额减去
// 代付打款中的金额减去
account.PayforAmount = account.PayforAmount - tmpPayFor.PayforTotalAmount
//减去余额,减去可用金额
// 减去余额,减去可用金额
account.Balance = account.Balance - tmpPayFor.PayforTotalAmount
//已结算金额减去
// 已结算金额减去
account.SettleAmount = account.SettleAmount - tmpPayFor.PayforTotalAmount
if _, err := txOrm.Update(&account); err != nil {
@@ -120,7 +118,7 @@ func PayForSuccess(p payfor.PayforInfo) bool {
return err
}
//添加一条动账记录
// 添加一条动账记录
accountHistory := accounts.AccountHistoryInfo{
AccountUid: tmpPayFor.MerchantUid,
AccountName: tmpPayFor.MerchantName,

View File

@@ -13,12 +13,13 @@ package query
import (
"encoding/json"
"fmt"
"strings"
"gateway/models/merchant"
"gateway/models/order"
"gateway/utils"
"github.com/beego/beego/v2/core/logs"
"github.com/beego/beego/v2/server/web"
"strings"
)
type MerchantQueryController struct {

View File

@@ -11,6 +11,9 @@ package query
****************************************************/
import (
"fmt"
"os"
"time"
"gateway/config"
"gateway/message"
"gateway/models/payfor"
@@ -20,8 +23,6 @@ import (
"gateway/utils"
"github.com/beego/beego/v2/core/logs"
"github.com/go-stomp/stomp/v3"
"os"
"time"
)
type PayForQueryTask struct {
@@ -35,8 +36,8 @@ type PayForQueryTask struct {
}
const (
PayForLimitTimes = 12 //最多查询次数
PayForQueryInterval = 5 //时间间隔为5分钟
PayForLimitTimes = 12 // 最多查询次数
PayForQueryInterval = 5 // 时间间隔为5分钟
)
func PayForQueryTimer(task PayForQueryTask) {
@@ -46,7 +47,7 @@ func PayForQueryTimer(task PayForQueryTask) {
PayForSupplier(task)
task.Delay.Stop()
return
//70分钟没有执行该协程那么退出协程
// 70分钟没有执行该协程那么退出协程
case <-time.After(time.Minute * 70):
return
}
@@ -65,13 +66,13 @@ func PayForSupplier(task PayForQueryTask) {
}
res, _ := supplier.PayForQuery(payFor)
if res == config.PAYFOR_SUCCESS {
//代付成功了
// 代付成功了
pay_for.PayForSuccess(payFor)
} else if res == config.PAYFOR_FAIL {
//代付失败
// 代付失败
pay_for.PayForFail(payFor)
} else if res == config.PAYFOR_BANKING {
//银行处理中,那么就继续执行查询,直到次数超过最大次数
// 银行处理中,那么就继续执行查询,直到次数超过最大次数
if task.QueryTimes <= task.LimitTimes {
task.QueryTimes += 1
task.Delay = time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute)
@@ -96,15 +97,17 @@ func payForQueryConsumer(bankOrderId string) {
return
}
payForQueryTask := PayForQueryTask{Delay: time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute), MerchantOrderId: payFor.MerchantOrderId,
BankOrderId: payFor.BankOrderId, FirstNotifyTime: utils.GetBasicDateTime(), QueryTimes: 1, LimitTimes: PayForLimitTimes, Status: payFor.Status}
payForQueryTask := PayForQueryTask{
Delay: time.NewTimer(time.Duration(PayForQueryInterval) * time.Minute), MerchantOrderId: payFor.MerchantOrderId,
BankOrderId: payFor.BankOrderId, FirstNotifyTime: utils.GetBasicDateTime(), QueryTimes: 1, LimitTimes: PayForLimitTimes, Status: payFor.Status,
}
go PayForQueryTimer(payForQueryTask)
}
// CreatePayForQueryConsumer 创建代付查询的消费者
func CreatePayForQueryConsumer() {
//启动定时任务
// 启动定时任务
conn := message.GetActiveMQConn()
if conn == nil {
logs.Error("启动消息队列消费者失败....")
@@ -125,7 +128,7 @@ func CreatePayForQueryConsumer() {
if v != nil {
bankOrderId := string(v.Body)
go payForQueryConsumer(bankOrderId)
//应答,重要
// 应答,重要
err := conn.Ack(v)
if err != nil {
logs.Error("消息应答失败!")

View File

@@ -12,6 +12,9 @@ package query
import (
"fmt"
"os"
"time"
"gateway/config"
"gateway/message"
"gateway/models/order"
@@ -20,8 +23,6 @@ import (
"gateway/supplier/third_party"
"github.com/beego/beego/v2/core/logs"
"github.com/go-stomp/stomp/v3"
"os"
"time"
)
type OrderQueryTask struct {
@@ -31,8 +32,8 @@ type OrderQueryTask struct {
}
const (
DelayTime = 5 //延时时间为5分钟查询一次
LimitTimes = 5 //最多查询5次
DelayTime = 5 // 延时时间为5分钟查询一次
LimitTimes = 5 // 最多查询5次
)
func SupplierOrderQueryResult(bankOrderId string) supply_model.MsgModel {
@@ -112,7 +113,7 @@ func CreateSupplierOrderQueryCuConsumer() {
logs.Info("消费者正在处理订单查询: " + bankOrderId)
task := OrderQueryTask{BankOrderId: bankOrderId, OrderQueryTimer: time.NewTimer(time.Second * 1), Times: 1}
DelayOrderQueryQueue(task)
//应答,重要
// 应答,重要
err := conn.Ack(v)
if err != nil {
logs.Error("消息应答失败!")

View File

@@ -1 +1,29 @@
package request
import (
"strconv"
)
type CreatedOrder struct {
PayKey string `json:"payKey" description:"用户key"`
OrderNo string `json:"orderNo" description:"订单号"`
OrderPrice float64 `json:"orderPrice" description:"订单金额"`
PayWayCode string `json:"payWayCode" description:"下游支付通道"`
OsType string `json:"osType" description:"操作系统"`
OrderPeriod string `json:"orderPeriod" description:"订单周期"`
NotifyUrl string `json:"notifyUrl" description:"回调地址"`
Sign string `json:"Sign" description:"签名"`
}
// ToMap 转换为map类型
func (c *CreatedOrder) ToMap() map[string]string {
var data map[string]string
data["payKey"] = c.PayKey
data["orderNo"] = c.OrderNo
data["orderPrice"] = strconv.FormatFloat(c.OrderPrice, 'g', -1, 64)
data["osType"] = c.OsType
data["orderPeriod"] = c.OrderPeriod
data["notifyUrl"] = c.NotifyUrl
data["payWayCode"] = c.PayWayCode
return data
}

View File

@@ -6,11 +6,11 @@ import (
)
type PayBaseResp struct {
Params map[string]string //请求的基本参数
ClientIP string //商户ip
MerchantInfo merchant.MerchantInfo //商户信息
Msg string //信息
Code int //状态码 200正常
Params map[string]string // 请求的基本参数
ClientIP string // 商户ip
MerchantInfo merchant.MerchantInfo // 商户信息
Msg string // 信息
Code int // 状态码 200正常
RoadInfo road.RoadInfo
RoadPoolInfo road.RoadPoolInfo
OrderAmount float64

View File

@@ -1,8 +1,6 @@
package response
/**
* 返回自动代付结果
*/
// PayForResponse 返回自动代付结果
type PayForResponse struct {
ResultCode string `json:"resultCode,omitempty"`
ResultMsg string `json:"resultMsg,omitempty"`
@@ -12,9 +10,7 @@ type PayForResponse struct {
Sign string `json:"sign,omitempty"`
}
/**
* 返回商户代付结果查询结果
*/
// PayForQueryResponse 返回商户代付结果查询结果
type PayForQueryResponse struct {
ResultMsg string `json:"resultMsg,omitempty"`
MerchantOrderId string `json:"merchantOrderId,omitempty"`
@@ -24,9 +20,7 @@ type PayForQueryResponse struct {
Sign string `json:"sign,omitempty"`
}
/**
* 返回商户查询余额结果
*/
// BalanceResponse 返回商户查询余额结果
type BalanceResponse struct {
ResultCode string `json:"resultCode,omitempty"`
Balance string `json:"balance,omitempty"`

View File

@@ -7,22 +7,24 @@ import (
)
func init() {
//网关处理函数
// 网关处理函数
web.Router("/gateway/scan", &gateway.ScanController{}, "*:Scan")
web.Router("/err/params", &gateway.ErrorGatewayController{}, "*:ErrorParams")
web.Router("/gateway/getAllowedMM", &gateway.ScanController{}, "*:GetAllowedMM")
//代付相关的接口
web.Router("/gateway/createOrder", &gateway.ScanController{}, "*:CreateOrder")
// 代付相关的接口
web.Router("/gateway/payfor", &gateway.PayForGateway{}, "*:PayFor")
web.Router("/gateway/payfor/query", &gateway.PayForGateway{}, "*:PayForQuery")
web.Router("/gateway/balance", &gateway.PayForGateway{}, "*:Balance")
web.Router("/gateway/supplier/payfor/query", &gateway.PayForGateway{}, "*:QuerySupplierPayForResult")
web.Router("/solve/payfor/result", &gateway.PayForGateway{}, "*:SolvePayForResult")
// 接收回调
//web.Router("/daili/notify", &third_party.DaiLiImpl{}, "*:PayNotify")
//web.Router("/mfcard/notify", &third_party.MFCardImpl{}, "*:PayNotify")
//web.Router("/mfcard/test", &third_party.MFCardImpl{}, "*:Test")
// web.Router("/daili/notify", &third_party.DaiLiImpl{}, "*:PayNotify")
// web.Router("/mfcard/notify", &third_party.MFCardImpl{}, "*:PayNotify")
// web.Router("/mfcard/test", &third_party.MFCardImpl{}, "*:Test")
web.Router("/mfcard/notifyV2", &third_party.MFCardV2Impl{}, "*:PayNotify")
web.Router("/gateway/supplier/order/query", &gateway.OrderController{}, "*:OrderQuery")
@@ -30,7 +32,7 @@ func init() {
web.Router("/gateway/merchant/query", &gateway.OrderController{}, "*:MerchantQuery")
//网关可视化
//web.Router("/order/create", &gateway.OrderController{}, "*:OrderCreate")
//web.Router("/order/cardsuit", &gateway.OrderController{}, "*:CardSuit")
// 网关可视化
// web.Router("/order/create", &gateway.OrderController{}, "*:OrderCreate")
// web.Router("/order/cardsuit", &gateway.OrderController{}, "*:CardSuit")
}

View File

@@ -1,17 +1,16 @@
package service
import (
"context"
"errors"
"strconv"
"strings"
"gateway/config"
"gateway/models/merchant"
"gateway/models/merchant_deploy"
"gateway/models/order"
"gateway/response"
"github.com/beego/beego/v2/client/orm"
"github.com/beego/beego/v2/core/logs"
"strconv"
"strings"
)
// GetMerchantInfoByUID 获取商户信息
@@ -48,7 +47,6 @@ func GetMerchantInfoByPayKey(payKey string) (merchantInfo merchant.MerchantInfo,
// GetMerchantInfo 获取商户信息
func GetMerchantInfo(params map[string]string) *response.PayBaseResp {
c := new(response.PayBaseResp)
c.Params = make(map[string]string)
c.Params = params
@@ -74,33 +72,12 @@ func JudgeParams(c *response.PayBaseResp) *response.PayBaseResp {
c = OsTypeIsValid(c)
c = PayWayCodeIsValid(c)
c = OrderPeriodIsValid(c)
//c = IpIsWhite()
// c = IpIsWhite()
c = OrderPriceIsValid(c)
return c
}
// InsertOrderAndOrderProfit 插入支付订单记录和订单利润记录,保证一致性
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
}
// NotifyUrlIsValid 判断回调地址是否符合规则
func NotifyUrlIsValid(c *response.PayBaseResp) *response.PayBaseResp {
if c.Params["notifyUrl"] == "" || len(c.Params["notifyUrl"]) == 0 {
@@ -192,7 +169,7 @@ func OrderIsValid(c *response.PayBaseResp) *response.PayBaseResp {
// IpIsWhite 判断ip是否在白名单中
func IpIsWhite() bool {
//TODO
// TODO
return true
}

View File

@@ -3,18 +3,22 @@ package service
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
"gateway/config"
"gateway/models/merchant"
"gateway/models/merchant_deploy"
"gateway/models/order"
"gateway/models/road"
"gateway/request"
"gateway/response"
"gateway/supplier"
"gateway/utils"
"github.com/beego/beego/v2/core/logs"
"github.com/rs/xid"
"strconv"
"strings"
"time"
"github.com/shopspring/decimal"
)
func ChooseRoadWith(payWayCode, merchantUid string) (roadInfo road.RoadInfo, roadPoolInfo road.RoadPoolInfo, err error) {
@@ -32,7 +36,6 @@ func ChooseRoadWith(payWayCode, merchantUid string) (roadInfo road.RoadInfo, roa
func ChooseRoad(c *response.PayBaseResp) *response.PayBaseResp {
payWayCode := c.Params["payWayCode"]
orderPrice, err := strconv.ParseFloat(c.Params["orderPrice"], 64)
if err != nil {
c.Code = -1
c.Msg = "输入金额错误!"
@@ -41,7 +44,7 @@ func ChooseRoad(c *response.PayBaseResp) *response.PayBaseResp {
merchantUid := c.MerchantInfo.MerchantUid
//通道配置信息
// 通道配置信息
deployInfo := merchant_deploy.GetMerchantDeployByUidAndPayType(merchantUid, payWayCode)
if deployInfo.MerchantUid == "" {
@@ -76,7 +79,7 @@ func ChooseRoad(c *response.PayBaseResp) *response.PayBaseResp {
c.Code = -1
c.Msg = msg
}
//如果单通道没有有效的,那么寻找通道池里面的通道
// 如果单通道没有有效的,那么寻找通道池里面的通道
if c.RoadPoolInfo.RoadPoolCode == "" {
c.Code = -1
c.Msg = "该商户没有配置通道"
@@ -135,7 +138,7 @@ func RoadIsValid(roadInfo road.RoadInfo, c *response.PayBaseResp) (string, bool)
logs.Error(FORMAT + "达到了总量限制")
return "订单金额达到总量限制", false
}
//如果通道被选中,那么总请求数+1
// 如果通道被选中,那么总请求数+1
roadInfo.RequestAll = roadInfo.RequestAll + 1
roadInfo.TodayRequestAll = roadInfo.RequestAll + 1
roadInfo.UpdateTime = utils.GetBasicDateTime()
@@ -145,9 +148,9 @@ func RoadIsValid(roadInfo road.RoadInfo, c *response.PayBaseResp) (string, bool)
// GenerateOrderInfo 获取基本订单记录
func GenerateOrderInfo(c *response.PayBaseResp) order.OrderInfo {
//6666是自己系统订单号
// 6666是自己系统订单号
bankOrderNo := "6666" + xid.New().String()
//获取支付类型的名称,例如支付宝扫码等
// 获取支付类型的名称,例如支付宝扫码等
payTypeName := config.GetNameByPayWayCode(c.Params["payWayCode"])
orderInfo := order.OrderInfo{
MerchantUid: c.MerchantInfo.MerchantUid,
@@ -185,21 +188,58 @@ func GenerateOrderInfo(c *response.PayBaseResp) order.OrderInfo {
return orderInfo
}
// CreateOrderInfo 创建订单
func CreateOrderInfo(createdOrder request.CreatedOrder, info merchant.MerchantInfo, roadPoolInfo road.RoadPoolInfo, roadInfo road.RoadInfo) (orderInfo order.OrderInfo, err error) {
// 6666是自己系统订单号
orderInfo = order.OrderInfo{}
// 获取支付类型的名称,例如支付宝扫码等
payTypeName := config.GetNameByPayWayCode(createdOrder.PayWayCode)
orderInfo = order.OrderInfo{
MerchantUid: info.MerchantUid,
MerchantName: info.MerchantName,
MerchantOrderId: createdOrder.OrderNo,
BankOrderId: "6666" + xid.New().String(),
OrderAmount: createdOrder.OrderPrice,
FactAmount: createdOrder.OrderPrice,
ShowAmount: createdOrder.OrderPrice,
RollPoolCode: roadPoolInfo.RoadPoolCode,
RollPoolName: roadPoolInfo.RoadPoolName,
RoadUid: roadInfo.RoadUid,
RoadName: roadInfo.RoadName,
PayProductName: roadInfo.ProductName,
Freeze: config.NO,
Refund: config.NO,
Unfreeze: config.NO,
PayProductCode: roadInfo.ProductUid,
PayTypeCode: createdOrder.PayWayCode,
PayTypeName: payTypeName,
OsType: createdOrder.OsType,
Status: config.Created,
NotifyUrl: createdOrder.NotifyUrl,
OrderPeriod: createdOrder.OrderPeriod,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
}
return
}
// GenerateOrderProfit 计算收益,平台利润,代理利润
func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) order.OrderProfitInfo {
//因为所有的手续费率都是百分率所以需要除以100
// 因为所有的手续费率都是百分率所以需要除以100
payTypeName := config.GetNameByPayWayCode(c.PayWayCode)
supplierProfit := c.OrderAmount / 100 * c.RoadInfo.BasicFee
platformProfit := c.OrderAmount / 100 * c.PlatformRate //平台费率
agentProfit := c.OrderAmount / 100 * c.AgentRate //代理费率
//如果用户没有设置代理那么代理利润为0.000
supplierProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(c.RoadInfo.BasicFee))
platformProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(c.PlatformRate))
agentProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(c.AgentRate))
// 如果用户没有设置代理那么代理利润为0.000
if c.MerchantInfo.BelongAgentUid == "" || len(c.MerchantInfo.BelongAgentUid) == 0 {
agentProfit = config.ZERO
agentProfit = decimal.NewFromFloat(config.ZERO)
}
allProfit := supplierProfit + platformProfit + agentProfit
allProfit := supplierProfit.Add(platformProfit).Add(agentProfit)
if allProfit >= c.OrderAmount {
if allProfit.GreaterThanOrEqual(decimal.NewFromFloat(orderInfo.OrderAmount)) {
logs.Error("手续费已经超过订单金额bankOrderId = %s", orderInfo.BankOrderId)
c.Msg = "手续费已经超过了订单金额"
c.Code = -1
@@ -213,11 +253,11 @@ func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) ord
Status: config.WAIT,
MerchantOrderId: c.Params["orderNo"],
BankOrderId: orderInfo.BankOrderId,
OrderAmount: c.OrderAmount,
FactAmount: c.OrderAmount,
ShowAmount: c.OrderAmount,
OrderAmount: decimal.NewFromFloat(c.OrderAmount),
FactAmount: decimal.NewFromFloat(c.OrderAmount),
ShowAmount: decimal.NewFromFloat(c.OrderAmount),
AllProfit: allProfit,
UserInAmount: c.OrderAmount - allProfit,
UserInAmount: decimal.NewFromFloat(orderInfo.OrderAmount).Sub(allProfit),
SupplierProfit: supplierProfit,
PlatformProfit: platformProfit,
AgentProfit: agentProfit,
@@ -225,14 +265,14 @@ func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) ord
CreateTime: utils.GetBasicDateTime(),
MerchantUid: c.MerchantInfo.MerchantUid,
MerchantName: orderInfo.MerchantName,
SupplierRate: c.RoadInfo.BasicFee,
PlatformRate: c.PlatformRate,
AgentRate: c.AgentRate,
SupplierRate: decimal.NewFromFloat(c.RoadInfo.BasicFee),
PlatformRate: decimal.NewFromFloat(c.PlatformRate),
AgentRate: decimal.NewFromFloat(c.AgentRate),
AgentName: orderInfo.AgentName,
AgentUid: orderInfo.AgentUid,
}
//如果该条订单设置了代理利率,并且设置了代理
// 如果该条订单设置了代理利率,并且设置了代理
if c.MerchantInfo.BelongAgentUid != "" || c.AgentRate > config.ZERO {
orderProfit.AgentUid = c.MerchantInfo.BelongAgentUid
orderProfit.AgentName = c.MerchantInfo.BelongAgentName
@@ -240,20 +280,83 @@ func GenerateOrderProfit(orderInfo order.OrderInfo, c *response.PayBaseResp) ord
return orderProfit
}
func CreateOrderProfitInfo(createdOrder request.CreatedOrder, merchantInfo merchant.MerchantInfo, merchantDeployInfo merchant_deploy.MerchantDeployInfo, orderInfo order.OrderInfo, roadInfo road.RoadInfo) (orderProfitInfo order.OrderProfitInfo, err error) {
// 因为所有的手续费率都是百分率所以需要除以100
payTypeName := config.GetNameByPayWayCode(createdOrder.PayWayCode)
platFormRate, err := merchantDeployInfo.GetSingleRoadPlatformRateByPrice(createdOrder.OrderPrice)
if err != nil {
platFormRate = 0.0
}
supplierProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(roadInfo.BasicFee))
platformProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(platFormRate))
agentProfit := decimal.NewFromFloat(orderInfo.OrderAmount).Div(decimal.NewFromInt(100)).Mul(decimal.NewFromFloat(merchantDeployInfo.SingleRoadAgentRate))
// 如果用户没有设置代理那么代理利润为0.000
if merchantInfo.BelongAgentUid == "" || len(merchantInfo.BelongAgentUid) == 0 {
agentProfit = decimal.NewFromFloat(config.ZERO)
}
allProfit := supplierProfit.Add(platformProfit).Add(agentProfit)
if allProfit.GreaterThanOrEqual(decimal.NewFromFloat(orderInfo.OrderAmount)) {
logs.Error("手续费已经超过订单金额bankOrderId = %s", orderInfo.BankOrderId)
err = errors.New("手续费已经超过订单金额")
return
}
orderProfitInfo = order.OrderProfitInfo{
PayProductCode: roadInfo.ProductUid,
PayProductName: roadInfo.ProductName,
PayTypeCode: createdOrder.PayWayCode,
PayTypeName: payTypeName,
Status: config.Created,
MerchantOrderId: createdOrder.OrderNo,
BankOrderId: orderInfo.BankOrderId,
OrderAmount: decimal.NewFromFloat(orderInfo.OrderAmount),
FactAmount: decimal.NewFromFloat(orderInfo.FactAmount),
ShowAmount: decimal.NewFromFloat(orderInfo.ShowAmount),
AllProfit: allProfit,
UserInAmount: decimal.NewFromFloat(orderInfo.OrderAmount).Sub(allProfit),
SupplierProfit: supplierProfit,
PlatformProfit: platformProfit,
AgentProfit: agentProfit,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
MerchantUid: merchantInfo.MerchantUid,
MerchantName: orderInfo.MerchantName,
SupplierRate: decimal.NewFromFloat(roadInfo.BasicFee),
PlatformRate: decimal.NewFromFloat(platFormRate),
AgentRate: decimal.NewFromFloat(merchantDeployInfo.SingleRoadAgentRate),
AgentName: orderInfo.AgentName,
AgentUid: orderInfo.AgentUid,
}
return
}
// GenerateRecord 生成订单一系列的记录
func GenerateRecord(c *response.PayBaseResp) (order.OrderInfo, order.OrderProfitInfo) {
//生成订单记录,订单利润利润
orderInfo := GenerateOrderInfo(c)
orderProfit := GenerateOrderProfit(orderInfo, c)
if c.Code == -1 {
return orderInfo, orderProfit
func GenerateRecord(c *response.PayBaseResp) (order.OrderInfo, order.OrderProfitInfo, error) {
// 获取订单和订单利润
orderInfo := order.GetOrderByMerchantOrderId(c.Params["orderNo"])
orderProfitInfo := order.GetOrderProfitByMerchantOrderId(c.Params["orderNo"])
if orderProfitInfo.Id == 0 || orderInfo.Id == 0 {
err := errors.New("订单不存在")
return orderInfo, orderProfitInfo, err
}
if !InsertOrderAndOrderProfit(orderInfo, orderProfit) {
c.Code = -1
return orderInfo, orderProfit
if !order.InsertOrderExValue(c.Params["orderNo"], c.Params["exValue"]) {
err := errors.New("订单数据插入失败")
return orderInfo, orderProfitInfo, err
}
if !SwitchOrderInfoIntoWait(orderInfo.MerchantOrderId) {
err := errors.New("订单状态转换失败")
return orderInfo, orderProfitInfo, err
}
logs.Info("插入支付订单记录和支付利润记录成功")
return orderInfo, orderProfit
return orderInfo, orderProfitInfo, nil
}
func GenerateSuccessData(scanData supplier.ScanData, c *response.PayBaseResp) *response.ScanSuccessData {
@@ -280,3 +383,41 @@ func GenerateSuccessData(scanData supplier.ScanData, c *response.PayBaseResp) *r
return scanSuccessData
}
func CreateOrderInfoAndOrderProfitInfo(createdOrder request.CreatedOrder, info merchant.MerchantInfo) (err error) {
merchantDeploy := merchant_deploy.GetMerchantDeployByUidAndPayType(info.MerchantUid, createdOrder.PayWayCode)
if merchantDeploy.Id == 0 {
err = errors.New("未配置支付方式")
return
}
roadPoolInfo := road.GetRoadPoolByRoadPoolCode(merchantDeploy.RollRoadCode)
if roadPoolInfo.Id == 0 {
err = errors.New("未配置支付方式")
return
}
roadInfo := road.GetRoadInfoByRoadUid(merchantDeploy.SingleRoadUid)
if roadInfo.Id == 0 {
err = errors.New("未配置支付方式")
return
}
orderInfo, err := CreateOrderInfo(createdOrder, info, roadPoolInfo, roadInfo)
if err != nil {
err = errors.New("创建订单失败")
return
}
orderProfitInfo, err := CreateOrderProfitInfo(createdOrder, info, merchantDeploy, orderInfo, roadInfo)
if err != nil {
err = errors.New("创建订单失败")
return
}
if !order.InsertOrderAndOrderProfit(orderInfo, orderProfitInfo) {
err = errors.New("创建订单失败")
return
}
return
}
// SwitchOrderInfoIntoWait 切换订单状态为待支付状态
func SwitchOrderInfoIntoWait(merchantOrderUid string) bool {
return true
}

View File

@@ -4,6 +4,9 @@ import (
"context"
"errors"
"fmt"
"net/url"
"strconv"
"gateway/config"
"gateway/message"
"gateway/models/accounts"
@@ -12,10 +15,10 @@ import (
"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"
"github.com/shopspring/decimal"
)
// SolvePaySuccess 处理支付成功的加款等各项操作
@@ -23,7 +26,6 @@ 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).
@@ -90,26 +92,29 @@ func SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool
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 {
Update((orm.Params{
"balance": orderProfitInfo.UserInAmount.Add(decimal.NewFromFloat(accountInfo.Balance)),
"wait_amount": orderProfitInfo.UserInAmount.Add(decimal.NewFromFloat(accountInfo.WaitAmount)),
})); 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: config.PLUS_AMOUNT,
OrderID: orderInfo.MerchantOrderId,
Amount: orderProfitInfo.UserInAmount,
Balance: accountInfo.Balance + orderProfitInfo.UserInAmount,
Amount: orderProfitInfo.UserInAmount.InexactFloat64(),
Balance: orderProfitInfo.UserInAmount.Add(decimal.NewFromFloat(accountInfo.Balance)).InexactFloat64(),
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
}
@@ -119,22 +124,22 @@ func SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool
return err
}
//更新通道信息
// 更新通道信息
roadInfo := road.GetRoadInfoByRoadUid(orderInfo.RoadUid)
roadInfo.RequestSuccess += 1
roadInfo.TodayRequestSuccess += 1 //今日成功
roadInfo.TodayRequestSuccess += 1 // 今日成功
roadInfo.TotalIncome += orderInfo.FactAmount
roadInfo.TodayIncome += orderInfo.FactAmount
roadInfo.TodayProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
roadInfo.TotalProfit += orderProfitInfo.PlatformProfit + orderProfitInfo.AgentProfit
roadInfo.TodayProfit += orderProfitInfo.PlatformProfit.Add(orderProfitInfo.AgentProfit).InexactFloat64()
roadInfo.TotalProfit += orderProfitInfo.PlatformProfit.Add(orderProfitInfo.AgentProfit).InexactFloat64()
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 = config.SUCCESS
orderProfitInfo.UpdateTime = utils.GetBasicDateTime()
if _, err := txOrm.Update(&orderProfitInfo); err != nil {
@@ -147,7 +152,6 @@ func SolvePaySuccess(bankOrderId string, factAmount float64, trxNo string) bool
return nil
})
if err != nil {
logs.Error("SolvePaySuccess失败", err)
return false
@@ -182,7 +186,6 @@ func SolvePayFail(bankOrderId, transId string) bool {
return nil
})
if err != nil {
logs.Error("SolvePayFail", err)
return false
@@ -197,7 +200,6 @@ 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)
@@ -229,19 +231,19 @@ func SolveOrderFreeze(bankOrderId string) bool {
}
accountInfo.UpdateTime = utils.GetBasicDateTime()
accountInfo.FreezeAmount = accountInfo.FreezeAmount + orderProfitInfo.UserInAmount
accountInfo.FreezeAmount = orderProfitInfo.UserInAmount.Add(decimal.NewFromFloat(accountInfo.FreezeAmount)).InexactFloat64()
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: config.FREEZE_AMOUNT,
OrderID: orderInfo.MerchantOrderId,
Amount: orderProfitInfo.UserInAmount,
Amount: orderProfitInfo.UserInAmount.InexactFloat64(),
Balance: accountInfo.Balance,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
@@ -254,7 +256,6 @@ func SolveOrderFreeze(bankOrderId string) bool {
return nil
})
if err != nil {
logs.Error("SolveOrderFreeze", err)
return false
@@ -270,7 +271,6 @@ 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)
@@ -294,7 +294,7 @@ func SolveOrderUnfreeze(bankOrderId string) bool {
return err
}
accountInfo.UpdateTime = utils.GetBasicDateTime()
accountInfo.FreezeAmount = accountInfo.FreezeAmount - orderProfitInfo.UserInAmount
accountInfo.FreezeAmount = decimal.NewFromFloat(accountInfo.FreezeAmount).Sub(orderProfitInfo.UserInAmount).InexactFloat64()
if _, err := txOrm.Update(accountInfo); err != nil {
logs.Error("solve order unfreeze fail: ", err)
@@ -306,7 +306,7 @@ func SolveOrderUnfreeze(bankOrderId string) bool {
AccountName: accountInfo.AccountName,
OrderID: orderInfo.MerchantOrderId,
Type: config.UNFREEZE_AMOUNT,
Amount: orderProfitInfo.UserInAmount,
Amount: orderProfitInfo.UserInAmount.InexactFloat64(),
Balance: accountInfo.Balance,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
@@ -328,7 +328,6 @@ func SolveOrderUnfreeze(bankOrderId string) bool {
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)
@@ -346,11 +345,11 @@ func SolveRefund(bankOrderId string) bool {
}
account.UpdateTime = utils.GetBasicDateTime()
account.SettleAmount = account.SettleAmount - orderProfitInfo.UserInAmount
account.Balance = account.Balance - orderProfitInfo.UserInAmount
account.SettleAmount = decimal.NewFromFloat(account.SettleAmount).Sub(orderProfitInfo.UserInAmount).InexactFloat64()
account.Balance = decimal.NewFromFloat(account.Balance).Sub(orderProfitInfo.UserInAmount).InexactFloat64()
if orderInfo.Freeze == config.YES {
account.FreezeAmount = account.FreezeAmount - orderProfitInfo.UserInAmount
account.FreezeAmount = decimal.NewFromFloat(account.FreezeAmount).Sub(orderProfitInfo.UserInAmount).InexactFloat64()
if account.FreezeAmount < 0 {
account.FreezeAmount = config.ZERO
}
@@ -371,7 +370,7 @@ func SolveRefund(bankOrderId string) bool {
AccountUid: account.AccountUid,
Type: config.REFUND,
OrderID: orderInfo.MerchantOrderId,
Amount: orderProfitInfo.UserInAmount,
Amount: orderProfitInfo.UserInAmount.InexactFloat64(),
Balance: account.Balance,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
@@ -393,7 +392,6 @@ func SolveRefund(bankOrderId string) bool {
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 {
@@ -416,8 +414,8 @@ func SolveOrderRoll(bankOrderId string) bool {
account.UpdateTime = utils.GetBasicDateTime()
if orderInfo.Refund == config.YES {
account.Balance = account.Balance + orderProfitInfo.UserInAmount
account.SettleAmount = account.SettleAmount + orderProfitInfo.UserInAmount
account.Balance = decimal.NewFromFloat(account.Balance).Add(orderProfitInfo.UserInAmount).InexactFloat64()
account.SettleAmount = decimal.NewFromFloat(account.SettleAmount).Add(orderProfitInfo.UserInAmount).InexactFloat64()
orderInfo.Refund = config.NO
}
@@ -435,7 +433,7 @@ func SolveOrderRoll(bankOrderId string) bool {
AccountName: account.AccountName,
Type: config.PLUS_AMOUNT,
OrderID: orderInfo.MerchantOrderId,
Amount: orderProfitInfo.UserInAmount,
Amount: orderProfitInfo.UserInAmount.InexactFloat64(),
Balance: account.Balance,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime(),
@@ -447,7 +445,6 @@ func SolveOrderRoll(bankOrderId string) bool {
}
return nil
}); err != nil {
logs.Error("SolveOrderRoll处理失败", err)
return false
@@ -459,11 +456,11 @@ func SolveOrderRoll(bankOrderId string) bool {
// CompareOrderAndFactAmount 比较订单金额和实际支付金额的大小
func CompareOrderAndFactAmount(factAmount float64, orderInfo order.OrderInfo) int {
orderAmount := orderInfo.OrderAmount
//将金额放大1000倍
// 将金额放大1000倍
oa := int64(orderAmount * 1000)
fa := int64(factAmount * 1000)
if oa > fa {
//如果实际金额大返回1
// 如果实际金额大返回1
return 1
} else if oa == fa {
return 0
@@ -474,7 +471,6 @@ func CompareOrderAndFactAmount(factAmount float64, orderInfo order.OrderInfo) in
// CreateOrderNotifyInfo 支付完成后,处理给商户的回调信息
func CreateOrderNotifyInfo(orderInfo order.OrderInfo, tradeStatus string) {
notifyInfo := new(notify.NotifyInfo)
notifyInfo.Type = "order"
notifyInfo.BankOrderId = orderInfo.BankOrderId
@@ -522,6 +518,6 @@ func CreateOrderNotifyInfo(orderInfo order.OrderInfo, tradeStatus string) {
} else {
logs.Error(fmt.Sprintf("订单bankOrderId=%s插入回调数据库失败", orderInfo.BankOrderId))
}
//将订单发送到消息队列,给下面的商户进行回调
// 将订单发送到消息队列,给下面的商户进行回调
go message.SendMessage(config.MqOrderNotify, orderInfo.BankOrderId)
}

View File

@@ -4,25 +4,28 @@ import (
"context"
"errors"
"fmt"
"time"
"github.com/shopspring/decimal"
"gateway/config"
"gateway/models/accounts"
"gateway/models/merchant"
"gateway/models/merchant_deploy"
"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分钟进行扫码看有没有隔天押款金额
Interval = 2 // 隔多少分钟进行结算
Minutes = 1 // 每隔15分钟进行扫码看有没有隔天押款金额
)
// OrderSettle 订单结算,将那些支付成功的订单金额加入到商户账户的结算金额中
func OrderSettle() {
params := make(map[string]string)
params["is_allow_settle"] = config.YES
params["is_complete_settle"] = config.NO
@@ -64,16 +67,17 @@ func settle(orderSettle order.OrderSettleInfo, orderProfit order.OrderProfitInfo
// 商户有押款操作
loadAmount := 0.0
merchantDeployInfo := merchant_deploy.GetMerchantDeployByUidAndPayType(accountInfo.AccountUid, orderSettle.PayTypeCode)
merchantDeployInfo := merchant_deploy.GetMerchantDeployByUidAndPayType(accountInfo.AccountUid,
orderSettle.PayTypeCode,
)
if merchantDeployInfo.IsLoan == config.YES {
loadAmount = merchantDeployInfo.LoanRate * 0.01 * orderProfit.FactAmount
loadAmount = orderProfit.FactAmount.Mul(decimal.NewFromFloat(merchantDeployInfo.LoanRate * 0.01)).InexactFloat64()
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: config.NO,
MerchantUid: orderSettle.MerchantUid,
@@ -81,7 +85,8 @@ func settle(orderSettle order.OrderSettleInfo, orderProfit order.OrderProfitInfo
LoadDate: utils.GetDateAfterDays(merchantDeployInfo.LoanDays),
LoadAmount: loadAmount,
UpdateTime: utils.GetBasicDateTime(),
CreateTime: utils.GetBasicDateTime()}
CreateTime: utils.GetBasicDateTime(),
}
if _, err := txOrm.Insert(&tmp); err != nil {
logs.Error("結算插入merchantLoad失敗失败信息", err)
@@ -108,15 +113,15 @@ func settle(orderSettle order.OrderSettleInfo, orderProfit order.OrderProfitInfo
logs.Info(fmt.Sprintf("结算过程中,该商户不需要押款,全款结算"))
}
if accountInfo.WaitAmount < orderProfit.UserInAmount {
if orderProfit.UserInAmount.GreaterThan(decimal.NewFromFloat(accountInfo.WaitAmount)) {
logs.Error("系统出现严重故障,账户的带结算金额小于订单结算金额")
return errors.New("系统出现严重故障,账户的带结算金额小于订单结算金额, 账户 = " + accountInfo.AccountName + "订单id = " + orderProfit.BankOrderId)
}
needAmount := orderProfit.UserInAmount - loadAmount
needAmount := orderProfit.UserInAmount.Sub(decimal.NewFromFloat(loadAmount))
accountInfo.SettleAmount = accountInfo.SettleAmount + needAmount
accountInfo.WaitAmount = accountInfo.WaitAmount - orderProfit.UserInAmount
accountInfo.SettleAmount = needAmount.Add(decimal.NewFromFloat(accountInfo.SettleAmount)).InexactFloat64()
accountInfo.WaitAmount = decimal.NewFromFloat(accountInfo.WaitAmount).Sub(orderProfit.UserInAmount).InexactFloat64()
accountInfo.LoanAmount = accountInfo.LoanAmount + loadAmount
if _, err := txOrm.Update(accountInfo); err != nil {
@@ -201,7 +206,6 @@ func MerchantAbleAmount(merchantLoad merchant.MerchantLoadInfo) bool {
}
return nil
}); err != nil {
return false
}
@@ -209,7 +213,7 @@ func MerchantAbleAmount(merchantLoad merchant.MerchantLoadInfo) bool {
}
func OrderSettleInit() {
//每隔5分钟巡查有没有可以进行结算的订单
// 每隔5分钟巡查有没有可以进行结算的订单
go func() {
settleTimer := time.NewTimer(time.Duration(Interval) * time.Minute)
oneMinuteTimer := time.NewTimer(time.Duration(Minutes) * time.Minute)

View File

@@ -20,16 +20,16 @@ import (
// ScanData 定义扫码支付的返回值
type ScanData struct {
Supplier string //上游的通道供应商
PayType string //支付类型
OrderNo string //下游商户请求订单号
BankNo string //本系统的请求订单号
OrderPrice string //订单金额
FactPrice string //实际的展示在客户面前的金额
Status string //状态码 '00' 成功
PayUrl string //支付二维码链接地址
Msg string //附加的信息
ReturnData string //对方返回数据
Supplier string // 上游的通道供应商
PayType string // 支付类型
OrderNo string // 下游商户请求订单号
BankNo string // 本系统的请求订单号
OrderPrice string // 订单金额
FactPrice string // 实际的展示在客户面前的金额
Status string // 状态码 '00' 成功
PayUrl string // 支付二维码链接地址
Msg string // 附加的信息
ReturnData string // 对方返回数据
}
type PayInterface interface {

View File

@@ -11,6 +11,9 @@ package third_party
****************************************************/
import (
"strconv"
"strings"
"gateway/models/merchant"
"gateway/models/order"
"gateway/models/payfor"
@@ -24,16 +27,16 @@ import (
"github.com/beego/beego/v2/server/web"
"github.com/rs/xid"
"github.com/widuu/gojson"
"strconv"
"strings"
)
type DaiLiImpl struct {
web.Controller
}
const NOTITY_URL = "http://localhost:12306/accept/notify"
const URL = "http://zhaoyin.lfwin.com/payapi/pay/jspay3"
const (
NOTITY_URL = "http://localhost:12306/accept/notify"
URL = "http://zhaoyin.lfwin.com/payapi/pay/jspay3"
)
func (c *DaiLiImpl) Scan(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) supplier.ScanData {
// 从boss后台获取数据
@@ -136,15 +139,15 @@ func (c *DaiLiImpl) PayNotify() {
params["tradeStatus"] = strings.TrimSpace(c.GetString("tradeStatus"))
params["field1"] = strings.TrimSpace(c.GetString("field1"))
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
//对参数进行验签
// 对参数进行验签
keys := utils.SortMap(params)
tmpSign := utils.GetMD5Sign(params, keys, paySecret)
sign := strings.TrimSpace(c.GetString("sign"))
if tmpSign != sign {
logs.Error("代丽回调签名异常,回调失败")
//c.StopRun()
// c.StopRun()
}
//实际支付金额
// 实际支付金额
factAmount, err := strconv.ParseFloat(params["orderPrice"], 64)
if err != nil {
orderInfo.FactAmount = 0
@@ -153,7 +156,7 @@ func (c *DaiLiImpl) PayNotify() {
orderInfo.BankTransId = params["trxNo"]
tradeStatus := params["tradeStatus"]
//paySolveController := new(service.PaySolveController)
// paySolveController := new(service.PaySolveController)
if tradeStatus == "FAILED" {
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
logs.Error("solve order fail fail")
@@ -165,19 +168,18 @@ func (c *DaiLiImpl) PayNotify() {
} else if tradeStatus == "WAITING_PAYMENT" {
logs.Notice("快付回调该订单还处于等待支付订单id=", orderNo)
} else if tradeStatus == "SUCCESS" {
//订单支付成功,需要搞很多事情 TODO
// 订单支付成功,需要搞很多事情 TODO
service.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo"))
}
c.Ctx.WriteString("success")
}
func (c *DaiLiImpl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInfo) bool {
tradeStatus := "SUCCESS"
trxNo := orderInfo.BankOrderId
factAmount := 100.00
if tradeStatus == "SUCCESS" {
//调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
// 调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
if !service.SolvePaySuccess(orderInfo.BankOrderId, factAmount, trxNo) {
return false
}

View File

@@ -16,8 +16,7 @@ var supplierCode2Name = map[string]string{
var registerSupplier = make(map[string]supplier.PayInterface)
//注册各种上游的支付接口
// 注册各种上游的支付接口
func init() {
registerSupplier["KF"] = new(KuaiFuImpl)
logs.Notice(CheckSupplierByCode("KF"))
@@ -25,8 +24,8 @@ func init() {
registerSupplier["DAILI"] = new(DaiLiImpl)
logs.Notice(CheckSupplierByCode("DAILI"))
//registerSupplier["MF178"] = new(MFCardImpl)
//logs.Notice(CheckSupplierByCode("MF178"))
// registerSupplier["MF178"] = new(MFCardImpl)
// logs.Notice(CheckSupplierByCode("MF178"))
registerSupplier["MF178"] = new(MFCardV2Impl)
logs.Notice(CheckSupplierByCode("MF178"))

View File

@@ -11,6 +11,9 @@ package third_party
import (
"fmt"
"strconv"
"strings"
"gateway/config"
"gateway/models/merchant"
"gateway/models/order"
@@ -25,8 +28,6 @@ import (
beego "github.com/beego/beego/v2/server/web"
"github.com/rs/xid"
"github.com/widuu/gojson"
"strconv"
"strings"
)
type KuaiFuImpl struct {
@@ -58,7 +59,7 @@ func (c *KuaiFuImpl) Scan(orderInfo order.OrderInfo, roadInfo road.RoadInfo, mer
case "BAIDU_SCAN":
case "JD_SCAN":
}
//将金额转为带有2位小数点的float
// 将金额转为带有2位小数点的float
order := fmt.Sprintf("%0.2f", orderInfo.OrderAmount)
params := make(map[string]string)
params["orderNo"] = orderInfo.BankOrderId
@@ -69,7 +70,7 @@ func (c *KuaiFuImpl) Scan(orderInfo order.OrderInfo, roadInfo road.RoadInfo, mer
params["osType"] = orderInfo.OsType
params["notifyUrl"] = "KF"
params["payKey"] = KF_PAY_KEY
//params["field1"] = "field1"
// params["field1"] = "field1"
keys := utils.SortMap(params)
sign := utils.GetMD5Sign(params, keys, KF_PAY_SECRET)
@@ -159,7 +160,7 @@ func (c *KuaiFuImpl) PayNotify() {
params["tradeStatus"] = strings.TrimSpace(c.GetString("tradeStatus"))
params["field1"] = strings.TrimSpace(c.GetString("field1"))
params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
//对参数进行验签
// 对参数进行验签
keys := utils.SortMap(params)
tmpSign := utils.GetMD5Sign(params, keys, paySecret)
sign := strings.TrimSpace(c.GetString("sign"))
@@ -167,7 +168,7 @@ func (c *KuaiFuImpl) PayNotify() {
logs.Error("快付回调签名异常,回调失败")
c.StopRun()
}
//实际支付金额
// 实际支付金额
factAmount, err := strconv.ParseFloat(params["orderPrice"], 64)
if err != nil {
logs.Error("快付回调实际金额有误, factAmount=", params["orderPrice"])
@@ -187,7 +188,7 @@ func (c *KuaiFuImpl) PayNotify() {
} else if tradeStatus == "WAITING_PAYMENT" {
logs.Notice("快付回调该订单还处于等待支付订单id=", orderNo)
} else if tradeStatus == "SUCCESS" {
//订单支付成功,需要搞很多事情 TODO
// 订单支付成功,需要搞很多事情 TODO
service.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, c.GetString("trxNo"))
}
c.Ctx.WriteString("success")
@@ -220,18 +221,18 @@ func (c *KuaiFuImpl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInfo)
logs.Error("err: ", response)
return false
}
//获取用户的实际支付金额
// 获取用户的实际支付金额
orderPrice := gojson.Json(response).Get("orderPrice").Tostring()
factAmount, err := strconv.ParseFloat(orderPrice, 64)
if err != nil {
logs.Error("快速查询得到的实际金额错误, orderPrice=", orderPrice)
}
//orderInfo.FactAmount = orderInfo.OrderAmount
// orderInfo.FactAmount = orderInfo.OrderAmount
tradeStatus := gojson.Json(response).Get("tradeStatus").Tostring()
trxNo := gojson.Json(response).Get("trxNo").Tostring()
if tradeStatus == "SUCCESS" {
//调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
// 调用支付成功的接口,做加款更新操作,需要把实际支付金额传入
if !service.SolvePaySuccess(orderInfo.BankOrderId, factAmount, trxNo) {
return false
}
@@ -263,7 +264,7 @@ func (c *KuaiFuImpl) PayFor(payFor payfor.PayforInfo) string {
params["province"] = payFor.BankAccountAddress
params["city"] = payFor.BankAccountAddress
params["bankAccountAddress"] = payFor.BankAccountAddress
//将float64转为字符串
// 将float64转为字符串
params["amount"] = strconv.FormatFloat(payFor.PayforAmount, 'f', 2, 64)
params["moblieNo"] = payFor.PhoneNo
params["merchantOrderId"] = payFor.BankOrderId

View File

@@ -6,6 +6,10 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"
"gateway/config"
"gateway/models/merchant"
"gateway/models/order"
@@ -20,9 +24,6 @@ import (
"github.com/beego/beego/v2/server/web"
"github.com/bytedance/sonic"
"github.com/widuu/gojson"
"strconv"
"strings"
"time"
)
type MFCardV2Impl struct {
@@ -50,8 +51,8 @@ func (c *MFCardV2Impl) SendCard(jsonStr string, cardInfo CardInfo, attach string
params := make(map[string]string)
params["app_key"] = appKey
//params["face_type"] = cardInfo.FaceType // 官方面值还是自定义面值
//params["discount"] = strconv.Itoa(0) // 折扣
// params["face_type"] = cardInfo.FaceType // 官方面值还是自定义面值
// params["discount"] = strconv.Itoa(0) // 折扣
params["goods_sku"] = goodsSku // 卡片类型
params["face_val"] = cardInfo.FaceType // 提交面值
params["callback_url"] = cfg.GetNotifyUrl() // 回调地址
@@ -68,8 +69,8 @@ func (c *MFCardV2Impl) SendCard(jsonStr string, cardInfo CardInfo, attach string
return false, "加密失败"
}
//params["third_order_id"] = "" // 业务方自己的订单号
//params["valid_day"] = strconv.Itoa(10) // 卡卷有效期
// params["third_order_id"] = "" // 业务方自己的订单号
// params["valid_day"] = strconv.Itoa(10) // 卡卷有效期
params["timestamp"] = strconv.FormatInt(time.Now().Unix(), 10)
sign := utils.GetMD5SignMF(params, appSecret)
@@ -77,7 +78,6 @@ func (c *MFCardV2Impl) SendCard(jsonStr string, cardInfo CardInfo, attach string
logs.Info("params", params)
url, err := cfg.GetMFCardSubmitUrl()
if err != nil {
return false, ""
}
@@ -86,7 +86,7 @@ func (c *MFCardV2Impl) SendCard(jsonStr string, cardInfo CardInfo, attach string
marshal, err := json.Marshal(params)
if err != nil {
logs.Error("Map转化为byte数组失败,异常。", err)
//fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
// fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
return false, "内部错误请稍后再试试01"
}
logs.Info("请求参数:" + string(marshal))
@@ -178,7 +178,7 @@ func (c *MFCardV2Impl) Syt(orderInfo order.OrderInfo, roadInfo road.RoadInfo, me
return supplier.ScanData{Status: "-1", Msg: "订单有有误,请稍后再试(01)"}
}
// 类型 171 京东卡
//ok, str := c.SendCard(roadInfo.Params, cdata, orderInfo.BankOrderId)
// ok, str := c.SendCard(roadInfo.Params, cdata, orderInfo.BankOrderId)
ok, str := c.SendCard(roadInfo.Params, cdata, orderInfo.BankOrderId)
if !ok {
return supplier.ScanData{Status: "-1", Msg: "错误:" + str}
@@ -202,6 +202,7 @@ func (c *MFCardV2Impl) Syt(orderInfo order.OrderInfo, roadInfo road.RoadInfo, me
// 对方返回数据
return scanData
}
func (c *MFCardV2Impl) Fast(orderInfo order.OrderInfo, roadInfo road.RoadInfo, merchantInfo merchant.MerchantInfo) bool {
var scanData supplier.ScanData
scanData.Status = "01"
@@ -266,7 +267,6 @@ func (c *MFCardV2Impl) PayNotify() {
}
paySecretGroup, err := sonic.GetFromString(roadInfo.Params)
if err != nil {
logs.Error("获取蜜蜂秘钥失败", merchantUid)
c.StopRun()
@@ -274,22 +274,22 @@ func (c *MFCardV2Impl) PayNotify() {
paySecret, _ := paySecretGroup.Get("appSecret").String()
params["order_id"] = strings.TrimSpace(c.GetString("order_id"))
params["third_order_id"] = strings.TrimSpace(c.GetString("third_order_id")) //时间戳
params["card_no"] = strings.TrimSpace(c.GetString("card_no")) //卡号
params["card_pwd"] = strings.TrimSpace(c.GetString("card_pwd")) //时间戳
params["face_val"] = strings.TrimSpace(c.GetString("face_val")) //时间戳
params["amount"] = strings.TrimSpace(c.GetString("amount")) //时间戳
params["discount"] = strings.TrimSpace(c.GetString("discount")) //时间戳
params["remark"] = strings.TrimSpace(c.GetString("remark")) //备注
params["attach"] = attach //附加备注
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp")) //时间戳
params["status"] = strings.TrimSpace(c.GetString("status")) //状态
params["third_order_id"] = strings.TrimSpace(c.GetString("third_order_id")) // 时间戳
params["card_no"] = strings.TrimSpace(c.GetString("card_no")) // 卡号
params["card_pwd"] = strings.TrimSpace(c.GetString("card_pwd")) // 时间戳
params["face_val"] = strings.TrimSpace(c.GetString("face_val")) // 时间戳
params["amount"] = strings.TrimSpace(c.GetString("amount")) // 时间戳
params["discount"] = strings.TrimSpace(c.GetString("discount")) // 时间戳
params["remark"] = strings.TrimSpace(c.GetString("remark")) // 备注
params["attach"] = attach // 附加备注
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp")) // 时间戳
params["status"] = strings.TrimSpace(c.GetString("status")) // 状态
//对参数进行验签
// 对参数进行验签
tmpSign := utils.GetMD5SignMF(params, paySecret)
sign := strings.TrimSpace(c.GetString("sign"))
params["sign"] = sign //签名
params["sign"] = sign // 签名
if tmpSign != sign {
logs.Error("【MF178】回调签名异常回调失败")
@@ -304,13 +304,13 @@ func (c *MFCardV2Impl) PayNotify() {
orderInfo.FactAmount = factAmount
orderInfo.BankTransId = params["order_id"]
if params["status"] == "8" { //失败
if params["status"] == "8" { // 失败
logs.Info("【MF178】回调失败订单信息", params)
if !service.SolvePayFail(orderInfo.BankOrderId, "") {
logs.Error("solve order fail fail")
}
} else if params["status"] == "9" {
//TODO 订单支付成功
// TODO 订单支付成功
service.SolvePaySuccess(orderInfo.BankOrderId, orderInfo.FactAmount, params["order_id"])
}
c.Ctx.WriteString("SUCCESS")
@@ -341,7 +341,7 @@ func (c *MFCardV2Impl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInf
marshal, err := json.Marshal(params)
if err != nil {
logs.Error("Map转化为byte数组失败,异常。", err)
//fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
// fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
return false
}
@@ -351,7 +351,6 @@ func (c *MFCardV2Impl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInf
req.Header("Accept-Charset", "utf-8")
response, err := req.String()
if err != nil {
logs.Error("MF GetToken 请求失败:", err)
return false
@@ -370,7 +369,6 @@ func (c *MFCardV2Impl) PayQuery(orderInfo order.OrderInfo, roadInfo road.RoadInf
}
resCode, err := resData.Get("code").Int64()
if err != nil {
return false
}
@@ -406,7 +404,7 @@ func (c *MFCardV2Impl) PayQueryV2(orderInfo order.OrderInfo, roadInfo road.RoadI
marshal, err := json.Marshal(params)
if err != nil {
logs.Error("Map转化为byte数组失败,异常。", err)
//fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
// fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
return supply_model.DataErr
}
@@ -416,7 +414,6 @@ func (c *MFCardV2Impl) PayQueryV2(orderInfo order.OrderInfo, roadInfo road.RoadI
req.Header("Accept-Charset", "utf-8")
response, err := req.String()
if err != nil {
return supply_model.RemoteDataErr
}
@@ -473,7 +470,7 @@ func (c *MFCardV2Impl) PayForQuery(payFor payfor.PayforInfo) (string, string) {
marshal, err := json.Marshal(params)
if err != nil {
logs.Error("Map转化为byte数组失败,异常。", err)
//fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
// fmt.Printf("Map转化为byte数组失败,异常:%s\n", err)
return config.PAYFOR_FAIL, "内部错误请稍后再试试01"
}
logs.Info("请求参数:" + string(marshal))
@@ -482,7 +479,6 @@ func (c *MFCardV2Impl) PayForQuery(payFor payfor.PayforInfo) (string, string) {
req.Header("Accept-Charset", "utf-8")
response, err := req.String()
if err != nil {
logs.Error("MF GetToken 请求失败:", err)
return config.PAYFOR_FAIL, ""

View File

@@ -2,42 +2,43 @@ package third_party
import (
"fmt"
"gateway/utils"
"testing"
"gateway/utils"
)
func TestMFCardV2Impl_Scan(t *testing.T) {
params := map[string]string{}
params["order_id"] = "23111611000344"
params["third_order_id"] = "" //时间戳
params["card_no"] = "2326992090248120052" //卡号
params["card_pwd"] = "123456" //时间戳
params["face_val"] = "100" //时间戳
params["amount"] = "0" //时间戳
params["discount"] = "970" //时间戳
params["remark"] = "卡密错误卡密处理失败" //备注
params["attach"] = "6666clased65n2ns73c84ho0" //附加备注
params["timestamp"] = "1700122001" //时间戳
params["status"] = "8" //状态
params["third_order_id"] = "" // 时间戳
params["card_no"] = "2326992090248120052" // 卡号
params["card_pwd"] = "123456" // 时间戳
params["face_val"] = "100" // 时间戳
params["amount"] = "0" // 时间戳
params["discount"] = "970" // 时间戳
params["remark"] = "卡密错误卡密处理失败" // 备注
params["attach"] = "6666clased65n2ns73c84ho0" // 附加备注
params["timestamp"] = "1700122001" // 时间戳
params["status"] = "8" // 状态
paySecret := "8dc29e5993e66937"
tmpSign := utils.GetMD5SignMF(params, paySecret)
fmt.Println(tmpSign)
} //对参数进行验签
} // 对参数进行验签
//"attach":"6666clcqg5u5n2ns7394hm3g","callback_url":"http://121.37.253.228:12309/mfcard/notifyV2","card_no":"123456","card_pwd":"7Bnu42gE1aUi/eDzruO7Rw==","face_val":"100","goods_sku":"SK000116","sign":"c94152fc05772c4510b3f097f9d70519","timestamp":"1700374551"}
func TestMFCardV3Impl_Scan(t *testing.T) {
params := map[string]string{}
params["goods_sku"] = "SK000116"
params["card_no"] = "123456" //卡号
params["card_pwd"] = "7Bnu42gE1aUi/eDzruO7Rw==" //时间戳
params["face_val"] = "100" //时间戳
params["attach"] = "6666clcqg5u5n2ns7394hm3g" //附加备注
params["timestamp"] = "1700374551" //时间戳
params["app_key"] = "972381004" //状态
params["callback_url"] = "http://121.37.253.228:12309/mfcard/notifyV2" //状态
params["card_no"] = "123456" // 卡号
params["card_pwd"] = "7Bnu42gE1aUi/eDzruO7Rw==" // 时间戳
params["face_val"] = "100" // 时间戳
params["attach"] = "6666clcqg5u5n2ns7394hm3g" // 附加备注
params["timestamp"] = "1700374551" // 时间戳
params["app_key"] = "972381004" // 状态
params["callback_url"] = "http://121.37.253.228:12309/mfcard/notifyV2" // 状态
paySecret := "8dc29e5993e66937"
tmpSign := utils.GetMD5SignMF(params, paySecret)

View File

@@ -5,11 +5,10 @@ import (
)
func TestA(t *testing.T) {
//GetNotityUrl()
//jsonStr := `{"ret":0,"msg":"提交成功共提交1条请耐心等待后台处理","data":[{"id":"74614089","cardpwd":"48D9-1551-3FE3-CCCC"}],"error_data":{"msg":"","data":[]}}`
//data := gojson.Json(jsonStr).Get("error_data").Getdata()
//println(data)
// GetNotityUrl()
// jsonStr := `{"ret":0,"msg":"提交成功共提交1条请耐心等待后台处理","data":[{"id":"74614089","cardpwd":"48D9-1551-3FE3-CCCC"}],"error_data":{"msg":"","data":[]}}`
// data := gojson.Json(jsonStr).Get("error_data").Getdata()
// println(data)
//data := new(third_party.MFCardImpl)
//

View File

@@ -1,6 +1,8 @@
package test
import (
"testing"
"gateway/config"
_ "gateway/message"
_ "gateway/models"
@@ -9,7 +11,6 @@ import (
"gateway/utils"
"github.com/beego/beego/v2/core/logs"
"github.com/rs/xid"
"testing"
)
func TestAutoPayFor(t *testing.T) {

View File

@@ -1,6 +1,9 @@
package test
import (
"net/url"
"testing"
_ "gateway/message"
_ "gateway/models"
"gateway/service"
@@ -8,8 +11,6 @@ import (
"github.com/astaxie/beego/httplib"
"github.com/astaxie/beego/logs"
"github.com/rs/xid"
"net/url"
"testing"
)
import _ "gateway/routers"
@@ -39,10 +40,8 @@ func TestPay(t *testing.T) {
resp := httplib.Get(l)
s, err := resp.String()
if err != nil {
logs.Error("请求错误:" + err.Error())
}
logs.Info("微信扫码返回结果:" + s)

View File

@@ -14,6 +14,7 @@ import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"github.com/astaxie/beego/logs"
)
@@ -56,8 +57,8 @@ func AesEncrypt(src []byte, key string) []byte {
crypted := make([]byte, len(src))
ecb.CryptBlocks(crypted, src)
// 普通base64编码加密 区别于urlsafe base64
//fmt.Println("base64 result:", base64.StdEncoding.EncodeToString(crypted))
//fmt.Println("base64UrlSafe result:", Base64UrlSafeEncode(crypted))
// fmt.Println("base64 result:", base64.StdEncoding.EncodeToString(crypted))
// fmt.Println("base64UrlSafe result:", Base64UrlSafeEncode(crypted))
return crypted
}

File diff suppressed because one or more lines are too long

View File

@@ -204,7 +204,7 @@ func (req *Request) pull() (*Response, error) {
}
func (req *Request) push() (*Response, error) {
var buf = new(bytes.Buffer)
buf := new(bytes.Buffer)
if req.bodyJSON != nil {
body, err := json.Marshal(req.bodyJSON)

View File

@@ -30,7 +30,6 @@ func GetMD5Upper(s string) string {
// MapToString 将map数据变成key=value形式的字符串
func MapToString(m map[string]string) string {
res := ""
for k, v := range m {
res = res + k + "=" + v + "&"

View File

@@ -4,16 +4,6 @@ import (
"strings"
)
/***************************************************
** @Desc : This file for ...
** @Time : 2019/10/26 11:08
** @Author : yuebin
** @File : sign_verify
** @Last Modified by : yuebin
** @Last Modified time: 2019/10/26 11:08
** @Software: GoLand
****************************************************/
func GetMD5Sign(params map[string]string, keys []string, paySecret string) string {
str := ""
for i := 0; i < len(keys); i++ {

View File

@@ -1,21 +1,10 @@
/***************************************************
** @Desc : This file for ...
** @Time : 2019/10/26 11:17
** @Author : yuebin
** @File : sort_go
** @Last Modified by : yuebin
** @Last Modified time: 2019/10/26 11:17
** @Software: GoLand
****************************************************/
package utils
import (
"sort"
)
/*
* 对map的key值进行排序
*/
// SortMap 对map的key值进行排序
func SortMap(m map[string]string) []string {
var arr []string
for k := range m {
@@ -25,9 +14,7 @@ func SortMap(m map[string]string) []string {
return arr
}
/**
** 按照key的ascii值从小到大给map排序
*/
// SortMapByKeys 按照key的ascii值从小到大给map排序
func SortMapByKeys(m map[string]string) map[string]string {
keys := SortMap(m)
tmp := make(map[string]string)