package com.fdkankan.ucenter.controller; import com.alibaba.fastjson.JSONObject; import com.fdkankan.common.constant.Constant; import com.fdkankan.common.constant.ConstantUrl; import com.fdkankan.common.constant.ErrorCode; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.redis.util.RedisUtil; import com.fdkankan.ucenter.common.BaseController; import com.fdkankan.ucenter.common.Result; import com.fdkankan.ucenter.entity.*; import com.fdkankan.ucenter.pay.factory.PayFactory; import com.fdkankan.ucenter.pay.factory.impl.PayOrderService; import com.fdkankan.ucenter.pay.paypal.sdk.UrlUtils; import com.fdkankan.ucenter.pay.strategy.OrderStrategyFactory; import com.fdkankan.ucenter.pay.wx.WXPayConstants; import com.fdkankan.ucenter.pay.wx.WXPayDefaultConfig; import com.fdkankan.ucenter.pay.wx.WXPayUtil; import com.fdkankan.ucenter.service.*; import com.fdkankan.ucenter.vo.request.PlaceOrderParam; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; 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 java.io.BufferedOutputStream; import java.io.InputStream; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Map; @Log4j2 /**支付中心-微信支付模块"*/ @Controller @RequestMapping("/ucenter/order/pay") public class OrderWechatPayController extends BaseController { @Autowired private OrderStrategyFactory orderStrategyFactory; @Autowired private PayFactory payFactory; @Autowired private IOrderService orderService; @Autowired private IVirtualOrderService virtualOrderService; @Autowired private IExpansionOrderService expansionOrderService; @Autowired private IIncrementOrderService incrementOrderService; @Autowired IOrderItemService orderItemService; @Autowired RedisUtil redisUtil; @Autowired PayOrderService payOrderService; @Value("${main.url}") private String mainUrl; @ResponseBody @RequestMapping(value = "/wechatPay", method = RequestMethod.POST) public Result wechatPay(@RequestBody PlaceOrderParam order) throws Exception { return Result.success(payFactory.scanPay("wechat", order)); } @ResponseBody @RequestMapping(value = "/wechatMobilePay", method = RequestMethod.POST) public Result wechatMobilePay(@RequestBody PlaceOrderParam order) throws Exception { return Result.success(payFactory.h5Pay("wechat", order, UrlUtils.getIpAddr(request))); } @RequestMapping(value = "/wechatPreJsPay") public String wechatPreJsPay(Long orderId, int orderType, String code, Long spaceId) throws Exception { InputStream is = null; WXPayDefaultConfig config = new WXPayDefaultConfig(); // 这个url链接地址和参数皆不能变 String url = ConstantUrl.WEIXIN_TOKEN_URL1 + config.getAppID() + "&secret=" + config.getSecret() + "&grant_type=authorization_code" + "&code=" + code; try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必须是get方式请求 http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒 System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒 http.connect(); is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); String message = new String(jsonBytes, "UTF-8"); log.debug("获取access_token返回的message:"+message); JSONObject oppidObj = JSONObject.parseObject(message); String access_token = (String) oppidObj.get("access_token"); String openid = (String) oppidObj.get("openid"); String orderSn = null; StringBuilder sb = new StringBuilder(); BigDecimal totalFee = null; switch (orderType){ case 0: Order responseOrder = orderService.getById(orderId); if (responseOrder.getId() == null) return "redirect:" + mainUrl + "mobile.html#/payresult/fail"; List items = orderItemService.getByOrderId(orderId); for (int i = 0; i < items.size(); i++){ sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName()); if (i != items.size() - 1){ sb.append(","); } } totalFee = responseOrder.getTotalAmount().multiply(new BigDecimal(100)); orderSn = responseOrder.getOrderSn(); orderSn += "_entity"; break; case 1: VirtualOrder virtualOrderEntity = virtualOrderService.getById(orderId); if (virtualOrderEntity == null){ return "redirect:" + mainUrl + "mobile.html#/payresult/fail"; } sb.append(Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints()); totalFee = new BigDecimal(virtualOrderEntity.getPoints()).multiply(new BigDecimal(100)); orderSn = virtualOrderEntity.getOrderSn(); orderSn += "_recharge"; break; case 2: ExpansionOrder expansion = expansionOrderService.getById(orderId); if (expansion == null){ return "redirect:" + mainUrl + "mobile.html#/payresult/fail"; } //订单金额为国外金额就报错 if(expansion.getAbroad() == 1){ throw new BusinessException(ErrorCode.FAILURE_CODE_8004); } String date = "1年"; if(expansion.getMonth() < 12){ date = expansion.getMonth() + "个月"; } String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date; sb.append(subject); totalFee = expansion.getAmount().multiply(new BigDecimal(100)); orderSn = expansion.getOrderSn(); orderSn += "_expansion"; break; case 3: break; case 4: IncrementOrder incrementOrderEntity = incrementOrderService.getById(orderId); if (incrementOrderEntity == null){ return "redirect:" + mainUrl + "mobile.html#/payresult/fail"; } //订单金额为国外金额就报错 if(incrementOrderEntity.getAbroad() == 1){ throw new BusinessException(ErrorCode.FAILURE_CODE_8004); } sb.append(Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年"); totalFee = incrementOrderEntity.getAmount().multiply(new BigDecimal(100)); orderSn = incrementOrderEntity.getOrderSn(); orderSn += "_increment"; break; case 5: break; } String body = sb.toString(); if(spaceId != null){ orderSn = orderSn.replace("expansion", String.valueOf(spaceId)); } Map resp = payOrderService.wechatPay(orderSn, sb.toString(), body, totalFee, UrlUtils.getIpAddr(request), openid); String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); return "redirect:" + mainUrl + ConstantUrl.WEIXIN_MOBILE_PAY_URL + timeStamp + "&signType=MD5&appId=" + resp.get("appid") + "&nonceStr=" + resp.get("nonce_str") + "&prepay_id=" + resp.get("prepay_id") + "&paySign=" + resp.get("paySign"); }catch (Exception e){ log.debug("获取access_token发生异常",e); }finally { if (is != null){ is.close(); } } return "redirect:" + mainUrl + "mobile.html#/payresult/fail"; } @RequestMapping(value = {"/wechatPay/notify"}, method = RequestMethod.POST) public void callback() { log.warn("微信回调接口方法 start"); String inputLine = ""; String notifyXml = ""; try { while((inputLine = request.getReader().readLine()) != null){ notifyXml += inputLine; } //关闭流 request.getReader().close(); log.warn("微信回调内容信息:"+notifyXml); //解析成Map Map map = WXPayUtil.xmlToMap(notifyXml); WXPayDefaultConfig config = new WXPayDefaultConfig(); if (WXPayUtil.isSignatureValid(map, config.getKey(), WXPayConstants.SignType.MD5) || WXPayUtil.isSignatureValid(map, config.getKey(), WXPayConstants.SignType.HMACSHA256)) { //判断 支付是否成功 if("SUCCESS".equals(map.get("result_code"))){ log.warn("微信回调返回是否支付成功:是"); //获得 返回的商户订单号 String out_trade_no = map.get("out_trade_no"); String trade_no = map.get("transaction_id"); String openid = map.get("openid"); log.warn("微信回调返回商户订单号:" + out_trade_no); //修改订单状态 String orderSnE = out_trade_no.substring(0, out_trade_no.lastIndexOf("_")); String orderSn = out_trade_no.split("_")[0]; if(!out_trade_no.contains("recharge") && !out_trade_no.contains("commerce") && !out_trade_no.contains("entity") && !out_trade_no.contains("expansion") && !out_trade_no.contains("increment") && !out_trade_no.contains("download")){ // orderSn += "_" + out_trade_no.split("_")[1]; log.warn("orderSnE:" + orderSn + "_expansion"); if (redisUtil.hasKey(orderSn + "_expansion")){ redisUtil.del(orderSn + "_expansion"); } redisUtil.set(orderSn + "_expansion", out_trade_no,5*60); }else { log.warn("orderSnE:" + orderSnE); if (redisUtil.hasKey(orderSnE)){ redisUtil.del(orderSnE); } redisUtil.set(orderSnE, out_trade_no,5*60); } orderStrategyFactory.doHandler(orderSn, trade_no, openid, out_trade_no.split("_")[1], 0); log.warn("微信支付成功,订单号:" + orderSn); //通知微信服务器已经支付成功 notifyXml = "" + " "; }else{ notifyXml = "" + " "; } } else{ log.error("签名验证错误"); notifyXml = "" + ""; } BufferedOutputStream out = new BufferedOutputStream( response.getOutputStream()); out.write(notifyXml.getBytes()); out.flush(); out.close(); } catch (Exception e) { log.error("微信支付回调数据异常, errorMsg:{}", e.getMessage()); } } }