公众号支付就尼玛是个天坑
首先场景介绍
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
看完场景介绍后脑子里会觉得这个东西也太简单了8? 然而。。
ps:因为没有登平台没有配图只有文字了。
官方配置
需要在微信公众号平台开通认证(开发者配置迁移到了商户平台),商户平台获取一些必要的参数;
微信公众号平台里获取Appid,开发者密码AppStore,支付的商户号。
商户平台API密钥:之前签名我都是用开发者密码签名一直返回签名错误!
商户平台坑的一批 两分钟没操作就登录超时, 期间我要重置API密钥一直找老板发短信验证码跟扫二维码,老板都想砍我了。
---
拿到(配置)这些之后还要去公众号平台的接口权限配置网页授权域名访问(这个不能家http:// 只能是项目域名!比如www.baidu.com)
配置域名访问还要在服务器目录下放置一个text的文件 在公众号平台可以下载。域名最多配置3个,每个月可修改3次。
---
还有一项非常重要的配置
商户平台还需要在产品中心配置支付url访问,就是你项目调用微信支付的上一层url。
比如http://www.baidu.com/wxpay 不配这个调起微信支付控件会一闪而过报支付url未注册。
开发流程
微信有开发流程文档(垃圾),JSAPI支付(公众号支付)。
首先需要获取openid --- 一个openid对应的是一个用户对应一个公众号 不变。
获取到openid后调用统一下单接口 微信接收openid等参数返回一个预支付id等数据。
拿到预支付id跟一些参数后调起微信支付控件同时调用微信查询订单状态获取返回信息跳转支付成功还是失败的页面。
工具类
请求微信url我用的HttpClient
需要在pom里配置微信的SDK调用WXPayUtil
<!-- 微信支付 -->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
最后调起微信支付界面需要下载JSAPI
开发接口
1、首先需要获取到openid
window.location.href ='https://open.weixin.qq.com/connect/oauth2/authorize?appid='+appid+'&redirect_uri='+encodeURIComponent(local)+'&response_type=code&scope=snsapi_base#wechat_redirect';
获取openid的前提需要先GET请求到open.weixin.qq.com/connect/oauth2/authorize获取用户的code
appid:配置好的appid
redirect_uri:这是请求完后微信回跳咱们的url(需要加http://)比如http://www.baidu.com/login.html。回跳会把code放在url后面
response_type:这个就写code
scope:这里可以填两种【snsapi_base,snsapi_userinfo】snsapi_base是静默授权,获取用户code的时候是不通知用户获取的,snsapi_userinfo是非静默授权,获取时用户界面会弹出一个界面获取微信用户的用户名,性别,地址,用户点击确认。
#wechat_redirect:这个不用管,这样填就完了。
之后会回跳到我们填的url然后我们需要获取到code
// 获取地址栏参数
getUrlParam(param) {
var reg = new RegExp("(^|&)" + param + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null){
return decodeURIComponent(r[2]);
}
return null; //返回参数值
},
获取code后,请求以下链接获取openid:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
secret:上面配置的开发者密码--AppSecret
code:上一步url里的code
最后那个参数就那样填;
完事会返回一个json串,里边就有openid。 存在session里以后用。
2、统一下单
在用户选择金额点击充值时请求统一下单接口 https://api.mch.weixin.qq.com/pay/unifiedorder
请求参数类型皆为String就行
appid:公众号id
mch_id:商户号
nonce_str:一个随机字符串,可用微信SDK里的WXPayUtil.generateNonceStr()随机生成
sign:签名,这个是所有其他参数和API密钥合成的签名
body:商品描述,比如:英雄联盟--微信充值
out_trade_no:开发者自带的订单号,可用new IdWorker().nextId()随机生成或从数据库里取
total_fee:金额,充值的金额。单位为分。
spbill_create_ip:终端ip,随便填:127.0.0.1
notify_url:通知地址 没用 随便填http://www.weixin.qq.com/wxpay/pay.php
trade_type:公众号需填JSAPI
openid:这个就是上面取来的openid了
把这些参数全部封装在一个Map里(签名除外,map的key一定要跟参数名一样)
WXPayUtil.generateSignedXml(parm, PayConfigUtil.apikey);
用此方法将参数1(Map),参数2(API密钥)自动MD5加密成XML返回。
将XML请求给
https://api.mch.weixin.qq.com/pay/unifiedorder
返回接受一个XML拿到预支付id -- prepay_id
3、调起微信支付控件
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":abc.data.appid, //公众号名称,由商户传入
"timeStamp":abc.data.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":abc.data.nonce_str, //随机串
"package":abc.data.prepay_id,
"signType":"MD5", //微信签名方式:
"paySign":abc.data.paySign //微信签名
},
function(res){
console.log(res);
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
alert("o");
}else{
}
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
);
注意package参数应该是 package:prepay_id='prepay_id' 这样的格式 不然会签名错误
4、调用微信查询订单接口
https://api.mch.weixin.qq.com/pay/orderquery
跟统一下单同样的方式传递参数
appid
mch_id
out_trade_no
nonce_str
循环查询
返回的 trade_state为SUCCESS时跳转成功页面。
如果碰到返回签名错误可能是商户平台的API密钥需要重置设置一下,有时候更改了一些小参数也需要更新不然可能导致签名错误而且找不到错的地方,应该是微信支付加密签名存在内部缓存,更新API密钥可清除他的内部缓存。。。很坑。。。
https://www.cnblogs.com/yimiyan/p/5603657.html
网上看到一个妹子写的 有点意思
还有微信web开发者工具
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html