//微信扫码支付主要为返回预生成交易链接,所以需要生成二维码,前端可使用jquery.QRcode.js进行生成//主要的Controllerpackage Controllers; import Entity.UnifiedOrderRequest;import Entity.UnifiedOrderRespose;import com.alibaba.fastjson.JSONObject;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;import com.thoughtworks.xstream.io.xml.XppDriver;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;import utils.MD5Util; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;import java.text.SimpleDateFormat;import java.util.*; @Controller@RequestMapping("/createQRCode")public class createQRCode { @RequestMapping(method = RequestMethod.GET, value = "/pay", produces = "text/plain;charset=GBK") public ModelAndView createCheck(){ ModelAndView view = new ModelAndView(); view.setViewName("forward:/jsp/wxPay.jsp"); return view ; } /*** * 查询订单 * @param map * @param response * @param request * @return */ @ResponseBody @RequestMapping(method = RequestMethod.POST, value = "/payCheck", produces = "text/plain;charset=GBK") public String payCheck(@RequestBody Map<String,String> map, HttpServletResponse response, HttpServletRequest request){ try { String tradeNo = map.get("tradeNo"); //生成订单 String orderInfo = createSearchOrderInfo(tradeNo); //调统一下单API UnifiedOrderRespose code_return = httpSearchOrder(orderInfo); JSONObject return_flag = new JSONObject(); if (code_return == null) { return_flag.put("msg", 0); } else { return_flag.put("msg", code_return.getTrade_state_desc()); } return return_flag.toString(); }catch (Exception e) { e.printStackTrace(); JSONObject return_flag = new JSONObject(); return_flag.put("msg", 0); return return_flag.toString(); } } /*** * 返回订单交易链接 * @param map * @param response * @param request * @return */ @ResponseBody @RequestMapping(method = RequestMethod.POST, value = "/check", produces = "text/plain;charset=GBK") public String createCheck(@RequestBody Map<String,String> map, HttpServletResponse response, HttpServletRequest request){ try { String Ip = null; if (request.getHeader("x-forwarded-for") == null) { Ip = request.getRemoteAddr(); } else { Ip = request.getHeader("x-forwarded-for"); } String money = map.get("money"); String tradeNo = map.get("tradeNo"); String name = map.get("name"); String realMoney = String.valueOf((int) (Float.parseFloat(money) * 100)); //生成订单 String orderInfo = createOrderInfo(Ip, realMoney, tradeNo, name); //调统一下单API String code_url = httpOrder(orderInfo); JSONObject return_flag = new JSONObject(); if (code_url.equals("0")) { return_flag.put("msg", 0); } else { return_flag.put("msg", code_url); } return return_flag.toString(); }catch (Exception e) { e.printStackTrace(); JSONObject return_flag = new JSONObject(); return_flag.put("msg", 0); return return_flag.toString(); } } /** * 生成订单 * @param * @return */ private String createOrderInfo(String IP, String money, String tradeNo, String name){ //生成订单对象 UnifiedOrderRequest unifiedOrderRequest = new UnifiedOrderRequest(); unifiedOrderRequest.setAppid("");//公众账号ID unifiedOrderRequest.setMch_id("");//商户号 unifiedOrderRequest.setNonce_str(makeUUID());//随机字符串 unifiedOrderRequest.setBody(name);//商品描述 unifiedOrderRequest.setOut_trade_no(tradeNo);//商户订单号 unifiedOrderRequest.setTotal_fee(money); //金额需要扩大100倍:1代表支付时是0.01 unifiedOrderRequest.setSpbill_create_ip(IP);//终端IP unifiedOrderRequest.setNotify_url("");//通知地址,虽然有,但仍需通过查询订单的方式进行确认状态 unifiedOrderRequest.setTrade_type("NATIVE");//JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付 unifiedOrderRequest.setSign(createSign(unifiedOrderRequest));//签名说明5(见文末,签名方法一并给出) //将订单对象转为xml格式 XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xml return xStream.toXML(unifiedOrderRequest); } /*** *生成查询订单序列化 * @param tradeNo * @return */ private String createSearchOrderInfo(String tradeNo){ //生成订单对象 UnifiedOrderRequest unifiedOrderRequest = new UnifiedOrderRequest(); unifiedOrderRequest.setAppid("");//公众账号ID unifiedOrderRequest.setMch_id("");//商户号 unifiedOrderRequest.setNonce_str(makeUUID());//随机字符串 unifiedOrderRequest.setOut_trade_no(tradeNo);//商户订单号 unifiedOrderRequest.setSign(createSearchSign(unifiedOrderRequest));//签名说明5(见文末,签名方法一并给出) //将订单对象转为xml格式 XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xml return xStream.toXML(unifiedOrderRequest); } /** * 调统一下单API * @param orderInfo * @return */ private String httpOrder(String orderInfo) { String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; try { HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); //加入数据 conn.setRequestMethod("POST"); conn.setDoOutput(true); BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream()); buffOutStr.write(orderInfo.getBytes("UTF-8")); buffOutStr.flush(); buffOutStr.close(); //获取输入流 InputStream is = null; BufferedReader reader = null; is = conn.getInputStream(); reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));// BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; StringBuffer sb = new StringBuffer(); while((line = reader.readLine())!= null){ sb.append(line); } XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//说明3(见文末) //将请求返回的内容通过xStream转换为UnifiedOrderRespose对象 xStream.alias("xml", UnifiedOrderRespose.class); UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString()); //根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url if(null!=unifiedOrderRespose && "SUCCESS".equals(unifiedOrderRespose.getReturn_code()) && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){ return unifiedOrderRespose.getCode_url(); }else{ return "0"; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 调统一下单API * @param orderInfo * @return */ private UnifiedOrderRespose httpSearchOrder(String orderInfo) { String url = "https://api.mch.weixin.qq.com/pay/orderquery"; try { HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); //加入数据 conn.setRequestMethod("POST"); conn.setDoOutput(true); BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream()); buffOutStr.write(orderInfo.getBytes("UTF-8")); buffOutStr.flush(); buffOutStr.close(); //获取输入流 InputStream is = null; BufferedReader reader = null; is = conn.getInputStream(); reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));// BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; StringBuffer sb = new StringBuffer(); while((line = reader.readLine())!= null){ sb.append(line); } XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//说明3(见文末) //将请求返回的内容通过xStream转换为UnifiedOrderRespose对象 xStream.alias("xml", UnifiedOrderRespose.class); UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString()); //根据微信文档return_code 和result_code都为SUCCESS的时候 if(null!=unifiedOrderRespose && "SUCCESS".equals(unifiedOrderRespose.getReturn_code()) && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){ return unifiedOrderRespose; }else{ return null; } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 创建UUID * @return */ public static synchronized String makeUUID() { Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); StringBuffer s = new StringBuffer(dateFormat.format(date)); return s.append((new Random().nextInt(900) + 100)).toString(); } /** * 生成签名 * @return */ private String createSign(UnifiedOrderRequest unifiedOrderRequest) { //根据规则创建可排序的map集合 SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", unifiedOrderRequest.getAppid()); packageParams.put("body", unifiedOrderRequest.getBody()); packageParams.put("mch_id", unifiedOrderRequest.getMch_id()); packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str()); packageParams.put("notify_url", unifiedOrderRequest.getNotify_url()); packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no()); packageParams.put("spbill_create_ip", unifiedOrderRequest.getSpbill_create_ip()); packageParams.put("trade_type", unifiedOrderRequest.getTrade_type()); packageParams.put("total_fee", unifiedOrderRequest.getTotal_fee()); StringBuffer sb = new StringBuffer(); Set es = packageParams.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 + "&"); } } //第二步拼接key,key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 sb.append("key=" +""); String sign = MD5Util.MD5Encode(sb.toString(), "utf-8") .toUpperCase();//MD5加密 return sign; } /*** * 生成查询订单签名 * @param unifiedOrderRequest * @return */ private String createSearchSign(UnifiedOrderRequest unifiedOrderRequest) { //根据规则创建可排序的map集合 SortedMap<String, String> packageParams = new TreeMap<String, String>(); packageParams.put("appid", unifiedOrderRequest.getAppid()); packageParams.put("mch_id", unifiedOrderRequest.getMch_id()); packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str()); packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no()); StringBuffer sb = new StringBuffer(); Set es = packageParams.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 + "&"); } } //第二步拼接key,key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 sb.append("key=" +""); String sign = MD5Util.MD5Encode(sb.toString(), "utf-8") .toUpperCase();//MD5加密 return sign; }}//定义请求的实体类
package Entity;/** * 统一下单请求参数(必填) * @author moucong * */public class UnifiedOrderRequest { public String getAppid() { return appid; } public void setAppid(String appid) { this.appid = appid; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getOut_trade_no() { return out_trade_no; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public String getTotal_fee() { return total_fee; } public void setTotal_fee(String total_fee) { this.total_fee = total_fee; } public String getSpbill_create_ip() { return spbill_create_ip; } public void setSpbill_create_ip(String spbill_create_ip) { this.spbill_create_ip = spbill_create_ip; } public String getNotify_url() { return notify_url; } public void setNotify_url(String notify_url) { this.notify_url = notify_url; } public String getTrade_type() { return trade_type; } public void setTrade_type(String trade_type) { this.trade_type = trade_type; } private String appid; //公众账号ID private String mch_id; //商户号 private String nonce_str; //随机字符串 private String sign; //签名 private String body; //商品描述 private String out_trade_no; //商户订单号 private String total_fee; //总金额 private String spbill_create_ip; //终端IP private String notify_url; //通知地址 private String trade_type; //交易类型 }//返回接收数据的实体类
package Entity;/** * 统一下单返回参数 * @author moucong * */public class UnifiedOrderRespose { private String return_code; //返回状态码 private String return_msg; //返回信息 private String appid; //公众账号ID private String mch_id; //商户号 private String device_info; //设备号 private String nonce_str; //随机字符串 private String sign; //签名 private String result_code; //业务结果 private String err_code; //错误代码 private String err_code_des; //错误代码描述 private String trade_type; //交易类型 private String prepay_id; //预支付交易会话标识 private String code_url; //二维码链接 private String total_fee; //总金额 private String out_trade_no; //商户订单号 private String trade_state; //交易状态 private String trade_state_desc; //交易状态描述 private String openid; //用户标识 private String is_subscribe; //是否关注公众账号 private String bank_type; //付款银行 private String cash_fee; //现金支付金额 private String transaction_id; //微信支付订单号 private String time_end; //支付完成时间 private String fee_type; //标价币种 private String attach; //附加数据 private String cash_fee_type; //现金支付币种 private String coupon_fee; //代金券金额 private String coupon_count; //代金券使用数量 private String coupon_type_$n; //代金券类型 private String coupon_id_$n; //代金券ID private String coupon_fee_$n; //单个代金券支付金额 public String getCash_fee_type() { return cash_fee_type; } public void setCash_fee_type(String cash_fee_type) { this.cash_fee_type = cash_fee_type; } public String getCoupon_fee() { return coupon_fee; } public void setCoupon_fee(String coupon_fee) { this.coupon_fee = coupon_fee; } public String getCoupon_count() { return coupon_count; } public void setCoupon_count(String coupon_count) { this.coupon_count = coupon_count; } public String getCoupon_type_$n() { return coupon_type_$n; } public void setCoupon_type_$n(String coupon_type_$n) { this.coupon_type_$n = coupon_type_$n; } public String getCoupon_id_$n() { return coupon_id_$n; } public void setCoupon_id_$n(String coupon_id_$n) { this.coupon_id_$n = coupon_id_$n; } public String getCoupon_fee_$n() { return coupon_fee_$n; } public void setCoupon_fee_$n(String coupon_fee_$n) { this.coupon_fee_$n = coupon_fee_$n; } public String getAttach() { return attach; } public void setAttach(String attach) { this.attach = attach; } public String getFee_type() { return fee_type; } public void setFee_type(String fee_type) { this.fee_type = fee_type; } public String getReturn_code() { return return_code; } public void setReturn_code(String return_code) { this.return_code = return_code; } public String getReturn_msg() { return return_msg; } public void setReturn_msg(String return_msg) { this.return_msg = return_msg; } public String getAppid() { return appid; } public void setAppid(String appid) { this.appid = appid; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getDevice_info() { return device_info; } public void setDevice_info(String device_info) { this.device_info = device_info; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getResult_code() { return result_code; } public void setResult_code(String result_code) { this.result_code = result_code; } public String getErr_code() { return err_code; } public void setErr_code(String err_code) { this.err_code = err_code; } public String getErr_code_des() { return err_code_des; } public void setErr_code_des(String err_code_des) { this.err_code_des = err_code_des; } public String getTrade_type() { return trade_type; } public void setTrade_type(String trade_type) { this.trade_type = trade_type; } public String getPrepay_id() { return prepay_id; } public void setPrepay_id(String prepay_id) { this.prepay_id = prepay_id; } public String getCode_url() { return code_url; } public void setCode_url(String code_url) { this.code_url = code_url; } public String getIs_subscribe() { return is_subscribe; } public void setIs_subscribe(String is_subscribe) { this.is_subscribe = is_subscribe; } public String getBank_type() { return bank_type; } public void setBank_type(String bank_type) { this.bank_type = bank_type; } public String getCash_fee() { return cash_fee; } public void setCash_fee(String cash_fee) { this.cash_fee = cash_fee; } public String getTransaction_id() { return transaction_id; } public void setTransaction_id(String transaction_id) { this.transaction_id = transaction_id; } public String getTime_end() { return time_end; } public void setTime_end(String time_end) { this.time_end = time_end; } public String getOpenid() { return openid; } public void setOpenid(String openid) { this.openid = openid; } public String getTrade_state_desc() { return trade_state_desc; } public void setTrade_state_desc(String trade_state_desc) { this.trade_state_desc = trade_state_desc; } public String getOut_trade_no() { return out_trade_no; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public String getTotal_fee() { return total_fee; } public void setTotal_fee(String total_fee) { this.total_fee = total_fee; } public String getTrade_state() { return trade_state; } public void setTrade_state(String trade_state) { this.trade_state = trade_state; }}//MD5算法
package utils; import java.security.MessageDigest; /** * *************************************************** * * @Auther: zianY -.-- .- -. --. --.. .. .- -. * @Descipion: MD5 * @CreateDate: 2019-12-19 * **************************************************** */public class MD5Util { public static void main(String[] args) { // 99B26BE5F5F7AF4A576DFB6DF0DD38FF System.out.println(MD5EncodeUtf8("123456")); } private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } /** * 返回大写MD5 * * @param origin * @param charsetname * @return */ public static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = origin; MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString.getBytes())); else resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } catch (Exception exception) { } return resultString.toUpperCase(); } /** * @param origin * @return */ public static String MD5EncodeUtf8(String origin) { origin = origin + "[email protected]#@$1234da"; return MD5Encode(origin.trim(), "utf-8"); } private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; }
原文地址:https://www.cnblogs.com/setname/p/12199892.html
时间: 2024-10-18 19:27:43