Commit 53ec7e65 authored by zhangyong's avatar zhangyong

1

parent 7c795ff3
......@@ -26,6 +26,7 @@
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......@@ -40,11 +41,20 @@
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.egolm</groupId>
<artifactId>common</artifactId>
<version>0.0.1-RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
......@@ -64,6 +74,16 @@
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -4,7 +4,6 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
......@@ -13,7 +12,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@SpringBootApplication
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.egolm.payment.alipay,com.egolm.payment.wxpay"})//包名
public class PaymentApplication {
private static ApplicationContext applicationContext;
......
......@@ -18,7 +18,7 @@ public class SwaggerConfig {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.egolm.msc"))
.apis(RequestHandlerSelectors.basePackage("com.egolm.payment"))
.paths(PathSelectors.any())
.build();
}
......
package com.egolm.payment.wxpay.controller;
package com.egolm.payment.controller;
import javax.servlet.http.HttpServletRequest;
......@@ -11,10 +11,10 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@Api(tags={"微信测试管理"})
@Api(tags={"微信公众号接口管理"})
@RestController
@RequestMapping("wxpay")
public class WXTestController {
@RequestMapping("wx")
public class WxApiController {
@ApiOperation("测试")
@ApiImplicitParams({
......
package com.egolm.payment.controller;
import java.util.Date;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.egolm.common.StringUtil;
import com.egolm.payment.entiry.WxPayResponse;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Api(tags={"微信支付回调 事件控制器"})
@RestController
@RequestMapping("notify")
public class WxPayNotifyController {
protected final Logger logger = LoggerFactory.getLogger(WxPayNotifyController.class);
/**
*
* <p>Title: 微信回調</p>
* <p>Description: </p>
* @param req
* @param resp
*/
@ApiOperation("微信支付回调通知接口")
@RequestMapping(value="/wxMiniJsApiNotify",method=RequestMethod.POST)
public String jsApiPayNotify(HttpServletRequest req,HttpServletResponse resp){
Date startTime = new Date();
WxPayResponse postData = null;
try {
//postData = PayApiXmlConver.toRequestBean(req,postData);
ServletInputStream in = req.getInputStream();
// 转换微信post过来的xml内容
XStream xs = new XStream(new DomDriver());
xs.alias("xml", WxPayResponse.class);
String xmlMsg = StringUtil.inputStream2String(in);
postData = (WxPayResponse) xs.fromXML(xmlMsg);
String appid = postData.getAppid();
Date endTime = new Date();
try {
//添加日志
/* WxApiLog wxApiLog = new WxApiLog();
wxApiLog.setPaytypeid(payTypeId);
wxApiLog.setPaytype(payTpye);
wxApiLog.setRequestXml("");
wxApiLog.setResponseXml(xmlMsg);
wxApiLog.setStarttime(startTime);
wxApiLog.setEndtime(endTime);
wxApiLog.setLogcode("jsApiNotify");
wxApiLog.setLogname("微信支付回调");
wxApiLog.setOutTradeNo(postData.getOut_trade_no());
wxApiLog.setTransactionId(postData.getTransaction_id());
wxApiLogService.insert(wxApiLog);*/
} catch (Exception e) {
e.printStackTrace();
}
try {
/*WxPayFlow wxPayFlow = new WxPayFlow();
String refundId = postData.getRefund_id();
wxPayFlow.setPaytypeid(payTypeId);
wxPayFlow.setPaytype(payTpye);
wxPayFlow.setAppid(appid);
wxPayFlow.setOrderid(postData.getOut_trade_no());
wxPayFlow.setTotalfee(postData.getTotal_fee().intValue());
if(StringUtil.isNotEmpty(refundId)){
wxPayFlow.setStatus("REFUND");
wxPayFlow.setStatusdesc("退款");
}else{
wxPayFlow.setStatus("PAY");
wxPayFlow.setStatusdesc("支付");
}
wxPayFlow.setErrorcode(postData.getErr_code());
wxPayFlow.setErrormsg(postData.getErr_code_des());
wxPayFlow.setTransactionid(postData.getTransaction_id());
wxPayFlow.setRefundid(postData.getRefund_id());
wxPayFlow.setRefundfee(StringUtil.isNotEmpty(postData.getRefund_fee())?Integer.valueOf(postData.getRefund_fee()):0);
wxPayFlow.setCashfee(postData.getCash_fee().intValue());
wxPayFlow.setCouponrefundcount(StringUtil.isNotEmpty(postData.getCoupon_refund_count())?Integer.valueOf(postData.getCoupon_refund_count()):0);
wxPayFlow.setCashrefundfee(StringUtil.isNotEmpty(postData.getCash_refund_fee())?Integer.valueOf(postData.getCash_refund_fee()):0);
wxPayFlowService.insert(wxPayFlow);*/
} catch (Exception e) {
e.printStackTrace();
}
logger.info("收到微信的回调結果---"+xmlMsg);
} catch (Exception e) {
e.printStackTrace();
}
return "收到";
}
}
This diff is collapsed.
package com.egolm.payment.service;
import java.util.Map;
public interface SystemCtrlService {
public Map<String, Object> queryTSystemCtrlByCode(String sCode,String langID);
}
package com.egolm.payment.service;
import java.util.Map;
import java.util.SortedMap;
public interface WxChatService {
public Map<String, Object> loadAppID(String code,String langID);
public String getWxOpenId(Map<String,String> params);
public Map<String,String> unifiedorder(SortedMap<Object, Object> params) throws Exception;
public Map<String,String> refund(SortedMap<Object, Object> params) throws Exception;
}
package com.egolm.payment.service.impl;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.egolm.common.jdbc.JdbcTemplate;
import com.egolm.common.jdbc.dialect.SqlServerDialect;
import com.egolm.payment.service.SystemCtrlService;
@Service
public class SystemCtrlServiceImpl implements SystemCtrlService {
private static final Log logger = LogFactory.getLog(SystemCtrlServiceImpl.class);
@Autowired
private JdbcTemplate jdbcTemplate;
public Map<String, Object> queryTSystemCtrlByCode(String sCode,String langID) {
try {
jdbcTemplate.setDialect(new SqlServerDialect());
String sql = "select sDesc, sSysTypeID, sSysType, sValue1, sValue2, sValue3,sMemo,sValue4,sValue5 from tSystemCtrl where sCode = ? and nTag&1 = 0";
Map<String, Object> mapRsult = jdbcTemplate.queryForMap(sql,sCode);
return mapRsult;
}catch (Exception e) {
logger.error("支付服务数据字典查询出错: "+e.getMessage());
}
return null;
}
}
package com.egolm.payment.service.impl;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import javax.servlet.http.HttpUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.egolm.common.HttpsUtil;
import com.egolm.payment.service.SystemCtrlService;
import com.egolm.payment.service.WxChatService;
import com.egolm.payment.util.PayContstrant;
import com.egolm.payment.util.WxApiXmlComer;
import com.egolm.payment.util.WxSignUtil;
@Service
public class WeChatServiceImpl implements WxChatService{
private static final Log logger = LogFactory.getLog(WeChatServiceImpl.class);
@Value("${wx.refund.ssl.path}")
private String sslPath;
@Autowired
private RedisTemplate<String, ?> redisTemplate;
@Autowired
private SystemCtrlService systemCtrlService;
/**
*
* @Title: loadAppID
* @Description: 获取appid 和密钥信息
* @param: @param code
* @param: @param langID
* @param: @return
* @return: Map<String,Object>
* @throws
*/
public Map<String, Object> loadAppID(String code,String langID) {
System.out.println(redisTemplate);
System.out.println(redisTemplate.opsForHash());
Map<String, Object> map = (Map<String, Object>)redisTemplate.opsForHash().get(PayContstrant.WX_APP_KEY, code);
System.out.println(map);
if(map == null) {
map = systemCtrlService.queryTSystemCtrlByCode(code, langID);
if(map != null) {
redisTemplate.opsForHash().put(PayContstrant.WX_APP_KEY, code, map);
}
}
return map;
}
/**
*
* @Title: getWxOpenId
* @Description: TODO(小程序获取openid)
* @param @param params
* @param @return 设定文件
* @return 返回类型
* @throws
*/
public String getWxOpenId(Map<String,String> params){
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
String openIdStr = HttpsUtil.doGet(requestUrl, params);
try {
//记日志
} catch (Exception e) {
e.printStackTrace();
}
return openIdStr;
}
/**
* @throws Exception
*
* @Title: unifiedorder
* @Description: TODO(生成预支付单号)
* @param @param params
* @param @return 设定文件
* @return 返回类型
* @throws
*/
@Override
public Map<String,String> unifiedorder(SortedMap<Object, Object> params) throws Exception {
Date startTime = new Date();
String requestUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String sign = WxSignUtil.createSign(params); //计算签名
params.put("sign",sign);
String requestXml = WxApiXmlComer.mapToXml(params);
logger.info("预支付生成的XML请求: "+requestXml);
String responseXml = HttpsUtil.doPostForXml(requestUrl, requestXml);
logger.info("预支付生成的XML返回: "+responseXml);
Map<String,String> resultMap = WxApiXmlComer.doXMLParse(responseXml);
Date endTime = new Date();
try {
/*WxApiLog wxApiLog = new WxApiLog();
wxApiLog.setPaytypeid(wxAppIdObject.getString("payTypeId"));
wxApiLog.setPaytype(wxAppIdObject.getString("payTpye"));
wxApiLog.setRequestXml(requestXml);
wxApiLog.setResponseXml(responseXml);
wxApiLog.setStarttime(startTime);
wxApiLog.setEndtime(endTime);
wxApiLog.setLogcode("unifiedorder");
wxApiLog.setLogname("生成预支付单号");
wxApiLog.setOutTradeNo(params.get("out_trade_no")+"");
wxApiLog.setTransactionId(resultMap.containsKey("prepay_id")==true?resultMap.get("prepay_id"):"");
wxApiLogService.insert(wxApiLog);*/
//加日志
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
/**
* 发起退款
* <p>Title: </p>
* <p>Description: </p>
* @param params
* @param wxAppIdObject
* @return
* @throws Exception
*/
public Map<String,String> refund(SortedMap<Object, Object> params) throws Exception {
Date startTime = new Date();
String requestUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
String sign = WxSignUtil.createSign(params); //计算签名
params.put("sign",sign);
logger.info("退款签名:"+sign);
String requestXml = WxApiXmlComer.mapToXml(params);
String mch_id = params.get("mch_id")+""; //商户号
String responseXml = HttpsUtil.doPostBySSL(mch_id, sslPath, requestXml, requestUrl);
logger.info("退款返回---:"+responseXml);
Map<String,String> resultMap = WxApiXmlComer.doXMLParse(responseXml);
Date endTime = new Date();
try {
String return_code = resultMap.get("return_code");
String result_code = resultMap.get("result_code");
/* WxApiLog wxApiLog = new WxApiLog();
wxApiLog.setPaytypeid(wxAppIdObject.getString("payTypeId"));
wxApiLog.setPaytype(wxAppIdObject.getString("payTpye"));
wxApiLog.setRequestXml(requestXml);
wxApiLog.setResponseXml(responseXml);
wxApiLog.setStarttime(startTime);
wxApiLog.setEndtime(endTime);
wxApiLog.setLogcode("refund");
wxApiLog.setLogname("申请退款");
wxApiLog.setOutTradeNo(params.get("out_trade_no")+"");
wxApiLog.setTransactionId(params.get("transaction_id")+"");
if(return_code.equals("SUCCESS") && result_code.equals("SUCCESS")){ //当退款成功,全部重取这两个参数
wxApiLog.setOutTradeNo(resultMap.get("out_trade_no"));
wxApiLog.setTransactionId(resultMap.get("transaction_id"));
}
wxApiLogService.insert(wxApiLog);*/
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
}
package com.egolm.payment.util;
import java.security.MessageDigest;
public class MD5Util {
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];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(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;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
package com.egolm.payment.util;
public class PayContstrant {
public static final String WX_APP_KEY="WX_APP_KEY"; //微信app信息存储前缀
public static final String WX_CHAT_APP_KEY = "WxChatKey"; //微信公众号KEY 存放appid 密钥 信息的
public static final String WX_MINI_APP_KEY = "WxMiniProgramKey"; //微信小程序KEY 存放appid 密钥 信息的
}
package com.egolm.payment.util;
import java.io.UnsupportedEncodingException;
import java.util.SortedMap;
import java.util.TreeMap;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* @Title:
* @Description:
* @author zhangyong
* @date 2016年3月11日 下午6:04:03
* @version V1.0
*
*/
public class SAXXmlContentHandler extends DefaultHandler {
private String tagName;
private SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
@Override
public void startDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tagName = qName;
}
@Override
public void characters(char[] ch, int start, int length) {
String dataStr = new String(ch, start, length);
try {
dataStr = new String(dataStr.getBytes(),"UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try {
if(tagName != null && !tagName.equals("sign") ){
parameters.put(tagName, dataStr);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(tagName!= null && tagName.equals(qName)){
tagName= null;
}
}
public SortedMap<Object, Object> getMap(){
return parameters;
}
}
package com.egolm.payment.util;
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;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
public class WxApiXmlComer {
/**
* 将MAP转换成微信需要的XML
* <p>
* Title:
* </p>
* <p>
* Description:
* </p>
*
* @param params
* @return
*/
public static String mapToXml(SortedMap<Object, Object> params) {
StringBuffer sbuff = new StringBuffer();
sbuff.append("<xml>");
if (params != null && params.size() > 0) {
Set<Entry<Object, Object>> set = params.entrySet();
Iterator<Entry<Object, Object>> itor = set.iterator();
Entry<Object, Object> tmpEntry = null;
while (itor.hasNext()) {
tmpEntry = itor.next();
String key = (String)tmpEntry.getKey();
String value = (String)tmpEntry.getValue();
if (!key.equals("md5Key")) {
if (key.equals("body")) {
sbuff.append("<" + key + ">").append("<![CDATA[" + value + "]]>").append("</" + key + ">");
} else {
sbuff.append("<" + key + ">").append(value).append("</" + key + ">");
}
}
}
}
sbuff.append("</xml>");
return sbuff.toString();
}
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
*
* @param strxml
* @return
* @throws JDOMException
* @throws IOException
*/
public static Map<String,String> doXMLParse(String strxml) throws Exception {
if (null == strxml || "".equals(strxml)) {
return null;
}
Map<String,String> m = new HashMap<String,String>();
InputStream in = String2Inputstream(strxml);
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
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 = getChildrenText(children);
}
m.put(k, v);
}
// 关闭流
in.close();
return m;
}
/**
* 获取子结点的xml
*
* @param children
* @return String
*/
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.append(getChildrenText(list));
}
sb.append(value);
sb.append("</" + name + ">");
}
}
return sb.toString();
}
public static InputStream String2Inputstream(String str) {
return new ByteArrayInputStream(str.getBytes());
}
}
package com.egolm.payment.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class WxSignUtil {
public static final String characterEncoding = "UTF8";
/**
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
*/
public static String createSign(SortedMap<Object, Object> packageParams) {
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) && !"md5Key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + packageParams.get("md5Key"));
System.out.println(sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
/**
* 根据微信返回的数据生成签名
* @param wxXml
* @return
* @throws Exception
*/
public static String getSignKey(String wxXml,String md5Key) throws Exception {
System.out.println(">>>>>>>>>>>>>"+wxXml);
SAXXmlContentHandler sch = new SAXXmlContentHandler();
InputStream is = new ByteArrayInputStream(wxXml.getBytes("UTF-8"));
// 创建一个SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
// ②创建SAX解析器
SAXParser parser = factory.newSAXParser();
parser.parse(is, sch);
SortedMap<Object, Object> parameters = sch.getMap();
parameters.put("md5Key", md5Key);
String mySign = createSign(parameters);
return mySign;
}
public static boolean checkSign(Map<String,String> resultMap,String sign) throws Exception{
String createSign = createSign(mapToStoredMap(resultMap));
if(createSign.equals(sign)){
return true;
}
return false;
}
public static SortedMap<Object, Object> mapToStoredMap(Map<String,String> resultMap){
SortedMap<Object,Object> params = new TreeMap<Object,Object>();
if(resultMap != null && resultMap.size() >0 ){
for(Map.Entry<String, String> result:resultMap.entrySet()){
params.put(result.getKey(), result.getValue());
}
}
return params;
}
}
......@@ -19,4 +19,21 @@ spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.testWhileIdle=true
spring.datasource.validationQueryTimeout=5
spring.datasource.validationQuery=SELECT 1
spring.datasource.timeBetweenEvictionRunsMillis=3600000
\ No newline at end of file
spring.datasource.timeBetweenEvictionRunsMillis=3600000
spring.redis.database=0
spring.redis.host=10.10.0.15
spring.redis.port=16379
spring.redis.password=
spring.redis.timeout=2000
spring.redis.pool.max-active=20
spring.redis.pool.max-wait=2000
spring.redis.pool.max-idle=5
spring.redis.pool.min-idle=0
#微信退款证书地址
wx.refund.ssl.path=
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment