ResponseWechatPayHandler.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. package com.iamberry.wechat.handles.pay;
  2. import java.io.BufferedOutputStream;
  3. import java.io.IOException;
  4. import java.io.StringReader;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import org.jdom.Document;
  12. import org.jdom.Element;
  13. import org.jdom.input.SAXBuilder;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.stereotype.Controller;
  16. import org.springframework.web.bind.annotation.RequestMapping;
  17. import org.xml.sax.InputSource;
  18. import com.iamberry.app.tool.log.RatFWLogger;
  19. import com.iamberry.wechat.core.entity.coupon.CouponItem;
  20. import com.iamberry.wechat.core.entity.drp.PlaceInfo;
  21. import com.iamberry.wechat.core.entity.drp.PlaceOrder;
  22. import com.iamberry.wechat.core.entity.member.CashLog;
  23. import com.iamberry.wechat.core.entity.member.Member;
  24. import com.iamberry.wechat.core.entity.mq.MQMessage;
  25. import com.iamberry.wechat.core.entity.order.Order;
  26. import com.iamberry.wechat.core.entity.wx.WxPayResult;
  27. import com.iamberry.wechat.face.cart.CartService;
  28. import com.iamberry.wechat.face.coupon.CouponItemService;
  29. import com.iamberry.wechat.face.drp.PlaceInfoService;
  30. import com.iamberry.wechat.face.drp.PlaceOrderService;
  31. import com.iamberry.wechat.face.member.CashLogService;
  32. import com.iamberry.wechat.face.member.MemberService;
  33. import com.iamberry.wechat.face.order.AdminOrderService;
  34. import com.iamberry.wechat.face.qrcode.QrcodeService;
  35. import com.iamberry.wechat.face.reback.RebackServices;
  36. import com.iamberry.wechat.handles.mq.MQServiceProxy;
  37. import com.iamberry.wechat.tools.StaticInfo;
  38. /**
  39. * @author 何秀刚
  40. * Class Description: 微信支付回调handler,所有的支付回调,都在本类完成
  41. * Create Date:2016年4月19日
  42. * Update Date:2016年4月19日
  43. */
  44. @Controller
  45. @RequestMapping("/callback")
  46. public class ResponseWechatPayHandler {
  47. @Autowired
  48. private RatFWLogger ratFWLogger;
  49. private Object lock = new Object();
  50. @Autowired
  51. private CartService cartService;
  52. @Autowired
  53. private PlaceOrderService placeOrderService;
  54. @Autowired
  55. private PlaceInfoService placeInfoService;
  56. @Autowired
  57. private MemberService memberService;
  58. @Autowired
  59. private AdminOrderService adminOrderService;
  60. @Autowired
  61. private MQServiceProxy mQservice;
  62. @Autowired
  63. private RebackServices rebackServices;
  64. @Autowired
  65. private QrcodeService qrcodeService; //二维码处理
  66. @Autowired
  67. CashLogService cashLogService;
  68. @Autowired
  69. CouponItemService couponItemService;
  70. /**
  71. * 销售订单支付回调方法
  72. */
  73. @SuppressWarnings("rawtypes")
  74. @RequestMapping("/orderPayBack")
  75. public void orderPayBack(HttpServletRequest request,
  76. HttpServletResponse response) throws IOException {
  77. synchronized (lock) {
  78. String inputLine;
  79. String notityXml = "";
  80. String resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  81. try {
  82. //获取XML参数
  83. while ((inputLine = request.getReader().readLine()) != null) {
  84. notityXml += inputLine;
  85. }
  86. request.getReader().close();
  87. //解析XML格式的数据
  88. Map m = parseXmlToList2(notityXml);
  89. WxPayResult wpr = new WxPayResult();
  90. wpr=setWxPayResultObj(wpr,m);
  91. //判断
  92. if("SUCCESS".equalsIgnoreCase(wpr.getResultCode())){
  93. //resXml:返回给微信服务器的数据
  94. resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  95. String orderIdMD5 = StaticInfo.orderIdMD5.decrypt(wpr.getAttach());
  96. //System.out.println("===========pay 117==============");
  97. if (orderIdMD5.equals(wpr.getOutTradeNo())) {
  98. Date nowDate = new Date();
  99. // 组装数据
  100. Order order = new Order();
  101. order.setSalesOrderid(orderIdMD5);
  102. order.setSalesStatus(2); // 已支付
  103. order.setSalesTransactionId(wpr.getTransactionId()); // 微信支付ID
  104. order.setSalesTransactionDate(new Date()); // 微信支付时间
  105. order.setSalesOpenid(wpr.getOpenid());
  106. // 修改订单状态
  107. int count = cartService.updateOrderStatus(order);
  108. //System.out.println("===========pay 132 修改订单状态==============");
  109. //修改优惠券状态
  110. order=cartService.selectOrderInfoById(order);
  111. //System.out.println("===========pay 136 修改订单状态=============="+order.getSalesOrderid());
  112. String couponId=order.getCouponId();
  113. if(couponId!=null && !couponId.equals("")){
  114. CouponItem couponItem=new CouponItem();
  115. couponItem.setCouponItemId(couponId);
  116. couponItem.setCouponUseStatus(2);
  117. couponItem.setCouponUseDate(new Date());
  118. couponItemService.updateCouponItemById(couponItem);
  119. }
  120. //更新账户余额
  121. int balancePayAmount=order.getBalancePayAmount();
  122. if(balancePayAmount>0){
  123. Member member=new Member();
  124. member.setUserOpenid(order.getSalesOpenid());
  125. member.setUserIncome(-balancePayAmount);
  126. memberService.updateUserIncomeByOpenId(member);
  127. //现金使用记录
  128. CashLog log=new CashLog();
  129. log.setCashLogsIntroduction("订单支出");
  130. log.setCashLogsNum(balancePayAmount);
  131. log.setCashLogsOpenid(member.getUserOpenid());
  132. log.setCashLogsType(2);
  133. log.setCashLogsResType(3);
  134. log.setCashLogsOrderid(order.getSalesOrderid());
  135. log.setCashLogsCreateDate(nowDate);
  136. count=cashLogService.addCashLog(log);
  137. }
  138. if (count < 1) {
  139. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
  140. }
  141. //System.out.println("===========pay 168 快速插入=============="+count);
  142. // 给订单的回调修改状态
  143. try {
  144. MQMessage message = new MQMessage();
  145. message.setServiceToMessage(orderIdMD5);
  146. message.setServiceOtherMessage(wpr.getTransactionId());
  147. message.setServiceIsSend(2); // 没有推送的信息
  148. message.setServiceStatus(1); // 推送成功
  149. message.setServiceHandlerObjectName("cartServiceImpl");
  150. message.setServiceHandlerMethodName("supdateStateByOrderId");
  151. message.setServiceType(1);
  152. mQservice.insertMQMessage(message);
  153. } catch (Exception e) {
  154. // TODO: handle exception
  155. }
  156. //System.out.println("===========pay 182 插入返利到mq=============="+count);
  157. //rebackServices.loadSingleOrderReward(order);
  158. //添加到返利表
  159. //rebackServices.loadSingleOrderReward(order);
  160. // 给百胜推送信息
  161. try {
  162. MQMessage message = new MQMessage();
  163. message.setServiceToMessage(orderIdMD5);
  164. message.setServiceOtherMessage("efast.trade.new.add");
  165. message.setServiceIsSend(2); // 没有推送的信息
  166. message.setServiceStatus(1); // 推送成功
  167. message.setServiceType(1); // 添加订单信息
  168. message.setServiceHandlerObjectName("efastOrderServiceImpl");
  169. message.setServiceHandlerMethodName("addOrderInfoToEfast");
  170. mQservice.insertMQMessage(message);
  171. } catch (Exception e) {
  172. //System.out.println("===========pay 201 插入返利到百胜失败==============");
  173. }
  174. //System.out.println("===========pay 201 插入返利到百胜完成==============");
  175. try {
  176. //给父节点推送返利消息
  177. // rewardsMessage(member,orderIdMD5);
  178. } catch (Exception e) {
  179. e.printStackTrace();
  180. }
  181. } else {
  182. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
  183. ratFWLogger.error(this, "订单:" + orderIdMD5 + "支付成功,但是没有通过校验!");
  184. }
  185. }else{
  186. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
  187. }
  188. BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
  189. out.write(resXml.getBytes());
  190. out.flush();
  191. out.close();
  192. } catch (Exception e) {
  193. e.printStackTrace();
  194. }
  195. }
  196. }
  197. /**
  198. * 销售订单支付回调方法
  199. */
  200. @SuppressWarnings("rawtypes")
  201. @RequestMapping("/drpPayBack")
  202. public void drpPayBack(HttpServletRequest request,
  203. HttpServletResponse response) throws IOException {
  204. synchronized (lock) {
  205. String inputLine;
  206. String notityXml = "";
  207. String resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  208. try {
  209. //获取XML参数
  210. while ((inputLine = request.getReader().readLine()) != null) {
  211. notityXml += inputLine;
  212. }
  213. request.getReader().close();
  214. //解析XML格式的数据
  215. Map m = parseXmlToList2(notityXml);
  216. WxPayResult wpr = new WxPayResult();
  217. wpr=setWxPayResultObj(wpr,m);
  218. //判断
  219. if("SUCCESS".equalsIgnoreCase(wpr.getResultCode())){
  220. //resXml:返回给微信服务器的数据
  221. resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  222. String orderIdMD5 = StaticInfo.orderIdMD5.decrypt(wpr.getAttach());
  223. if (orderIdMD5.equals(wpr.getOutTradeNo())) {
  224. PlaceOrder placeOrder=new PlaceOrder();
  225. placeOrder.setId(orderIdMD5);
  226. placeOrder.setStatus(2); //已付款
  227. int count = placeOrderService.UpdateOrder(placeOrder);
  228. if (count < 1) {
  229. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
  230. }
  231. } else {
  232. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文有误]]></return_msg></xml>";
  233. ratFWLogger.error(this, "订单:" + orderIdMD5 + "支付成功,但是没有通过校验!");
  234. }
  235. }else{
  236. resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
  237. }
  238. BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
  239. out.write(resXml.getBytes());
  240. out.flush();
  241. out.close();
  242. } catch (Exception e) {
  243. e.printStackTrace();
  244. }
  245. }
  246. }
  247. /**
  248. * 解析xml片段为Map
  249. * @param xml
  250. * @return
  251. */
  252. @SuppressWarnings({ "rawtypes", "unchecked" })
  253. private Map parseXmlToList2(String xml) {
  254. Map retMap = new HashMap();
  255. try {
  256. StringReader read = new StringReader(xml);
  257. // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
  258. InputSource source = new InputSource(read);
  259. // 创建一个新的SAXBuilder
  260. SAXBuilder sb = new SAXBuilder();
  261. // 防止XXE
  262. sb.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
  263. sb.setFeature("http://xml.org/sax/features/external-general-entities", false);
  264. sb.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
  265. sb.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
  266. // 通过输入源构造一个Document
  267. Document doc = (Document) sb.build(source);
  268. Element root = doc.getRootElement();// 指向根节点
  269. List<Element> es = root.getChildren();
  270. if (es != null && es.size() != 0) {
  271. for (Element element : es) {
  272. retMap.put(element.getName(), element.getValue());
  273. }
  274. }
  275. } catch (Exception e) {
  276. e.printStackTrace();
  277. }
  278. return retMap;
  279. }
  280. //封装参数
  281. public WxPayResult setWxPayResultObj(WxPayResult wpr ,Map m){
  282. //解析参数
  283. wpr.setAppid(m.get("appid").toString());
  284. wpr.setBankType(m.get("bank_type").toString());
  285. wpr.setCashFee(m.get("cash_fee").toString());
  286. wpr.setFeeType(m.get("fee_type").toString());
  287. wpr.setIsSubscribe(m.get("is_subscribe").toString());
  288. wpr.setMchId(m.get("mch_id").toString());
  289. wpr.setNonceStr(m.get("nonce_str").toString());
  290. wpr.setOpenid(m.get("openid").toString());
  291. wpr.setOutTradeNo(m.get("out_trade_no").toString());
  292. wpr.setAttach(m.get("attach").toString());
  293. wpr.setResultCode(m.get("result_code").toString());
  294. wpr.setReturnCode(m.get("return_code").toString());
  295. wpr.setSign(m.get("sign").toString());
  296. wpr.setTimeEnd(m.get("time_end").toString());
  297. wpr.setTotalFee(m.get("total_fee").toString());
  298. wpr.setTradeType(m.get("trade_type").toString());
  299. wpr.setTransactionId(m.get("transaction_id").toString());
  300. return wpr;
  301. }
  302. /**
  303. * 奖励提醒 下线成功购买后 提示直接上线
  304. * create date 2016年5月14日
  305. * @author 穆再兴
  306. * @return
  307. */
  308. private boolean rewardsMessage(Member member,String orderid){
  309. boolean result = false;
  310. // Integer i = cartService.getItemNumByOrderId(orderid);
  311. // if(i == null || i.intValue() == 0){return false;}
  312. // if(member == null || member.getUserResType() == null) return false;
  313. //
  314. // switch(member.getUserResType().intValue()){//用户来源
  315. // case 2: //用户来源 微代理
  316. //// if(member.getUserRefereeid() == null){return false;}
  317. // Member fatherMember = memberService.getMemberByUserId(member.getUserRefereeid()); //微代理父节点信息
  318. // if(fatherMember != null && StringUtils.isNotEmpty(fatherMember.getUserOpenid())){
  319. // String temp = ResultInfo.REWARDSREMINDTEMP;
  320. // temp = temp.replaceFirst("firstValueIamberry", ResultInfo.REWARDSWILLMESSAGE)
  321. // .replaceFirst("orderValueIamberry", orderid)
  322. // .replaceFirst("moneyValueIamberry", "¥" + new Integer(i.intValue() * 100).toString())
  323. // .replaceFirst("remarkValueIamberry", ResultInfo.INTOSHOP);
  324. // result = wxService.rewardsRemind(temp, fatherMember.getUserOpenid(), ResultInfo.INDEX_PAGE);
  325. // }
  326. // break;
  327. // case 3: //用户来源 线下
  328. //// if(member.getUserResOnline() == null ){return false;}
  329. // PlaceInfo fatherPlace = placeInfoService.getPlaceInfoById(member.getUserResOnline());//分销父节点信息
  330. // /*if(fatherPlace == null || fatherPlace.getPlaceRole() == 7){ return result; }*/
  331. // int num = getRewardsMoneyOfFather(fatherPlace);
  332. // if(num !=0 && StringUtils.isNotEmpty(fatherPlace.getOpenid())){
  333. // String temp = ResultInfo.REWARDSREMINDTEMP;
  334. // temp = temp.replaceFirst("firstValueIamberry", ResultInfo.REWARDSWILLMESSAGE)
  335. // .replaceFirst("orderValueIamberry", orderid)
  336. // .replaceFirst("moneyValueIamberry", "¥" + new Integer(i.intValue() * num / 100).toString())
  337. // .replaceFirst("remarkValueIamberry", ResultInfo.INTOSHOP);
  338. // result = wxService.rewardsRemind(temp, fatherPlace.getOpenid(), ResultInfo.INDEX_PAGE);
  339. // }
  340. // break;
  341. // }
  342. return result;
  343. }
  344. /**
  345. * 获取 返给父节点的 金额
  346. * create date 2016年5月14日
  347. * @author 穆再兴
  348. * @param fatherplace 父节点
  349. * @return
  350. */
  351. private int getRewardsMoneyOfFather(PlaceInfo fatherplace){
  352. if(fatherplace == null ){return 0;}
  353. return 0;
  354. /*ShopSystemRule ruleMoney = null;
  355. switch(fatherplace.getType()){ //父节点类型
  356. case 2: //二级的角色
  357. if(fatherplace.getPlaceRole() == 7){ //角色:奶粉厂 每台机器返利100元
  358. ruleMoney = this.adminOrderService.getReluByRid(97);
  359. break;
  360. }else if(fatherplace.getPlaceRole() == 4){ //角色:特殊渠道管理员 每台机器返利140元
  361. ruleMoney = this.adminOrderService.getReluByRid(98);
  362. break;
  363. }
  364. case 3: //三级的角色
  365. if(fatherplace.getPlaceRole() == 5){ //角色:导购 每台机器返利40元
  366. ruleMoney = this.adminOrderService.getReluByRid(96);
  367. break;
  368. }else if(fatherplace.getPlaceRole() == 6){ //角色:分销员 每台机器返利100元
  369. ruleMoney = this.adminOrderService.getReluByRid(97);
  370. break;
  371. }
  372. }
  373. if(ruleMoney == null){return 0;}
  374. return ruleMoney.getRuleNum() == null ? 0 : ruleMoney.getRuleNum().intValue();
  375. */
  376. }
  377. }