123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- 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<OrderItem> 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<String, String> 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<String,String> 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 = "<xml><return_code><![CDATA[SUCCESS]]></return_code>"
- + "<return_msg><![CDATA[OK]]></return_msg></xml> ";
- }else{
- notifyXml = "<xml><return_code><![CDATA[FAIL]]></return_code>"
- + "<return_msg><![CDATA[报文为空]]></return_msg></xml> ";
- }
- } else{
- log.error("签名验证错误");
- notifyXml = "<xml><return_code><![CDATA[FAIL]]></return_code>"
- + "<return_msg><![CDATA[签名验证错误]]></return_msg></xml>";
- }
- BufferedOutputStream out = new BufferedOutputStream(
- response.getOutputStream());
- out.write(notifyXml.getBytes());
- out.flush();
- out.close();
- } catch (Exception e) {
- log.error("微信支付回调数据异常, errorMsg:{}", e.getMessage());
- }
- }
- }
|