最近由于业务需要,参考别人的代码,然后加上自己整合,总算写出来了,在这里得跟大家一起分享下。
这是官方开发文档模式二的地址:.php?chapter=6_5
大家可以仔细看看这里面,里面的内容我就不写了,大家可以自己看。
先看看我的项目结构:
pom文件的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wky</groupId><artifactId>wechat</artifactId><version>0.0.1-SNAPSHOT</version><name>wechat</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--微信扫码支付所需要的依赖--><dependency><groupId&le.zxing</groupId><artifactId>core</artifactId><version>3.2.1</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency><dependency><groupId>ph</groupId><artifactId>ezmorph</artifactId><version>1.0.6</version></dependency><!--jsp--><dependency><groupId>at.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.2.3</version><classifier>jdk15</classifier><!-- 指定jdk版本 --></dependency><dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version></dependency><!-- fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.24</version></dependency><!-- gson --><dependency><groupId&le.code.gson</groupId><artifactId>gson</artifactId><version>2.8.2</version></dependency><dependency><groupId>at.embed</groupId><artifactId>tomcat-embed-core</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.4</version></dependency><dependency><groupId>commons-httpclient</groupId><artifactId>commons-httpclient</artifactId><version>3.0</version></dependency><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>org.jdom</groupId><artifactId>jdom</artifactId><version>1.1</version></dependency><dependency><groupId&hanobut</groupId><artifactId>logger</artifactId><version>1.14</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version><scope>test</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.25</version><scope>test</scope></dependency><!--屏蔽自带的tomcat--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>compile</scope></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
先来看看util包下面的几个工具类代码:
MD5Util:
package com.wky.wechat.Util;import java.security.MessageDigest;public class MD5Util {//md5加密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];}private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++)resultSb.append(byteToHexString(b[i]));String();}public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = Instance("MD5");if (charsetname == null || "".equals(charsetname))resultString = byteArrayToHexString(md.Bytes()));elseresultString = byteArrayToHexString(md.Bytes(charsetname)));} catch (Exception exception) {}return resultString;}private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };}
XMLUtil:
package com.wky.wechat.Util;import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;public class XMLUtil {/*** 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。* @param strxml* @return* @throws JDOMException* @throws IOException*/public static Map doXMLParse(String strxml) throws JDOMException, IOException {strxml = placeFirst("encoding=".*"", "encoding="UTF-8"");if(null == strxml || "".equals(strxml)) {return null;}Map m = new HashMap();InputStream in = new Bytes("UTF-8"));SAXBuilder builder = new SAXBuilder();Document doc = builder.build(in);Element root = RootElement();List list = Children();Iterator it = list.iterator();while(it.hasNext()) {Element e = (Element) it.next();String k = e.getName();String v = "";List children = e.getChildren();if(children.isEmpty()) {v = e.getTextNormalize();} else {v = ChildrenText(children);}m.put(k, v);}//关闭流in.close();return m;}/**59 * 获取子结点的xml60 * @param children61 * @return String62 */public static String getChildrenText(List children) {StringBuffer sb = new StringBuffer();if(!children.isEmpty()) {Iterator it = children.iterator();while(it.hasNext()) {Element e = (Element) it.next();String name = e.getName();String value = e.getTextNormalize();List list = e.getChildren();sb.append("<" + name + ">");if(!list.isEmpty()) {sb.ChildrenText(list));}sb.append(value);sb.append("</" + name + ">");}}String();}
}
HttpUtil:
package com.wky.wechat.Util;import org.apachemons.logging.Log;
import org.apachemons.logging.LogFactory;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.URL;
import java.URLConnection;public class HttpUtil {
//用http连接提交支付信息参数private static final Log logger = Log("org.ibes.MESSAGES" );private final static int CONNECT_TIMEOUT = 5000; // in millisecondsprivate final static String DEFAULT_ENCODING = "UTF-8";public static String postData(String urlStr, String data){return postData(urlStr, data, null);}public static String postData(String urlStr, String data, String contentType){BufferedReader reader = null;try {URL url = new URL(urlStr);URLConnection conn = url.openConnection();conn.setDoOutput(true);conn.setConnectTimeout(CONNECT_TIMEOUT);conn.setReadTimeout(CONNECT_TIMEOUT);if(contentType != null)conn.setRequestProperty("content-type", contentType);OutputStreamWriter writer = new OutputStream(), DEFAULT_ENCODING);if(data == null)data = "";writer.write(data);writer.flush();writer.close();reader = new BufferedReader(new InputStream(), DEFAULT_ENCODING));System.out.String());StringBuilder sb = new StringBuilder();String line = null;while ((line = adLine()) != null) {sb.append(line);sb.append("rn");}String();} catch (IOException e) {("Error connecting to " + urlStr + ": " + e.getMessage());} finally {try {if (reader != null)reader.close();} catch (IOException e) {}}return null;}
}
GetWeixinUrlUtil:
package com.wky.wechat.Util;le.zxing.BarcodeFormat;
le.zxing.MultiFormatWriter;
le.zxing.WriterException;
le.zxingmon.BitMatrix;
import org.apachemons.lang.StringUtils;import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;public class GetWeixinUrlUtil {private static final int BLACK = 0xff000000;private static final int WHITE = 0xFFFFFFFF;//获取二维码urlpublic static String weixin_pay(String ip) throws Exception {// 账号信息String appid = PayConfigUtil.APP_ID; // appidString mch_id = PayConfigUtil.MCH_ID; // 商户号String key = PayConfigUtil.API_KEY; // keyString currTime = CurrTime();String strTime = currTime.substring(8, currTime.length());String strRandom = PayCommonUtil.buildRandom(4) + "";String nonce_str = strTime + strRandom;int order_price = 1; // 商品价格 注意:价格的单位是分String body = "商品名称"; // 商品名称String out_trade_no = CurrTime() + PayCommonUtil.buildRandom(4); // 商户订单号// 获取发起电脑 ipString spbill_create_ip = ip;// 回调接口String notify_url = PayConfigUtil.NOTIFY_URL;String trade_type = "NATIVE"; //交易类型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", body);packageParams.put("out_trade_no", out_trade_no);packageParams.put("total_fee", String.valueOf(order_price));packageParams.put("spbill_create_ip", spbill_create_ip);packageParams.put("notify_url", notify_url);packageParams.put("trade_type", trade_type);//生成签名String sign = ateSign("UTF-8", packageParams,key);packageParams.put("sign", sign);String requestXML = RequestXml(packageParams);System.out.println(requestXML);String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);Map map = XMLUtil.doXMLParse(resXml);String urlCode = (String) ("code_url");System.out.println(urlCode);return urlCode;}// 特殊字符处理public static String UrlEncode(String src) throws UnsupportedEncodingException {de(src, "UTF-8").replace("+", "%20");}/*** 将路径生成二维码图片* @author xiaoloutingyu* @param content* @param response*/@SuppressWarnings({ "unchecked", "rawtypes" })public static void encodeQrcode(String content, HttpServletResponse response){if(StringUtils.isBlank(content))return;MultiFormatWriter multiFormatWriter = new MultiFormatWriter();Map hints = new HashMap();BitMatrix bitMatrix = null;try {bitMatrix = de(content, BarcodeFormat.QR_CODE, 250, 250,hints);BufferedImage image = toBufferedImage(bitMatrix);//输出二维码图片流try {ImageIO.write(image, "png", OutputStream());} catch (IOException e) {e.printStackTrace();}} catch (WriterException e1) {e1.printStackTrace();}}/*** 类型转换* @author xiaoloutingyu* @param matrix* @return*/public static BufferedImage toBufferedImage(BitMatrix matrix) {int width = Width();int height = Height();BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, (x, y) == true ? BLACK : WHITE);}}return image;}
}
PayCommonUtil:
package com.wky.wechat.Util;SimpleDateFormat;
import java.util.*;public class PayCommonUtil {/*** 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。* @return boolean*/public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = Set();Iterator it = es.iterator();while(it.hasNext()) {Map.Entry entry = (Map.();String k = (Key();String v = (Value();if(!"sign".equals(k) && null != v && !"".equals(v)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);//算出摘要String mysign = MD5Util.String(), characterEncoding).toLowerCase();String tenpaySign = ((("sign")).toLowerCase();//System.out.println(tenpaySign + " " + mysign);return tenpaySign.equals(mysign);}/*** @author xiaoloutingyu* @date 2016-4-22* @Description:sign签名* @param characterEncoding* 编码格式* @param** @return*/public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = Set();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) Key();String v = (String) Value();if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);String sign = MD5Util.String(), characterEncoding).toUpperCase();return sign;}/**65 * @author xiaoloutingyu66 * @date 2016-4-2267 * @Description:将请求参数转换为xml格式的string68 * @param parameters69 * 请求参数70 * @return71 */public static String getRequestXml(SortedMap<Object, Object> parameters) {StringBuffer sb = new StringBuffer();sb.append("<xml>");Set es = Set();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = (String) Key();String v = (String) Value();if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");} else {sb.append("<" + k + ">" + v + "</" + k + ">");}}sb.append("</xml>");String();}/**92 * 取出一个指定长度大小的随机正整数.93 *94 * @param length95 * int 设定所取出随机数的长度。length小于1196 * @return int 返回生成的随机数。97 */public static int buildRandom(int length) {int num = 1;double random = Math.random();if (random < 0.1) {random = random + 0.1;}for (int i = 0; i < length; i++) {num = num * 10;}return (int) ((random * num));}/**111 * 获取当前时间 yyyyMMddHHmmss112 *113 * @return String114 */public static String getCurrTime() {Date now = new Date();SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");String s = outFormat.format(now);return s;}}
PayConfigUtil:
package com.wky.wechat.Util;import javax.servlet.http.HttpServletRequest;public class PayConfigUtil {
//这里的必要参数填写自己的,另外回调地址必须是外网能访问的,我这里是用netapp开通了一个隧道,免费的,大家测试的时候也可以申请个,可以百度netapp教程几分钟学习一下就可以public static final String APP_ID = "";//微信开发平台应用ID(公众号ID)public static final String MCH_ID = "";//商户号(商户号ID)public static final String API_KEY = "";//API key(商户号里面的)public static final String CREATE_IP = "";//发起支付的ippublic static final String NOTIFY_URL = "";//回调地址public static final String UFDODER_URL = "";//微信统一下单接口public static final String APP_SECRET = "4b438be89862ab64a2cb2960a8f696bd";//应用对应的凭证(在公众号里面)//获取ippublic static String getIP(HttpServletRequest request){String ip = RemoteAddr();return ip;}
}
service层:
WechatService:
package com.wky.wechat.Service;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public interface WechatService {void weixin_notify(HttpServletRequest request, HttpServletResponse response) throws Exception;;
} 看看实现类的代码:
package com.wky.wechat.Service.impl;import com.wky.wechat.Service.WechatService;
import com.wky.wechat.Util.PayCommonUtil;
import com.wky.wechat.Util.PayConfigUtil;
import com.wky.wechat.Util.XMLUtil;
import org.springframework.stereotype.Service;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.util.*;@Service
public class WechatServiceImpl implements WechatService {@Overridepublic void weixin_notify(HttpServletRequest request, HttpServletResponse response) throws Exception {System.out.println("调用回调方法");//读取参数InputStream inputStream ;StringBuffer sb = new StringBuffer();inputStream = InputStream();String s ;BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));while ((s = in.readLine()) != null){sb.append(s);}in.close();inputStream.close();//解析xml成mapMap<String, String> m = new HashMap<String, String>();m = XMLUtil.String());//过滤空 设置 TreeMapSortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();Iterator it = m.keySet().iterator();while (it.hasNext()) {String parameter = (String) it.next();String parameterValue = m.get(parameter);String v = "";if(null != parameterValue) {v = im();}packageParams.put(parameter, v);}// 账号信息String key = PayConfigUtil.API_KEY; // key//logger.info(packageParams);System.out.println(packageParams);//判断签名是否正确if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {//------------------------------//处理业务开始//------------------------------String resXml = "";if("SUCCESS".equals((String) ("result_code"))){// 这里是支付成功//执行自己的业务逻辑String mch_id = (String) ("mch_id");String openid = (String) ("openid");String is_subscribe = (String) ("is_subscribe");String out_trade_no = (String) ("out_trade_no");String total_fee = (String) ("total_fee");String cash_fee_s = (String) ("cash_fee");String cash_fee = String.valueOf(Integer.parseInt(cash_fee_s) / 100);//String time_end = MctsUtils.numberDateToDate((String) ("time_end"));String transaction_id = (String) ("transaction_id");//执行自己的业务逻辑(报存订单信息到数据库)System.out.println("支付成功 ,处理业务成功");//logger.info("支付成功");//通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";//------------------------------//处理业务完毕//------------------------------//向微信服务器发送确认信息,若不发送,微信服务器会间隔不同的时间调用回调方法BufferedOutputStream out = new OutputStream());out.Bytes());out.flush();out.close();System.out.println("通知微信.异步确认成功");} else {System.out.println("支付失败,错误信息:" + ("err_code"));// logger.info("支付失败,错误信息:" + ("err_code"));resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";BufferedOutputStream out = new OutputStream());out.Bytes());out.flush();out.close();System.out.println("执行回调函数失败");}} else{//logger.info("通知签名验证失败");System.out.println("通知签名验证失败");}}}controller:@RequestMapping(value="/image",method = RequestMethod.GET)public void payWexin(@RequestParam String ip, HttpServletResponse response)throws Exception{String url=GetWeixinUrlUtil.weixin_pay(ip);deQrcode(url,response);}
本文发布于:2024-01-31 04:53:15,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170664799825663.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |