| package com.xzx.gc.pay.controller;  | 
|   | 
| import cn.hutool.core.lang.Snowflake;  | 
| import cn.hutool.core.util.IdUtil;  | 
| import com.google.zxing.BarcodeFormat;  | 
| import com.google.zxing.MultiFormatWriter;  | 
| import com.google.zxing.WriterException;  | 
| import com.google.zxing.common.BitMatrix;  | 
| import com.xzx.gc.common.constant.Constants;  | 
| import com.xzx.gc.common.request.BaseController;  | 
| import com.xzx.gc.model.admin.PayInfoModel;  | 
| import com.xzx.gc.model.admin.WeChatParams;  | 
| import com.xzx.gc.pay.service.PayService;  | 
| import com.xzx.gc.util.HttpUtil;  | 
| import com.xzx.gc.util.PayForUtil;  | 
| import com.xzx.gc.util.WeChatConfig;  | 
| import com.xzx.gc.util.XMLUtil;  | 
| import io.swagger.annotations.Api;  | 
| import io.swagger.annotations.ApiOperation;  | 
| import lombok.extern.slf4j.Slf4j;  | 
| import org.apache.commons.lang3.StringUtils;  | 
| import org.springframework.beans.factory.annotation.Autowired;  | 
| import org.springframework.web.bind.annotation.*;  | 
|   | 
| import javax.imageio.ImageIO;  | 
| import javax.servlet.http.HttpServletRequest;  | 
| import javax.servlet.http.HttpServletResponse;  | 
| import java.awt.image.BufferedImage;  | 
| import java.io.*;  | 
| import java.math.BigDecimal;  | 
| import java.net.URLEncoder;  | 
| import java.util.*;  | 
|   | 
| @RestController  | 
| @Api(tags = "微信充值接口类")  | 
| @Slf4j  | 
| public class WeixinPayController extends BaseController {  | 
|   | 
|   | 
|     @Autowired  | 
|     private PayService payService;  | 
|     /**  | 
|      * 获取微信支付的二维码地址  | 
|      * @return  | 
|      * @author chenp  | 
|      * @throws Exception  | 
|      */  | 
|     public static String getCodeUrl(WeChatParams ps) throws Exception {  | 
|         /**  | 
|          * 账号信息  | 
|          */  | 
|         String appid = WeChatConfig.APPID;//微信服务号的appid  | 
|         String mch_id = WeChatConfig.MCHID; //微信支付商户号  | 
|         String key = WeChatConfig.APIKEY; // 微信支付的API密钥  | 
|         String notify_url = WeChatConfig.WECHAT_NOTIFY_URL_PC;//回调地址【注意,这里必须要使用外网的地址】  | 
|         String ufdoder_url=WeChatConfig.UFDODER_URL;//微信下单API地址  | 
|         String trade_type = "NATIVE"; //类型【网页扫码支付】  | 
|   | 
|         /**  | 
|          * 时间字符串  | 
|          */  | 
|         String currTime = PayForUtil.getCurrTime();  | 
|         String strTime = currTime.substring(8, currTime.length());  | 
|         String strRandom = PayForUtil.buildRandom(4) + "";  | 
|         String nonce_str = strTime + strRandom;  | 
|   | 
|         /**  | 
|          * 参数封装  | 
|          */  | 
|         SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  | 
|         packageParams.put("appid", appid);  | 
|         packageParams.put("mch_id", mch_id);  | 
|         packageParams.put("nonce_str", nonce_str);//随机字符串  | 
|         packageParams.put("body", ps.body);//支付的商品名称  | 
|         packageParams.put("out_trade_no", ps.out_trade_no+nonce_str);//商户订单号【备注:每次发起请求都需要随机的字符串,否则失败。】  | 
|         packageParams.put("total_fee", ps.total_fee);//支付金额  | 
|         packageParams.put("spbill_create_ip", PayForUtil.localIp());//客户端主机  | 
|         packageParams.put("notify_url", notify_url);  | 
|         packageParams.put("trade_type", trade_type);  | 
|         packageParams.put("attach", ps.attach);//额外的参数【业务类型+会员ID+支付类型】  | 
|   | 
|   | 
|         String sign = PayForUtil.createSign("UTF-8", packageParams,key);  //获取签名  | 
|         packageParams.put("sign", sign);  | 
|   | 
|         String requestXML = PayForUtil.getRequestXml(packageParams);//将请求参数转换成String类型  | 
|         log.info("微信支付请求参数的报文"+requestXML);  | 
|         String resXml = HttpUtil.postData(ufdoder_url,requestXML);  //解析请求之后的xml参数并且转换成String类型  | 
|         Map map = XMLUtil.doXMLParse(resXml);  | 
|         log.info("微信支付响应参数的报文"+resXml);  | 
|         String urlCode = (String) map.get("code_url");  | 
|   | 
|         return urlCode;  | 
|     }  | 
|   | 
|   | 
|   | 
|     //微信支付接口  | 
|     @PostMapping(Constants.ADMIN_VIEW_PREFIX + "/weixinPay/wxPay.json")  | 
|     @ResponseBody  | 
|     @ApiOperation(value="获取微信付款地址(该地址用于生成微信付款二维码)", notes="test: 仅0有正确返回")  | 
|     public String wxPay(@RequestBody WeChatParams ps) throws Exception {  | 
|         Snowflake snowflake = IdUtil.getSnowflake(0, 3);  | 
|         String payOrderId = "ZF"+snowflake.nextIdStr();  | 
|         ps.setOut_trade_no(payOrderId);  | 
|         ps.setTotal_fee(new BigDecimal(ps.getTotal_fee()).multiply(new BigDecimal("100")).toString());  | 
|         String urlCode =getCodeUrl(ps);  | 
|         System.out.println(urlCode);  | 
|   | 
|         PayInfoModel model = new PayInfoModel();  | 
|         model.setPayOrderId(payOrderId);  | 
|         model.setMoney(ps.getTotal_fee());  | 
|         int num =payService.addPayInfo(model);  | 
|         return urlCode;  | 
|     }  | 
|   | 
|     /**  | 
|      * pc端微信支付之后的回调方法  | 
|      * @param request  | 
|      * @param response  | 
|      * @throws Exception  | 
|      */  | 
|     @RequestMapping(value="wechat_notify_url_pc",method= RequestMethod.POST)  | 
|     public void wechat_notify_url_pc(HttpServletRequest request, HttpServletResponse response) throws Exception{  | 
|   | 
|         //读取参数  | 
|         InputStream inputStream ;  | 
|         StringBuffer sb = new StringBuffer();  | 
|         inputStream = request.getInputStream();  | 
|         String s ;  | 
|         BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  | 
|         while ((s = in.readLine()) != null){  | 
|             sb.append(s);  | 
|         }  | 
|         in.close();  | 
|         inputStream.close();  | 
|   | 
|         //解析xml成map  | 
|         Map<String, String> m = new HashMap<String, String>();  | 
|         m = XMLUtil.doXMLParse(sb.toString());  | 
|   | 
|         //过滤空 设置 TreeMap  | 
|         SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  | 
|         Iterator<String> it = m.keySet().iterator();  | 
|         while (it.hasNext()) {  | 
|             String parameter = it.next();  | 
|             String parameterValue = m.get(parameter);  | 
|   | 
|             String v = "";  | 
|             if(null != parameterValue) {  | 
|                 v = parameterValue.trim();  | 
|             }  | 
|             packageParams.put(parameter, v);  | 
|         }  | 
|         // 微信支付的API密钥  | 
|         String key = WeChatConfig.APIKEY; // key  | 
|         log.info("微信支付返回回来的参数:"+packageParams);  | 
|         //判断签名是否正确  | 
|         if(PayForUtil.isTenpaySign("UTF-8", packageParams,key)) {  | 
|             //------------------------------  | 
|             //处理业务开始  | 
|             //------------------------------  | 
|             String resXml = "";  | 
|             if("SUCCESS".equals((String)packageParams.get("result_code"))){  | 
|                 // 这里是支付成功  | 
|   | 
|                 //执行自己的业务逻辑开始  | 
|                 String app_id = (String)packageParams.get("appid");  | 
|                 String mch_id = (String)packageParams.get("mch_id");  | 
|                 String openid = (String)packageParams.get("openid");  | 
|                 String is_subscribe = (String)packageParams.get("is_subscribe");//是否关注公众号  | 
|   | 
|                 //附加参数【商标申请_0bda32824db44d6f9611f1047829fa3b_15460】--【业务类型_会员ID_订单号】  | 
|                 String attach = (String)packageParams.get("attach");  | 
|                 //商户订单号  | 
|                 String out_trade_no = (String)packageParams.get("out_trade_no");  | 
|                 //付款金额【以分为单位】  | 
|                 String total_fee = (String)packageParams.get("total_fee");  | 
|                 //微信生成的交易订单号  | 
|                 String transaction_id = (String)packageParams.get("transaction_id");//微信支付订单号  | 
|                 //支付完成时间  | 
|                 String time_end=(String)packageParams.get("time_end");  | 
|   | 
|                 //out_trade_no  | 
|   | 
|                 log.info("app_id:"+app_id);  | 
|                 log.info("mch_id:"+mch_id);  | 
|                 log.info("openid:"+openid);  | 
|                 log.info("is_subscribe:"+is_subscribe);  | 
|                 log.info("out_trade_no:"+out_trade_no);  | 
|                 log.info("total_fee:"+total_fee);  | 
|                 log.info("额外参数_attach:"+attach);  | 
|                 log.info("time_end:"+time_end);  | 
|   | 
|                 //执行自己的业务逻辑结束  | 
|                 log.info("支付成功");  | 
|                 //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.  | 
|                 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  | 
|                         + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  | 
|   | 
|             } else {  | 
|                 log.info("支付失败,错误信息:" + packageParams.get("err_code"));  | 
|                 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  | 
|                         + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";  | 
|             }  | 
|             //------------------------------  | 
|             //处理业务完毕  | 
|             //------------------------------  | 
|             BufferedOutputStream out = new BufferedOutputStream(  | 
|                     response.getOutputStream());  | 
|             out.write(resXml.getBytes());  | 
|             out.flush();  | 
|             out.close();  | 
|         } else{  | 
|             log.info("通知签名验证失败");  | 
|         }  | 
|   | 
|     }  | 
| }  |