本文共 3993 字,大约阅读时间需要 13 分钟。
之前说过,有时间把微信支付的H5支付讲解下,一直拖了半年时间,最近的项目正好又温习了支付功能,趁着热乎,抓紧起来。
微信的H5支付,相对公众号支付,容易了跟多,很多相似的东西,也有不同之处,这里只介绍H5支付的关键点,其他内容请先去看我的微信支付(公众号支付)那篇文章。
(传送门:)。
官网定义:要求商户已有H5商城网站,并且已经过ICP备案。通过微信H5支付可以实现在非微信浏览器(如QQ浏览器、谷歌浏览器、Safari等)中使用微信支付的场景。ps:说白了就是在微信外的所有浏览器如UC浏览器来点击“微信支付”然后自动唤起微信客户端来支付。
如果要测试支付的话,可以找个内网穿透的软件如(花生壳或natapp)他们的域名都是ICP备注过的,然后从手机浏览器访问微信支付的页面。
1. 预备好微信支付的“四大参数”--(默认已准备好)。
2.1 在“商户平台”-我的产品-中开通H5支付,大概半天左右的时间可以审核通过。
2.2在-开发配置中填写H5支付域名,必须填写,要不然不能支付。
1.前端部分:H5支付前端的东西很少,就是点击“微信支付”,后端接口只返回一个用来跳转的地址(下面还会提到),然后跳转到这个地址就OK了,所以难点是后台部分。
2.后端部分:后台还是调用微信的“统一下单”接口,不过H5的“统一下单”所需参数少了很多。咱们看看都有那些参数:
其中必须的参数有:
1.appid--“四大参数”之一
2.mch_id--“四大参数”之一
3.nonce_str--随机字符串--用工具类获取
4.body--商品描述
5.out_trade_no--商城的订单号保持唯一
6.total_fee--支付金额单位:分
7.spbill_create_ip--ip地址
8.notify_url--支付成功回调地址
9.trade_type--交易类型--只能用“MWEB”
10.scene_info--场景信息值是个json字符串,注意给值时转义“双引号”,例子:"{\"h5_info\":{\"type\":\"Wap\",\"wap_url\":" 可以填应该网站的URL地址 ",\"wap_name\": \"订单支付\"}}"
11.sing--签名加密
H5支付的“统一下单”参数就是这么简单,把上面的参数整理好POST发送微信统一下单接口,返回的是个XML的字符串,如果成功,返回的是类似如下(美化后的字符串-微信后台返回的是一行):
里面的 mweb_url就是上面提到的前端要的跳转页面了,如果你想在支付完后,跳到指定页面可以在值的后面拼接指定redirect_url即可(要urlencode)如下:。
前端只需 location.href = mweb_url就可以开心的唤起微信来支付了。
一般我们的代码需要处理公众号和H5支付的情况,js代码navigator.userAgent返回客户端信息如果里面有"MicroMessenger"表示是微信浏览器,可以用公众号支付,否则用H5支付,可以参考如下代码:
页面有“微信支付”按钮,点击执行pay()方法。
function pay() { if (navigator.userAgent.indexOf("MicroMessenger") != -1) { pay_weixin();//微信浏览器支付 } else { pay_other();//其他浏览器H5支付 }}function pay_other() { var url = WEB + "/pay/orders_other $.get(url,function(result) { location.href = result.mweb_url; });}function pay_weixin() { //公众号支付方法}
2.后端代码 里面的工具类,可以参考公众号支付里面有。
/** * @Description H5调起微信支付微信浏览器外支付 * @param request * @return Map */ @RequestMapping(value="orders_other", method = RequestMethod.GET)@ResponseBodypublic Maporders_other(HttpServletRequest request) { try { //拼接下单地址参数 Map paraMap = new HashMap (); //获取请求ip地址 String ip = getIP(request); paraMap.put("appid", appid); paraMap.put("mch_id", mchId); paraMap.put("nonce_str", WXPayUtil.generateNonceStr()); paraMap.put("body", "XX商城-订单结算"); paraMap.put("out_trade_no", "201810102938949");//商品的订单号每次要唯一 paraMap.put("total_fee", "1"); paraMap.put("spbill_create_ip", ip); paraMap.put("notify_url", "www.xxxxxx.com/pay/callback"));// 此路径是微信服务器调用支付结果通知路径 paraMap.put("trade_type", "MWEB"); paraMap.put("scene_info", "{\"h5_info\":{\"type\":\"Wap\",\"wap_url\":"随意地址可以是公司官网地址",\"wap_name\": \"订单支付\"}}"); String sign = WXPayUtil.generateSignature(paraMap, paternerKey); paraMap.put("sign", sign); String xml = WXPayUtil.mapToXml(paraMap);//将所有参数(map)转xml格式 // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder String unifiedorder_url = https://api.mch.weixin.qq.com/pay/unifiedorder; String xmlStr = HttpRequest.sendPost(unifiedorder_url, xml);//发送post请求"统一下单接口" //以下内容是返回前端页面的json数据 String mweb_url = "";//跳转链接 if (xmlStr.indexOf("SUCCESS") != -1) { Map map = WXPayUtil.xmlToMap(xmlStr); mweb_url = (String) map.get("mweb_url"); //支付完返回浏览器跳转的地址,如跳到查看订单页面 String redirect_url = "www.xxxxx.com/orders"; String redirect_urlEncode = URLEncoder.encode(redirect_url,"utf-8");//对上面地址urlencode mweb_url = mweb_url + "&redirect_url=" + redirect_urlEncode;//拼接返回地址 } Map payMap = new HashMap (); payMap.put("mweb_url", mweb_url); return payMap; } catch (Exception e) { _log.info("微信支付异常"); } return null; }
返回给前端的结果如下所示:
H5支付就是这么多了,可能不会一次调通,耐心看错误提示,祝早日支付成功。(完)