Java-Web微信网页支付开发流程以及各种坑

微信网页支付流程概览

  • 生成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拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)

使用开源的“weixin-java-tools”可以方便地生成授权链接:

//首先配置你的公众号信息
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进行支付

欢迎到我的博客里坐坐 http://www.xiaomilu.top

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值