TWeixinPayController.java 18 KB

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