kefu/controller/pay.go

494 lines
16 KiB
Go
Raw Normal View History

2024-12-10 02:50:12 +00:00
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": "充值成功",
})
}