Java将微信和支付宝支付的个二维码合二为一的方法
因公司需要将支付宝和微信的二维码合成一个,不管用户用支付宝扫还是微信扫都能打开对应的支付页面,在网上找了一些文章,很感谢各位大神的经验,我也记录下我是如何将两个二维码合二为一的~。
原理:支付宝或微信生成的二维码中本质都内嵌了一个url,在扫码时实际是定向去访问二维码中内嵌的url,这样我就可以将这个url指定到我的一个控制器,在控制器中判断是微信还是支付宝软件扫的,然后去唤醒各自的支付即可。
1.首先生成二维码:
folderName:存储二维码图片的文件夹名
imageName:二维码图片名称
content:是在二维码中写入的内容,这里我传入的是URL:指定我判断软件类型的控制器
publicstaticStringgenQRImage(StringfolderName,StringimageName,Stringcontent){ //StringfilePath=System.getProperty("twtwebapp.root"); StringfileName=imageName+".png"; try{ //检查是否存在imageQR目录,不存在则先创建 Filefile=newFile(folderName); if(!file.exists()&&!file.isDirectory()){ file.mkdir(); } folderName=file.getAbsolutePath(); intwidth=200;//图像宽度 intheight=200;//图像高度 Stringformat="png";//图像类型 Maphints=newHashMap (); hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); hints.put(EncodeHintType.MARGIN,1); BitMatrixbitMatrix=newMultiFormatWriter().encode(content,BarcodeFormat.QR_CODE,width,height,hints);//生成矩阵 Pathpath=FileSystems.getDefault().getPath(folderName,fileName); MatrixToImageWriter.writeToPath(bitMatrix,format,path);//输出图像 log.info("二维码已经生成,"+path); fileName=path.toString(); }catch(Exceptione){ log.error(e.getMessage(),e); fileName=null; } returnfileName; }
2.定义类型控制器:
大家一定都想问是如何判断打开软件的类型,把RequestHeaderCookie都看看就明白了,扫码二维码时不会传入任何参数,
但会有一个请求头,就是这个请求头告知了我打开软件的类型。
使用request获取名为User-Agent的请求头,
支付宝的请求头:ucbrowser/1.0.0.100u3/0.8.0mobilesafari/534.30alipaydefined(nt:wifi,ws:360|604|3.0)aliapp(ap/9.9.7.112401)alipayclient/9.9.7.112401language/zh-hansusestatusbar/true
微信的请求头:mqqbrowser/6.8tbs/036887safari/537.36micromessenger/6.3.31.940nettype/wifilanguage/zh_cn
就是根据这两个请求头去判断对应的软件类型,根据不同的软件类型去唤醒不同的支付。
@RequestMapping("qrcallback") publicvoidqrcallback(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException,AlipayApiException{ Stringagent=request.getHeader("User-Agent").toLowerCase(); System.out.println("响应头的类型:"+agent); if(agent.indexOf("micromessenger")>0){ System.out.println("微信支付"); }elseif(agent.indexOf("alipayclient")>0){ System.out.println("阿里支付"); Stringform=testService.aliPay(); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(form);//直接将完整的表单html输出到页面 response.getWriter().flush(); //response.sendRedirect("/ali.html"); } }
3.先说简单的,唤醒支付宝支付,其实使用的是支付宝手机网站支付:这个需要签约噢~
https://b.alipay.com/signing/productDetail.htm?productId=I1011000290000001001
这个唤起支付可以看看官网是怎么写的:https://doc.open.alipay.com/docs/doc.htm?treeId=203&articleId=105285&docType=1
有两种方式:一种是页面唤醒,自己构建请求form参数然后请求支付宝唤醒支付操作,另一种是服务端调用支付宝的SDK去生
成form参数然后去请求支付宝,我使用的是第二种。
步骤:
1.首先引入pom.xml依赖
com.twt.charge alipay-sdk-java 20160519120058
2.生成form参数:
里面的参数自己填写从支付宝获取的那些参数,copy我的肯定出错哈
publicStringaliPay()throwsAlipayApiException{ AlipayClientalipayClient=newDefaultAlipayClient(openapi,SecurityUtil.decodeBase64(appid), SecurityUtil.decodeBase64(rsa_private_key),"json","utf-8",SecurityUtil.decodeBase64(alipay_pub_key)); AlipayTradeWapPayRequestalipayRequest=newAlipayTradeWapPayRequest();//创建API对应的request alipayRequest.setReturnUrl("http://192.168.1.219:22222/ali.html"); alipayRequest.setNotifyUrl("http://192.168.1.219:22222/callback");//在公共参数中设置回跳和通知地址 alipayRequest.setBizContent("{"+"\"out_trade_no\":\"20160320020192222\","+"\"total_amount\":66.66," +"\"subject\":\"主题\","+"\"seller_id\":\"213215dsa\","+ //"\"product_code\":\"QUICK_WAP_PAY\""+ "}");//填充业务参数 Stringform=alipayClient.pageExecute(alipayRequest).getBody();//调用SDK生成表单 returnform; }
将这个form以流的形式输出即可。
如:
response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(form);//直接将完整的表单html输出到页面 response.getWriter().flush();
唤起支付宝支付就这么简单,但要注意参数中的账单号要是商户系统中唯一的账单号。
4.唤起微信支付:唤起的其实是微信公众号支付,做过公众号支付的同学都知道,调用微信公众号的统一下单API时
需要传入openID,即用户在该公众号的下的唯一标识,这个过程需要用于授权登录该公众号,这个过程是一个缺点,
用户仅仅只是微信的扫码支付,但你中间不是黑箱子的形式展示,而是在支付中多出了一个授权登录的页面,并且
也比较繁琐,在唤醒微信支付的过程中请求次数较多,所以微信支付会比正在的扫码支付会慢很多。
唤起微信公众号支付:
步骤:
1.首先拼装好你的授权登录url。在类型控制中判断如果是微信支付则重定向到微信授权登录页面,微信会重定向到
你在授权登录url中设置重定向url参数的页面,
2.跳转到这个页面后,先获取到用户code然后利用ajax访问服务端,
3.服务端使用code去获取用户的openID,
4.根据openID去调用微信公众号的统一下单API生成参数,然后返回给页面唤醒支付,这就是整个微信的流程,
中间访问了3次微信获取数据,整个流程共6次请求,需要将微信跳转的页面放到官网的微信目录下。
在写这篇博文的时候因为支付宝我还没有签约,所以没有调通,而微信也只成功了一次,但第二次什么都没改的情况
下就不行了,写这篇博文顺便捋捋思路,怎么更简单。
注:访问微信授权页面中的redirect_url参数可以添加请求参数。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。