刚刚调试通微信公众号支付,写个博客记录一下。
jsapi必要的几个参数
微信公众号的账户密码,微信商户账号密码.
登陆微信公众号,左下角开发-基本配置,查看APPID
1、公众APPID(已经得到)
2、APPSECEPT(已经得到)
进入微信商户平台:
https://pay.weixin.qq.com/index.php/partner/public/home
3、微信支付商户号(获取到)
API秘钥在商户平台--账户中心--API安全里面,安装证书后可获取到API秘钥
4、API秘钥(获取到)
------------------------------------如果拿到四大参数就可以继续往下看了-------------------------------------------------
二、微信统一下单接口
官方文档地址:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
其中的必填参数
1. appid APPID (已有)
2. mch_id 商户ID (已有)
3. nonce_str 随机字符串
4. sign 签名
5. body 所支付的名称
6. out_trade_no 咱们自己所提供的订单号,需要唯一
7. total_fee 支付金额
8. spbill_create_ip IP地址
9. notify_url 回调地址
10. trade_type 支付类型
11. openid 支付人的微信公众号对应的唯一标识
共有11个参数,两个已经有,还需要九个参数,我们一个一个来获取
nonce_str :微信提供的工具类里面获得,DEMO下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
//获取随机字符串
String nonce_str = WXPayUtil.generateNonceStr();
sign签名:我们需要获得其他十个参数,然后在用工具类来生成(我们后面来做)
body :随便定义
out_trade_no :随便定义,唯一即可
total_fee 支付金额
spbill_create_ip 填写本机局域网地址,不会的在cmd命令里敲一下ipconfig,回车,得到ip地址
notify_url :支付成功后回调地址,随意定义,后面可修改
如果前面的你都搞定了,那么重点来了 openid,这个参数很难搞。企业号号获取方式有点区别,企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换,普通公众号请往下看:
1、登陆微信公众号,在公众号设置--功能设置里面,添加网页授权域名
2、记住网页授权名,用URLEncoder编码一下
String text1= java.net.URLEncoder.encode("https://www.tes-sys.com","utf-8");
System.out.println(text1);
拿到这种东西:https%3A%2F%2Fwww.tes-sys.com
3、拼接参数
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx20ea285ce626dd6f&redirect_uri=https%3A%2F%2Fwww.tes-sys.com&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
需要修改点appid、redirect_uri。其他都不用变,然后发到你的手机上去吧,在微信浏览器中打开,完成授权
如果进来了你刚输入的网页,便是你已经成功了,
4、右上角,复制链接,随便找个地方复制出来,你会神奇的发现你网址后面跟了参数
https://www.tes-sys.com/?code=011mn0uX0B7GL22xHqtX0ez2uX0mn0u2&state=STATE
我们需要这个code:赶紧记录下来
011mn0uX0B7GL22xHqtX0ez2uX0mn0u2
5、获取code后,请求以下链接获取access_token和openid:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx20ea285ce626dd6f&secret=7883468df98ad41001a9521a2b69c9cc&code=011mn0uX0B7GL22xHqtX0ez2uX0mn0u2&grant_type=authorization_code
需要替换的地方appid、secret、code
在浏览器打开网址,你就能获取到json字符串
折腾这么久,终于拿到openid,喝个下午茶庆祝一下\(^o^)/~~~~~~
所有参数都已经拿到,就剩下sign签名了,不急,我们有工具类
首先写个集合
Map map = new HashMap(); map.put("appid",appid); map.put("mch_id",mch_id); map.put("nonce_str",nonce_str); map.put("body",body); map.put("out_trade_no",out_trade_no); map.put("total_fee",total_fee); map.put("spbill_create_ip",spbill_create_ip); map.put("notify_url",notify_url); map.put("trade_type",trade_type); map.put("openid",openid); //签名 String sign = WXPayUtil.generateSignature(map, "TesPay20**********ghaiZhenbe"); System.out.println("微信签名: "+sign);
这个方法里面前面放map,后面放API秘钥,拿到微信签名。记得将sign也放入集合里面
map.put("sign",sign);
继续使用工具类,把集合转化为xml格式的字符串
String weChatXML = WXPayUtil.mapToXml(map); <?xml version="1.0" encoding="UTF-8"?> <xml> <sign>DE6698C6AF5315F4F981FB9104BF1943</sign> <body>测试</body> <mch_id>1356014002</mch_id> <spbill_create_ip>192.168.110.124</spbill_create_ip> <total_fee>1</total_fee> <notify_url>192.168.110.124:8181/sample/weChat</notify_url> <appid>wx20e********26dd6f</appid> <openid>orDFks7S********6CNLnGJpkgnLY</openid> <out_trade_no>2018013000001</out_trade_no> <nonce_str>wPo7Ibivx5clIPzInUJipROh0Biwgg8p</nonce_str> <trade_type>JSAPI</trade_type> </xml>
发送post请求,到统一下单接口
String xxxx =HttpClientUtils.ZjsSendPost("https://api.mch.weixin.qq.com/pay/unifiedorder",weChatXML);
如果上述步骤都没有错误的话,你就可以拿到
<package>prepay_id=wx16175508554*****ace6fe0866171705</package>
至此,你已经完成一大半了,还剩下前台调用jsapi代码
--------------------------------------------------前台操作华丽分割线--------------------------------------------------------
前端页面需要引入微信的js
<script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script> WeixinJSBridge:为微信浏览器内置js对象,只有在微信浏览器中才有效 if (typeof WeixinJSBridge == "undefined"){ $(document).on('WeixinJSBridgeReady', function() { //公众号支付 WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":appId, //公众号名称,由商户传入 "timeStamp":timeStamp, //时间戳,自1970年以来的秒数 "nonceStr":nonceStr, //随机串 "package":package1, "signType":signType, //微信签名方式: "paySign":paySign //微信签名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } }); }); }else{ onBridgeReady(); }
上述六个参数是从java端传过来的
"appId":appId, //公众号名称,由商户传入
"timeStamp":timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":nonceStr, //随机串
"package":package1,
"signType":signType, //微信签名方式:
"paySign":paySign //微信签名
在微信浏览器里面打开H5网页中执行JS调起支付,文档地址
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
我们需要传递的这些参数切勿和之前的弄混。
1、appId(已有)
2、timeStamp,下方给出
String timeStamp = System.currentTimeMillis()/1000+"";
3、nonceStr,
String nonceStr=WXPayUtil.generateNonceStr();
4、package
我们之前获取到的<package>prepay_id=wx16175508554*****ace6fe0866171705</package>,此时可以用了,注意提交的格式,前面加上prepay_id=
String package1="prepay_id=wx16175508554*****ace6fe0866171705";
5、signType
String signType="MD5";
6、paySign (微信支付签名,需要我们重新获取)
获取方式和之前获取签名一样,新建map集合,将五个参数放进去,拿到签名之后传递到前台就好了。
//调用微信接口,唤起微信支付 String appId="wx20ea285ce626dd6f"; String timeStamp = System.currentTimeMillis()/1000+""; String nonceStr=WXPayUtil.generateNonceStr(); String package1="prepay_id="+prepay_id; String signType="MD5"; Map map2 = new HashMap(); map2.put("appId",appId); map2.put("timeStamp",timeStamp); map2.put("nonceStr",nonceStr); map2.put("package",package1); map2.put("signType",signType); //第二个参数商户api秘钥 String paySign = WXPayUtil.generateSignature(map2, "TesPay201820182018ShanghaiZhenbe"); System.out.println("公众号支付签名: "+paySign);
写到这里为止,代码工作已经完成,我们还有一个授权目录没有设置,登陆商户平台--产品中心--开发配置--支付授权目录
添加规则是,我的当前支付页面是aa.vm,我的访问路径是www.xxx.com/sample/code,我是ssm框架,code是我的方法,调用次方法返回我的aa.vm页面,那么我这里就应该填写:www.xxx.com/sample/。
此篇文章由DurkBlue博客申请发布,转载吧请注明来处