package com.subscription.restful.web; import java.io.BufferedReader; import java.io.PrintWriter; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.avalon.framework.ExceptionUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; 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.bind.annotation.RestController; import com.alibaba.fastjson.JSON; import com.cku.core.RESTResponse; import com.cku.oa.finance.entity.PaymentOrder; import com.cku.oa.finance.service.PaymentOrderService; import com.cku.oa.finance.service.PaymentPayLogService; import com.cku.restful.v1.finance.service.RestOrderService; import com.cku.restful.v1.sys.model.WXPayResult; import com.cku.restful.v1.sys.utils.JdomParseXmlUtils; import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayUtil; import com.subscription.restful.service.WXpayServiceImpl; import com.subscription.restful.utils.MyWXPayConfig; import com.thinkgem.jeesite.common.web.BaseController; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; @Api(value = "公众号微信支付-xuxue", tags = { "公众号微信支付-xuxue" }) @RestController @RequestMapping(value = "subscription") public class WXController extends BaseController { @Autowired private WXpayServiceImpl wxpayServiceImpl; @Autowired private PaymentPayLogService paymentPayLogService; @Autowired private PaymentOrderService paymentOrderService; @Autowired private RestOrderService restOrderService; @Autowired private MyWXPayConfig wxPayConfig; /** * 第一步、根据前端传入的URL生产签名数据,拉起支付使用 * 先通过code来获取AccessToken,再用AccessToken获取票据,票据获取成功后签名给前台,用来拉起支付 * * @param code * @param request * @return * @throws Exception */ @ApiOperation(value = "(1)根据前端传入的URL生产签名数据,拉起支付使用", notes = "入参:\n" + "{\n" + "   \"url\":\"000857962\" \n" + "}\n") @ApiResponses(@ApiResponse(code = 200, message = "{\n" + " \"rc\": 0,\n" + "\"msg\": \"OK\",\n" + " \"data\": {\n" + " \"appId\": \"wx254077ea0c1077dd\",\n" + " \"noncestr\": \"3ffb8b50007844d29680ad9449b19733\",\n" + " \"timestamp\": \"1588041456\",\n" + " \"signature\": \"e6fcae3f6258c3d2041377591ea53f2a374e6851\"\n" + " }\n" + "}\n" + "")) @RequestMapping(value = "getTicket", method = RequestMethod.POST) @ResponseBody public RESTResponse getTicket(@RequestBody String json, HttpServletRequest request) throws Exception { HashMap map = JSON.parseObject(json, HashMap.class); String url = map.get("url"); try { return new RESTResponse(wxpayServiceImpl.getTicket(url)); } catch (Exception e) { logger.error(e.getMessage(), e); return new RESTResponse(10001, e.getMessage()); } } /** * 第二步 新建微信付款单 * * @param json * @param request * @return * @throws Exception */ @ApiOperation(value = "(2)新建微信付款单", notes = "入参:\n" + "{\n" + "\"orderId\":\"db0ebc31bc7f489eafae6e74f927e576\",\n" + "\"openId\":\"oxAyL0-qeHJ9igGkaCltksl87_f8\"\n" + "}\n") @ApiResponses(@ApiResponse(code = 200, message = "{\n" + " \"rc\": 0,\n" + "\"msg\": \"OK\",\n" + " \"data\": {\n" + " \"timeStamp\": \"1588041331\",\n" + " \"package\": \"prepay_id=wx281035312710378552cf1c881463197800\",\n" + " \"appId\": \"wx254077ea0c1077dd\",\n" + " \"sign\": \"44CD955D5D293BEB24DE16E9AE011116\",\n" + " \"signType\":\"MD5\",\n" + " \"nonceStr\": \"0a7871b3602c47c2b10dbf4d8ba0a6ac\",\n" + " \"timestamp\": \"1588041331\"\n" + " }\n" + "}\n")) @RequestMapping(value = "WXPay/create", method = RequestMethod.POST) @ResponseBody public RESTResponse createPayOrder(@RequestBody String json, HttpServletRequest request) throws Exception { HashMap mapP = JSON.parseObject(json, HashMap.class); String orderId = mapP.get("orderId"); String openId = mapP.get("openId"); String userIp = getIpAddress(request); try { return wxpayServiceImpl.createPayOrder(orderId, userIp, openId); } catch (Exception e) { logger.error(e.getMessage(), e); return new RESTResponse(10001, e.getMessage()); } } /** * 获取真实ip地址,避免获取代理ip * * @throws UnknownHostException */ public String getIpAddress(HttpServletRequest request) throws UnknownHostException { String ip = request.getRemoteAddr(); if (StringUtils.isBlank(ip)) { ip = "0:0:0:0:0:0:0:1"; } return ip; } /** * 第三步 查询付款结果 * * @param json * @return * @throws Exception */ @ApiOperation(value = "(3)查询付款结果", notes = "入参:\n" + "{\n" + "\"orderId\":\"db0ebc31bc7f489eafae6e74f927e576\"\n" + "}") @ApiResponses(@ApiResponse(code = 200, message = "{\n" + " \"rc\": 0,\n" + "\"msg\": \"OK\",\n" + " \"data\": {\n" + " \"result\": \"FAIL\" -- 支付SUCCESS 未支付FAIL\n" + " }\n" + "}")) @RequestMapping(value = "WXPay/check", method = RequestMethod.POST) public RESTResponse check(@RequestBody String json) throws Exception { logger.debug("~~~~~~~~~~~~~~~~前端调用1~~~~~~~~~" + json); HashMap mapP = JSON.parseObject(json, HashMap.class); String orderId = mapP.get("orderId"); RESTResponse response = wxpayServiceImpl.check(orderId); logger.debug("~~~~~~~~~~~~~~~~前端调用2~~~~~~~~~" + response); return response; } // @ApiIgnore @RequestMapping(value = "notifyUrlWeixin") public void notifySubscription(HttpServletRequest request, HttpServletResponse response) { Map data = new HashMap<>(2); try { BufferedReader reader = request.getReader(); String line = ""; StringBuffer inputString = new StringBuffer(); PrintWriter writer = response.getWriter(); while ((line = reader.readLine()) != null) { inputString.append(line); } if (reader != null) { reader.close(); } logger.info("----[微信回调]接收到的报文---" + inputString.toString()); if (!StringUtils.isEmpty(inputString.toString())) { // 增加支付日志 WXPayResult wxPayResult = JdomParseXmlUtils.getWXPayResult(inputString.toString()); // 保存回调的支付日志 paymentPayLogService.updatePayInfo(wxPayResult.getOut_trade_no(), wxPayResult.getTransaction_id(), inputString.toString()); if ("SUCCESS".equalsIgnoreCase(wxPayResult.getReturn_code())) { WXPay wxpay = new WXPay(wxPayConfig); boolean result = wxpay.isPayResultNotifySignatureValid(WXPayUtil.xmlToMap(inputString.toString())); String orderId = wxPayResult.getOut_trade_no(); try { if (result) { // 修改订单的状态 PaymentOrder order = paymentOrderService.get(orderId); if (order != null && order.getPaymentState().equals("1") && !StringUtils.isEmpty(order.getOrderCode())) { // 修改支付方式 order.setPaymentWay("24");// 24代表微信支付 order.setTransactionId(wxPayResult.getTransaction_id()); // 会员端支付后处理逻辑 restOrderService.afterPay(order); // 修改支付日志支付状态 paymentPayLogService.updatePayState(orderId, "2", null); } else if (order != null && order.getPaymentState().equals("2") && !StringUtils.isEmpty(order.getOrderCode())) { logger.info("用户支付成功,订单已经处理过"); } else { logger.error("用户支付成功,但是处理失败,没有找到待处理订单"); // 修改支付日志支付状态 paymentPayLogService.updatePayState(orderId, "3", "用户支付成功,但是处理失败,没有找到待处理订单"); } data.put("return_code", "SUCCESS"); data.put("return_msg", "OK"); writer.write(WXPayUtil.mapToXml(data)); } else { data.put("return_code", "FAIL"); writer.write(WXPayUtil.mapToXml(data)); logger.error("---------微信支付验证签名失败----------"); // 修改支付日志支付状态 paymentPayLogService.updatePayState(orderId, "3", "验证签名失败"); } } catch (Exception e) { // 修改支付日志支付状态 paymentPayLogService.updatePayState(orderId, "3", ExceptionUtil.printStackTrace(e)); logger.error("----微信支付处理失败---", e); } } else { data.put("return_code", "FAIL"); writer.write(WXPayUtil.mapToXml(data)); // 修改支付日志支付状态 paymentPayLogService.updatePayState(wxPayResult.getOut_trade_no(), "3", "返回码错误:" + wxPayResult.getReturn_msg()); logger.error("---------微信支付返回Fail----------" + wxPayResult.getReturn_msg()); } if (writer != null) { writer.close(); } } else { data.put("return_code", "FAIL"); writer.write(WXPayUtil.mapToXml(data)); } } catch (Exception ex) { ex.printStackTrace(); } } }