mirror of
https://github.com/kongyuebin1/dongfeng-pay.git
synced 2025-09-18 14:49:12 +08:00
提交新项目
This commit is contained in:
367
jhgateway/controllers/gateway/base_gateway.go
Normal file
367
jhgateway/controllers/gateway/base_gateway.go
Normal file
@@ -0,0 +1,367 @@
|
||||
/***************************************************
|
||||
** @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
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/rs/xid"
|
||||
"juhe/service/common"
|
||||
"juhe/service/controller"
|
||||
"juhe/service/models"
|
||||
"juhe/service/utils"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BaseGateway struct {
|
||||
beego.Controller
|
||||
Params map[string]string //请求的基本参数
|
||||
ClientIp string //商户ip
|
||||
MerchantInfo models.MerchantInfo //商户信息
|
||||
Msg string //信息
|
||||
Code int //状态码 200正常
|
||||
RoadInfo models.RoadInfo
|
||||
RoadPoolInfo models.RoadPoolInfo
|
||||
OrderAmount float64
|
||||
PayWayCode string
|
||||
PlatformRate float64
|
||||
AgentRate float64
|
||||
}
|
||||
|
||||
//获取商户请求过来的基本参数参数
|
||||
func (c *BaseGateway) PayPrepare() {
|
||||
c.Params = make(map[string]string)
|
||||
//获取客户端的ip
|
||||
c.ClientIp = c.Ctx.Input.IP()
|
||||
c.Params["orderNo"] = strings.TrimSpace(c.GetString("orderNo"))
|
||||
c.Params["productName"] = strings.TrimSpace(c.GetString("productName"))
|
||||
c.Params["orderPeriod"] = strings.TrimSpace(c.GetString("orderPeriod"))
|
||||
c.Params["orderPrice"] = strings.TrimSpace(c.GetString("orderPrice"))
|
||||
c.Params["payWayCode"] = strings.TrimSpace(c.GetString("payWayCode"))
|
||||
c.Params["osType"] = strings.TrimSpace(c.GetString("osType"))
|
||||
c.Params["notifyUrl"] = strings.TrimSpace(c.GetString("notifyUrl"))
|
||||
//c.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
c.Params["payKey"] = strings.TrimSpace(c.GetString("payKey"))
|
||||
c.Params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
c.GetMerchantInfo()
|
||||
c.JudgeParams()
|
||||
|
||||
if c.Code != -1 {
|
||||
c.Code = 200
|
||||
}
|
||||
}
|
||||
|
||||
//判断参数的
|
||||
func (c *BaseGateway) JudgeParams() {
|
||||
//c.ReturnUrlIsValid()
|
||||
c.OrderIsValid()
|
||||
c.NotifyUrlIsValid()
|
||||
c.OsTypeIsValid()
|
||||
c.PayWayCodeIsValid()
|
||||
c.ProductIsValid()
|
||||
c.OrderPeriodIsValid()
|
||||
c.IpIsWhite()
|
||||
c.OrderPriceIsValid()
|
||||
}
|
||||
|
||||
func (c *BaseGateway) ReturnUrlIsValid() {
|
||||
if c.Params["returnUrl"] == "" || len(c.Params["returnUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功后跳转地址不能为空"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) NotifyUrlIsValid() {
|
||||
if c.Params["notifyUrl"] == "" || len(c.Params["notifyUrl"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付成功订单回调地址不能空位"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) OsTypeIsValid() {
|
||||
if c.Params["osType"] == "" || len(c.Params["osType"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付设备系统类型不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) PayWayCodeIsValid() {
|
||||
if c.Params["payWayCode"] == "" || len(c.Params["payWayCode"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "支付类型字段不能为空"
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.Contains(c.Params["payWayCode"], "SCAN") {
|
||||
c.Code = -1
|
||||
c.Msg = "扫码支付不支持这种支付类型"
|
||||
} else {
|
||||
scanPayWayCodes := common.GetScanPayWayCodes()
|
||||
for _, v := range scanPayWayCodes {
|
||||
if c.Params["payWayCode"] == v {
|
||||
c.PayWayCode = strings.Replace(c.Params["payWayCode"], "-", "_", -1)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Code = -1
|
||||
c.Msg = "不存在这种支付类型,请仔细阅读对接文档"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) ProductIsValid() {
|
||||
if c.Params["productName"] == "" || len(c.Params["productName"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商品描述信息字段不能为空"
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BaseGateway) OrderPeriodIsValid() {
|
||||
if c.Params["orderPeriod"] == "" || len(c.Params["orderPeriod"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单过期时间不能为空,默认填写\"1\"即可"
|
||||
}
|
||||
}
|
||||
|
||||
//获取商户信息
|
||||
func (c *BaseGateway) GetMerchantInfo() {
|
||||
merchantInfo := models.GetMerchantByPaykey(c.Params["payKey"])
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户不存在,或者paykey有误,请联系管理员"
|
||||
} else if merchantInfo.Status != common.ACTIVE {
|
||||
c.Code = -1
|
||||
c.Msg = "商户状态已经被冻结或者被删除,请联系管理员!"
|
||||
} else {
|
||||
c.MerchantInfo = merchantInfo
|
||||
}
|
||||
}
|
||||
|
||||
//判断订单金额
|
||||
func (c *BaseGateway) OrderPriceIsValid() {
|
||||
if c.Params["orderPrice"] == "" || len(c.Params["orderPrice"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "订单金额不能为空"
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
//判断金额订单号是否为空或者有重复
|
||||
func (c *BaseGateway) OrderIsValid() {
|
||||
if c.Params["orderNo"] == "" || len(c.Params["orderNo"]) == 0 {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号不能为空"
|
||||
return
|
||||
}
|
||||
if models.OrderNoIsEixst(c.Params["orderNo"]) {
|
||||
c.Code = -1
|
||||
c.Msg = "商户订单号重复"
|
||||
}
|
||||
}
|
||||
|
||||
//判断ip是否在白名单中
|
||||
func (c *BaseGateway) IpIsWhite() bool {
|
||||
//TODO
|
||||
return true
|
||||
}
|
||||
|
||||
//选择通道
|
||||
func (c *BaseGateway) ChooseRoad() {
|
||||
payWayCode := c.Params["payWayCode"]
|
||||
merchantUid := c.MerchantInfo.MerchantUid
|
||||
//通道配置信息
|
||||
deployInfo := models.GetMerchantDeployByUidAndPayType(merchantUid, payWayCode)
|
||||
if deployInfo.MerchantUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置"
|
||||
return
|
||||
}
|
||||
|
||||
singleRoad := models.GetRoadInfoByRoadUid(deployInfo.SingleRoadUid)
|
||||
c.RoadPoolInfo = models.GetRoadPoolByRoadPoolCode(deployInfo.RollRoadCode)
|
||||
if c.RoadIsValid(singleRoad) {
|
||||
c.RoadInfo = singleRoad
|
||||
c.PlatformRate = deployInfo.SingleRoadPlatformRate
|
||||
c.AgentRate = deployInfo.SingleRoadAgentRate
|
||||
return
|
||||
}
|
||||
//如果单通道没有有效的,那么寻找通道池里面的通道
|
||||
if c.RoadPoolInfo.RoadPoolCode == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道"
|
||||
return
|
||||
}
|
||||
roadUids := strings.Split(c.RoadPoolInfo.RoadUidPool, "||")
|
||||
roadInfos := models.GetRoadInfosByRoadUids(roadUids)
|
||||
for _, roadInfo := range roadInfos {
|
||||
if c.RoadIsValid(roadInfo) {
|
||||
c.RoadInfo = roadInfo
|
||||
c.PlatformRate = deployInfo.RollRoadPlatformRate
|
||||
c.AgentRate = deployInfo.RollRoadAgentRate
|
||||
return
|
||||
}
|
||||
}
|
||||
if c.RoadInfo.RoadUid == "" {
|
||||
c.Code = -1
|
||||
c.Msg = "该商户没有配置通道或者通道不可用"
|
||||
}
|
||||
}
|
||||
|
||||
//判断通道是否是合法的
|
||||
func (c *BaseGateway) RoadIsValid(roadInfo models.RoadInfo) 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()
|
||||
models.UpdateRoadInfo(roadInfo)
|
||||
return true
|
||||
}
|
||||
|
||||
//获取基本订单记录
|
||||
func (c *BaseGateway) GetOrderInfo() models.OrderInfo {
|
||||
//6666是自己系统订单号
|
||||
bankOrderNo := "6666" + xid.New().String()
|
||||
//获取支付类型的名称,例如支付宝扫码等
|
||||
payTypeName := common.GetNameByPayWayCode(c.Params["payWayCode"])
|
||||
orderInfo := models.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: common.NO,
|
||||
Refund: common.NO, Unfreeze: common.NO, PayProductCode: c.RoadInfo.ProductUid, PayTypeCode: c.PayWayCode, PayTypeName: payTypeName,
|
||||
OsType: c.Params["osType"], Status: common.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 > common.ZERO {
|
||||
orderInfo.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderInfo.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderInfo
|
||||
}
|
||||
|
||||
//计算收益,平台利润,代理利润
|
||||
func (c *BaseGateway) GetOrderProfit(orderInfo models.OrderInfo) models.OrderProfitInfo {
|
||||
//因为所有的手续费率都是百分率,所以需要除以100
|
||||
payTypeName := common.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 = common.ZERO
|
||||
}
|
||||
allProfit := supplierProfit + platformProfit + agentProfit
|
||||
|
||||
if allProfit >= c.OrderAmount {
|
||||
logs.Error("手续费已经超过订单金额,bankOrderId = %s", orderInfo.BankOrderId)
|
||||
c.Msg = "手续费已经超过了订单金额"
|
||||
c.Code = -1
|
||||
}
|
||||
orderProfit := models.OrderProfitInfo{
|
||||
PayProductCode: c.RoadInfo.ProductUid, PayProductName: c.RoadInfo.ProductName, PayTypeCode: c.PayWayCode, PayTypeName: payTypeName,
|
||||
Status: common.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 > common.ZERO {
|
||||
orderProfit.AgentUid = c.MerchantInfo.BelongAgentUid
|
||||
orderProfit.AgentName = c.MerchantInfo.BelongAgentName
|
||||
}
|
||||
return orderProfit
|
||||
}
|
||||
|
||||
/*
|
||||
* 生成订单一系列的记录
|
||||
*/
|
||||
func (c *BaseGateway) GenerateRecord() (models.OrderInfo, models.OrderProfitInfo) {
|
||||
//生成订单记录,订单利润利润
|
||||
orderInfo := c.GetOrderInfo()
|
||||
orderProfit := c.GetOrderProfit(orderInfo)
|
||||
if c.Code == -1 {
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
if !controller.InsertOrderAndOrderProfit(orderInfo, orderProfit) {
|
||||
c.Code = -1
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
logs.Info("插入支付订单记录和支付利润记录成功")
|
||||
return orderInfo, orderProfit
|
||||
}
|
||||
|
||||
func (c *BaseGateway) GenerateSuccessData(scanData controller.ScanData) *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(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
|
||||
}
|
23
jhgateway/controllers/gateway/error_gateway.go
Normal file
23
jhgateway/controllers/gateway/error_gateway.go
Normal file
@@ -0,0 +1,23 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/10/26 16:56
|
||||
** @Author : yuebin
|
||||
** @File : error_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/26 16:56
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
type ErrorGatewayController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (c *ErrorGatewayController) ErrorParams() {
|
||||
beego.ReadFromRequest(&c.Controller)
|
||||
c.TplName = "err/params.html"
|
||||
}
|
82
jhgateway/controllers/gateway/merchant_query.go
Normal file
82
jhgateway/controllers/gateway/merchant_query.go
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************
|
||||
** @Desc : 供下游订单状态查询和代付结果查询
|
||||
** @Time : 2019/11/6 13:59
|
||||
** @Author : yuebin
|
||||
** @File : order_query
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/6 13:59
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"juhe/service/models"
|
||||
"juhe/service/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type QueryController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
type OrderQueryFailData struct {
|
||||
PayKey string `json:"payKey"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
/*
|
||||
** 改接口是为下游商户提供订单查询
|
||||
*/
|
||||
func (c *QueryController) OrderQuery() {
|
||||
orderNo := strings.TrimSpace(c.GetString("orderNo"))
|
||||
payKey := strings.TrimSpace(c.GetString("payKey"))
|
||||
sign := strings.TrimSpace(c.GetString("sign"))
|
||||
params := make(map[string]string)
|
||||
params["orderNo"] = orderNo
|
||||
params["payKey"] = payKey
|
||||
|
||||
failData := new(OrderQueryFailData)
|
||||
failData.StatusCode = "01"
|
||||
failData.PayKey = payKey
|
||||
|
||||
merchantInfo := models.GetMerchantByPaykey(payKey)
|
||||
if merchantInfo.MerchantUid == "" || len(merchantInfo.MerchantUid) == 0 {
|
||||
failData.Msg = "商户不存在,请核对payKey字段"
|
||||
}
|
||||
orderInfo := models.GetOrderByMerchantOrderId(orderNo)
|
||||
if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
|
||||
failData.Msg = "不存在这样的订单,请核对orderNo字段"
|
||||
}
|
||||
keys := utils.SortMap(params)
|
||||
paySercet := merchantInfo.MerchantSecret
|
||||
tmpSign := utils.GetMD5Sign(params, keys, paySercet)
|
||||
if tmpSign != sign {
|
||||
failData.Msg = "签名错误"
|
||||
}
|
||||
if failData.Msg != "" {
|
||||
c.Data["json"] = failData
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
p := make(map[string]string)
|
||||
p["orderNo"] = orderNo
|
||||
p["orderTime"] = strings.TrimSpace(strings.Replace("-", "", orderInfo.UpdateTime, -1))
|
||||
p["trxNo"] = orderInfo.BankOrderId
|
||||
p["tradeStatus"] = orderInfo.Status
|
||||
p["payKey"] = payKey
|
||||
p["orderPrice"] = fmt.Sprintf("%.2f", orderInfo.OrderAmount)
|
||||
p["factPrice"] = fmt.Sprintf("%.2f", orderInfo.FactAmount)
|
||||
p["statusCode"] = "00"
|
||||
keys = utils.SortMap(p)
|
||||
p["sign"] = utils.GetMD5Sign(p, keys, paySercet)
|
||||
s, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
logs.Error("json marshal fail: ", err)
|
||||
}
|
||||
c.Data["json"] = s
|
||||
}
|
256
jhgateway/controllers/gateway/payfor_gateway.go
Normal file
256
jhgateway/controllers/gateway/payfor_gateway.go
Normal file
@@ -0,0 +1,256 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for ...
|
||||
** @Time : 2019/12/5 14:05
|
||||
** @Author : yuebin
|
||||
** @File : payfor_gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/12/5 14:05
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/rs/xid"
|
||||
"juhe/service/common"
|
||||
"juhe/service/models"
|
||||
"juhe/service/utils"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PayForGateway struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
type PayForResponse struct {
|
||||
ResultCode string `json:"resultCode,omitempty"`
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
type PayForQueryResponse struct {
|
||||
ResultMsg string `json:"resultMsg,omitempty"`
|
||||
MerchantOrderId string `json:"merchantOrderId,omitempty"`
|
||||
SettAmount string `json:"settAmount,omitempty"`
|
||||
SettFee string `json:"settFee,omitempty"`
|
||||
SettStatus string `json:"settStatus,omitempty"`
|
||||
Sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
type BalanceResponse struct {
|
||||
resultCode string `json:"resultCode,omitempty"`
|
||||
balance string `json:"balance,omitempty"`
|
||||
availableAmount string `json:"availableAmount,omitempty"`
|
||||
freezeAmount string `json:"freezeAmount,omitempty"`
|
||||
waitAmount string `json:"waitAmount,omitempty"`
|
||||
loanAmount string `json:"loanAmount,omitempty"`
|
||||
payforAmount string `json:"payforAmount,omitempty"`
|
||||
resultMsg string `json:"resultMsg,omitempty"`
|
||||
sign string `json:"sign,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* 接受下游商户的代付请求
|
||||
*/
|
||||
func (c *PayForGateway) PayFor() {
|
||||
params := make(map[string]string)
|
||||
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["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["amount"] = strings.TrimSpace(c.GetString("amount"))
|
||||
params["moblieNo"] = strings.TrimSpace(c.GetString("moblieNo"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
payForResponse := new(PayForResponse)
|
||||
res, msg := c.checkParams(params)
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
logs.Error(fmt.Sprintf("下游商户代付请求,签名失败,商户信息: %+v", merchantInfo))
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "下游商户代付请求,签名失败。"
|
||||
} else {
|
||||
res, msg = c.checkSettAmount(params["amount"])
|
||||
if !res {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = msg
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
exist := models.IsExistPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if exist {
|
||||
logs.Error(fmt.Sprintf("代付订单号重复:merchantOrderId = %s", params["merchantOrderId"]))
|
||||
payForResponse.ResultMsg = "商户订单号重复"
|
||||
payForResponse.ResultCode = "01"
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
settAmount, _ := strconv.ParseFloat(params["amount"], 64)
|
||||
payFor := models.PayforInfo{PayforUid: "pppp" + xid.New().String(), MerchantUid: merchantInfo.MerchantUid, MerchantName: merchantInfo.MerchantName,
|
||||
MerchantOrderId: params["merchantOrderId"], BankOrderId: "4444" + xid.New().String(), PayforAmount: settAmount, Status: common.PAYFOR_COMFRIM,
|
||||
BankCode: params["bankCode"], BankName: params["bankAccountAddress"], BankAccountName: params["realname"], BankAccountNo: params["cardNo"],
|
||||
BankAccountType: params["accType"], City: params["city"], Ares: params["province"] + params["city"], PhoneNo: params["mobileNo"], Type: common.SELF_API,
|
||||
UpdateTime: utils.GetBasicDateTime(), CreateTime: utils.GetBasicDateTime(),
|
||||
}
|
||||
|
||||
if !models.InsertPayfor(payFor) {
|
||||
payForResponse.ResultCode = "01"
|
||||
payForResponse.ResultMsg = "代付记录插入失败"
|
||||
} else {
|
||||
payForResponse.ResultMsg = "代付订单已生成"
|
||||
payForResponse.ResultCode = "00"
|
||||
payForResponse.SettAmount = params["amount"]
|
||||
payForResponse.MerchantOrderId = params["MerchantOrderId"]
|
||||
|
||||
tmp := make(map[string]string)
|
||||
tmp["resultCode"] = payForResponse.ResultCode
|
||||
tmp["resultMsg"] = payForResponse.ResultMsg
|
||||
tmp["merchantOrderId"] = payForResponse.MerchantOrderId
|
||||
tmp["settAmount"] = payForResponse.SettAmount
|
||||
keys := utils.SortMap(tmp)
|
||||
sign := utils.GetMD5Sign(params, keys, merchantInfo.MerchantSecret)
|
||||
tmp["sign"] = sign
|
||||
|
||||
c.Data["json"] = payForResponse
|
||||
c.ServeJSON()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PayForGateway) checkSettAmount(settAmount string) (bool, string) {
|
||||
_, err := strconv.ParseFloat(settAmount, 64)
|
||||
if err != nil {
|
||||
logs.Error(fmt.Sprintf("代付金额有误,settAmount = %s", settAmount))
|
||||
return false, "代付金额有误"
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (c *PayForGateway) checkParams(params map[string]string) (bool, string) {
|
||||
for k, v := range params {
|
||||
if v == "" || len(v) == 0 {
|
||||
return false, fmt.Sprintf("字段: %s 为必填!", k)
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
/*
|
||||
* 代付结果查询,
|
||||
*/
|
||||
func (c *PayForGateway) PayForQuery() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["merchantOrderId"] = strings.TrimSpace(c.GetString("merchantOrderId"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
query := make(map[string]string)
|
||||
query["merchantOrderId"] = params["merchantOrderId"]
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
query["resultMsg"] = "签名错误"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
payForInfo := models.GetPayForByMerchantOrderId(params["merchantOrderId"])
|
||||
if payForInfo.BankOrderId == "" {
|
||||
query["resultMsg"] = "不存在这样的代付订单"
|
||||
query["settStatus"] = "03"
|
||||
query["sign"] = utils.GetMD5Sign(params, utils.SortMap(params), merchantInfo.MerchantSecret)
|
||||
} else {
|
||||
switch payForInfo.Status {
|
||||
case common.PAYFOR_BANKING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_SOLVING:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_COMFRIM:
|
||||
query["resultMsg"] = "打款中"
|
||||
query["settStatus"] = "02"
|
||||
case common.PAYFOR_SUCCESS:
|
||||
query["resultMsg"] = "打款成功"
|
||||
query["settStatus"] = "00"
|
||||
query["settAmount"] = strconv.FormatFloat(payForInfo.PayforAmount, 'f', 2, 64)
|
||||
query["settFee"] = strconv.FormatFloat(payForInfo.PayforFee, 'f', 2, 64)
|
||||
case common.PAYFOR_FAIL:
|
||||
query["resultMsg"] = "打款失败"
|
||||
query["settStatus"] = "01"
|
||||
}
|
||||
query["sign"] = utils.GetMD5Sign(query, utils.SortMap(query), merchantInfo.MerchantSecret)
|
||||
}
|
||||
}
|
||||
|
||||
mJson, err := json.Marshal(query)
|
||||
if err != nil {
|
||||
logs.Error("PayForQuery json marshal fail:", err)
|
||||
}
|
||||
|
||||
c.Data["json"] = string(mJson)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
/*
|
||||
* 商户查找余额
|
||||
*/
|
||||
func (c *PayForGateway) Balance() {
|
||||
params := make(map[string]string)
|
||||
params["merchantKey"] = strings.TrimSpace(c.GetString("merchantKey"))
|
||||
params["timestamp"] = strings.TrimSpace(c.GetString("timestamp"))
|
||||
params["sign"] = strings.TrimSpace(c.GetString("sign"))
|
||||
|
||||
balanceResponse := new(BalanceResponse)
|
||||
res, msg := c.checkParams(params)
|
||||
if !res {
|
||||
balanceResponse.resultCode = "-1"
|
||||
balanceResponse.resultMsg = msg
|
||||
c.Data["json"] = balanceResponse
|
||||
} else {
|
||||
merchantInfo := models.GetMerchantByPaykey(params["merchantKey"])
|
||||
if !utils.Md5Verify(params, merchantInfo.MerchantSecret) {
|
||||
balanceResponse.resultCode = "-1"
|
||||
balanceResponse.resultMsg = "签名错误"
|
||||
c.Data["json"] = balanceResponse
|
||||
} else {
|
||||
accountInfo := models.GetAccountByUid(merchantInfo.MerchantUid)
|
||||
tmp := make(map[string]string)
|
||||
tmp["resultCode"] = "00"
|
||||
tmp["balance"] = strconv.FormatFloat(accountInfo.Balance, 'f', 2, 64)
|
||||
tmp["availableAmount"] = strconv.FormatFloat(accountInfo.SettleAmount, 'f', 2, 64)
|
||||
tmp["freezeAmount"] = strconv.FormatFloat(accountInfo.FreezeAmount, 'f', 2, 64)
|
||||
tmp["waitAmount"] = strconv.FormatFloat(accountInfo.WaitAmount, 'f', 2, 64)
|
||||
tmp["loanAmount"] = strconv.FormatFloat(accountInfo.LoanAmount, 'f', 2, 64)
|
||||
tmp["payforAmount"] = strconv.FormatFloat(accountInfo.PayforAmount, 'f', 2, 64)
|
||||
tmp["resultMsg"] = "查询成功"
|
||||
tmp["sign"] = utils.GetMD5Sign(tmp, utils.SortMap(tmp), merchantInfo.MerchantSecret)
|
||||
mJson, _ := json.Marshal(tmp)
|
||||
c.Data["json"] = string(mJson)
|
||||
}
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
86
jhgateway/controllers/gateway/scan_gateway.go
Normal file
86
jhgateway/controllers/gateway/scan_gateway.go
Normal file
@@ -0,0 +1,86 @@
|
||||
/***************************************************
|
||||
** @Desc : 下游请求扫码支付的处理逻辑
|
||||
** @Time : 2019/10/24 11:15
|
||||
** @Author : yuebin
|
||||
** @File : gateway
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/10/24 11:15
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"juhe/service/controller"
|
||||
"juhe/service/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ScanController struct {
|
||||
BaseGateway
|
||||
}
|
||||
|
||||
type ScanSuccessData struct {
|
||||
OrderNo string `json:"orderNo"`
|
||||
Sign string `json:"sign"`
|
||||
OrderPrice string `json:"orderPrice"`
|
||||
PayKey string `json:"payKey"`
|
||||
PayUrl string `json:"payURL"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
type ScanFailData struct {
|
||||
PayKey string `json:"payKey"`
|
||||
StatusCode string `json:"statusCode"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
//处理错误的返回
|
||||
func (c *ScanController) SolveFailJSON() {
|
||||
scanFailJSON := new(ScanFailData)
|
||||
scanFailJSON.StatusCode = "01"
|
||||
scanFailJSON.PayKey = c.Params["payKey"]
|
||||
scanFailJSON.Msg = c.Msg
|
||||
c.Data["json"] = scanFailJSON
|
||||
c.ServeJSON()
|
||||
c.StopRun()
|
||||
}
|
||||
|
||||
//处理扫码的请求
|
||||
func (c *ScanController) Scan() {
|
||||
|
||||
c.PayPrepare()
|
||||
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//签名验证
|
||||
c.Params["returnUrl"] = strings.TrimSpace(c.GetString("returnUrl"))
|
||||
paySecret := c.MerchantInfo.MerchantSecret
|
||||
if !utils.Md5Verify(c.Params, paySecret) {
|
||||
c.Code = -1
|
||||
c.Msg = "签名异常"
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//选择通道
|
||||
c.ChooseRoad()
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//升级订单记录
|
||||
orderInfo, _ := c.GenerateRecord()
|
||||
if c.Code == -1 {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
//获取到对应的上游
|
||||
supplierCode := c.RoadInfo.ProductUid
|
||||
supplier := controller.GetPaySupplierByCode(supplierCode)
|
||||
scanData := supplier.Scan(orderInfo, c.RoadInfo, c.MerchantInfo)
|
||||
if scanData.Status == "00" {
|
||||
scanSuccessData := c.GenerateSuccessData(scanData)
|
||||
c.Data["json"] = scanSuccessData
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
c.SolveFailJSON()
|
||||
}
|
||||
}
|
10
jhgateway/controllers/gateway/supplier_notify.go
Normal file
10
jhgateway/controllers/gateway/supplier_notify.go
Normal file
@@ -0,0 +1,10 @@
|
||||
/***************************************************
|
||||
** @Desc : 接受上游通道商的订单结果异步回调
|
||||
** @Time : 2019/11/22 23:27
|
||||
** @Author : yuebin
|
||||
** @File : supplier_notify
|
||||
** @Last Modified by : yuebin
|
||||
** @Last Modified time: 2019/11/22 23:27
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package gateway
|
Reference in New Issue
Block a user