TWeixinPayController.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. package com.szwl.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  7. import com.google.gson.Gson;
  8. import com.szwl.feign.bean.SzwlFeign;
  9. import com.szwl.model.bo.JsonMessage;
  10. import com.szwl.model.bo.R;
  11. import com.szwl.model.bo.ResponseModel;
  12. import com.szwl.model.entity.*;
  13. import com.szwl.constant.JoinpayConstant;
  14. import com.szwl.model.utils.PushUtils;
  15. import com.szwl.service.TEquipmentService;
  16. import com.szwl.service.TOrderService;
  17. import com.szwl.service.TWeixinPayConfigService;
  18. import com.szwl.weixin.refund.model.CreateRequest;
  19. import com.szwl.weixin.util.HttpUtils;
  20. import com.wechat.pay.java.service.refund.model.AmountReq;
  21. import com.wechat.pay.java.service.refund.model.Refund;
  22. import io.swagger.annotations.ApiOperation;
  23. import org.apache.commons.lang.StringUtils;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.web.bind.annotation.*;
  26. import org.springframework.web.bind.annotation.RequestBody;
  27. import org.springframework.web.bind.annotation.ResponseBody;
  28. import javax.servlet.http.HttpServletRequest;
  29. import javax.servlet.http.HttpServletResponse;
  30. import java.math.BigDecimal;
  31. import java.math.RoundingMode;
  32. import java.text.ParseException;
  33. import java.text.SimpleDateFormat;
  34. import java.util.*;
  35. import static com.wechat.pay.java.service.refund.model.Status.PROCESSING;
  36. /**
  37. * <p>
  38. * 前端控制器
  39. * </p>
  40. *
  41. * @author wuhs
  42. * @since 2023-04-08
  43. */
  44. @RestController
  45. @RequestMapping("/tWeixinPay")
  46. public class TWeixinPayController {
  47. @Autowired
  48. SzwlFeign szwlFeign;
  49. @Autowired
  50. TOrderService orderService;
  51. @Autowired
  52. TWeixinPayConfigService weixinPayConfigService;
  53. @Autowired
  54. TEquipmentService equipmentService;
  55. @ApiOperation(value = "购物车 请求在线支付 ")
  56. @PostMapping("/carsPay")
  57. public Object carsPay(String clientId, @RequestBody Map<String,String> productNameMap) {
  58. if(productNameMap==null){
  59. return JsonMessage.error("数据出错");
  60. }
  61. StringBuffer productName1 = new StringBuffer();
  62. StringBuffer note = new StringBuffer();
  63. StringBuffer productName = new StringBuffer();
  64. TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
  65. if(equipment==null||equipment.getId()==null){
  66. return JsonMessage.error("找不到设备");
  67. }
  68. BigDecimal price = new BigDecimal("0.00");
  69. // JSONObject mapList = JSON.parseObject(productNameMap);
  70. TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
  71. if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
  72. //1,type=0,原始设定,没有第二件半价
  73. for (String key : productNameMap.keySet()) {
  74. String entryValue = String.valueOf(productNameMap.get(key));
  75. List<String> value = JSON.parseArray(entryValue, String.class);
  76. List<TPromoCode> promoCodeList = new ArrayList<>();
  77. //1,校验优惠码
  78. if(value.size()>0){
  79. for(String code:value){
  80. if(!code.equals("0")){
  81. TPromoCode promoCode = new TPromoCode();
  82. ResponseModel<TPromoCode> tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
  83. TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
  84. // TPromoCode tPromoCode = R.getDataIfSuccess(szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString()));
  85. promoCode = tPromoCode;
  86. if (tPromoCode == null||tPromoCode.getId()==null) {
  87. //不存在
  88. return JsonMessage.success("1");
  89. }
  90. Date lastUseDate = null;
  91. if (promoCode != null) {
  92. lastUseDate = promoCode.getLastUseDate();
  93. }
  94. if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
  95. promoCode.setIsUse("2");
  96. szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
  97. //过期
  98. return JsonMessage.success("4");
  99. }
  100. if (promoCode.getId() == null) {
  101. //不存在
  102. return JsonMessage.success("1");
  103. }
  104. if (promoCode.getIsUse().equals("1")) {
  105. //被使用
  106. return JsonMessage.success("2");
  107. }
  108. if(!promoCode.getAdminId().equals("1")){
  109. if (String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
  110. } else {
  111. //不是本机
  112. return JsonMessage.success("3");
  113. }
  114. }
  115. if (promoCode.getDiscount() == null) {
  116. //旧优惠码
  117. return JsonMessage.success("0");
  118. }
  119. if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
  120. //0折
  121. return JsonMessage.success("0");
  122. }
  123. promoCodeList.add(promoCode);
  124. }
  125. }
  126. }
  127. String[] productNum = key.split("-");
  128. String productNamea = productNum[0];
  129. String num = productNum[1];
  130. productName.append(productNamea).append(num);
  131. note.append(productNamea).append(num).append(":");
  132. productName1.append(productNamea).append(num);
  133. //确定价格,然后叠加R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipmentId), productName));
  134. TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
  135. if (product == null) {
  136. return JsonMessage.error("找不到商品");
  137. }
  138. BigDecimal productPrice = product.getRmbPrice();
  139. if(promoCodeList.size()>0){
  140. //有优惠码
  141. BigDecimal onePrice = new BigDecimal("0.00");
  142. int i;
  143. for( i = 0;i<promoCodeList.size();i++){
  144. BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
  145. BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
  146. price = price.add(price1);
  147. onePrice = onePrice.add(price1);
  148. }
  149. if(i<Integer.valueOf(num)){
  150. int a = Integer.valueOf(num)-i;
  151. BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
  152. price =price.add(price2);
  153. onePrice = onePrice.add(price2);
  154. }
  155. note.append(onePrice).append(",");
  156. }else {
  157. //1,type=0,原始设定,没有第二件半价
  158. int a = Integer.valueOf(num);
  159. BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
  160. price =price.add(price2);
  161. note.append(price2).append(",");
  162. }
  163. }
  164. }else {
  165. //2,type=1,第二件半价
  166. //2.1 判定是否有第二件,有多少个第二件半价
  167. for (String key : productNameMap.keySet()) {
  168. // System.out.println("key= "+ key + " and value= " + productNameMap.get(key));
  169. String entryValue = String.valueOf(productNameMap.get(key));
  170. List<String> value = JSON.parseArray(entryValue, String.class);
  171. String[] productNum = key.split("-");
  172. String productNamea = productNum[0];
  173. String num = productNum[1];
  174. TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
  175. BigDecimal productPrice = product.getRmbPrice();
  176. productName.append(productNamea).append(num);
  177. productName1.append(productNamea).append(num);
  178. note.append(productNamea).append(num).append(":");
  179. switch (num) {
  180. case "1":
  181. //1个 0个半价
  182. price =price.add(productPrice);
  183. note.append(price).append(",");
  184. break;
  185. case "2":
  186. //2个 1个半价
  187. price =price.add(productPrice);
  188. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  189. note.append(price).append(",");
  190. break;
  191. case "3":
  192. //3个 1个半价
  193. price =price.add(productPrice);
  194. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  195. price =price.add(productPrice);
  196. note.append(price).append(",");
  197. break;
  198. case "4":
  199. //4个 2个半价
  200. price =price.add(productPrice);
  201. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  202. price =price.add(productPrice);
  203. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  204. note.append(price).append(",");
  205. break;
  206. case "5":
  207. //5个 2个半价
  208. price =price.add(productPrice);
  209. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  210. price =price.add(productPrice);
  211. price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
  212. price =price.add(productPrice);
  213. note.append(price).append(",");
  214. break;
  215. }
  216. }
  217. }
  218. if (equipment == null) {
  219. return JsonMessage.error("找不到设备");
  220. }
  221. Long equipmentId = equipment.getId();
  222. //查找商品
  223. // TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipmentId), productName.toString()));
  224. // if (product == null) {
  225. // return JsonMessage.error("找不到商品");
  226. // }
  227. if (BigDecimal.ZERO.compareTo(price) >= 0) {
  228. return JsonMessage.error("商品价格异常");
  229. }
  230. String sn1 = orderService.initSn(equipmentId);
  231. //获取分销 关联设备
  232. TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
  233. if (admin == null) {
  234. return JsonMessage.error("找不到设备商家");
  235. }
  236. JSONArray altInfo = new JSONArray();
  237. String orderNo1 = sn1;
  238. BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
  239. amount = amount.multiply(new BigDecimal(100));
  240. String notifyUrl = JoinpayConstant.Notify_Url;
  241. String frpCode1 = "WEIXIN_NATIVE";
  242. TOrder order = new TOrder();
  243. order.setCreateDate(new Date());
  244. order.setModifyDate(new Date());
  245. order.setAdminId(admin.getId());
  246. order.setSn(sn1);
  247. order.setProductName(productName.toString());
  248. order.setPrice(price);
  249. order.setClientId(equipment.getClientId());
  250. order.setEquipmentId(equipmentId);
  251. order.setFrpCode(frpCode1);
  252. order.setAltInfo(altInfo.toString());
  253. order.setStatus(0);
  254. String payPlatform = "3";
  255. order.setPayPlatform(payPlatform);
  256. if(StringUtils.isNotEmpty(payPlatform)&&payPlatform.equals("1")){
  257. order.setIsSettlement("0");
  258. }
  259. order.setNote(note.toString());
  260. orderService.save(order);
  261. Iterator<Object> iterator = altInfo.iterator();
  262. while (iterator.hasNext()) {
  263. JSONObject jsonObject = (JSONObject) iterator.next();
  264. String altAmount = jsonObject.getString("altAmount");
  265. if (altAmount.equals("0.00")) {
  266. iterator.remove();
  267. }
  268. }
  269. String result = null;
  270. try {
  271. result = orderService.weixinPay(
  272. orderNo1, amount, productName.toString(), admin.getId(), notifyUrl
  273. );
  274. } catch (Exception e) {
  275. e.printStackTrace();
  276. return JsonMessage.error("申请支付失败");
  277. }
  278. // 微信支付支付申请返回支付二维码图片
  279. JSONObject kindData = new JSONObject();
  280. kindData.put("sn", sn1);
  281. kindData.put("code_url", result);
  282. return JsonMessage.success(kindData.toString());
  283. }
  284. /**
  285. * 成功回调 微信
  286. *
  287. * @return
  288. */
  289. @RequestMapping(value = "/notify", method = RequestMethod.POST)
  290. @ResponseBody
  291. public Object notify(HttpServletRequest request, HttpServletResponse response) {
  292. Gson gson = new Gson();
  293. //应答对象
  294. Map<String, String> map = new HashMap<>();
  295. String body = HttpUtils.readData(request);
  296. Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
  297. //处理支付回调成功的订单
  298. String plainText = weixinPayConfigService.decryptFromResource(bodyMap);
  299. if(StringUtils.isNotEmpty(plainText)){
  300. JSONObject resultJson = JSONObject.parseObject(plainText);
  301. String sn = resultJson.getString("out_trade_no");
  302. if(StringUtils.isNotEmpty(sn)){
  303. LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
  304. query.eq(TOrder::getSn,sn);
  305. query.eq(TOrder::getStatus,0);
  306. TOrder order = orderService.getOne(query);
  307. order.setStatus(1);
  308. String success_time = resultJson.getString("success_time");
  309. Date date = new Date();
  310. try {
  311. date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(success_time);
  312. } catch (ParseException e) {
  313. //LOGGER.error("时间转换错误, string = {}", s, e);
  314. }
  315. order.setPayDate(date);
  316. order.setTrxNo(resultJson.getString("transaction_id"));
  317. orderService.updateById(order);
  318. TEquipment byClientId = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
  319. JSONObject kindData = new JSONObject();
  320. kindData.put("sn", order.getSn());
  321. kindData.put("productName", order.getProductName());
  322. equipmentService.sentMessage(byClientId.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
  323. }
  324. }
  325. return "success";
  326. }
  327. @ApiOperation(value = "退款")
  328. @GetMapping("/refund")
  329. ResponseModel<String> refund(@RequestParam String sn,@RequestParam BigDecimal refusePrice){
  330. if(StringUtils.isEmpty(sn)){
  331. return R.fail("订单为空/error");
  332. }
  333. LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
  334. query.eq(TOrder::getSn,sn);
  335. query.eq(TOrder::getStatus,1);
  336. TOrder order = orderService.getOne(query);
  337. if(order==null){
  338. return R.fail("订单为空/error");
  339. }
  340. CreateRequest createRequest = new CreateRequest();
  341. createRequest.setOutTradeNo(order.getSn());
  342. AmountReq amount = new AmountReq();
  343. amount.setRefund(refusePrice.multiply(new BigDecimal(100)).longValue());
  344. if(order.getRefundAmount()!=null){
  345. BigDecimal refusep = order.getPrice().add(order.getRefundAmount()).multiply(new BigDecimal(100));
  346. amount.setTotal(refusep.longValue());
  347. }else {
  348. BigDecimal multiply = order.getPrice().multiply(new BigDecimal(100));
  349. amount.setTotal(multiply.longValue());
  350. }
  351. amount.setCurrency("CNY");
  352. createRequest.setAmount(amount);
  353. String refundNo = orderService.initSn(order.getEquipmentId());
  354. createRequest.setOutRefundNo(refundNo);
  355. createRequest.setNotifyUrl("https://app.sunzee.com.cn/PAY-SERVER/tWeixinPay/refundNotify");
  356. // createRequest.setNotifyUrl("http://mianhuatang.gz2vip.91tunnel.com/tWeixinPay/refundNotify");
  357. // createRequest.setNotifyUrl("http://soobin.5gzvip.91tunnel.com/tWeixinPay/refundNotify");
  358. Refund refund = orderService.weixinRefundApi(createRequest,order.getAdminId());
  359. System.out.println("退款参数"+refund.toString());
  360. if(refund.getStatus()==PROCESSING){
  361. return R.ok("退款申请中,请30秒后再查询");
  362. }else {
  363. return R.ok("退款失败,请重试");
  364. }
  365. };
  366. @ApiOperation(value = "退款成功回调")
  367. @PostMapping("/refundNotify")
  368. ResponseModel<String> refundNotify(HttpServletRequest request, HttpServletResponse response){
  369. String result = orderService.weixinRefund(request,response);
  370. return R.ok(result);
  371. };
  372. }