Java-Web微信网页支付开发流程以及各种坑
2016-12-28 15:09
585 查看
微信网页支付流程概览
生成Oauth2.0授权链接获得code使用code获得用户信息(OpenId)
向微信统一下单接口提交订单获得PrepayID
在JS页面中向用户发起支付请求
用户输入支付密码完成支付
使用weixin-java-tools工具可以快速完成以下开发
1.生成Oauth2.0授权链接
为什么要生成授权链接:当要为某用户提交支付订单时必须要得到该用户的OpenId(OpenId是加密后的微信帐号,同一个用户在不同的公众号内的该值是不同的)而获得用户的OpenId,就需要用户对你的公众账号进行授权(可以不需要关注),用户授权之后微信将会发送一个code到你提供的页面(redirect_uri)
你需要提供和关心的内容
参数 | 说明 |
---|---|
appid | 公众号的唯一标识 |
redirect_uri | 授权后重定向的回调链接地址,请使用urlencode对链接进行处理 |
scope | 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) |
//首先配置你的公众号信息 WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage(); config.setAppId("你的APPID"); WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(config); //轻松地拼接一个Oauth2.0授权链接 System.out.println(wxMpService.oauth2buildAuthorizationUrl("你的redirect_uri","snsapi_userinfo","传递一个state参数(可为null)"));
例如这里redirect_uri填写: http://mytest.com/test/pay
运行后会生成类似如下链接:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx19c7c9777756d0cc&redirect_uri=http%3A%2F%2Fmytest.com%2Ftest%2Fpay&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
上述链接需要你放置在你的微信公众号或者提交订单时的H5页面中,引导用户点击进行授权。从而可以进行以后的支付操作。
用户在该链接中选择授权您的公众号之后,微信会立即发送code值和state(你自己设定的字段)到你的redirect_uri中:
http://mytest.com/test/pay?code=CODE&state=STATE
因此你的redirect_uri应当指向一个服务而不是一个静态页面,这里使用tomcat+Java Servlet实现后续步骤
本章节会遇到的坑:
1.实际测试点击授权页面时提示redirect_uri参数错误
这里需要在微信公众号后台-接口权限-网页授权获取用户基本信息-修改 中添加你的redirect_uri的域名,注意是域名哦!此时会获得一个授权文件(txt)需要将该文件放置到你站点的根目录下。
2.使用code获得用户信息(OpenId)
上一步结束之后我们已经在Servlet中拿到code值,接下来我们需要去请求Access_Token和用户的OpenId(关键是要得到OpenId)(注意此处的Access_Token不同于微信开发中的Access_Token并不混用也不会互相刷新。code的有效期限为5分钟,且每申请一次只能使用一次)//同样需要先配置公众号信息,但本次要求的参数为4个 WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage(); config.setAppId("你的APPID"); config.setSecret("你的APPSECRET"); config.setPartnerId("你的商户ID"); config.setPartnerKey("你的商户SecretKey"); WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(config); //使用已经得到的code获取AccessToken和OpenId WxMpOAuth2AccessToken wxMpOAuth2AccessToken= null; WxMpUser wxMpUser = null; try { wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); //下面的方法会获得用户的详细信息,本例用不到但是如有需要之前的步骤也是这么进行 wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null); } catch (WxErrorException e) { e.printStackTrace(); } String Openid=wxMpOAuth2AccessToken.getOpenId(); System.out.println("已经获得获得用户Openid:"+ Openid);
3.向微信统一下单接口提交订单
在下单之前我们需要组织参数官方:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
下述实例将只进行关键必要参数的设置
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest(); //由于我们前面的config配置 因此各种ID会被默认配置进去,NonceStr生成方法是System.currentTimeMillis()也已经默认添加。MD5签名加密问题也无需考虑,其内置的签名方法已经搞定。 orderRequest.setBody("商品描述"); orderRequest.setOutTradeNo("订单ID"); //商户唯一订单号 orderRequest.setTotalFee(1);//价格单位为‘分’ orderRequest.setOpenid(Openid); orderRequest.setNotifyURL("http://www.weixin.qq.com/wxpay/pay.php");//微信回调地址 用户支付成功后微信会向该接口推送结果 orderRequest.setTradeType("JSAPI");//不要修改 orderRequest.setSpbillCreateIp("172.168.1.1");//当前用户的IP WxMpPayService wxMpPayService = wxMpService.getPayService(); String mypackage=""; String nonceStr=""; try { mypackage=""+wxMpPayService.getPayInfo(orderRequest).get("package"); nonceStr=""+wxMpPayService.getPayInfo(orderRequest).get("nonceStr"); System.out.println("prepayID:"+mypackage); } catch (WxErrorException e) { e.printStackTrace(); }
我们现在已经在微信上创建了一笔订单,并且返回我们需要的关键信息为package(包含prepayId),当然nonce_str是之前weixin-java-tools生成的,此时微信也会返回该值直接取得即可。
万事俱备,只欠从界面向用户发起支付请求
4.在JS页面中向用户发起支付请求
我们需要准备一个JSP请求支付的页面,并且在Servlet向其转发刚才获取的关键订单信息<%@ page import="java.sql.Timestamp" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title><link rel="stylesheet" href="js/weui/css/weui.min.css" type="text/css"> <script type="text/javascript" src="js/weui/js/zepto.min.js"></script> <script type="text/javascript" src="js/weui/js/jweixin.js"></script> <script type="text/javascript" src="js/weui/js/weui.min.js"></script> </head> <body ontouchstart> <div> <div class="page"> <a href="javascript:;" class="weui-btn weui-btn_primary" id="btnPay">立即支付</a> </div> </div> <script type="text/javascript"> $("#btnPay").on('click',function(){ console.log("TEST"); }); function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId" : "${APPID}", //公众号名称,由商户传入 "timeStamp":"${TIMEST}", //时间戳,自1970年以来的秒数 "nonceStr" : "${NOCESTR}", //随机串 "package" : "${PREPAYID}", "signType" : "MD5", //微信签名方式: "paySign" : "${MYMD5}" //微信签名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) {} } ); } if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ alert('调用WeiXin支付'); onBridgeReady(); } </script> </body> </html>
本章节会遇到的坑:
1.实际测试时页面提示当前URL页面未注册
这里需要在微信公众号后台-微信支付-授权测试目录里面添加你当前支付JSP页面的目录。
比如我的支付页面是 http://a.com/test/pay/pay.jsp
那么我就需要填写 http://a.com/test/pay/
然而这里有一个坑就是,在实际发起支付的时候他会检查你发起支付的路径是什么,也就是说如果你如果之前使用servler获取数据后向JSP转发数据的话,那么用户在支付的时候url就不是http://a.com/test/pay/pay.jsp
而可能变成了http://a.com/test/pay?key=value
如此一来你填写的支付测试路径就出现了错误。因此需要修改测试路径为 http://a.com/test/ 即可通过。
至此用户在微信中访问第一步的授权链接后,会提示授权,然后跳转到JSP进行支付
相关文章推荐
- 微信扫码支付模式二功能实现,回调,记录充值,整个完整流程,java开发
- 微信小程序开发之webview组件内网页实现微信原生支付
- .net 微信APP支付接口的开发流程以及坑
- 为微信开发填坑:微信网页支付的开发流程及填坑技巧
- 为微信开发填坑:微信网页支付的开发流程及填坑技巧
- JAVAWEB开发之Struts2详解(一)——Struts2框架介绍与快速入门、流程分析与工具配置以及Struts2的配置以及Action和Result的详细使用
- [置顶] java后端 三方登录之微信登录 开发详细流程以及遇到过的坑 总结(非常详细) 2017-12-26
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- java web项目开发流程
- Java Web开发中各种数据库连接方式速查表
- java 集成手机网页支付流程
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- java web开发中各种注意点总结(4)
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- 微信公众帐号开发教程第5篇-各种消息的接收与响应(Java版)
- 红薯 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开始(转)
- java web 开发中各种注意点总结(转)-后期可能会出原创版
- java web开发中各种注意点总结(1)
- Go Web开发之Revel - 网页请求处理流程