|
@@ -1,10 +1,8 @@
|
|
|
-package front
|
|
|
+package pay
|
|
|
|
|
|
import (
|
|
|
- "encoding/json"
|
|
|
"encoding/xml"
|
|
|
"fmt"
|
|
|
- "io/ioutil"
|
|
|
"jfw/config"
|
|
|
"jfw/tools"
|
|
|
"jfw/wx"
|
|
@@ -18,27 +16,55 @@ import (
|
|
|
"github.com/go-xweb/xweb"
|
|
|
)
|
|
|
|
|
|
-type Pay struct {
|
|
|
+type WxPayAction struct {
|
|
|
*xweb.Action
|
|
|
+ //打赏
|
|
|
redirectOauth xweb.Mapper `xweb:"/front/pay/redirect"` //微信支付授权
|
|
|
getUserInfo xweb.Mapper `xweb:"/front/pay/getUserInfo"` //微信支付获取用户信息
|
|
|
+ qr xweb.Mapper `xweb:"/front/pay/qr/([^.]*)"` //生成二维码图片
|
|
|
payIndex xweb.Mapper `xweb:"/weixin/pay/index"` //微信支付页面
|
|
|
wxPay xweb.Mapper `xweb:"/weixin/pay/pay"` //微信支付
|
|
|
- payCallback xweb.Mapper `xweb:"/weixin/pay/callback"` //微信支付回调
|
|
|
- qr xweb.Mapper `xweb:"/front/pay/qr/([^.]*)"` //生成二维码图片
|
|
|
+ //pc端扫码支付
|
|
|
+ sacnPay_GetQrCode xweb.Mapper `xweb:"/weixin/sacnPay/getQrCode"` //生成支付二维码
|
|
|
+ sacnPay_CreateOrder xweb.Mapper `xweb:"/weixin/sacnPay/createOrder"` //创建订单
|
|
|
+ //统一回调函数
|
|
|
+ payCallback xweb.Mapper `xweb:"/weixin/pay/callback"` //微信支付回调
|
|
|
+}
|
|
|
+
|
|
|
+type WeixinStruct struct {
|
|
|
+ payCallBackChan chan bool
|
|
|
+ appid string
|
|
|
+ mchid string
|
|
|
+ key string
|
|
|
+ dashang_attachmsg string
|
|
|
+ dashang_bodymsg string
|
|
|
+ dashang_detailmsg string
|
|
|
+ sjdc_attachmsg string
|
|
|
+ sjdc_bodymsg string
|
|
|
+ sjdc_detailmsg string
|
|
|
}
|
|
|
|
|
|
-var jianyuConfig map[string]interface{}
|
|
|
-var payConfig map[string]interface{}
|
|
|
+var weixinStruct *WeixinStruct
|
|
|
|
|
|
func init() {
|
|
|
- xweb.AddAction(&Pay{})
|
|
|
- jianyuConfig = config.Sysconfig["wxJianyu"].(map[string]interface{})
|
|
|
- payConfig = jianyuConfig["pay"].(map[string]interface{})
|
|
|
+ xweb.AddAction(&WxPayAction{})
|
|
|
+ payConfig := config.WeixinConfig["pay"].(map[string]interface{})
|
|
|
+ weixinStruct = &WeixinStruct{
|
|
|
+ payCallBackChan: make(chan bool, 1),
|
|
|
+ appid: util.ObjToString(config.WeixinConfig["appid"]),
|
|
|
+ mchid: util.ObjToString(payConfig["mchid"]),
|
|
|
+ key: util.ObjToString(payConfig["key"]),
|
|
|
+ dashang_attachmsg: util.ObjToString(payConfig["attachmsg"]),
|
|
|
+ dashang_bodymsg: util.ObjToString(payConfig["bodymsg"]),
|
|
|
+ dashang_detailmsg: util.ObjToString(payConfig["detailmsg"]),
|
|
|
+ sjdc_attachmsg: util.ObjToString(payConfig["sjdc_attachmsg"]),
|
|
|
+ sjdc_bodymsg: util.ObjToString(payConfig["sjdc_bodymsg"]),
|
|
|
+ sjdc_detailmsg: util.ObjToString(payConfig["sjdc_detailmsg"]),
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//转发
|
|
|
-func (p *Pay) RedirectOauth() {
|
|
|
+func (p *WxPayAction) RedirectOauth() {
|
|
|
param := p.GetString("source") + "_" + p.GetString("id")
|
|
|
webdomain := config.Sysconfig["webdomain"].(string)
|
|
|
openId, _ := p.GetSession("payOpenId").(string)
|
|
@@ -50,39 +76,25 @@ func (p *Pay) RedirectOauth() {
|
|
|
p.Redirect(webdomain+"/weixin/pay/index?param="+param, http.StatusFound)
|
|
|
return
|
|
|
}
|
|
|
- urlstr := "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + jianyuConfig["appid"].(string) + "&redirect_uri=" + webdomain + "/front/pay/getUserInfo?param=" + param + "&response_type=code&scope=snsapi_base&state=1#wechat_redirect"
|
|
|
+ urlstr := fmt.Sprintf(config.Wxoauth, fmt.Sprintf("%s/front/pay/getUserInfo?param=%s", webdomain, param), "1")
|
|
|
p.Redirect(urlstr, http.StatusFound)
|
|
|
}
|
|
|
|
|
|
//取用户信息,取完以后再跳转到实际支付页面
|
|
|
-func (p *Pay) GetUserInfo() {
|
|
|
- api_url := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
|
|
|
- //取用户信息
|
|
|
- recturl := fmt.Sprintf(api_url, jianyuConfig["appid"].(string), jianyuConfig["appsecret"].(string), p.GetString("code"))
|
|
|
- resp, err := http.Get(recturl)
|
|
|
- defer resp.Body.Close()
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
- bs, _ := ioutil.ReadAll(resp.Body)
|
|
|
- resp.Body.Close()
|
|
|
- data := map[string]interface{}{}
|
|
|
- json.Unmarshal(bs, &data)
|
|
|
- openid, _ := data["openid"].(string)
|
|
|
+func (p *WxPayAction) GetUserInfo() {
|
|
|
//传入openid,进入支付页面,正常情况下应该存入session
|
|
|
- p.SetSession("payOpenId", openid)
|
|
|
+ p.SetSession("payOpenId", tools.Getopenid(p.GetString("code")))
|
|
|
p.Redirect("/weixin/pay/index?param="+p.GetString("param"), http.StatusFound)
|
|
|
}
|
|
|
-func (p *Pay) PayIndex() error {
|
|
|
+func (p *WxPayAction) PayIndex() error {
|
|
|
param := p.GetString("param")
|
|
|
params := strings.Split(param, "_")
|
|
|
id := util.DecodeArticleId2ByCheck(params[1])[0]
|
|
|
title := ""
|
|
|
if id != "" {
|
|
|
- data, ok := mongodb.FindById("bidding", id, `{"title":1}`)
|
|
|
+ data, ok := tools.MQFW.FindById("bidding", id, `{"title":1}`)
|
|
|
if ok && (data == nil || *data == nil || len(*data) == 0) {
|
|
|
- data, ok = mongodb.FindById("bidding_back", id, `{"title":1}`)
|
|
|
+ data, ok = tools.MQFW.FindById("bidding_back", id, `{"title":1}`)
|
|
|
}
|
|
|
if ok && data != nil && len(*data) > 0 {
|
|
|
title, _ = (*data)["title"].(string)
|
|
@@ -95,7 +107,7 @@ func (p *Pay) PayIndex() error {
|
|
|
p.T["signature"] = wx.SignJSSDK(p.Site() + p.Url())
|
|
|
return p.Render("/weixin/pay.html", &p.T)
|
|
|
}
|
|
|
-func (p *Pay) WxPay() error {
|
|
|
+func (p *WxPayAction) WxPay() error {
|
|
|
openId, _ := p.GetSession("payOpenId").(string)
|
|
|
if openId == "" {
|
|
|
p.ServeJson(map[string]interface{}{
|
|
@@ -117,15 +129,15 @@ func (p *Pay) WxPay() error {
|
|
|
tradeno := "jy-" + fmt.Sprint(time.Now().Unix()) + util.Uuid(12)
|
|
|
//获取预订单号
|
|
|
ret, err := tools.GetPrepayId(map[string]string{
|
|
|
- "attachmsg": payConfig["attachmsg"].(string),
|
|
|
- "bodymsg": payConfig["bodymsg"].(string),
|
|
|
- "detailmsg": fmt.Sprintf(payConfig["detailmsg"].(string), title, fmt.Sprint(float64(totalfee)/100)),
|
|
|
+ "attachmsg": weixinStruct.dashang_attachmsg,
|
|
|
+ "bodymsg": weixinStruct.dashang_bodymsg,
|
|
|
+ "detailmsg": fmt.Sprintf(weixinStruct.dashang_detailmsg, title, fmt.Sprint(float64(totalfee)/100)),
|
|
|
"useropenid": openId,
|
|
|
"tradeno": tradeno,
|
|
|
"userip": p.IP(),
|
|
|
"totalfee": fmt.Sprint(totalfee),
|
|
|
- "mchid": payConfig["mchid"].(string),
|
|
|
- "key": payConfig["key"].(string),
|
|
|
+ "mchid": weixinStruct.mchid,
|
|
|
+ "key": weixinStruct.key,
|
|
|
"notifyUrl": config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback",
|
|
|
})
|
|
|
if err != nil || ret == nil {
|
|
@@ -143,10 +155,10 @@ func (p *Pay) WxPay() error {
|
|
|
}
|
|
|
nonceStr := util.Uuid(32)
|
|
|
timestamp := time.Now().Unix()
|
|
|
- sign := util.WxSign(fmt.Sprintf("appId=%s&nonceStr=%s&package=%s&signType=%s&timeStamp=%d&key=%s", jianyuConfig["appid"].(string), nonceStr, "prepay_id="+prepayId, "MD5", timestamp, payConfig["key"].(string)))
|
|
|
+ sign := util.WxSign(fmt.Sprintf("appId=%s&nonceStr=%s&package=%s&signType=%s&timeStamp=%d&key=%s", weixinStruct.appid, nonceStr, "prepay_id="+prepayId, "MD5", timestamp, weixinStruct.key))
|
|
|
//保存记录
|
|
|
now := time.Now()
|
|
|
- mongodb.Save("reward", map[string]interface{}{
|
|
|
+ tools.MQFW.Save("reward", map[string]interface{}{
|
|
|
"s_source": p.GetString("source"),
|
|
|
"s_prepayid": prepayId,
|
|
|
"s_title": title,
|
|
@@ -166,7 +178,7 @@ func (p *Pay) WxPay() error {
|
|
|
})
|
|
|
p.ServeJson(map[string]interface{}{
|
|
|
"status": 1,
|
|
|
- "appId": jianyuConfig["appid"].(string),
|
|
|
+ "appId": weixinStruct.appid,
|
|
|
"timestamp": fmt.Sprint(timestamp),
|
|
|
"signType": "MD5",
|
|
|
"sign": sign,
|
|
@@ -177,7 +189,7 @@ func (p *Pay) WxPay() error {
|
|
|
operation, _ := p.GetInteger("operation")
|
|
|
prepayId := p.GetString("prepayId")
|
|
|
if operation == 1 || operation == -1 {
|
|
|
- mongodb.Update("reward", `{"s_openid":"`+openId+`","s_prepayid":"`+prepayId+`"}`, map[string]interface{}{
|
|
|
+ tools.MQFW.Update("reward", `{"s_openid":"`+openId+`","s_prepayid":"`+prepayId+`"}`, map[string]interface{}{
|
|
|
"$set": map[string]interface{}{
|
|
|
"i_operation": operation,
|
|
|
"l_updatetime": time.Now().Unix(),
|
|
@@ -187,10 +199,10 @@ func (p *Pay) WxPay() error {
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
-func (p *Pay) PayCallback() {
|
|
|
- payCallBackChan <- true
|
|
|
+func (p *WxPayAction) PayCallback() {
|
|
|
+ weixinStruct.payCallBackChan <- true
|
|
|
defer func() {
|
|
|
- <-payCallBackChan
|
|
|
+ <-weixinStruct.payCallBackChan
|
|
|
}()
|
|
|
by := p.Body()
|
|
|
fmt.Println("回调通知参数", string(by))
|
|
@@ -215,23 +227,29 @@ func (p *Pay) PayCallback() {
|
|
|
}{}
|
|
|
err := xml.Unmarshal(by, &ret)
|
|
|
if err == nil {
|
|
|
- if ret.ReturnCode == "SUCCESS" && ret.Appid == jianyuConfig["appid"].(string) && ret.MchId == payConfig["mchid"].(string) {
|
|
|
- sign := util.WxSign("appid=%s&attach=%s&bank_type=%s&cash_fee=%d&fee_type=%s&is_subscribe=%s&mch_id=%s&nonce_str=%s&openid=%s&out_trade_no=%s&result_code=%s&return_code=%s&time_end=%s&total_fee=%s&trade_type=%s&transaction_id=%s&key=%s", ret.Appid, ret.Attach, ret.BankType, ret.CashFee, ret.FeeType, ret.IsSubscribe, ret.MchId, ret.NonceStr, ret.OpenId, ret.OutTradeNo, ret.ResultCode, ret.ReturnCode, ret.TimeEnd, ret.TotalFee, ret.TradeType, ret.TransactionId, payConfig["key"].(string))
|
|
|
+ if ret.ReturnCode == "SUCCESS" && ret.Appid == weixinStruct.appid && ret.MchId == weixinStruct.mchid {
|
|
|
+ sign := util.WxSign("appid=%s&attach=%s&bank_type=%s&cash_fee=%d&fee_type=%s&is_subscribe=%s&mch_id=%s&nonce_str=%s&openid=%s&out_trade_no=%s&result_code=%s&return_code=%s&time_end=%s&total_fee=%s&trade_type=%s&transaction_id=%s&key=%s", ret.Appid, ret.Attach, ret.BankType, ret.CashFee, ret.FeeType, ret.IsSubscribe, ret.MchId, ret.NonceStr, ret.OpenId, ret.OutTradeNo, ret.ResultCode, ret.ReturnCode, ret.TimeEnd, ret.TotalFee, ret.TradeType, ret.TransactionId, weixinStruct.key)
|
|
|
if ret.Sign == sign {
|
|
|
- query := map[string]interface{}{
|
|
|
- "s_openid": ret.OpenId,
|
|
|
- "s_tradeno": ret.OutTradeNo,
|
|
|
- "i_totalfee": ret.CashFee,
|
|
|
- "i_status": 0,
|
|
|
+ //打赏
|
|
|
+ if strings.HasPrefix(ret.OutTradeNo, "jy_") {
|
|
|
+ query := map[string]interface{}{
|
|
|
+ "s_openid": ret.OpenId,
|
|
|
+ "s_tradeno": ret.OutTradeNo,
|
|
|
+ "i_totalfee": ret.CashFee,
|
|
|
+ "i_status": 0,
|
|
|
+ }
|
|
|
+ tools.MQFW.Update("reward", query, map[string]interface{}{
|
|
|
+ "$set": map[string]interface{}{
|
|
|
+ "i_status": 1,
|
|
|
+ "s_timeend": ret.TimeEnd,
|
|
|
+ "l_updatetime": time.Now().Unix(),
|
|
|
+ "s_transactionid": ret.TransactionId,
|
|
|
+ },
|
|
|
+ }, false, false)
|
|
|
+ } else if strings.HasPrefix(ret.OutTradeNo, "jysjdc_") { //订阅数据导出
|
|
|
+ //操作mysql库
|
|
|
+
|
|
|
}
|
|
|
- mongodb.Update("reward", query, map[string]interface{}{
|
|
|
- "$set": map[string]interface{}{
|
|
|
- "i_status": 1,
|
|
|
- "s_timeend": ret.TimeEnd,
|
|
|
- "l_updatetime": time.Now().Unix(),
|
|
|
- "s_transactionid": ret.TransactionId,
|
|
|
- },
|
|
|
- }, false, false)
|
|
|
p.Write(`<xml>
|
|
|
<return_code><![CDATA[SUCCESS]]></return_code>
|
|
|
<return_msg><![CDATA[OK]]></return_msg>
|
|
@@ -254,7 +272,7 @@ func (p *Pay) PayCallback() {
|
|
|
}
|
|
|
|
|
|
//打赏二维码图片
|
|
|
-func (c *Pay) Qr(code string) error {
|
|
|
+func (c *WxPayAction) Qr(code string) error {
|
|
|
w := c.ResponseWriter
|
|
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
|
|
w.Header().Set("Pragma", "no-cache")
|
|
@@ -266,3 +284,71 @@ func (c *Pay) Qr(code string) error {
|
|
|
_, err := w.Write(pngdat)
|
|
|
return err
|
|
|
}
|
|
|
+func (p *WxPayAction) SacnPay_CreateOrder() {
|
|
|
+ money, _ := p.GetInt("money")
|
|
|
+ content := p.GetString("content")
|
|
|
+ openId, _ := p.GetSession("s_m_openid").(string)
|
|
|
+ //
|
|
|
+ money = 1
|
|
|
+ content = "jsdlkfjsdlkfj"
|
|
|
+ openId = "test"
|
|
|
+ if content == "" || openId == "" {
|
|
|
+ p.ServeJson(map[string]interface{}{"status": "n"})
|
|
|
+ return
|
|
|
+ }
|
|
|
+ nickname, _ := p.GetSession("s_nickname").(string)
|
|
|
+ totalfee := 1
|
|
|
+ tradeno := "jysjdc-" + fmt.Sprint(time.Now().Unix()) + util.Uuid(12)
|
|
|
+ //获取预订单号
|
|
|
+ ret, err := tools.GetPrepayId(map[string]string{
|
|
|
+ "attachmsg": weixinStruct.sjdc_attachmsg,
|
|
|
+ "bodymsg": weixinStruct.sjdc_bodymsg,
|
|
|
+ "detailmsg": weixinStruct.sjdc_detailmsg,
|
|
|
+ "useropenid": openId,
|
|
|
+ "tradeno": tradeno,
|
|
|
+ "userip": p.IP(),
|
|
|
+ "totalfee": fmt.Sprint(totalfee),
|
|
|
+ "mchid": weixinStruct.mchid,
|
|
|
+ "key": weixinStruct.key,
|
|
|
+ "notifyUrl": config.Sysconfig["webdomain"].(string) + "/weixin/pay/callback",
|
|
|
+ "appid": weixinStruct.appid,
|
|
|
+ "tradeType": "NATIVE",
|
|
|
+ })
|
|
|
+ //存库
|
|
|
+ log.Println(ret)
|
|
|
+ result := map[string]interface{}{}
|
|
|
+ if err != nil && ret != nil && util.IntAll((*ret)["status"]) == 1 {
|
|
|
+ now := time.Now()
|
|
|
+ tools.Mysql.Insert("jianyu_order", map[string]interface{}{
|
|
|
+ "order_money": money,
|
|
|
+ "user_nickname": nickname,
|
|
|
+ "user_openid": openId,
|
|
|
+ "content": content,
|
|
|
+ "prepay_id": (*ret)["prepayid"],
|
|
|
+ "code_url": (*ret)["codeurl"],
|
|
|
+ "out_trade_no": tradeno,
|
|
|
+ "create_time": util.FormatDate(&now, util.Date_Full_Layout),
|
|
|
+ })
|
|
|
+ result["status"] = "y"
|
|
|
+ result["code"] = tradeno
|
|
|
+ result["token"] = (*ret)["sign"]
|
|
|
+ } else {
|
|
|
+ log.Println("生成预支付交易单失败", ret)
|
|
|
+ result["status"] = "n"
|
|
|
+ }
|
|
|
+ p.ServeJson(result)
|
|
|
+}
|
|
|
+func (p *WxPayAction) SacnPay_GetQrCode() error {
|
|
|
+ code := p.GetString("code")
|
|
|
+ //sign := p.GetString("sign")
|
|
|
+ w := p.ResponseWriter
|
|
|
+ w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
|
|
+ w.Header().Set("Pragma", "no-cache")
|
|
|
+ w.Header().Set("Expires", "0")
|
|
|
+ w.Header().Set("Content-Type", "image/png")
|
|
|
+ data := fmt.Sprintf("%s/front/pay/redirect?id=%s&source=p", config.Sysconfig["webdomain"].(string), code)
|
|
|
+ r, _ := qr.Encode(data, qr.M)
|
|
|
+ pngdat := r.PNG()
|
|
|
+ _, err := w.Write(pngdat)
|
|
|
+ return err
|
|
|
+}
|