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": "充值成功", }) }