加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用golang快速开发微信公众平台(五):公众号支付

发布时间:2020-12-16 18:25:55 所属栏目:大数据 来源:网络整理
导读:微信又TMD改版了 2个月前我做的一个微信公众号商城支付是正常的,但是同样的设置,目前做的这个却不正常了,老给我报invalid url domain,试遍了所有能找到的法子依然不行,卧槽他大爷,连写博客的欲望都没了,此坑待填。 跨过该死的设置,说下之前解决掉的2

微信又TMD改版了

2个月前我做的一个微信公众号商城支付是正常的,但是同样的设置,目前做的这个却不正常了,老给我报invalid url domain,试遍了所有能找到的法子依然不行,卧槽他大爷,连写博客的欲望都没了,此坑待填。


跨过该死的设置,说下之前解决掉的2个问题:

  1. 微信安全设置要求服务器在你填写业务域名或js安全域名的位置,可以访问到一个MP_verify_xxxx.txt(之前无此硬性要求 我CNNND)
  2. 支付 而支付又分页面和后台

先说这个MP_verify_xxxx.txt咋办

直接说结果,beego框架有个缺点,不支持这么搞。比如我的域名是www.baidu.com,微信要求你,如果你这么填,就要求www.baidu.com/MP_verify_xxxx.txt能访问到,太悲催了。
2个解决办法:

  1. 不在根目录下,添加个2级目录,然后在main.go中设置beego.SetStaticPath("/wx_shop_cart","mp")注意要写到beego.Run()之前
  2. 非得在根目录下,没其他可能,那可以这么搞:
beego.Router("/*",&controllers.MainController{})

先在main.go中这样写,同beego.Run()之前,然后在MainController中

func (c *MainController) Get() {

    orpath := c.Ctx.Request.URL.Path
    //fmt.Println("url : ",c.Ctx.Request.RequestURI)
    //fmt.Println("访问的路径中是否包含微信所要求的txt文本 : ",orpath)

    if strings.Index(orpath,"MP_verify_xxxx.txt") >= 0 {

        //path := filepath.Join(`static`,"MP_verify_xxxx.txt")
        //fmt.Println("path---------",path)
        //http.ServeFile(c.Ctx.ResponseWriter,c.Ctx.Request,path)
        c.Ctx.WriteString("txt文本中的内容")
    } else {
        c.TplName = "index.html"
    }
}

这样就OK了,简单粗暴有效。

该死的支付

先说后台代码

WXShopCartPayTestController

package controllers

import (
    "github.com/astaxie/beego"
    "fmt"
    "sort"
    "crypto/md5"
    "strings"
    "encoding/hex"
    "github.com/astaxie/beego/orm"
    "rbearserver/models"
    "rbearserver/shopUtils/logUtils"
    "crypto/sha1"
    "io"
)

/** 订单付款 下单 提起请求 */


type WXShopCartPayTestController struct {
    beego.Controller
}

//var uid string
func (c *WXShopCartPayTestController) Get() {

    //if uid != "" {
    // fmt.Println("非正式支付接口-----------1")
    // getShopCartForm(c)
    //} else {
    // fmt.Println("WXShopCartPayTestController uid==空")
    //}
    c.TplName = "wx_shop_cart_pay_test.html"
}
func (c *WXShopCartPayTestController) Post() {

    c.EnableRender = false
    fmt.Println("WXShopCartPayTestController 接收微信支付订单结果--------------post")
    //微信支付回调函数 成功后跳转至订单页面
    //WxpayCallback(c.Ctx.ResponseWriter.ResponseWriter,c.Ctx.Request,c.Ctx)
}

//首先定义一个UnifyOrderReq用于填入我们要传入的参数。
type UnifyOrderReq struct {
    Appid            string `xml:"appid"`            //公众账号ID
    Body             string `xml:"body"`             //商品描述
    Mch_id           string `xml:"mch_id"`           //商户号
    Nonce_str        string `xml:"nonce_str"`        //随机字符串
    Notify_url       string `xml:"notify_url"`       //通知地址
    Trade_type       string `xml:"trade_type"`       //交易类型
    Spbill_create_ip string `xml:"spbill_create_ip"` //支付提交用户端ip
    Total_fee        int    `xml:"total_fee"`        //总金额
    Out_trade_no     string `xml:"out_trade_no"`     //商户订单号
    Sign             string `xml:"sign"`             //签名
    Openid           string `xml:"openid"`           //购买商品的用户wxid
}

//微信支付 下单签名
func wxpayCalcSign(mReq map[string]interface{},key string) string {

    //fmt.Println("========STEP 1,对key进行升序排序.========")
    //fmt.Println("微信支付签名计算,API KEY:",key)
    //STEP 1,对key进行升序排序.
    sorted_keys := make([]string, 0)
    for k,_ := range mReq {
        sorted_keys = append(sorted_keys,k)
    }

    sort.Strings(sorted_keys)

    //fmt.Println("========STEP2,对key=value的键值对用&连接起来,略过空值========")
    //STEP2,对key=value的键值对用&连接起来,略过空值
    var signStrings string
    for _,k := range sorted_keys {
        //fmt.Printf("k=%v,v=%vn",k,mReq[k])
        value := fmt.Sprintf("%v",mReq[k])
        if value != "" {
            signStrings = signStrings + k + "=" + value + "&"
        }
    }

    //fmt.Println("========STEP3,在键值对的最后加上key=API_KEY========")
    //STEP3,在键值对的最后加上key=API_KEY
    if key != "" {
        signStrings = signStrings + "key=" + key
    }

    //fmt.Println("========STEP4,进行MD5签名并且将所有字符转为大写.========")
    //STEP4,进行MD5签名并且将所有字符转为大写.
    md5Ctx := md5.New()
    md5Ctx.Write([]byte(signStrings))
    cipherStr := md5Ctx.Sum(nil)
    upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))

    return upperSign
}

type UnifyOrderResp struct {
    Return_code string `xml:"return_code"`
    Return_msg  string `xml:"return_msg"`
    Appid       string `xml:"appid"`
    Mch_id      string `xml:"mch_id"`
    Nonce_str   string `xml:"nonce_str"`
    Sign        string `xml:"sign"`
    Result_code string `xml:"result_code"`
    Prepay_id   string `xml:"prepay_id"`
    Trade_type  string `xml:"trade_type"`
}

//func getShopCartForm(c *WXShopCartPayTestController) {
//
// fmt.Println("非正式支付接口-----------2")
// orderid_str := c.GetString("orderid")
// orderid,_ := strconv.Atoi(orderid_str)//订单id 根据此id可以查询good_order表获取商品及购买者信息
// o := orm.NewOrm()
// order := models.GoodOrder{Id:orderid}
//
// if err := o.Read(&order,"id"); err == nil {
//
// orderPrice,_ := strconv.ParseFloat(order.OrderValue,64)
// totalFee := int(orderPrice * 100)
//
// //请求UnifiedOrder的代码
// var yourReq UnifyOrderReq
// yourReq.Appid = beego.AppConfig.String("APPID")
// yourReq.Body = "mlshop-" + order.Goodname//浏览器打开的移动网页的主页title名-商品概述
// yourReq.Mch_id = beego.AppConfig.String("shopKey")
// yourReq.Nonce_str = RandomStrUtil.GetRandomString(32)
// yourReq.Notify_url = "http://www.molan888.com/wx_shop_cart/payt/pay"
// yourReq.Trade_type = "JSAPI"
// yourReq.Spbill_create_ip = c.Ctx.Input.IP()
// yourReq.Total_fee = totalFee // 单位是分 单位换为真实大小 注意要把元转换为分
// yourReq.Openid = uid
// yourReq.Out_trade_no = strconv.FormatInt(time.Now().Unix(),10) + RandomStrUtil.GetRandomString(3)//订单号
//
// var m map[string]interface{}
// m = make(map[string]interface{},0)
// m["appid"] = yourReq.Appid
// m["body"] = yourReq.Body
// m["mch_id"] = yourReq.Mch_id
// m["notify_url"] = yourReq.Notify_url
// m["trade_type"] = yourReq.Trade_type
// m["spbill_create_ip"] = yourReq.Spbill_create_ip
// m["total_fee"] = yourReq.Total_fee
// m["out_trade_no"] = yourReq.Out_trade_no
// m["nonce_str"] = yourReq.Nonce_str
// m["openid"] = yourReq.Openid
// yourReq.Sign = wxpayCalcSign(m,PAY_API_KEY) //这个key 微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全
//
// bytes_req,err := xml.Marshal(yourReq)
// if err != nil {
// fmt.Println("转换为xml错误:",err)
// logUtils.GetLog().Error("转换为xml错误:",err)
// }
//
// str_req := strings.Replace(string(bytes_req),"UnifyOrderReq","xml",-1)
// //fmt.Println("转换为xml--------",str_req)
//
// bytes_req = []byte(str_req)
//
// //发送unified order请求.
// req,err := http.NewRequest("POST","https://api.mch.weixin.qq.com/pay/unifiedorder",bytes.NewReader(bytes_req))
// if err != nil {
// fmt.Println("New Http Request发生错误,原因:",err)
// logUtils.GetLog().Error("New Http Request发生错误,原因:",err)
// return
//
// }
// req.Header.Set("Accept","application/xml")
// //这里的http header的设置是必须设置的.
// req.Header.Set("Content-Type","application/xml;charset=utf-8")
//
// client := http.Client{}
// resp,_err := client.Do(req)
// if _err != nil {
// fmt.Println("请求微信支付统一下单接口发送错误,原因:",_err)
// logUtils.GetLog().Error("请求微信支付统一下单接口发送错误,_err)
// return
// }
//
// //------------------到这里统一下单接口就已经执行完成了-------------------
//
// respBytes,err := ioutil.ReadAll(resp.Body)
// if err != nil {
// fmt.Println("解析返回body错误",err)
// logUtils.GetLog().Error("解析返回body错误",err)
// return
// }
// xmlResp := UnifyOrderResp{}
// _err = xml.Unmarshal(respBytes,&xmlResp)
// //处理return code.
// if xmlResp.Return_code == "FAIL" {
// fmt.Println("微信支付统一下单不成功,原因:",xmlResp.Return_msg," str_req-->",str_req)
// return
// }
//
// //这里已经得到微信支付的prepay id,需要返给客户端页面,由客户端继续完成支付流程

// //向数据库存入 WxBill 订单号yourReq.Out_trade_no user的wx_id orderId 时间 total_fee
// _,err = o.Insert(&models.WxBill{WxId:uid,OrderId:orderid_str,OutTradeNo:yourReq.Out_trade_no,TotalFee:strconv.Itoa(yourReq.Total_fee),CreateTime:time.Now().Format(TIMELAYOUT)})
// if err != nil {
// fmt.Println("记录wx_bill错误",err)
// logUtils.GetLog().Error("记录wx_bill错误",err)
// }
//
// c.Data["prepay_id"] = xmlResp.Prepay_id
// c.Data["appId"] = yourReq.Appid
// c.Data["timeStamp"] = yourReq.Out_trade_no
// c.Data["nonceStr"] = yourReq.Nonce_str
// c.Data["signature"] = getTicketSigNature(o,c.Ctx.Input.URI(),&yourReq)
//
// paySign := getPaySign(&yourReq,&xmlResp)
// c.Data["paySign"] = paySign
//
// } else {
// fmt.Println("查询订单错误",err,order)
// logUtils.GetLog().Error("查询订单错误",order)
// return
// }
//}

//获取支付签名 跟下单签名不同的地方在于 最后一个字符串连接没有&
func getPaySign(yourReq *UnifyOrderReq,xmlResp *UnifyOrderResp,timeStamp int64) string {

    wxbase := models.WxBase{Id:1}
    err := orm.NewOrm().Read(&wxbase)
    if err != nil {
        fmt.Println("获取wxbase错误",err)
        logUtils.GetLog().Error("获取wxbase错误",err)
        return ""
    }

    p := make(map[string]interface{}, 0)
    p["appId"] = yourReq.Appid
    //p["timeStamp"] = yourReq.Out_trade_no
    p["timeStamp"] = timeStamp
    p["nonceStr"] = yourReq.Nonce_str
    p["package"] = "prepay_id=" + xmlResp.Prepay_id
    p["signType"] = "MD5"

    return wxpaySign(p,wxbase.PayApiKey)
}

//计算支付签名 跟下单签名不同的地方在于 最后一个字符串连接没有&
func wxpaySign(mReq map[string]interface{},key string) string {

    //STEP 1,k)
    }

    sort.Strings(sorted_keys)

    //STEP2,对key=value的键值对用&连接起来,略过空值
    var signStrings string
    for i,mReq[k])
        if value != "" {
            if i != (len(sorted_keys) - 1) {
                signStrings = signStrings + k + "=" + value + "&"
            } else {
                signStrings = signStrings + k + "=" + value//最后一个不加此符号
            }
        }
    }
    //fmt.Println("=====键值对==============",signStrings)

    //STEP3,在键值对的最后加上key=API_KEY
    if key != "" {
        signStrings = signStrings + "&key=" + key
    }
    fmt.Println("=====wxpaySign 键值对加key==============",signStrings)

    //STEP4,进行MD5签名并且将所有字符转为大写.
    //md5Ctx := md5.New()
    //md5Ctx.Write([]byte(signStrings))
    //upperSign := strings.ToUpper(hex.EncodeToString(md5Ctx.Sum(nil)))

    md5Ctx := md5.New()
    md5Ctx.Write([]byte(signStrings))
    cipherStr := md5Ctx.Sum(nil)
    upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))

    fmt.Println("=====进行MD5签名并且将所有字符转为大写 ==============",upperSign)
    return upperSign
}

func getTicketSigNature(o orm.Ormer,uri string,yourReq *UnifyOrderReq) string {

    jsTicket := models.WxJsTicket{Id:1}
    if err := o.Read(&jsTicket,"id"); err == nil {

        //urlstr := beego.AppConfig.String("baseURL") + uri
        urlstr := `http://www.rollingbear.cn` + uri

        n := make(map[string]interface{}, 0)
        n["noncestr"] = yourReq.Nonce_str
        n["jsapi_ticket"] = jsTicket.Ticket
        n["timestamp"] = yourReq.Out_trade_no
        n["url"] = urlstr
        signature := wxJsTicketSign(n)
        fmt.Println("微信支付页面签名-----URI------",urlstr)
        fmt.Println("微信支付页面签名-----jsapi_ticket------",jsTicket.Ticket)
        fmt.Println("微信支付页面签名-----随机字符串------",yourReq.Nonce_str)
        fmt.Println("微信支付页面签名-----时间戳------",yourReq.Out_trade_no)
        fmt.Println("微信支付页面签名-----------",signature)
        return signature
    } else {
        fmt.Println("查询 jsticket 错误",err)
        logUtils.GetLog().Error("查询 jsticket 错误",err)
        return ""
    }
}

//微信支付页面config签名
func wxJsTicketSign(mReq map[string]interface{}) string {

    //fmt.Println("========STEP 1,mReq[k])
        if value != "" {
            if i != (len(sorted_keys) - 1) {
                signStrings = signStrings + k + "=" + value + "&"
            } else {
                signStrings = signStrings + k + "=" + value//最后一个不加此符号
            }
        }
    }

    //对字符串进行SHA1哈希
    t := sha1.New();
    io.WriteString(t,signStrings);
    upperSign := fmt.Sprintf("%x",t.Sum(nil));

    return upperSign
}

你看,这里的代码长的丧心病狂,实际上,连着注释掉的部分一起看,就是整个支付的逻辑,而上线的时候你不能还有test啊,否则不在白名单无法使用,那就得把test中的部分逻辑放到正式的WXShopCartPayController中去

WXShopCartPayController

package controllers

import (
    "github.com/astaxie/beego"
    "fmt"
    "io/ioutil"
    "strings"
    "net/http"
    "bytes"
    "github.com/astaxie/beego/orm"
    "strconv"
    "rbearserver/shopUtils/RandomStrUtil"
    "time"
    "rbearserver/models"
    "encoding/xml"
    "rbearserver/shopUtils/logUtils"
)


/** 接收微信支付订单结果 */


type WXShopCartPayController struct {
    beego.Controller
}

func (c *WXShopCartPayController) Get() {

    //if WXShopCartPayController_uid = GetWxIdInWxShop.GetWxId(c.Ctx,c.Ctx.Input.URI()); WXGoodInfoController_uid != "" {
    if wxid,_ := c.GetSession("uid").(string); wxid != "" {
        fmt.Println("WXShopCartPayController wxopenid = ",wxid)
        cgetShopCartForm(c,wxid)
    } else {
        fmt.Println("WXShopCartPayController uid==空")
    }
    c.TplName = "wx_shop_cart_pay_test.html"
}

func (c *WXShopCartPayController) Post() {

    c.EnableRender = false
    fmt.Println("WXShopCartPayController 接收微信支付订单结果--------------post")
    //微信支付回调函数 成功后跳转至订单页面
    WxpayCallback(c.Ctx.ResponseWriter.ResponseWriter,c.Ctx.Request)
}

func cgetShopCartForm(c *WXShopCartPayController,wxid string) {

    fmt.Println("走的是正式支付接口-----------2")
    orderid_str := c.GetString("orderid")
    orderid,_ := strconv.Atoi(orderid_str)//订单id 根据此id可以查询good_order表获取商品及购买者信息
    o := orm.NewOrm()
    order := models.GoodOrder{Id:orderid}

    if err := o.Read(&order,"id"); err == nil {

        orderPrice,_ := strconv.ParseFloat(order.OrderValue,64)
        totalFee := int(orderPrice * 100)

        //请求UnifiedOrder的代码
        var yourReq UnifyOrderReq

        wxbase := models.WxBase{Id:1}
        err := orm.NewOrm().Read(&wxbase)
        if err == nil {
            yourReq.Appid = wxbase.AppID
            yourReq.Mch_id = wxbase.ShopKey//账户中心---商户信息---微信支付商户号
        } else {
            fmt.Println("获取wxbase错误",err)
            logUtils.GetLog().Error("获取wxbase错误",err)
            return
        }

        //yourReq.Appid = beego.AppConfig.String("APPID")
        yourReq.Body = "rbshop-" + order.Goodname//浏览器打开的移动网页的主页title名-商品概述
        //yourReq.Mch_id = beego.AppConfig.String("shopKey")
        yourReq.Nonce_str = RandomStrUtil.GetRandomString(32)
        yourReq.Notify_url = beego.AppConfig.String("baseURL") + "/shop_cart/pay"
        yourReq.Trade_type = "JSAPI"
        yourReq.Spbill_create_ip = c.Ctx.Input.IP()
        yourReq.Total_fee = totalFee // 单位是分 单位换为真实大小 注意要把元转换为分
        yourReq.Openid = wxid
        yourReq.Out_trade_no = strconv.FormatInt(time.Now().Unix(),10) + RandomStrUtil.GetRandomString(3)//订单号

        var m map[string]interface{}
        m = make(map[string]interface{},0)
        m["appid"] = yourReq.Appid
        m["body"] = yourReq.Body
        m["mch_id"] = yourReq.Mch_id
        m["notify_url"] = yourReq.Notify_url
        m["trade_type"] = yourReq.Trade_type
        m["spbill_create_ip"] = yourReq.Spbill_create_ip
        m["total_fee"] = yourReq.Total_fee
        m["out_trade_no"] = yourReq.Out_trade_no
        m["nonce_str"] = yourReq.Nonce_str
        m["openid"] = yourReq.Openid
        yourReq.Sign = wxpayCalcSign(m,wxbase.PayApiKey) //这个key 微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全

        bytes_req,err := xml.Marshal(yourReq)
        if err != nil {
            fmt.Println("转换为xml错误:",err)
            logUtils.GetLog().Error("转换为xml错误:",err)
        }

        str_req := strings.Replace(string(bytes_req),"UnifyOrderReq","xml",-1)
        //fmt.Println("转换为xml--------",str_req)

        bytes_req = []byte(str_req)

        //发送unified order请求.
        req,err := http.NewRequest("POST","https://api.mch.weixin.qq.com/pay/unifiedorder",bytes.NewReader(bytes_req))
        if err != nil {
            fmt.Println("New Http Request发生错误,原因:",err)
            logUtils.GetLog().Error("New Http Request发生错误,原因:",err)
            return

        }
        req.Header.Set("Accept","application/xml")
        //这里的http header的设置是必须设置的.
        req.Header.Set("Content-Type","application/xml;charset=utf-8")

        client := http.Client{}
        resp,_err := client.Do(req)
        if _err != nil {
            fmt.Println("请求微信支付统一下单接口发送错误,原因:",_err)
            logUtils.GetLog().Error("请求微信支付统一下单接口发送错误,_err)
            return
        }

        //------------------到这里统一下单接口就已经执行完成了-------------------

        respBytes,err := ioutil.ReadAll(resp.Body)
        if err != nil {
            fmt.Println("解析返回body错误",err)
            logUtils.GetLog().Error("解析返回body错误",err)
            return
        }
        xmlResp := UnifyOrderResp{}
        _err = xml.Unmarshal(respBytes,&xmlResp)
        //处理return code.
        if xmlResp.Return_code == "FAIL" {
            fmt.Println("微信支付统一下单不成功,原因:",xmlResp.Return_msg," str_req-->",str_req)
            return
        }

        //这里已经得到微信支付的prepay id,需要返给客户端页面,由客户端继续完成支付流程

        //向数据库存入 WxBill 订单号yourReq.Out_trade_no user的wx_id orderId 时间 total_fee
        _,err = o.Insert(&models.WxBill{WxId:wxid,OutTradeNo:yourReq.Out_trade_no,TotalFee:strconv.Itoa(yourReq.Total_fee),CreateTime:time.Now().Format(TIMELAYOUT)})
        if err != nil {
            fmt.Println("记录wx_bill错误",err)
            logUtils.GetLog().Error("记录wx_bill错误",err)
        }

        timeStamp := time.Now().Unix()
        c.Data["prepay_id"] = xmlResp.Prepay_id
        c.Data["appId"] = yourReq.Appid
        c.Data["timeStamp"] = timeStamp
        c.Data["configtimeStamp"] = yourReq.Out_trade_no
        c.Data["nonceStr"] = yourReq.Nonce_str
        fmt.Println("走的是正式支付接口----uri----",c.Ctx.Input.URI())
        c.Data["signature"] = getTicketSigNature(o,c.Ctx.Input.URI(),&yourReq)

        paySign := getPaySign(&yourReq,&xmlResp,timeStamp)
        c.Data["paySign"] = paySign

    } else {
        fmt.Println("查询订单错误",order)
        logUtils.GetLog().Error("查询订单错误",order)
        return
    }
}

OK,你看完就发现跟上面那个test其实没啥区别。为啥我不抽方法呢?因为我一想起来支付的过程就想吐,实在没有改一个字的欲望。

接下来,就是恶心的支付页面

我是非常非常非常非常讨厌写js的,要不是老板不舍得招人,迫不得已我才不写这玩意。

wx_shop_cart_pay_test.html

<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no"> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <title>商城</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="user-scalable=no"> <link rel="stylesheet" type="text/css" href="../../static/css/bootstrap.min.css"> <script src="../../static/js/jquery-3.0.0.min.js"></script> <script src="../../static/js/bootstrap.min.js"></script> </head> <body> <div class="container" style="margin-top: 60px"> <input hidden type="text" id="prepay_id" value={{.prepay_id}}> <input hidden type="text" id="appId" value={{.appId}}> <input hidden type="text" id="configtimeStamp" value={{.configtimeStamp}}> <input hidden type="text" id="timeStamp" value={{.timeStamp}}> <input hidden type="text" id="nonceStr" value={{.nonceStr}}> <input hidden type="text" id="paySign" value={{.paySign}}> <input hidden type="text" id="signature" value={{.signature}}> <div class="center-block" style="width: 70%;margin-top: 10%"> <h1 class="text-center" style="font-size: 4rem;color: #2CB618"> 微信交易请求申请 </h1> <img class="center-block" src="../../static/images/wx-tishi.png" style="margin-top: 60px;height: 300px;width: 300px"/> <h1 class="text-center" style="font-size: 3.5rem;margin-top: 30px">正在提起微信订单</h1> <h1 class="text-center" style="font-size: 3rem;color:#7d7d7d;margin-top: 20px">请勿关闭该页面</h1> </div> </div> <script> var prepay_id = document.getElementById("prepay_id").value; var configtimeStamp = document.getElementById("configtimeStamp").value; var timeStamp = document.getElementById("timeStamp").value; var nonceStr = document.getElementById("nonceStr").value; var paySign = document.getElementById("paySign").value; var signature = document.getElementById("signature").value; var appId = document.getElementById("appId").value; wx.config({ debug: true,// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: appId,// 必填,公众号的唯一标识 timestamp: configtimeStamp,// 必填,生成签名的时间戳 nonceStr: nonceStr,// 必填,生成签名的随机串 signature: signature,// 必填,签名 jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function () { // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 wx.chooseWXPay({ timestamp: timeStamp,// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr: nonceStr,// 支付签名随机串,不长于 32 位 package: "prepay_id=" + prepay_id,// 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) signType: 'MD5',// 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: paySign,// 支付签名 success: function (res) { // 支付成功后的回调函数 alert("支付成功" + JSON.stringify(res)); location.href = "http://www.rollingbear.cn/wx_shop_cart/cart?showAll=1"; },fail: function (res) { console.log("支付失败-----" + res); alert("支付失败" + JSON.stringify(res)); },cancel: function (res) { alert("用户取消支付"); location.href = "http://www.rollingbear.cn/wx_shop_cart/cart"; } }); // WeixinJSBridge.invoke('getBrandWCPayRequest',{ // "appId": appId,//公众号名称,由商户传入 // "timeStamp": timeStamp,//时间戳,自1970年以来的秒数 // "nonceStr": nonceStr,//随机串 // "package": "prepay_id=" + prepay_id, // "signType": "MD5",//微信签名方式 // "paySign": paySign //微信签名 // },function (res) { // if (res.err_msg == "get_brand_wcpay_request:ok") { // alert("微信支付成功!"); // } else if (res.err_msg == "get_brand_wcpay_request:cancel") { // alert("用户取消支付!"); // } else { // alert(JSON.stringify(res)); // } // // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 // //因此微信团队建议,当收到ok返回时,向商户后台询问是否收到交易成功的通知,若收到通知,前端展示交易成功的界面;若此时未收到通知,商户后台主动调用查询订单接口,查询订单的当前状态,并反馈给前端展示相应的界面。 // }); // function onBridgeReady() { // // WeixinJSBridge.invoke( // 'getBrandWCPayRequest',{ //// "appId": appId,//公众号名称,由商户传入 //// "timeStamp": timeStamp,//时间戳,自1970年以来的秒数 //// "nonceStr": nonceStr,//随机串 //// "package": "prepay_id=" + prepay_id, //// "signType": "MD5",//微信签名方式 //// "paySign": paySign //微信签名 // }, // function (res) { // console.log("res.err_msg-----" + res.err_msg); // // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。 // if (res.err_msg == "get_brand_wcpay_request:ok") { // console.log("res.err_msg--okokok---"); // } // } // ); // } // // if (typeof WeixinJSBridge == "undefined") { // console.log("res.err_msg-----1"); // if (document.addEventListener) { // console.log("res.err_msg-----2"); // document.addEventListener('WeixinJSBridgeReady',onBridgeReady,false); // } else if (document.attachEvent) { // console.log("res.err_msg-----3"); // document.attachEvent('WeixinJSBridgeReady',onBridgeReady); // document.attachEvent('onWeixinJSBridgeReady',onBridgeReady); // } // } else { // console.log("res.err_msg-----4"); // onBridgeReady(); // } // }); wx.error(function (res) { // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 alert("wx config失败" + JSON.stringify(res)); }); </script> </body> </html>

如你所见,我使用了非常low的法子来获取传递过来的参数,先加载到页面的input上,然后再用js从input里获取传递过来的数据。而微信的处理代码被注释掉这么多,是因为我从文档里就找到这么多的奇葩代码,请容我再骂一句,这GRD文档,是哪个混球写的,不积德啊。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读