微信扫码支付-Native原生支付

来源:互联网 发布:2016淘宝商品排行榜 编辑:程序博客网 时间:2024/06/06 01:39

最近在接触微信第三方支付,自己在写的过程中走了很多弯路,现在写了一个可以使用的微信扫码支付,写到博客中以便自己跟他人参考

微信扫码支付分为两种模式,商户根据支付场景选择相应模式

【模式一】:

商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。

【模式二】:

商户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付

两种模式详情请参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_3

模式二微信接口会返回二维码信息给我们,而模式一需要我们自己去生成二维码信息,相较于模式二复杂,所以我用的是模式二,模式二的微信扫码支付需要先调用微信的统一下单接口,生成预交易订单,正确调用后,会返回含有交易标识的ID和二维码连接的URL
统一下单接口请求参数等详情请参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

java代码获取二维码连接URL案例:
public void QRCodeImg() throws ServletException, IOException {String appid="wxd678efh567hg6787";//公众账号appidString mch_id="1230000109";//商户号String currTime = TenpayUtil.getCurrTime();//8位日期String strTime = currTime.substring(8, currTime.length());//四位随机数String strRandom = TenpayUtil.buildRandom(4) + "";//10位序列号,可以自行调整。String strReq = strTime + strRandom;String nonce_str=strReq;//随机字符串String body="付款中心-订单付款";String out_trade_no="20150806125346";//订单号int total_fee=100;//标价金额,单位为分String spbill_create_ip="123.12.12.123";//终端IPString notify_url="http://www.weixin.qq.com/wxpay/pay.php";//通知地址String trade_type="NATIVE";//交易类型 NATIVE-原生扫码支付String attach=out_trade_no+"--"+dlcode;   //附件数据,通知结果原样返回,放置订单-代理商信息String product_id="123456";String openid="oYxxxxxxxxxxxc";System.out.println("*************************附加数据是oid.dlcode*******"+attach);String key="5xxxxxxxxxxxxxxx2C";//商户号API密钥//生成统一下单的签名参数,sign字母必须全为大写SortedMap<String,String> paramMap = new TreeMap<String,String>();paramMap.put("attach",attach);paramMap.put("appid", appid);paramMap.put("body", body);paramMap.put("mch_id", mch_id);paramMap.put("nonce_str", nonce_str);paramMap.put("notify_url", notify_url);paramMap.put("openid", openid);paramMap.put("out_trade_no", out_trade_no);paramMap.put("product_id", product_id);paramMap.put("total_fee", String.valueOf(total_fee));paramMap.put("trade_type", trade_type);paramMap.put("spbill_create_ip", spbill_create_ip);String sign=SignUtil.createSign(paramMap, key, "UTF-8");String xmlTest="<xml>"+"<appid>"+appid+"</appid>"+"<attach>"+attach+"</attach>"+"<body>"+body+"</body>"+"<product_id>"+product_id+"</product_id>"+"<mch_id>"+mch_id+"</mch_id>"+"<nonce_str>"+nonce_str+"</nonce_str>"+"<notify_url>"+notify_url+"</notify_url>"+"<openid>"+openid+"</openid>"+"<out_trade_no>"+out_trade_no+"</out_trade_no>"+"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+"<total_fee>"+total_fee+"</total_fee>"+"<trade_type>"+trade_type+"</trade_type>"+"<sign>"+sign+"</sign>"+"</xml> ";String url="https://api.mch.weixin.qq.com/pay/unifiedorder";String code_url=getCodeUrl(url,xmlTest);System.out.println(code_url);}
生成签名:
public static String createSign(SortedMap<String, String> paraMap,String key,String charset) {StringBuffer sb = new StringBuffer();Set es = paraMap.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();if (null != v && !"".equals(v) && !"sign".equals(k)&& !"key".equals(k)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + key);System.out.println("===========签名参数====="+sb.toString());String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();System.out.println("===========生成的签名是====="+sign);return sign;}
解析成功返回xml,获取二维码连接code_url:
/** * 解析xml,获取code_url */private String getCodeUrl(String url, String xmlTest) {String code_url=null;try {String resXml=HttpUtil.httpsRequest(url, "POST", xmlTest);Document dd=null;try{dd=DocumentHelper.parseText(resXml);}catch(DocumentException e){return "";}if(dd!=null){Element root=dd.getRootElement();if(root==null){return "";}Element codeUrl=root.element("code_url");if(codeUrl==null){return "";}code_url=codeUrl.getText();//解析xml获得code_url}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} return code_url;}
调用接口动态生成二维码图片并直接以流的方式返回图片:
/** * @2016年12月14日下午3:47:29 * @function:动态生成二维码图片,并直接以流的形式输出到页面 * @author :lj */public void getQRCode(HttpServletRequest request,HttpServletResponse response){ String code_url=request.getParameter("code_url");if(StringUtil.isEmpty(code_url))return;MultiFormatWriter multi=new MultiFormatWriter();Map map=new HashMap();map.put(EncodeHintType.CHARACTER_SET, "UTF-8");//设置字符集编码类型BitMatrix bitMatrix=null;try {bitMatrix=multi.encode(code_url, BarcodeFormat.QR_CODE, 300, 300,map);BufferedImage image=toBufferedImage(bitMatrix);//输出二维码图片流try {ImageIO.write(image, "png", response.getOutputStream());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} catch (WriterException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public BufferedImage toBufferedImage(BitMatrix matrix){int WHITE=0xFFFFFFFF;int BLACK=0xFF000000;int width=matrix.getWidth();int height=matrix.getHeight();BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for(int x=0;x<width;x++){for(int y=0;y<height;y++){image.setRGB(x, y, matrix.get(x,y) ? BLACK : WHITE);}}return image;}





2 0
原创粉丝点击