微信又TMD改版了
2个月前我做的一个微信公众号商城支付是正常的,但是同样的设置,目前做的这个却不正常了,老给我报invalid url domain,试遍了所有能找到的法子依然不行,卧槽他大爷,连写博客的欲望都没了,此坑待填。
跨过该死的设置,说下之前解决掉的2个问题:
- 微信安全设置要求服务器在你填写业务域名或js安全域名的位置,可以访问到一个MP_verify_xxxx.txt(之前无此硬性要求 我CNNND)
- 支付 而支付又分页面和后台
先说这个MP_verify_xxxx.txt咋办
直接说结果,beego框架有个缺点,不支持这么搞。比如我的域名是www.baidu.com,微信要求你,如果你这么填,就要求www.baidu.com/MP_verify_xxxx.txt能访问到,太悲催了。
2个解决办法:
- 不在根目录下,添加个2级目录,然后在main.go中设置
beego.SetStaticPath("/wx_shop_cart", "mp")
注意要写到beego.Run()之前 - 非得在根目录下,没其他可能,那可以这么搞:
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=%v\n", 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("查询订单错误", err, 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, 对key进行升序排序.
sorted_keys := make([]string, 0)
for k, _ := range mReq {
sorted_keys = append(sorted_keys, k)
}
sort.Strings(sorted_keys)
//STEP2, 对key=value的键值对用&连接起来,略过空值
var signStrings string
for i, k := range sorted_keys {
//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
value := fmt.Sprintf("%v", 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, 对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 i, k := range sorted_keys {
//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
value := fmt.Sprintf("%v", 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, 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)
}
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("查询订单错误", err, order)
logUtils.GetLog().Error("查询订单错误", err, 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文档,是哪个混球写的,不积德啊。