|
@@ -1,20 +1,56 @@
|
|
package com.szwl.service.impl;
|
|
package com.szwl.service.impl;
|
|
|
|
|
|
-import com.szwl.model.entity.TWechatPayConfig;
|
|
|
|
|
|
+import cn.hutool.core.util.XmlUtil;
|
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
+import com.google.gson.Gson;
|
|
|
|
+import com.szwl.constant.JoinpayConstant;
|
|
|
|
+import com.szwl.constant.ResponseCodesEnum;
|
|
|
|
+import com.szwl.constant.WXPayConstants;
|
|
|
|
+import com.szwl.feign.bean.OrderFeign;
|
|
|
|
+import com.szwl.feign.bean.SzwlFeign;
|
|
|
|
+import com.szwl.model.bo.JsonMessage;
|
|
|
|
+import com.szwl.model.bo.R;
|
|
|
|
+import com.szwl.model.bo.ResponseModel;
|
|
|
|
+import com.szwl.model.entity.*;
|
|
import com.szwl.mapper.TWechatPayConfigMapper;
|
|
import com.szwl.mapper.TWechatPayConfigMapper;
|
|
|
|
+import com.szwl.model.utils.PushUtils;
|
|
|
|
+import com.szwl.service.TEquipmentService;
|
|
|
|
+import com.szwl.service.TOrderDetailsService;
|
|
|
|
+import com.szwl.service.TOrderService;
|
|
import com.szwl.service.TWechatPayConfigService;
|
|
import com.szwl.service.TWechatPayConfigService;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.szwl.utils.HuifuUtils;
|
|
|
|
+import com.szwl.utils.IDGenerator;
|
|
|
|
+import com.szwl.utils.MyWXPay;
|
|
|
|
+import com.szwl.utils.WXPayUtil;
|
|
|
|
+import com.szwl.weixin.util.HttpUtils;
|
|
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
|
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
|
import com.wechat.pay.java.core.Config;
|
|
import com.wechat.pay.java.core.Config;
|
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
|
|
|
+import com.wechat.pay.java.service.refund.model.AmountReq;
|
|
|
|
+import com.wechat.pay.java.service.refund.model.CreateRequest;
|
|
|
|
+import com.wechat.pay.java.service.refund.model.Refund;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
+import org.apache.http.HttpStatus;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.math.RoundingMode;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.security.GeneralSecurityException;
|
|
import java.security.GeneralSecurityException;
|
|
-import java.util.HashMap;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
+import java.text.ParseException;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.*;
|
|
|
|
+
|
|
|
|
+import static com.wechat.pay.java.service.refund.model.Status.PROCESSING;
|
|
|
|
|
|
/**
|
|
/**
|
|
* <p>
|
|
* <p>
|
|
@@ -27,8 +63,28 @@ import java.util.Map;
|
|
@Service
|
|
@Service
|
|
public class TWechatPayConfigServiceImpl extends ServiceImpl<TWechatPayConfigMapper, TWechatPayConfig> implements TWechatPayConfigService {
|
|
public class TWechatPayConfigServiceImpl extends ServiceImpl<TWechatPayConfigMapper, TWechatPayConfig> implements TWechatPayConfigService {
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 用户输入密码,尝试30秒内去查询支付结果
|
|
|
|
+ */
|
|
|
|
+ private static Integer remainingTimeMs = 90000;
|
|
|
|
+
|
|
public static Map<Long, Config> configMap = new HashMap<>();
|
|
public static Map<Long, Config> configMap = new HashMap<>();
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ SzwlFeign szwlFeign;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ OrderFeign orderFeign;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ TOrderService orderService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ TEquipmentService equipmentService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ TOrderDetailsService orderDetailsService;
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public Config getWechatConfig(Long id) {
|
|
public Config getWechatConfig(Long id) {
|
|
if(configMap==null){
|
|
if(configMap==null){
|
|
@@ -80,4 +136,887 @@ public class TWechatPayConfigServiceImpl extends ServiceImpl<TWechatPayConfigMap
|
|
}
|
|
}
|
|
return plainText;
|
|
return plainText;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public JsonMessage carsPay(String clientId, Map<String, String> productNameMap, HttpServletRequest request) {
|
|
|
|
+ if(productNameMap==null){
|
|
|
|
+ return JsonMessage.error("数据出错");
|
|
|
|
+ }
|
|
|
|
+ StringBuffer note = new StringBuffer();
|
|
|
|
+ StringBuffer productName = new StringBuffer();
|
|
|
|
+ String productNo = "";
|
|
|
|
+ Map<String, Integer> productMap = new HashMap<>();
|
|
|
|
+ Integer productNumber = 0;
|
|
|
|
+
|
|
|
|
+ TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
|
|
|
|
+ if(equipment==null||equipment.getId()==null){
|
|
|
|
+ return JsonMessage.error("找不到设备");
|
|
|
|
+ }
|
|
|
|
+ BigDecimal price = new BigDecimal("0.00");
|
|
|
|
+ TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
|
|
|
|
+ if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
|
|
|
|
+ for (String key : productNameMap.keySet()) {
|
|
|
|
+ String entryValue = String.valueOf(productNameMap.get(key));
|
|
|
|
+ List<String> value = JSON.parseArray(entryValue, String.class);
|
|
|
|
+ List<TPromoCode> promoCodeList = new ArrayList<>();
|
|
|
|
+ //1,校验优惠码
|
|
|
|
+ if(value.size()>0){
|
|
|
|
+ for(String code:value){
|
|
|
|
+ if(!code.equals("0")){
|
|
|
|
+ TPromoCode promoCode = new TPromoCode();
|
|
|
|
+ ResponseModel<TPromoCode> tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
|
|
|
|
+ TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
|
|
|
|
+ promoCode = tPromoCode;
|
|
|
|
+ if (tPromoCode == null||tPromoCode.getId()==null) {
|
|
|
|
+ //不存在
|
|
|
|
+ return JsonMessage.success("1");
|
|
|
|
+ }
|
|
|
|
+ Date lastUseDate = null;
|
|
|
|
+ if (promoCode != null) {
|
|
|
|
+ lastUseDate = promoCode.getLastUseDate();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
|
|
|
|
+ promoCode.setIsUse("2");
|
|
|
|
+ szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
|
|
|
|
+ //过期
|
|
|
|
+ return JsonMessage.success("4");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getId() == null) {
|
|
|
|
+ //不存在
|
|
|
|
+ return JsonMessage.success("1");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getIsUse().equals("1")) {
|
|
|
|
+ //被使用
|
|
|
|
+ return JsonMessage.success("2");
|
|
|
|
+ }
|
|
|
|
+ if(!promoCode.getAdminId().equals("1")){
|
|
|
|
+ if (String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ //不是本机
|
|
|
|
+ return JsonMessage.success("3");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getDiscount() == null) {
|
|
|
|
+ //旧优惠码
|
|
|
|
+ return JsonMessage.success("0");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
|
|
|
|
+ //0折
|
|
|
|
+ return JsonMessage.success("0");
|
|
|
|
+ }
|
|
|
|
+ promoCodeList.add(promoCode);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ String[] productNum = key.split("-");
|
|
|
|
+ String productNamea = productNum[0];
|
|
|
|
+ String num = productNum[1];
|
|
|
|
+ productMap.put(productNamea,Integer.valueOf(num));
|
|
|
|
+ productNumber += Integer.valueOf(num);
|
|
|
|
+ productName.append(productNamea).append("x").append(num).append(",");
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
|
|
|
|
+ if (product == null) {
|
|
|
|
+ return JsonMessage.error("找不到商品");
|
|
|
|
+ }
|
|
|
|
+ note.append(productNamea).append("-").append(product.getNo()).append(":");
|
|
|
|
+ BigDecimal productPrice = product.getRmbPrice();
|
|
|
|
+ productNo = product.getNo();
|
|
|
|
+ if(promoCodeList.size()>0){
|
|
|
|
+ //有优惠码
|
|
|
|
+ BigDecimal onePrice = new BigDecimal("0.00");
|
|
|
|
+ int i;
|
|
|
|
+ for( i = 0;i<promoCodeList.size();i++){
|
|
|
|
+ BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price = price.add(price1);
|
|
|
|
+ onePrice = onePrice.add(price1);
|
|
|
|
+ }
|
|
|
|
+ if(i<Integer.valueOf(num)){
|
|
|
|
+ int a = Integer.valueOf(num)-i;
|
|
|
|
+ BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price =price.add(price2);
|
|
|
|
+ onePrice = onePrice.add(price2);
|
|
|
|
+ }
|
|
|
|
+ note.append(onePrice).append("-").append(num).append(",");
|
|
|
|
+ }else {
|
|
|
|
+ //1,type=0,原始设定,没有第二件半价
|
|
|
|
+ int a = Integer.valueOf(num);
|
|
|
|
+ BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price =price.add(price2);
|
|
|
|
+ note.append(price2).append("-").append(num).append(",");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+
|
|
|
|
+ for (String key : productNameMap.keySet()) {
|
|
|
|
+ String[] productNum = key.split("-");
|
|
|
|
+ String productNamea = productNum[0];
|
|
|
|
+ String num = productNum[1];
|
|
|
|
+ productMap.put(productNamea,Integer.valueOf(num));
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
|
|
|
|
+ productNo = product.getNo();
|
|
|
|
+ BigDecimal productPrice = product.getRmbPrice();
|
|
|
|
+ productName.append(productNamea).append("x").append(num).append(",");
|
|
|
|
+ note.append(productNamea).append("-").append(product.getNo()).append(":");
|
|
|
|
+ switch (num) {
|
|
|
|
+ case "1":
|
|
|
|
+ //1个 0个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "2":
|
|
|
|
+ //2个 1个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "3":
|
|
|
|
+ //3个 1个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "4":
|
|
|
|
+ //4个 2个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "5":
|
|
|
|
+ //5个 2个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Long equipmentId = equipment.getId();
|
|
|
|
+ //查找商品
|
|
|
|
+ if (BigDecimal.ZERO.compareTo(price) >= 0) {
|
|
|
|
+ return JsonMessage.error("商品价格异常");
|
|
|
|
+ }
|
|
|
|
+ Long client6 = Long.parseLong(clientId.substring(clientId.length() - 6));
|
|
|
|
+ String sn = orderService.initSn(client6);
|
|
|
|
+ //获取分销 关联设备
|
|
|
|
+ TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
|
|
|
|
+ String companyType = admin.getCompanyType();
|
|
|
|
+ JSONArray altInfo = new JSONArray();
|
|
|
|
+ BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ amount = amount.multiply(new BigDecimal(100));
|
|
|
|
+ String notifyUrl = JoinpayConstant.WECHAT_NOTIFY_URL;
|
|
|
|
+ String frpCode = "WEIXIN_NATIVE";
|
|
|
|
+ TOrder order = new TOrder();
|
|
|
|
+ order.setId(IDGenerator.orderID());
|
|
|
|
+ order.setCreateDate(new Date());
|
|
|
|
+ order.setModifyDate(new Date());
|
|
|
|
+ order.setAdminId(admin.getId());
|
|
|
|
+ order.setSn(sn);
|
|
|
|
+ if(productNumber == 1) {
|
|
|
|
+ productName.delete(productName.length() - 3, productName.length());
|
|
|
|
+ } else {
|
|
|
|
+ productName.deleteCharAt(productName.length() - 1);
|
|
|
|
+ }
|
|
|
|
+ order.setProductName(productName.toString());
|
|
|
|
+ order.setPrice(price);
|
|
|
|
+ order.setClientId(equipment.getClientId());
|
|
|
|
+ order.setEquipmentId(equipmentId);
|
|
|
|
+ order.setFrpCode(frpCode);
|
|
|
|
+ order.setProductNumber(productNumber);
|
|
|
|
+ order.setAltInfo(altInfo.toString());
|
|
|
|
+ order.setStatus(0);
|
|
|
|
+ String payPlatform = "3";
|
|
|
|
+ order.setPayPlatform(payPlatform);
|
|
|
|
+ order.setCompanyType(companyType);
|
|
|
|
+ order.setMachineType(equipment.getMachineType());
|
|
|
|
+ order.setProductNo(productNo);
|
|
|
|
+ if(StringUtils.isNotEmpty(payPlatform)&&payPlatform.equals("1")){
|
|
|
|
+ order.setIsSettlement("0");
|
|
|
|
+ }
|
|
|
|
+ order.setNote(note.toString());
|
|
|
|
+
|
|
|
|
+ // 订单明细表
|
|
|
|
+ TOrderDetails orderDetails = new TOrderDetails();
|
|
|
|
+ orderDetails.setAdminId(admin.getId());
|
|
|
|
+ orderDetails.setEquipmentId(equipmentId);
|
|
|
|
+ orderDetails.setCreateDate(new Date());
|
|
|
|
+ orderDetails.setCompanyType(companyType);
|
|
|
|
+ orderDetails.setRefundStatus("0");
|
|
|
|
+ orderDetails.setMachineType(equipment.getMachineType());
|
|
|
|
+ // 添加到订单明细表
|
|
|
|
+ for (String key : productMap.keySet()) {
|
|
|
|
+ Integer productNum = productMap.get(key);
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), key));
|
|
|
|
+ orderDetails.setProductNo(product.getNo());
|
|
|
|
+ orderDetails.setProductName(key);
|
|
|
|
+ orderDetails.setPrice(product.getRmbPrice());
|
|
|
|
+ orderDetails.setProductNumber(productNum);
|
|
|
|
+ orderDetails.setAmount(product.getRmbPrice().multiply(new BigDecimal(productNum)));
|
|
|
|
+ orderDetails.setId(HuifuUtils.initDetailsId());
|
|
|
|
+ orderDetails.setOrderSn(sn);
|
|
|
|
+ orderDetailsService.save(orderDetails);
|
|
|
|
+ }
|
|
|
|
+ orderService.save(order);
|
|
|
|
+ String productName1 = "";
|
|
|
|
+ if(productNumber > 1) {
|
|
|
|
+ productName1 = "棉花糖";
|
|
|
|
+ } else {
|
|
|
|
+ productName1 = productName.toString();
|
|
|
|
+ }
|
|
|
|
+ String result;
|
|
|
|
+ try {
|
|
|
|
+ result = orderService.wechatPay(
|
|
|
|
+ sn, amount, productName1, admin.getWechatPayId(), notifyUrl, clientId, request
|
|
|
|
+ );
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return JsonMessage.error("申请支付失败");
|
|
|
|
+ }
|
|
|
|
+ // 微信支付支付申请返回支付二维码图片
|
|
|
|
+ JSONObject kindData = new JSONObject();
|
|
|
|
+ kindData.put("sn", sn);
|
|
|
|
+ kindData.put("code_url", result);
|
|
|
|
+ return JsonMessage.success(kindData.toString());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String payNotify(HttpServletRequest request) {
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ // 读取请求体中的数据
|
|
|
|
+ String body = HttpUtils.readData(request);
|
|
|
|
+ Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
|
|
|
|
+ // 解密支付通知数据
|
|
|
|
+ String plainText = this.decryptFromResource(bodyMap);
|
|
|
|
+ if(StringUtils.isNotEmpty(plainText)){
|
|
|
|
+ JSONObject resultJson = JSONObject.parseObject(plainText);
|
|
|
|
+ // 根据订单号查询订单
|
|
|
|
+ String sn = resultJson.getString("out_trade_no");
|
|
|
|
+ if(StringUtils.isNotEmpty(sn)) {
|
|
|
|
+ LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
|
|
|
|
+ query.eq(TOrder::getSn, sn);
|
|
|
|
+ query.eq(TOrder::getStatus, 0);
|
|
|
|
+ List<TOrder> list = orderService.list(query);
|
|
|
|
+ // 更新订单状态和支付信息
|
|
|
|
+ if (list != null && list.size() > 0) {
|
|
|
|
+ TOrder order = list.get(0);
|
|
|
|
+ order.setStatus(1);
|
|
|
|
+ String success_time = resultJson.getString("success_time");
|
|
|
|
+ Date date = new Date();
|
|
|
|
+ try {
|
|
|
|
+ date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(success_time);
|
|
|
|
+ } catch (ParseException e) {
|
|
|
|
+ // 忽略时间转换错误
|
|
|
|
+ }
|
|
|
|
+ order.setPayDate(date);
|
|
|
|
+ order.setTrxNo(resultJson.getString("transaction_id"));
|
|
|
|
+ // 更新订单明细状态
|
|
|
|
+ LambdaQueryWrapper<TOrderDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
|
|
|
|
+ List<TOrderDetails> orderDetails = orderDetailsService.list(lambdaQueryWrapper);
|
|
|
|
+ for (TOrderDetails orderDetail : orderDetails) {
|
|
|
|
+ orderDetail.setRefundStatus("1");
|
|
|
|
+ orderDetailsService.updateById(orderDetail);
|
|
|
|
+ }
|
|
|
|
+ // 发送支付成功消息给设备
|
|
|
|
+ TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
|
|
|
|
+ JSONObject kindData = new JSONObject();
|
|
|
|
+ kindData.put("sn", order.getSn());
|
|
|
|
+ kindData.put("productName", order.getProductName());
|
|
|
|
+ if (!order.getIsNotified().equals("1")) {
|
|
|
|
+ String paySuccess = equipmentService.sentMessage(equipment.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
|
|
|
|
+ if (paySuccess.equals("success")) {
|
|
|
|
+ order.setIsNotified("1");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ orderService.updateById(order);
|
|
|
|
+ try {
|
|
|
|
+ // 保存订单信息到ES
|
|
|
|
+ if(order.getProductNumber()==null||order.getProductNumber()==0){
|
|
|
|
+ order.setProductNumber(1);
|
|
|
|
+ }
|
|
|
|
+ orderFeign.saveToEs(order);
|
|
|
|
+ }catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ LambdaQueryWrapper<TOrder> queryWrapper = Wrappers.lambdaQuery();
|
|
|
|
+ query.eq(TOrder::getSn, sn);
|
|
|
|
+ query.eq(TOrder::getStatus, 1);
|
|
|
|
+ List<TOrder> orderList = orderService.list(queryWrapper);
|
|
|
|
+ if (list != null && list.size() > 0) {
|
|
|
|
+ TOrder tOrder = orderList.get(0);
|
|
|
|
+ try {
|
|
|
|
+ // 保存订单信息到ES
|
|
|
|
+ if(tOrder.getProductNumber()==null||tOrder.getProductNumber()==0){
|
|
|
|
+ tOrder.setProductNumber(1);
|
|
|
|
+ }
|
|
|
|
+ orderFeign.saveToEs(tOrder);
|
|
|
|
+ }catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return "success";
|
|
|
|
+ }
|
|
|
|
+ return "fail";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return "success";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public ResponseModel refund(TOrder torder) {
|
|
|
|
+ // 退款金额: refusePrice
|
|
|
|
+ BigDecimal refusePrice = torder.getPrice().setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ // 退款数量: refundNumber
|
|
|
|
+ Integer refundNumber = torder.getProductNumber();
|
|
|
|
+ // 退款原因: refundReason
|
|
|
|
+ String refundReason = torder.getRefundReason();
|
|
|
|
+ // 退款明细:note
|
|
|
|
+ String note = torder.getNote();
|
|
|
|
+ String[] refundDetails = note.split(",");
|
|
|
|
+ Map<String, Integer> refundMap = new HashMap<>();
|
|
|
|
+ for (String refundDetail : refundDetails) {
|
|
|
|
+ String[] keyValue = refundDetail.split("-");
|
|
|
|
+ String key = keyValue[0];
|
|
|
|
+ String value = keyValue[1];
|
|
|
|
+ refundMap.put(key, Integer.valueOf(value));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(refusePrice.compareTo(new BigDecimal("0.00"))<=0){
|
|
|
|
+ return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TOrder order = orderService.getById(torder.getId());
|
|
|
|
+ if(order.getRefundQuantity() != null && order.getRefundQuantity()>0) {
|
|
|
|
+ order.setRefundQuantity(refundNumber + order.getRefundQuantity());
|
|
|
|
+ } else {
|
|
|
|
+ order.setRefundQuantity(refundNumber);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ LambdaQueryWrapper<TOrderDetails> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ wrapper.eq(TOrderDetails::getOrderSn, order.getSn());
|
|
|
|
+ List<TOrderDetails> orderDetails = orderDetailsService.list(wrapper);
|
|
|
|
+ if (order.getStatus().equals("0")) {
|
|
|
|
+ return R.fail(ResponseCodesEnum.A0002,"订单非支付状态");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CreateRequest createRequest = new CreateRequest();
|
|
|
|
+ createRequest.setOutTradeNo(order.getSn());
|
|
|
|
+ AmountReq amount = new AmountReq();
|
|
|
|
+ amount.setRefund(refusePrice.multiply(new BigDecimal(100)).longValue());
|
|
|
|
+ BigDecimal multiply = order.getPrice().multiply(new BigDecimal(100));
|
|
|
|
+ amount.setTotal(multiply.longValue());
|
|
|
|
+ amount.setCurrency("CNY");
|
|
|
|
+ createRequest.setAmount(amount);
|
|
|
|
+ String refundNo = orderService.initSn(order.getEquipmentId());
|
|
|
|
+ createRequest.setOutRefundNo(refundNo);
|
|
|
|
+ // 上线需要修改回调url
|
|
|
|
+ createRequest.setNotifyUrl(JoinpayConstant.WECHAT_NOTIFY_REFUND_URL);
|
|
|
|
+// createRequest.setNotifyUrl("http://evxz5m.natappfree.cc/wechatPay/refundNotify");
|
|
|
|
+ TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
|
|
|
|
+ Refund refund = orderService.weixinRefundApi(createRequest, admin.getWechatPayId());
|
|
|
|
+ System.out.println("退款参数"+refund.toString());
|
|
|
|
+ if(refund.getStatus()==PROCESSING){
|
|
|
|
+ order.setStatus(2);
|
|
|
|
+ order.setRefundReason(refundReason);
|
|
|
|
+ orderService.updateById(order);
|
|
|
|
+ // 修改订单明细
|
|
|
|
+ for (TOrderDetails orderDetail : orderDetails) {
|
|
|
|
+ String productNo = orderDetail.getProductNo();
|
|
|
|
+ Integer productNumber = refundMap.get(productNo);
|
|
|
|
+ if(productNumber != null) {
|
|
|
|
+ // 退款中
|
|
|
|
+ orderDetail.setRefundStatus("4");
|
|
|
|
+ // 退款数量
|
|
|
|
+ orderDetail.setRefundQuantity(productNumber);
|
|
|
|
+ // 退款金额
|
|
|
|
+ orderDetail.setRefundAmount(orderDetail.getPrice().multiply(new BigDecimal(productNumber)));
|
|
|
|
+ orderDetailsService.updateById(orderDetail);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return R.ok("申请退款已成功");
|
|
|
|
+ }else {
|
|
|
|
+ return R.fail(ResponseCodesEnum.B0001,"申请退款失败,请重试");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String refundNotify(HttpServletRequest request, HttpServletResponse response) {
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ Map<String, Object> hashMap = new HashMap<>(3);
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 处理退款通知参数
|
|
|
|
+ String body = HttpUtils.readData(request);
|
|
|
|
+ Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
|
|
|
|
+ String eventType = (String)bodyMap.get("event_type");
|
|
|
|
+ if (eventType.equals("REFUND.SUCCESS")) {
|
|
|
|
+ // 处理退款单
|
|
|
|
+ processRefund(bodyMap);
|
|
|
|
+ //成功应答
|
|
|
|
+ response.setStatus(HttpStatus.SC_OK);
|
|
|
|
+// hashMap.put("code", "SUCCESS");
|
|
|
|
+ } else {
|
|
|
|
+ response.setStatus(HttpStatus.SC_BAD_GATEWAY);
|
|
|
|
+ hashMap.put("code", "FAIL");
|
|
|
|
+ hashMap.put("message", "系统错误");
|
|
|
|
+ }
|
|
|
|
+ return gson.toJson(hashMap);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public JsonMessage cardPay(String authCode, String clientId, Map<String, String> productNameMap, HttpServletRequest request) {
|
|
|
|
+ if(productNameMap==null){
|
|
|
|
+ return JsonMessage.error("数据出错");
|
|
|
|
+ }
|
|
|
|
+ StringBuilder note = new StringBuilder();
|
|
|
|
+ StringBuilder productName = new StringBuilder();
|
|
|
|
+ String productNo = "";
|
|
|
|
+ Map<String, Integer> productMap = new HashMap<>();
|
|
|
|
+ int productNumber = 0;
|
|
|
|
+
|
|
|
|
+ TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
|
|
|
|
+ if(equipment==null||equipment.getId()==null){
|
|
|
|
+ return JsonMessage.error("找不到设备");
|
|
|
|
+ }
|
|
|
|
+ BigDecimal price = new BigDecimal("0.00");
|
|
|
|
+ TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
|
|
|
|
+ if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
|
|
|
|
+ for (String key : productNameMap.keySet()) {
|
|
|
|
+ String entryValue = String.valueOf(productNameMap.get(key));
|
|
|
|
+ List<String> value = JSON.parseArray(entryValue, String.class);
|
|
|
|
+ List<TPromoCode> promoCodeList = new ArrayList<>();
|
|
|
|
+ //1,校验优惠码
|
|
|
|
+ if(value.size()>0){
|
|
|
|
+ for(String code:value){
|
|
|
|
+ if(!code.equals("0")){
|
|
|
|
+ TPromoCode promoCode = new TPromoCode();
|
|
|
|
+ ResponseModel<TPromoCode> tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
|
|
|
|
+ TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
|
|
|
|
+ promoCode = tPromoCode;
|
|
|
|
+ if (tPromoCode == null||tPromoCode.getId()==null) {
|
|
|
|
+ //不存在
|
|
|
|
+ return JsonMessage.success("1");
|
|
|
|
+ }
|
|
|
|
+ Date lastUseDate = null;
|
|
|
|
+ if (promoCode != null) {
|
|
|
|
+ lastUseDate = promoCode.getLastUseDate();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
|
|
|
|
+ promoCode.setIsUse("2");
|
|
|
|
+ szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
|
|
|
|
+ //过期
|
|
|
|
+ return JsonMessage.success("4");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getId() == null) {
|
|
|
|
+ //不存在
|
|
|
|
+ return JsonMessage.success("1");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getIsUse().equals("1")) {
|
|
|
|
+ //被使用
|
|
|
|
+ return JsonMessage.success("2");
|
|
|
|
+ }
|
|
|
|
+ if(!promoCode.getAdminId().equals("1")){
|
|
|
|
+ if (!String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
|
|
|
|
+ return JsonMessage.success("3");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getDiscount() == null) {
|
|
|
|
+ //旧优惠码
|
|
|
|
+ return JsonMessage.success("0");
|
|
|
|
+ }
|
|
|
|
+ if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
|
|
|
|
+ //0折
|
|
|
|
+ return JsonMessage.success("0");
|
|
|
|
+ }
|
|
|
|
+ promoCodeList.add(promoCode);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ String[] productNum = key.split("-");
|
|
|
|
+ String productNamea = productNum[0];
|
|
|
|
+ String num = productNum[1];
|
|
|
|
+ productMap.put(productNamea,Integer.valueOf(num));
|
|
|
|
+ productNumber += Integer.parseInt(num);
|
|
|
|
+ productName.append(productNamea).append("x").append(num).append(",");
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
|
|
|
|
+ if (product == null) {
|
|
|
|
+ return JsonMessage.error("找不到商品");
|
|
|
|
+ }
|
|
|
|
+ note.append(productNamea).append("-").append(product.getNo()).append(":");
|
|
|
|
+ BigDecimal productPrice = product.getRmbPrice();
|
|
|
|
+ productNo = product.getNo();
|
|
|
|
+ if(promoCodeList.size()>0){
|
|
|
|
+ //有优惠码
|
|
|
|
+ BigDecimal onePrice = new BigDecimal("0.00");
|
|
|
|
+ int i;
|
|
|
|
+ for( i = 0;i<promoCodeList.size();i++){
|
|
|
|
+ BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price = price.add(price1);
|
|
|
|
+ onePrice = onePrice.add(price1);
|
|
|
|
+ }
|
|
|
|
+ if(i<Integer.parseInt(num)){
|
|
|
|
+ int a = Integer.parseInt(num)-i;
|
|
|
|
+ BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price =price.add(price2);
|
|
|
|
+ onePrice = onePrice.add(price2);
|
|
|
|
+ }
|
|
|
|
+ note.append(onePrice).append("-").append(num).append(",");
|
|
|
|
+ }else {
|
|
|
|
+ //1,type=0,原始设定,没有第二件半价
|
|
|
|
+ int a = Integer.parseInt(num);
|
|
|
|
+ BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ price =price.add(price2);
|
|
|
|
+ note.append(price2).append("-").append(num).append(",");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ for (String key : productNameMap.keySet()) {
|
|
|
|
+ String[] productNum = key.split("-");
|
|
|
|
+ String productNamea = productNum[0];
|
|
|
|
+ String num = productNum[1];
|
|
|
|
+ productMap.put(productNamea,Integer.valueOf(num));
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
|
|
|
|
+ productNo = product.getNo();
|
|
|
|
+ BigDecimal productPrice = product.getRmbPrice();
|
|
|
|
+ productName.append(productNamea).append("x").append(num).append(",");
|
|
|
|
+ note.append(productNamea).append("-").append(product.getNo()).append(":");
|
|
|
|
+ switch (num) {
|
|
|
|
+ case "1":
|
|
|
|
+ //1个 0个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "2":
|
|
|
|
+ //2个 1个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "3":
|
|
|
|
+ //3个 1个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "4":
|
|
|
|
+ //4个 2个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ case "5":
|
|
|
|
+ //5个 2个半价
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
|
|
|
|
+ price =price.add(productPrice);
|
|
|
|
+ note.append(price).append("-").append(num).append(",");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Long equipmentId = equipment.getId();
|
|
|
|
+ //查找商品
|
|
|
|
+ if (BigDecimal.ZERO.compareTo(price) >= 0) {
|
|
|
|
+ return JsonMessage.error("商品价格异常");
|
|
|
|
+ }
|
|
|
|
+ Long client6 = Long.parseLong(clientId.substring(clientId.length() - 6));
|
|
|
|
+ String sn = orderService.initSn(client6);
|
|
|
|
+ //获取分销 关联设备
|
|
|
|
+ TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
|
|
|
|
+ String companyType = admin.getCompanyType();
|
|
|
|
+ BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ amount = amount.multiply(new BigDecimal(100)).setScale(0);
|
|
|
|
+ String frpCode = "WEIXIN_PAYCODE";
|
|
|
|
+ TOrder order = new TOrder();
|
|
|
|
+ order.setId(IDGenerator.orderID());
|
|
|
|
+ order.setCreateDate(new Date());
|
|
|
|
+ order.setModifyDate(new Date());
|
|
|
|
+ order.setAdminId(admin.getId());
|
|
|
|
+ order.setSn(sn);
|
|
|
|
+ if(productNumber == 1) {
|
|
|
|
+ productName.delete(productName.length() - 3, productName.length());
|
|
|
|
+ } else {
|
|
|
|
+ productName.deleteCharAt(productName.length() - 1);
|
|
|
|
+ }
|
|
|
|
+ order.setProductName(productName.toString());
|
|
|
|
+ order.setPrice(price);
|
|
|
|
+ order.setClientId(equipment.getClientId());
|
|
|
|
+ order.setEquipmentId(equipmentId);
|
|
|
|
+ order.setFrpCode(frpCode);
|
|
|
|
+ order.setProductNumber(productNumber);
|
|
|
|
+ order.setStatus(0);
|
|
|
|
+ String payPlatform = "3";
|
|
|
|
+ order.setPayPlatform(payPlatform);
|
|
|
|
+ order.setCompanyType(companyType);
|
|
|
|
+ order.setMachineType(equipment.getMachineType());
|
|
|
|
+ order.setProductNo(productNo);
|
|
|
|
+ order.setNote(note.toString());
|
|
|
|
+
|
|
|
|
+ // 订单明细表
|
|
|
|
+ TOrderDetails orderDetails = new TOrderDetails();
|
|
|
|
+ orderDetails.setAdminId(admin.getId());
|
|
|
|
+ orderDetails.setEquipmentId(equipmentId);
|
|
|
|
+ orderDetails.setCreateDate(new Date());
|
|
|
|
+ orderDetails.setCompanyType(companyType);
|
|
|
|
+ orderDetails.setRefundStatus("0");
|
|
|
|
+ orderDetails.setMachineType(equipment.getMachineType());
|
|
|
|
+ // 添加到订单明细表
|
|
|
|
+ for (String key : productMap.keySet()) {
|
|
|
|
+ Integer productNum = productMap.get(key);
|
|
|
|
+ TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), key));
|
|
|
|
+ orderDetails.setProductNo(product.getNo());
|
|
|
|
+ orderDetails.setProductName(key);
|
|
|
|
+ orderDetails.setPrice(product.getRmbPrice());
|
|
|
|
+ orderDetails.setProductNumber(productNum);
|
|
|
|
+ orderDetails.setAmount(product.getRmbPrice().multiply(new BigDecimal(productNum)));
|
|
|
|
+ orderDetails.setId(HuifuUtils.initDetailsId());
|
|
|
|
+ orderDetails.setOrderSn(sn);
|
|
|
|
+ orderDetailsService.save(orderDetails);
|
|
|
|
+ }
|
|
|
|
+ orderService.save(order);
|
|
|
|
+ String productName1 = "";
|
|
|
|
+ if(productNumber > 1) {
|
|
|
|
+ productName1 = "棉花糖";
|
|
|
|
+ } else {
|
|
|
|
+ productName1 = productName.toString();
|
|
|
|
+ }
|
|
|
|
+ String result;
|
|
|
|
+ try {
|
|
|
|
+ result = wechatCardPay(
|
|
|
|
+ sn, amount, authCode, productName1, admin.getWechatPayId(), clientId, request
|
|
|
|
+ );
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return JsonMessage.error("申请支付失败");
|
|
|
|
+ }
|
|
|
|
+ // 微信支付支付申请返回支付二维码图片
|
|
|
|
+ if (result.equals(WXPayConstants.SUCCESS)) {
|
|
|
|
+ JSONObject kindData = new JSONObject();
|
|
|
|
+ kindData.put("sn", sn);
|
|
|
|
+ return JsonMessage.success(kindData.toString());
|
|
|
|
+ } else {
|
|
|
|
+ return JsonMessage.error(result);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String wechatCardPay(String sn, BigDecimal amount, String authCode, String productName, Long wechatPayId, String clientId, HttpServletRequest request) throws Exception {
|
|
|
|
+ TWechatPayConfig wechatPayConfig = getById(wechatPayId);
|
|
|
|
+ Map<String, String> resData = new HashMap<>();
|
|
|
|
+ resData.put("appid", wechatPayConfig.getAppId());
|
|
|
|
+ resData.put("auth_code", authCode);
|
|
|
|
+ resData.put("body", productName);
|
|
|
|
+ resData.put("device_info", clientId);
|
|
|
|
+ resData.put("mch_id", wechatPayConfig.getMerchantId());
|
|
|
|
+ resData.put("nonce_str", WXPayUtil.generateNonceStr());
|
|
|
|
+ resData.put("out_trade_no", sn);
|
|
|
|
+ resData.put("spbill_create_ip", "127.0.0.1");
|
|
|
|
+ resData.put("total_fee", amount.toString());
|
|
|
|
+ String sign = WXPayUtil.generateSignature(resData, wechatPayConfig.getApiv2key());
|
|
|
|
+ // 参数转换成xml的String字符串
|
|
|
|
+ resData.put("sign", sign);
|
|
|
|
+ String xmlStr = WXPayUtil.mapToXml(resData);
|
|
|
|
+ System.out.println("请求参数:" + xmlStr);
|
|
|
|
+ // 开始时间(毫秒)
|
|
|
|
+ long startTimestampMs = System.currentTimeMillis();
|
|
|
|
+ String responseXml = HttpUtil.post("https://api.mch.weixin.qq.com/pay/micropay", xmlStr);
|
|
|
|
+ System.out.println("返回参数:" + responseXml);
|
|
|
|
+ // 再把响应的xml转换成map
|
|
|
|
+ Map<String, Object> responseMap = XmlUtil.xmlToMap(responseXml);
|
|
|
|
+ // 先判断 协议字段返回(return_code),再判断 业务返回,最后判断 交易状态(trade_state)
|
|
|
|
+ // 通信标识,非交易标识
|
|
|
|
+ String returnCode = responseMap.get("return_code").toString();
|
|
|
|
+ if (WXPayConstants.SUCCESS.equals(returnCode)) {
|
|
|
|
+ String errCode = responseMap.get("err_code").toString();
|
|
|
|
+ // 余额不足,信用卡失效
|
|
|
|
+ if ("USERPAYING".equals(errCode) || "SYSTEMERROR".equals(errCode) || "BANKERROR".equals(errCode)) {
|
|
|
|
+ // 查询订单
|
|
|
|
+ Map<String, Object> orderQueryMap = null;
|
|
|
|
+ Map<String, String> requestData =new HashMap<>();
|
|
|
|
+ requestData.put("appid", wechatPayConfig.getAppId());
|
|
|
|
+ requestData.put("mch_id", wechatPayConfig.getMerchantId());
|
|
|
|
+ requestData.put("out_trade_no", sn);
|
|
|
|
+ requestData.put("nonce_str", WXPayUtil.generateNonceStr());
|
|
|
|
+ String sign1 = WXPayUtil.generateSignature(requestData, wechatPayConfig.getApiv2key());
|
|
|
|
+ requestData.put("sign", sign1);
|
|
|
|
+ String xmlStr1 = WXPayUtil.mapToXml(requestData);
|
|
|
|
+ // 用户支付中,需要输入密码或系统错误则去重新查询订单API
|
|
|
|
+ // 每次循环时的当前系统时间 - 开始时记录的时间 > 设定的30秒时间就退出
|
|
|
|
+ while (System.currentTimeMillis() - startTimestampMs < remainingTimeMs) {
|
|
|
|
+ // 商户收银台得到USERPAYING状态后,经过商户后台系统调用【查询订单API】查询实际支付结果。
|
|
|
|
+ String responseXml1 = HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery", xmlStr1);
|
|
|
|
+ orderQueryMap = XmlUtil.xmlToMap(responseXml1);
|
|
|
|
+ String returnCodeForQuery = orderQueryMap.get("return_code").toString();
|
|
|
|
+ if (WXPayConstants.SUCCESS.equals(returnCodeForQuery)) {
|
|
|
|
+ // 通讯成功
|
|
|
|
+ String tradeState = orderQueryMap.get("trade_state").toString();
|
|
|
|
+ if (WXPayConstants.SUCCESS.equals(tradeState)) {
|
|
|
|
+ String transactionId = orderQueryMap.get("transaction_id").toString();
|
|
|
|
+ String timeEnd = orderQueryMap.get("time_end").toString();
|
|
|
|
+ LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
|
|
|
|
+ query.eq(TOrder::getSn, sn);
|
|
|
|
+ query.eq(TOrder::getStatus, 0);
|
|
|
|
+ List<TOrder> list = orderService.list(query);
|
|
|
|
+ // 更新订单状态和支付信息
|
|
|
|
+ if (list != null && list.size() > 0) {
|
|
|
|
+ TOrder order = list.get(0);
|
|
|
|
+ order.setStatus(1);
|
|
|
|
+ order.setTrxNo(transactionId);
|
|
|
|
+ Date date = new Date();
|
|
|
|
+ try {
|
|
|
|
+ date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timeEnd);
|
|
|
|
+ } catch (ParseException e) {
|
|
|
|
+ // 忽略时间转换错误
|
|
|
|
+ }
|
|
|
|
+ order.setPayDate(date);
|
|
|
|
+ // 更新订单明细状态
|
|
|
|
+ LambdaQueryWrapper<TOrderDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
|
|
|
|
+ List<TOrderDetails> orderDetails = orderDetailsService.list(lambdaQueryWrapper);
|
|
|
|
+ for (TOrderDetails orderDetail : orderDetails) {
|
|
|
|
+ orderDetail.setRefundStatus("1");
|
|
|
|
+ orderDetailsService.updateById(orderDetail);
|
|
|
|
+ }
|
|
|
|
+ // 发送支付成功消息给设备
|
|
|
|
+ TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
|
|
|
|
+ JSONObject kindData = new JSONObject();
|
|
|
|
+ kindData.put("sn", order.getSn());
|
|
|
|
+ kindData.put("productName", order.getProductName());
|
|
|
|
+ if (!order.getIsNotified().equals("1")) {
|
|
|
|
+ String paySuccess = equipmentService.sentMessage(equipment.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
|
|
|
|
+ if (paySuccess.equals("success")) {
|
|
|
|
+ order.setIsNotified("1");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ orderService.updateById(order);
|
|
|
|
+ try {
|
|
|
|
+ // 保存订单信息到ES
|
|
|
|
+ if(order.getProductNumber()==null||order.getProductNumber()==0){
|
|
|
|
+ order.setProductNumber(1);
|
|
|
|
+ }
|
|
|
|
+ orderFeign.saveToEs(order);
|
|
|
|
+ }catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ // 如果成功了直接将查询结果返回
|
|
|
|
+ return tradeState;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 如果支付结果仍为USERPAYING,则每隔5秒循环调用【查询订单API】判断实际支付结果
|
|
|
|
+ Thread.sleep(10000);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 如果用户取消支付或累计90秒用户都未支付,商户收银台退出查询流程后继续调用【撤销订单API】撤销支付交易。
|
|
|
|
+ String tradeState = orderQueryMap.get("trade_state").toString();
|
|
|
|
+ if ("NOTPAY".equals(tradeState) || "PAYERROR".equals(tradeState)) {
|
|
|
|
+ String result = "";
|
|
|
|
+ // 调用撤销订单接口,并接受返回的结果
|
|
|
|
+ try{
|
|
|
|
+ result =
|
|
|
|
+ MyWXPay.cancelOrder(wechatPayConfig.getMerchantId(), wechatPayConfig.getApiCertPath(),
|
|
|
|
+ "https://api.mch.weixin.qq.com/secapi/pay/reverse", xmlStr1);
|
|
|
|
+ System.out.println("=======================撤销订单返回数据:" + result);
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ Map<String, Object> reverseMap = XmlUtil.xmlToMap(result);
|
|
|
|
+ String returnCodeForReverse = reverseMap.get("return_code").toString();
|
|
|
|
+ String resultCode = reverseMap.get("result_code").toString();
|
|
|
|
+ if (WXPayConstants.SUCCESS.equals(returnCodeForReverse) && WXPayConstants.SUCCESS.equals(resultCode)) {
|
|
|
|
+ // 如果撤销成功,需要告诉客户端已经撤销订单了
|
|
|
|
+ return "用户取消支付或尚未支付,后台已经撤销该订单,请重新支付!";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return WXPayConstants.FAIL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public void processRefund(Map<String, Object> bodyMap) {
|
|
|
|
+ String decrypt = this.decryptFromResource(bodyMap);
|
|
|
|
+ Gson gson = new Gson();
|
|
|
|
+ Map<String,Object> map = gson.fromJson(decrypt, HashMap.class);
|
|
|
|
+ String sn = map.get("out_trade_no").toString();
|
|
|
|
+ String refundNo = map.get("out_refund_no").toString();
|
|
|
|
+ String amount =map.get("amount").toString();
|
|
|
|
+ Map<String,Object> amountMap = gson.fromJson(amount, HashMap.class);
|
|
|
|
+ String refundPrice = amountMap.get("refund").toString();
|
|
|
|
+ if(StringUtils.isNotEmpty(sn)){
|
|
|
|
+ LambdaQueryWrapper<TOrder> query = Wrappers.lambdaQuery();
|
|
|
|
+ query.eq(TOrder::getSn,sn);
|
|
|
|
+ TOrder order = orderService.getOne(query);
|
|
|
|
+ // 已退款
|
|
|
|
+ if(order.getRefundQuantity() < order.getProductNumber()) {
|
|
|
|
+ order.setStatus(1);
|
|
|
|
+ } else {
|
|
|
|
+ order.setStatus(3);
|
|
|
|
+ }
|
|
|
|
+ // 更改订单明细表
|
|
|
|
+ LambdaQueryWrapper<TOrderDetails> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ queryWrapper.eq(TOrderDetails::getOrderSn, sn);
|
|
|
|
+ // 处理退款中状态的明细
|
|
|
|
+ queryWrapper.eq(TOrderDetails::getRefundStatus, "4");
|
|
|
|
+ List<TOrderDetails> tOrderDetails = orderDetailsService.list(queryWrapper);
|
|
|
|
+ for (TOrderDetails tOrderDetail : tOrderDetails) {
|
|
|
|
+ Integer refundQuantity = tOrderDetail.getRefundQuantity();
|
|
|
|
+ Integer productNumber = tOrderDetail.getProductNumber();
|
|
|
|
+ if(refundQuantity < productNumber) {
|
|
|
|
+ // 部分退款
|
|
|
|
+ tOrderDetail.setRefundStatus("2");
|
|
|
|
+ orderDetailsService.updateById(tOrderDetail);
|
|
|
|
+ } else {
|
|
|
|
+ // 全部退款
|
|
|
|
+ tOrderDetail.setRefundStatus("3");
|
|
|
|
+ orderDetailsService.updateById(tOrderDetail);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //退款金额要除以100
|
|
|
|
+ BigDecimal r4_refundAmount = new BigDecimal(refundPrice).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP).setScale(2, RoundingMode.HALF_DOWN);
|
|
|
|
+ BigDecimal refundAmount = order.getRefundAmount();
|
|
|
|
+ BigDecimal price = order.getPrice();
|
|
|
|
+ if(refundAmount != null) {
|
|
|
|
+ if (price.compareTo(refundAmount) == 0) {
|
|
|
|
+ order.setRefundAmount(refundAmount);
|
|
|
|
+ } else {
|
|
|
|
+ order.setRefundAmount(refundAmount.add(r4_refundAmount));
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ order.setRefundAmount(r4_refundAmount);
|
|
|
|
+ }
|
|
|
|
+ order.setRefundDate(new Date());
|
|
|
|
+ order.setModifyDate(new Date());
|
|
|
|
+ order.setRefundTrxNo(refundNo);
|
|
|
|
+ try {
|
|
|
|
+ orderFeign.saveToEs(order);
|
|
|
|
+ }catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }finally {
|
|
|
|
+ orderService.updateById(order);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
}
|
|
}
|