494 lines
16 KiB
Go
494 lines
16 KiB
Go
package controller
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/tidwall/gjson"
|
||
"kefu/common"
|
||
"kefu/lib"
|
||
"kefu/models"
|
||
"kefu/tools"
|
||
"kefu/types"
|
||
"log"
|
||
"sort"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// 易支付下单
|
||
func PostYiApiPay(c *gin.Context) {
|
||
entId := c.PostForm("entId")
|
||
kefuName := c.PostForm("kefuName")
|
||
amount := c.PostForm("amount")
|
||
openId := c.PostForm("openId")
|
||
email := c.PostForm("email")
|
||
product := c.PostForm("product")
|
||
tel := c.PostForm("tel")
|
||
contact := c.PostForm("contact")
|
||
|
||
virtualProduct := models.FindVirtualProduct("ent_id = ? and id = ?", entId, product)
|
||
description := fmt.Sprintf("%s,支付金额:%s (分)", tools.SubStr(virtualProduct.ProductName, 0, 20), amount)
|
||
snow, _ := tools.NewSnowflake(1)
|
||
orderId := fmt.Sprintf("%s%d", time.Now().Format("0601021504"), snow.Generate())
|
||
log.Println(tools.Str2Int(amount)/100, tools.Str2Int(amount))
|
||
config := models.GetEntConfigsMap(entId, "Nan66Api", "Nan66Shopid", "Nan66ShopSecret")
|
||
|
||
currentHost := tools.GetHost(c.Request)
|
||
params := map[string]interface{}{
|
||
"pid": config["Nan66Shopid"],
|
||
"type": "wxpay",
|
||
"out_trade_no": orderId,
|
||
"notify_url": currentHost + "/2/" + entId + "/yiApiPayNotifyUrl",
|
||
"return_url": currentHost + "/2/" + entId + "/yiApiPayNotifyUrl",
|
||
"name": description,
|
||
"money": float64(tools.Str2Int64(amount)) / 100,
|
||
"clientip": c.ClientIP(),
|
||
}
|
||
var keys []string
|
||
// 筛选、排序参数
|
||
for key := range params {
|
||
keys = append(keys, key)
|
||
}
|
||
sort.Strings(keys)
|
||
sortedParams := make([]string, len(keys))
|
||
for i, key := range keys {
|
||
sortedParams[i] = fmt.Sprintf("%s=%v", key, params[key])
|
||
}
|
||
waitSign := strings.Join(sortedParams, "&")
|
||
sign := tools.Md5(waitSign + config["Nan66ShopSecret"])
|
||
body := fmt.Sprintf("%s&sign=%s&sign_type=MD5", waitSign, sign)
|
||
log.Println("请求易支付", config["Nan66Api"], body)
|
||
resp, err := tools.Post(config["Nan66Api"], "", []byte(body))
|
||
log.Println("请求易支付", resp, err)
|
||
productOrder := &models.ProductOrder{
|
||
KefuName: kefuName,
|
||
OrderSn: orderId,
|
||
UserId: openId,
|
||
EntID: entId,
|
||
OrderStatus: "processing",
|
||
TotalAmount: tools.Str2Int64(amount),
|
||
PaymentMethod: "nan66",
|
||
PaymentStatus: "unpaid",
|
||
ShippingAddress: virtualProduct.ResourceLink,
|
||
OrderDesc: description,
|
||
Contact: contact,
|
||
Email: email,
|
||
Tel: tel,
|
||
}
|
||
productOrder.AddProductOrder()
|
||
c.Writer.Write([]byte(resp))
|
||
}
|
||
|
||
// 易支付回调
|
||
func GetYiApiPayNotifyUrl(c *gin.Context) {
|
||
entId := c.Param("entId")
|
||
config := models.GetEntConfigsMap(entId, "Nan66Api", "Nan66Shopid", "Nan66ShopSecret")
|
||
out_trade_no := c.Query("out_trade_no")
|
||
trade_status := c.Query("trade_status")
|
||
money := c.Query("money")
|
||
name := c.Query("name")
|
||
pid := c.Query("pid")
|
||
trade_no := c.Query("trade_no")
|
||
types := c.Query("type")
|
||
sign := c.Query("sign")
|
||
param := c.Query("param")
|
||
|
||
params := map[string]interface{}{
|
||
"pid": pid,
|
||
"type": types,
|
||
"out_trade_no": out_trade_no,
|
||
"trade_no": trade_no,
|
||
"name": name,
|
||
"money": money,
|
||
"param": param,
|
||
"trade_status": trade_status,
|
||
}
|
||
var keys []string
|
||
// 筛选、排序参数
|
||
for key := range params {
|
||
if params[key] == "" {
|
||
continue
|
||
}
|
||
keys = append(keys, key)
|
||
}
|
||
sort.Strings(keys)
|
||
sortedParams := make([]string, len(keys))
|
||
for i, key := range keys {
|
||
sortedParams[i] = fmt.Sprintf("%s=%v", key, params[key])
|
||
}
|
||
waitSign := strings.Join(sortedParams, "&")
|
||
newSign := tools.Md5(waitSign + config["Nan66ShopSecret"])
|
||
if sign != newSign {
|
||
log.Println("易支付验证签名失败", params, sign, newSign)
|
||
c.Writer.Write([]byte("success"))
|
||
return
|
||
}
|
||
|
||
order := models.FindProductOrder("order_sn = ?", out_trade_no)
|
||
if trade_status == "TRADE_SUCCESS" && order.PaymentStatus == "unpaid" {
|
||
newOrder := &models.ProductOrder{
|
||
PaymentStatus: "paid",
|
||
}
|
||
newOrder.SaveProductOrder("order_sn = ?", out_trade_no)
|
||
}
|
||
c.Writer.Write([]byte("success"))
|
||
}
|
||
|
||
// jsapi支付下单
|
||
func PostJsApiCreateOrder(c *gin.Context) {
|
||
entId := c.PostForm("entId")
|
||
kefuName := c.PostForm("kefuName")
|
||
amount := c.PostForm("amount")
|
||
openId := c.PostForm("openId")
|
||
email := c.PostForm("email")
|
||
product := c.PostForm("product")
|
||
tel := c.PostForm("tel")
|
||
contact := c.PostForm("contact")
|
||
|
||
virtualProduct := models.FindVirtualProduct("ent_id = ? and id = ?", entId, product)
|
||
description := fmt.Sprintf("%s,支付金额:%s(分)", tools.SubStr(virtualProduct.ProductName, 0, 20), amount)
|
||
snow, _ := tools.NewSnowflake(1)
|
||
orderId := fmt.Sprintf("%s%d", time.Now().Format("0601021504"), snow.Generate())
|
||
|
||
appId := models.FindConfig("WechatPayAppId") //公众号APPID
|
||
mchID := models.FindConfig("WechatPayMchID") //商户号
|
||
mchCertificateSerialNumber := models.FindConfig("WechatPayMchCertificateSerialNumber") //商户证书序列号
|
||
//商户API V3密钥
|
||
mchAPIv3Key := models.FindConfig("WechatPayMchAPIv3Key")
|
||
//商户私钥
|
||
mchPrivateKey := models.FindConfig("WechatPayMchPrivateKey")
|
||
notifyUrl := models.FindConfig("WechatJsApiNotifyUrl")
|
||
if appId == "" || mchID == "" || mchCertificateSerialNumber == "" || mchAPIv3Key == "" || mchPrivateKey == "" || notifyUrl == "" {
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": "微信支付配置为空",
|
||
})
|
||
return
|
||
}
|
||
|
||
wechatpay, err := lib.NewWechatPay(appId, mchID, mchCertificateSerialNumber, mchAPIv3Key, mchPrivateKey, notifyUrl)
|
||
resp, err := wechatpay.JsApiPreOrder(openId, tools.Str2Int64(amount), description, orderId)
|
||
log.Println("微信支付JSAPI下单:", resp, err)
|
||
if err != nil {
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
|
||
productOrder := &models.ProductOrder{
|
||
KefuName: kefuName,
|
||
OrderSn: orderId,
|
||
UserId: openId,
|
||
EntID: entId,
|
||
OrderStatus: "processing",
|
||
TotalAmount: tools.Str2Int64(amount),
|
||
PaymentMethod: "wechat",
|
||
PaymentStatus: "unpaid",
|
||
ShippingAddress: virtualProduct.ResourceLink,
|
||
OrderDesc: description,
|
||
Contact: contact,
|
||
Email: email,
|
||
Tel: tel,
|
||
}
|
||
productOrder.AddProductOrder()
|
||
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.SUCCESS,
|
||
"msg": "下单成功!",
|
||
"resource_link": virtualProduct.ResourceLink,
|
||
"result": resp,
|
||
})
|
||
}
|
||
|
||
// JSAPI支付回调
|
||
func PostjsApiPayNotifyUrl(c *gin.Context) {
|
||
appId := models.FindConfig("WechatPayAppId") //公众号APPID
|
||
mchID := models.FindConfig("WechatPayMchID") //商户号
|
||
mchCertificateSerialNumber := models.FindConfig("WechatPayMchCertificateSerialNumber") //商户证书序列号
|
||
//商户API V3密钥
|
||
mchAPIv3Key := models.FindConfig("WechatPayMchAPIv3Key")
|
||
//商户私钥
|
||
mchPrivateKey := models.FindConfig("WechatPayMchPrivateKey")
|
||
notifyUrl := models.FindConfig("WechatJsApiNotifyUrl")
|
||
|
||
wechatpay, _ := lib.NewWechatPay(appId, mchID, mchCertificateSerialNumber, mchAPIv3Key, mchPrivateKey, notifyUrl)
|
||
result, err := wechatpay.ParseNotifyRequest(c.Request)
|
||
resultStr, err := json.Marshal(result)
|
||
log.Println("微信支付回调:", string(resultStr), err)
|
||
|
||
//增加时间
|
||
trade_state := gjson.Get(string(resultStr), "trade_state").String()
|
||
out_trade_no := gjson.Get(string(resultStr), "out_trade_no").String()
|
||
amount := gjson.Get(string(resultStr), "amount.total").Int()
|
||
order := models.FindProductOrder("order_sn = ?", out_trade_no)
|
||
if trade_state == "SUCCESS" && order.PaymentStatus == "unpaid" {
|
||
|
||
newOrder := &models.ProductOrder{
|
||
PaymentStatus: "paid",
|
||
}
|
||
newOrder.SaveProductOrder("order_sn = ?", out_trade_no)
|
||
|
||
//增加余额
|
||
userAttr := models.FindUserAttrRow("ent_id = ? and kefu_name = ?", order.EntID, order.KefuName)
|
||
if userAttr.ID == 0 {
|
||
userAttr.Money = amount
|
||
userAttr.EntId = order.EntID
|
||
userAttr.KefuName = order.KefuName
|
||
userAttr.AddUserAttr()
|
||
} else {
|
||
userAttr.Money = userAttr.Money + amount
|
||
userAttr.EntId = order.EntID
|
||
userAttr.KefuName = order.KefuName
|
||
userAttr.SaveUserAttr("ent_id = ? and kefu_name = ?", order.EntID, order.KefuName)
|
||
}
|
||
}
|
||
}
|
||
|
||
// native支付下单在线支付
|
||
func PostCreateOrder(c *gin.Context) {
|
||
kefuName, _ := c.Get("kefu_name")
|
||
entId, _ := c.Get("ent_id")
|
||
payMonth := c.PostForm("pay_month")
|
||
months := tools.Str2Int64(payMonth)
|
||
|
||
//计算到期时间
|
||
incSecond := months * 30 * 24 * 60 * 60
|
||
kefuInfo := models.FindUser(kefuName.(string))
|
||
nowTime := time.Now().Unix()
|
||
expireTime := kefuInfo.ExpiredAt.Unix()
|
||
newExpireInt := expireTime + incSecond
|
||
//如果早就过期,当前时间增加
|
||
if expireTime < nowTime {
|
||
newExpireInt = nowTime + incSecond
|
||
}
|
||
newExpireStr := tools.IntToTimeStr(newExpireInt, "2006-01-02")
|
||
|
||
amount := months * 60 * (int64(kefuInfo.AgentNum) + 1) * 100
|
||
description := fmt.Sprintf("客服系统充值服务%s个月,到期时间:%s", payMonth, newExpireStr)
|
||
snow, _ := tools.NewSnowflake(1)
|
||
orderId := fmt.Sprintf("%s%d", time.Now().Format("0601021504"), snow.Generate())
|
||
|
||
appId := models.FindConfig("WechatPayAppId") //公众号APPID
|
||
mchID := models.FindConfig("WechatPayMchID") //商户号
|
||
mchCertificateSerialNumber := models.FindConfig("WechatPayMchCertificateSerialNumber") //商户证书序列号
|
||
//商户API V3密钥
|
||
mchAPIv3Key := models.FindConfig("WechatPayMchAPIv3Key")
|
||
//商户私钥
|
||
mchPrivateKey := models.FindConfig("WechatPayMchPrivateKey")
|
||
notifyUrl := models.FindConfig("WechatPayNotifyUrl")
|
||
|
||
wechatpay, err := lib.NewWechatPay(appId, mchID, mchCertificateSerialNumber, mchAPIv3Key, mchPrivateKey, notifyUrl)
|
||
if err != nil {
|
||
log.Println(err)
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
codeUrl, err := wechatpay.NativePayPreOrder(amount, description, orderId)
|
||
if err != nil {
|
||
log.Println(err)
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
orderModels := &models.User_order{
|
||
OrderSn: orderId,
|
||
Money: uint(amount),
|
||
NewExpireTime: newExpireStr,
|
||
Payment: "wechat",
|
||
Type: 1,
|
||
Comment: description,
|
||
CreatedAt: types.Time{time.Now()},
|
||
Operator: kefuName.(string),
|
||
KefuName: kefuName.(string),
|
||
EntId: entId.(string),
|
||
}
|
||
orderModels.AddUserOrder()
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.SUCCESS,
|
||
"msg": types.ApiCode.GetMessage(types.ApiCode.SUCCESS),
|
||
"result": gin.H{
|
||
"code_url": codeUrl,
|
||
"order_id": orderId,
|
||
"ammount": amount,
|
||
},
|
||
})
|
||
}
|
||
|
||
// 在线支付回调
|
||
func PostWechatPayNotifyUrl(c *gin.Context) {
|
||
appId := models.FindConfig("WechatPayAppId") //公众号APPID
|
||
mchID := models.FindConfig("WechatPayMchID") //商户号
|
||
mchCertificateSerialNumber := models.FindConfig("WechatPayMchCertificateSerialNumber") //商户证书序列号
|
||
//商户API V3密钥
|
||
mchAPIv3Key := models.FindConfig("WechatPayMchAPIv3Key")
|
||
//商户私钥
|
||
mchPrivateKey := models.FindConfig("WechatPayMchPrivateKey")
|
||
notifyUrl := models.FindConfig("WechatPayNotifyUrl")
|
||
|
||
wechatpay, _ := lib.NewWechatPay(appId, mchID, mchCertificateSerialNumber, mchAPIv3Key, mchPrivateKey, notifyUrl)
|
||
result, err := wechatpay.ParseNotifyRequest(c.Request)
|
||
log.Println("微信支付回调:", result, err)
|
||
|
||
//增加时间
|
||
trade_state := result["trade_state"].(string)
|
||
out_trade_no := result["out_trade_no"].(string)
|
||
order := models.FindUserOrder("order_sn = ?", out_trade_no)
|
||
if trade_state == "SUCCESS" && order.Type != 2 {
|
||
models.UpdateUserOrderTypedWhere(2, "order_sn = ?", out_trade_no)
|
||
models.UpdateUserExpiredWhere(order.NewExpireTime, " name = ? ", order.KefuName)
|
||
}
|
||
}
|
||
|
||
// 查询订单
|
||
func PostQueryWechatOrder(c *gin.Context) {
|
||
orderId := c.PostForm("order_id")
|
||
entId, _ := c.Get("ent_id")
|
||
kefuName, _ := c.Get("kefu_name")
|
||
|
||
appId := models.FindConfig("WechatPayAppId") //公众号APPID
|
||
mchID := models.FindConfig("WechatPayMchID") //商户号
|
||
mchCertificateSerialNumber := models.FindConfig("WechatPayMchCertificateSerialNumber") //商户证书序列号
|
||
//商户API V3密钥
|
||
mchAPIv3Key := models.FindConfig("WechatPayMchAPIv3Key")
|
||
//商户私钥
|
||
mchPrivateKey := models.FindConfig("WechatPayMchPrivateKey")
|
||
notifyUrl := models.FindConfig("WechatPayNotifyUrl")
|
||
|
||
wechatpay, _ := lib.NewWechatPay(appId, mchID, mchCertificateSerialNumber, mchAPIv3Key, mchPrivateKey, notifyUrl)
|
||
|
||
body, res, err := wechatpay.NativePayQueryOrder(orderId)
|
||
if err != nil {
|
||
log.Println(body, err)
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
if res != "SUCCESS" {
|
||
log.Println("微信支付订单查询:", body)
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.FAILED,
|
||
"msg": "订单未成功支付",
|
||
})
|
||
return
|
||
}
|
||
//查询订单状态
|
||
order := models.FindUserOrder("ent_id = ? and order_sn = ?", entId, orderId)
|
||
if order.Type == 2 {
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.SUCCESS,
|
||
"msg": "订单成功支付",
|
||
})
|
||
return
|
||
}
|
||
models.UpdateUserOrderTypedWhere(2, "ent_id = ? and order_sn = ?", entId, orderId)
|
||
models.UpdateUserExpiredWhere(order.NewExpireTime, " name = ? ", kefuName)
|
||
c.JSON(200, gin.H{
|
||
"code": types.ApiCode.SUCCESS,
|
||
"msg": "订单成功支付",
|
||
})
|
||
}
|
||
func GetSystemConfig(c *gin.Context) {
|
||
alipayImageUrl := models.FindConfig("AlipayImageUrl")
|
||
wechatImageUrl := models.FindConfig("WechatImageUrl")
|
||
bankInfo := models.FindConfig("BankInfo")
|
||
version := models.FindConfig("SystemVersion")
|
||
versionName := models.FindConfig("SystemVersionName")
|
||
kefuExpired := models.FindConfig("KefuExpired")
|
||
KefuBindTel := models.FindConfig("KefuBindTel")
|
||
c.JSON(200, gin.H{
|
||
"code": 200,
|
||
"msg": "ok",
|
||
"result": gin.H{
|
||
"alipayImageUrl": alipayImageUrl,
|
||
"wechatImageUrl": wechatImageUrl,
|
||
"bankInfo": bankInfo,
|
||
"version": version,
|
||
"versionName": versionName,
|
||
"kefuExpired": kefuExpired,
|
||
"KefuBindTel": KefuBindTel,
|
||
},
|
||
})
|
||
}
|
||
|
||
// 管理员充值
|
||
func PostAdminUserCharge(c *gin.Context) {
|
||
entId, _ := c.Get("ent_id")
|
||
myName, _ := c.Get("kefu_name")
|
||
username := c.PostForm("kefu_name")
|
||
money := c.PostForm("money")
|
||
payment := c.PostForm("payment")
|
||
var user *models.User
|
||
if tools.IsPhoneNumber(username) {
|
||
user = &models.User{
|
||
Tel: username,
|
||
}
|
||
} else if tools.IsEmail(username) {
|
||
user = &models.User{
|
||
Email: username,
|
||
}
|
||
} else {
|
||
user = &models.User{
|
||
Name: username,
|
||
}
|
||
}
|
||
|
||
kefuInfo := user.GetOneUser("*")
|
||
if kefuInfo.ID == 0 {
|
||
c.JSON(200, gin.H{
|
||
"code": 400,
|
||
"msg": "账号不存在",
|
||
})
|
||
return
|
||
}
|
||
//充值天数
|
||
moneyInt, _ := strconv.Atoi(money)
|
||
dayInt := int64(moneyInt * 24 * 3600)
|
||
|
||
nowTime := time.Now().Unix()
|
||
expireTime := kefuInfo.ExpiredAt.Unix()
|
||
newExpireInt := expireTime + dayInt
|
||
//如果早就过期,当前时间增加天数
|
||
if expireTime < nowTime {
|
||
newExpireInt = nowTime + dayInt
|
||
}
|
||
newExpireStr := tools.IntToTimeStr(newExpireInt, "2006-01-02 15:04:05")
|
||
|
||
query := " name = ? "
|
||
arg := []interface{}{
|
||
kefuInfo.Name,
|
||
}
|
||
models.UpdateUserExpiredWhere(newExpireStr, query, arg...)
|
||
|
||
//记录订单
|
||
snow, _ := tools.NewSnowflake(1)
|
||
orderModels := &models.User_order{
|
||
OrderSn: fmt.Sprintf("SN%d", snow.Generate()),
|
||
Money: uint(moneyInt) * uint(common.EveryDayYuan) * 100,
|
||
Payment: payment,
|
||
Type: 2,
|
||
Comment: "管理员充值 , 到期 " + newExpireStr,
|
||
CreatedAt: types.Time{time.Now()},
|
||
Operator: myName.(string),
|
||
KefuName: kefuInfo.Name,
|
||
EntId: fmt.Sprintf("%d", kefuInfo.ID),
|
||
}
|
||
orderModels.AddUserOrder()
|
||
logContent := fmt.Sprintf("'%s'为'%s'充值%s天,方式 %s,到期 %s", myName, kefuInfo.Name, money, payment, newExpireStr)
|
||
go models.CreateFlyLog(entId.(string), c.ClientIP(), logContent, "user")
|
||
c.JSON(200, gin.H{
|
||
"code": 200,
|
||
"msg": "充值成功",
|
||
})
|
||
}
|