做为一个刚刚做完微信公众号的小白,我不得不吐槽一下微信给的官方文档,里面那坑一个接一个,我这是跳进去再爬出来,一下给做了四天,本来技术就不够好,还被文档带的跑偏跑偏。。。我在这给大家整理一份超级详细的文档
首先:还是得参考官方文档滴,这个是必须滴
先贴上业务流程图镇贴,当初才开始开发的时候,看这个图真的是看不懂,也不想去看,相信大家都有这种感觉,但是,我想告诉 大家,这个图真的很是重要,看懂图会给开发带来很大的方便。实在不想看的就看我给大家分析吧,一张大图中有这么多的小图和文字,其实你我们需要注意的就只有标红的部分,这里微信文档还比较贴心,把侧重的地方都标上了红,从上往下来分析
第一处标红地方:生成图文消息链接,其实就是你跳转到支付页面的链接,也是你获取code的链接
第二处标红:生成商户订单和统一下单,到这就是我们后台的事了,统一下单就用微信提供的https://api.mch.weixin.qq.com/pay/unifiedorder这个下单接口,其实就是微信这个方法微信提供的sdk中的WXPay类中有,到时候先把pom依赖包导入
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
然后调用方法如下
导入依赖包之后这些就直接导包就行
WXpayConfig config = new WXpayConfig();
WXPay wxpay = new WXPay(config);
wxpay.unifiedOrder("参数")
参数呢:按照文档来,我是一个都没少(之前测试时参数不够,大小写不对时都调不起支付的框)
参数如下:
/**
* 支付
*
* appid 应用ID 是 String(32) wxd678efh567hg6787 微信开放平台审核通过的应用APPID
* mch_id 商户号 是 String(32) 1230000109 微信支付分配的商户号
* nonce_str 随机字符串 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
* sign 签名 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
* device_info 设备号 否 String(32) 013467007045764 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
* body 商品描述 是 String(128) 腾讯充值中心-QQ会员充值 商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
* out_trade_no 商户订单号 是 String(32) 20150806125346 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。详见商户订单号
* total_fee 总金额 是 Int 888 订单总金额,单位为分,详见支付金额
* spbill_create_ip 终端IP 是 String(16) 123.12.12.123 用户端实际ip
* notify_url 通知地址 是 String(256) http://www.weixin.qq.com/wxpay/pay.php 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
* trade_type 交易类型 是 String(16) APP 支付类型
* openid 用户标识String(128) 是 oUpF8uMuAJO_M2pxb1Q9zNjWeS6o trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换
* @throws Exception
*/
sign 签名 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
* device_info 设备号 否 String(32) 013467007045764 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
* body 商品描述 是 String(128) 腾讯充值中心-QQ会员充值 商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
* out_trade_no 商户订单号 是 String(32) 20150806125346 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。详见商户订单号
* total_fee 总金额 是 Int 888 订单总金额,单位为分,详见支付金额
* spbill_create_ip 终端IP 是 String(16) 123.12.12.123 用户端实际ip
* notify_url 通知地址 是 String(256) http://www.weixin.qq.com/wxpay/pay.php 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
* trade_type 交易类型 是 String(16) APP 支付类型
* openid 用户标识String(128) 是 oUpF8uMuAJO_M2pxb1Q9zNjWeS6o trade_type=JSAPI时(即公众号支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识。openid如何获取,可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid,再调用【企业号userid转openid接口】进行转换
* @throws Exception
*/
参数中特别需要注意的参数我都用红色标记出来了
官网上给的openid写的否,但是在公众号支付开发时openid是必传的东西,openid的获取方式参考我之前的文档(https://blog.csdn.net/m_y_y/article/details/80022695)这里有超详细的获取openid的方法
还有这个终端IP,这里也会出现很大的问题,终端IP指的是用户的IP,这里给出获取方法
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
这里给出我传的参数:
data是一个map
注意sign签名这里传的data只包含前面三个参数,这里顺序不能乱,并且大小写一定要注意,签名的加密方式必须是MD5加密,因为前端调起支付时的加密方式只能是MD5,方式不同也调不起来
回调地址必须是外网能访问到的的地址,这个地址是在你支付完成后执行的接口,是微信自己去调,这个大家不用管
打包之后传到下单的接口中,在下单完成后,会给你返回一个XML形式的东西,这个你可以将返回的东西log出来自己看,返回的东西里面有一个prepay_id的参数,这个就是你的预订单号,得到他之后开发就进行了一半了
再就是打包一个map,也就是前端调支付的那些个参数,全部打包返给前端,
这里需要再次签名一次,
打包参数:
这里的key值一定不能写错,写错返给前端也会调不起支付,将这些参数return了就行,,,注意这里的签名是重新去签的
返给前端之后,用前端H5调起支付框
function onBridgeReady(data){//这里的data就是你刚才打包的map
WeixinJSBridge.invoke(
'getBrandWCPayRequest',{
"appId":data.appId, //公众号名称,由商户传入
"timeStamp":data.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":data.nonceStr, //随机串
"package":data.package,
"signType":"MD5", //微信签名方式:
"paySign":data.data.paySign,//微信签名ign//微信签名,
},function(res){
if(res.err_msg == "get_brand_wcpay_request:ok"){
mui.toast("缴费成功!");
setTimeout(function(){
window.location.href = "success.html?webParam=" + escape(JSON.stringify(chargeObj));
},1000);
}else if(res.err_msg == "get_brand_wcpay_request:fail"){
//提示用户充值失败
mui.toast("缴费失败,稍后再试!");
}
}
);
}
这里就大功告成了,在你支付完成之后就会进入你的回调接口
小M微信二维码 : 有问题可以加微信
打赏二维码:觉得有用有帮助的可以给小M~打赏哦