package com.nova.sankuai.service.impl; import cn.hutool.http.*; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.nova.sankuai.domain.api.shantai.*; import com.nova.sankuai.domain.api.yinsheng.enums.SignStatusEnum; import com.nova.sankuai.domain.entity.*; import com.nova.sankuai.domain.enums.ServerNameEnum; import com.nova.sankuai.domain.enums.vipservice.VipCardOrderEnum; import com.nova.sankuai.domain.vo.VipEffectiveTimeVo; import com.nova.sankuai.infra.config.CommonException; import com.nova.sankuai.infra.config.ServerName; import com.nova.sankuai.infra.mapper.CustomerMapper; import com.nova.sankuai.infra.mapper.CustomerUserMapper; import com.nova.sankuai.infra.mapper.VipCardOrderMapper; import com.nova.sankuai.infra.utils.UserUtil; import com.nova.sankuai.infra.utils.baofu.FormatUtil; import com.nova.sankuai.security.UserDetail; import com.nova.sankuai.service.*; import io.swagger.annotations.ApiModelProperty; import lombok.RequiredArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * @author Lilinhong 2022/8/18 10:35 */ @Service @RequiredArgsConstructor public class ShanTaiServiceImpl implements IShanTaiService { @Value("${shantai.appId}") @ApiModelProperty(value = "对接用ApiId") private String appId; @Value("${shantai.appKey}") @ApiModelProperty(value = "对接用ApiKey") private String appKey; @Value("${shantai.notificationDomain}") @ApiModelProperty(value = "回调的域名") private String notificationDomain; @Value("${shantai.apiUrl}") @ApiModelProperty(value = "对接API域名") private String apiUrl; private static final Logger shanTaiLogger = LoggerFactory.getLogger("shanTaiLogger"); private final ICustomerUserService customerUserService; private final IShanTaiSignRecordService shanTaiSignRecordService; private final CustomerUserMapper customerUserMapper; private final CustomerMapper customerMapper; private final VipCardOrderMapper vipCardOrderMapper; private final IVipCardService vipCardService; private final ServerName serverName; /** * 获取accessToken */ @Override public String getAccessToken() { String secret = Base64.getEncoder().encodeToString(DigestUtils.sha256(appId + appKey)); String param = "appId=" + appId + "&secret=" + secret; String params = HttpUtil.encodeParams(param, StandardCharsets.UTF_8); shanTaiLogger.info("获取accessToken,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/secret/authorize") .contentType(ContentType.FORM_URLENCODED.getValue()) .body(params).execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态accessToken失败,调用结果:" + response.body()); throw new CommonException("闪态accessToken失败"); } shanTaiLogger.info("获取accessToken,返回参数" + response.body()); JSONObject parseObj = JSONUtil.parseObj(response.body()); return parseObj.getStr("accessToken"); } /** * 获取用户Token */ @Override public String getUserToken(String phone, String userId, String accessToken) { String param = "phone=" + phone + "&userId=" + userId; String params = HttpUtil.encodeParams(param, StandardCharsets.UTF_8); shanTaiLogger.info("获取用户Token,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/user/login") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .body(params).execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态Token失败,调用结果:" + response.body()); throw new CommonException("获取用户Token失败"); } shanTaiLogger.info("闪态Token,返回参数" + response.body()); JSONObject parseObj = JSONUtil.parseObj(response.body()); return parseObj.getStr("token"); } @Override public String auth(String validateCode, String bankCardNo, UserDetail userDetail) { CustomerUser userByPhone = getUser(userDetail.getPhone()); ShanTaiSignRecord shanTaiSignRecordDb = null; List signRecords = shanTaiSignRecordService.list(Wrappers.lambdaQuery(ShanTaiSignRecord.class).eq(ShanTaiSignRecord::getCustomerUserId, userByPhone.getId()).orderByDesc(ShanTaiSignRecord::getCreationDate)); if (!signRecords.isEmpty()) { shanTaiSignRecordDb = signRecords.get(0); } if (shanTaiSignRecordDb == null) { throw new CommonException("请先进行绑卡鉴权操作"); } Customer customer = customerMapper.getLatestCustomerRecord(userByPhone.getPhone()); String accessToken = getAccessToken(); String userToken = getUserToken(customer.getPhone(), userByPhone.getId().toString(), accessToken); Map param = new HashMap<>(16); param.put("validateCode", validateCode); param.put("bankCardNo", FormatUtil.toStringTrim(bankCardNo)); shanTaiLogger.info("闪态绑卡确认短信鉴权,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/paperCardV2/auth") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .header("token", userToken) .form(param).execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态绑卡确认短信鉴权失败,调用结果:" + response.body()); String body = response.body(); Map parse = (Map) JSON.parse(body); if (parse != null) { String message = String.valueOf(parse.get("message")); // 于2022-11-22新增:交易记录 Object codesb = parse.get("codes"); if (codesb != null) { String code = null; if ("com.alibaba.fastjson.JSONArray".equals(codesb.getClass().getName())) { JSONArray array = JSONArray.parseArray(codesb.toString()); code = array.getString(0); } PayRecord payRecord = new PayRecord(); String timestamp = String.valueOf(parse.get("timestamp")); if (StringUtils.isBlank(timestamp)) { LocalDateTime payDate = LocalDateTime.now(); payRecord.setPayDate(payDate); } else { if (timestamp.length() > 19) { timestamp = timestamp.substring(0, 19); } DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime payDate = LocalDateTime.parse(timestamp, df); payRecord.setPayDate(payDate); } payRecord.setUserId(userByPhone.getId()); payRecord.setPayType("sc"); payRecord.setPayStatus(2); payRecord.setPayError(message); payRecord.setPayErrorCode(code); payRecord.setMobileVerifyCode(validateCode); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 payRecord.setOutTradeNo(shanTaiSignRecordDb.getSignCardNumber()); payRecordImpl(payRecord); } // 完 if (StringUtils.isNotBlank(message)) throw new CommonException(message); } throw new CommonException("绑卡确认短信鉴权失败"); } // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("sc"); record.setPayStatus(1); record.setPayDate(LocalDateTime.now()); record.setMobileVerifyCode(validateCode); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(shanTaiSignRecordDb.getSignCardNumber()); payRecordImpl(record); // 完 shanTaiSignRecordDb.setLastUpdatedDate(new Date()); String returnString = null; if (StringUtils.isEmpty(response.body())) { shanTaiSignRecordDb.setSignResult(SignStatusEnum.SUCCESS.getCode()); } else { shanTaiSignRecordDb.setSignResult(SignStatusEnum.FAILED.getCode()); returnString = response.body(); } shanTaiSignRecordService.saveOrUpdate(shanTaiSignRecordDb); return returnString; } @Override public ShanTaiPayInfo buyCardStartDirect(ShanTaiPayDto shanTaiPayDto, UserDetail userDetail) { CustomerUser userByPhone = getUser(userDetail.getPhone()); Customer customer = customerMapper.getLatestCustomerRecord(userByPhone.getPhone()); String accessToken = getAccessToken(); String userToken = getUserToken(customer.getPhone(), userByPhone.getId().toString(), accessToken); Map param = new HashMap<>(16); param.put("cardId", shanTaiPayDto.getCardId()); param.put("notificationUrl", notificationDomain + "/api/v2/shanTai/callBack"); param.put("bankCardNo", FormatUtil.toStringTrim(shanTaiPayDto.getBankCardNo())); param.put("partnerThirdOrderId", shanTaiPayDto.getPartnerThirdOrderId()); shanTaiLogger.info("闪态支付内部订单号:" + shanTaiPayDto.getPartnerThirdOrderId() + ",闪态直接通知扣费,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/paperCard/v3BuyCardStartDirect") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .header("token", userToken) .form(param).execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("订单号:" + shanTaiPayDto.getPartnerThirdOrderId() + ",闪态直接通知扣费失败,调用结果:" + response.body()); String body = response.body(); Map parse = (Map) JSON.parse(body); if (parse != null) { String message = String.valueOf(parse.get("message")); // 于2022-11-22新增:交易记录 Object codesb = parse.get("codes"); if (codesb != null) { String code = null; if ("com.alibaba.fastjson.JSONArray".equals(codesb.getClass().getName())) { JSONArray array = JSONArray.parseArray(codesb.toString()); code = array.getString(0); } PayRecord payRecord = new PayRecord(); String timestamp = String.valueOf(parse.get("timestamp")); if (StringUtils.isBlank(timestamp)) { LocalDateTime payDate = LocalDateTime.now(); payRecord.setPayDate(payDate); } else { if (timestamp.length() > 19) { timestamp = timestamp.substring(0, 19); } DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime payDate = LocalDateTime.parse(timestamp, df); payRecord.setPayDate(payDate); } payRecord.setUserId(userByPhone.getId()); payRecord.setPayType("sd"); payRecord.setPayStatus(2); payRecord.setPayError(message); payRecord.setPayErrorCode(code); payRecord.setOutTradeNo(shanTaiPayDto.getPartnerThirdOrderId()); payRecordImpl(payRecord); } // 完 if (StringUtils.isNotBlank(message)) throw new CommonException(message); // throw new CommonException(parse.get("message")); } throw new CommonException("直接通知扣费失败"); } String body = response.body(); shanTaiLogger.info("闪态支付内部订单号:" + shanTaiPayDto.getPartnerThirdOrderId() + ",闪态直接通知扣费原始转换前返回数据:{}", body); ShanTaiPayInfo shanTaiPayInfo = null; try { shanTaiPayInfo = JSON.parseObject(body, ShanTaiPayInfo.class); shanTaiLogger.info("闪态支付内部订单号:" + shanTaiPayDto.getPartnerThirdOrderId() + ",闪态直接通知扣费原始转换后返回数据:{}", shanTaiPayInfo.toString()); // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("sd"); record.setPayStatus(1); record.setPayDate(LocalDateTime.now()); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(shanTaiPayDto.getPartnerThirdOrderId()); payRecordImpl(record); // 完 } catch (Exception e) { // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("sd"); record.setPayStatus(2); record.setPayDate(LocalDateTime.now()); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(shanTaiPayDto.getPartnerThirdOrderId()); payRecordImpl(record); // 完 shanTaiLogger.info("闪态支付内部订单号:" + shanTaiPayDto.getPartnerThirdOrderId() + ",闪态直接通知扣费原始返回数据转换失败"); e.printStackTrace(); } return shanTaiPayInfo; } @Override public ConfirmVo directConfirm(ShanTaiPaySureDto shanTaiPaySureDto, UserDetail userDetail) { CustomerUser userByPhone = getUser(userDetail.getPhone()); Customer customer = customerMapper.getLatestCustomerRecord(userByPhone.getPhone()); String accessToken = getAccessToken(); String userToken = getUserToken(customer.getPhone(), userByPhone.getId().toString(), accessToken); VipCardOrder vipCardOrder = vipCardOrderMapper.selectOne(new LambdaQueryWrapper() .eq(VipCardOrder::getOrderId, shanTaiPaySureDto.getPayOrderId())); if (vipCardOrder == null) { throw new CommonException("订单不存在"); } VipCard card = vipCardService.getOne(new LambdaQueryWrapper() .eq(VipCard::getCardId, vipCardOrder.getCardId())); if (card == null) { throw new CommonException("不存在此类会员卡"); } Map param = new HashMap<>(16); param.put("payOrderId", vipCardOrder.getOrderId()); if (ShanTaiSureTypeEnum.SMS_VERIFY.getCode().equalsIgnoreCase(shanTaiPaySureDto.getType())) { param.put("smsCode", shanTaiPaySureDto.getSmsCode()); param.put("type", ShanTaiSureTypeEnum.SMS_VERIFY.getCode()); } else if (ShanTaiSureTypeEnum.PROTOCOL_VERIFY.getCode().equalsIgnoreCase(shanTaiPaySureDto.getType())) { param.put("agreeProtocol", true); param.put("type", ShanTaiSureTypeEnum.PROTOCOL_VERIFY.getCode()); } shanTaiLogger.info("闪态确认支付,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/paperCard/v3DirectConfirm") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .header("token", userToken) .form(param).execute(); ConfirmVo confirmVo = null; String body = response.body(); shanTaiLogger.error("闪态确认支付返回原始参数:" + body); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态确认支付失败,调用结果:" + response.body()); vipCardOrder.setStatus(VipCardOrderEnum.STATUS_INVALID.getCode()); vipCardOrderMapper.update(null, Wrappers.lambdaUpdate() .set(VipCardOrder::getStatus, vipCardOrder.getStatus()) .eq(VipCardOrder::getId, vipCardOrder.getId())); Map parse = (Map) JSON.parse(body); if (parse != null) { String message = String.valueOf(parse.get("message")); // 于2022-11-22新增:交易记录 Object codesb = parse.get("codes"); if (codesb != null) { String code = null; if ("com.alibaba.fastjson.JSONArray".equals(codesb.getClass().getName())) { JSONArray array = JSONArray.parseArray(codesb.toString()); code = array.getString(0); } PayRecord payRecord = new PayRecord(); String timestamp = String.valueOf(parse.get("timestamp")); if (StringUtils.isBlank(timestamp)) { LocalDateTime payDate = LocalDateTime.now(); payRecord.setPayDate(payDate); } else { if (timestamp.length() > 19) { timestamp = timestamp.substring(0, 19); } DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime payDate = LocalDateTime.parse(timestamp, df); payRecord.setPayDate(payDate); } payRecord.setUserId(userByPhone.getId()); payRecord.setPayType("st"); payRecord.setPayStatus(2); payRecord.setPayError(message); payRecord.setPayErrorCode(code); payRecord.setOutTradeNo(shanTaiPaySureDto.getPayOrderId()); payRecordImpl(payRecord); } // 完 if (StringUtils.isNotBlank(message)) throw new CommonException(message); } throw new CommonException("确认支付失败"); } try { confirmVo = JSON.parseObject(body, ConfirmVo.class); shanTaiLogger.info("闪态确认支付原始转换后返回数据:{}", body); // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("st"); record.setPayStatus(1); record.setPayDate(LocalDateTime.now()); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(shanTaiPaySureDto.getPayOrderId()); payRecordImpl(record); // 完 } catch (Exception e) { shanTaiLogger.info("闪态确认支付原始返回数据转换失败"); e.printStackTrace(); confirmVo.setResult(false); // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("st"); record.setPayStatus(2); record.setPayDate(LocalDateTime.now()); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(shanTaiPaySureDto.getPayOrderId()); payRecordImpl(record); // 完 } if (confirmVo != null && confirmVo.getResult()) { vipCardOrder.setStatus(VipCardOrderEnum.STATUS_WAIT.getCode()); } else { vipCardOrder.setStatus(VipCardOrderEnum.STATUS_INVALID.getCode()); } vipCardOrderMapper.update(null, Wrappers.lambdaUpdate() .set(VipCardOrder::getStatus, vipCardOrder.getStatus()) .eq(VipCardOrder::getId, vipCardOrder.getId())); return confirmVo; } /** * 于2022-11-22注释:闪态获取短信验证码 */ @Override public String startAuth(BindCardDto bindCardDto, UserDetail userDetail) { CustomerUser userByPhone = getUser(userDetail.getPhone()); ShanTaiSignRecord shanTaiSignRecordDb = null; List signRecords = shanTaiSignRecordService.list(Wrappers.lambdaQuery(ShanTaiSignRecord.class).eq(ShanTaiSignRecord::getCustomerUserId, userByPhone.getId()).orderByDesc(ShanTaiSignRecord::getCreationDate)); if (!signRecords.isEmpty()) { shanTaiSignRecordDb = signRecords.get(0); } if (shanTaiSignRecordDb != null && SignStatusEnum.SUCCESS.getCode().equals(shanTaiSignRecordDb.getSignResult())) { throw new CommonException("该用户已是成功签约用户"); } Customer customer = customerMapper.getLatestCustomerRecord(userByPhone.getPhone()); String accessToken = getAccessToken(); String userToken = getUserToken(customer.getPhone(), userByPhone.getId().toString(), accessToken); Map param = new HashMap<>(16); // 新增于2022-12-07 String signIdNo = FormatUtil.toStringTrim(bindCardDto.getSignIdNo()); String signCardNumber = FormatUtil.toStringTrim(bindCardDto.getSignCardNumber()); // signCardNumber = signCardNumber.replace(" ",""); bindCardDto.setSignCardNumber(signCardNumber); param.put("bankCardNo", signCardNumber); param.put("idCardNo", signIdNo); param.put("phone", bindCardDto.getSignPhone()); param.put("userName", bindCardDto.getSignName()); if (StringUtils.isNotEmpty(customer.getIpAddres())) { param.put("userIp", customer.getIpAddres()); } else { param.put("userIp", "127.0.0.1"); } shanTaiLogger.info("闪态绑卡鉴权,传递参数" + param); HttpResponse response = HttpRequest.post(apiUrl + "/paperCardV2/startAuth") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .header("token", userToken) .form(param).execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态绑卡鉴权失败,调用结果:" + response.body()); String body = response.body(); Map parse = (Map) JSON.parse(body); if (parse != null) { String message = String.valueOf(parse.get("message")); // 于2022-11-22新增:交易记录 Object codesb = parse.get("codes"); if (codesb != null) { String code = null; if ("com.alibaba.fastjson.JSONArray".equals(codesb.getClass().getName())) { JSONArray array = JSONArray.parseArray(codesb.toString()); code = array.getString(0); } PayRecord payRecord = new PayRecord(); String timestamp = String.valueOf(parse.get("timestamp")); if (StringUtils.isBlank(timestamp)) { LocalDateTime payDate = LocalDateTime.now(); payRecord.setPayDate(payDate); } else { if (timestamp.length() > 19) { timestamp = timestamp.substring(0, 19); } DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime payDate = LocalDateTime.parse(timestamp, df); payRecord.setPayDate(payDate); } payRecord.setUserId(userByPhone.getId()); payRecord.setPayType("sp"); payRecord.setPayStatus(2); payRecord.setPayError(message); payRecord.setPayErrorCode(code); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 payRecord.setOutTradeNo(signCardNumber); payRecordImpl(payRecord); } // 完 if (StringUtils.isNotBlank(message)) throw new CommonException(message); } throw new CommonException("绑卡鉴权失败"); } // 于2022-11-22新增:交易记录 PayRecord record = new PayRecord(); record.setUserId(userByPhone.getId()); record.setPayType("sp"); record.setPayStatus(1); record.setPayDate(LocalDateTime.now()); // 因为闪态绑卡鉴权没有订单号,所以这里以银行卡号来代替 record.setOutTradeNo(signCardNumber); payRecordImpl(record); // 完 ShanTaiSignRecord shanTaiSignRecord; if (shanTaiSignRecordDb == null) { shanTaiSignRecord = new ShanTaiSignRecord(); shanTaiSignRecord.setCustomerUserId(userByPhone.getId()); shanTaiSignRecord.setSignIdNo(signIdNo); shanTaiSignRecord.setSignName(bindCardDto.getSignName()); shanTaiSignRecord.setSignPhone(bindCardDto.getSignPhone()); shanTaiSignRecord.setCreationDate(new Date()); } else { shanTaiSignRecord = shanTaiSignRecordDb; } shanTaiSignRecord.setLastUpdatedDate(new Date()); shanTaiSignRecord.setSignCardNumber(signCardNumber); String returnString = null; if (!StringUtils.isEmpty(response.body())) { returnString = response.body(); } shanTaiSignRecordService.saveOrUpdate(shanTaiSignRecord); return returnString; } @Override public void callBack(Map params, UserDetail userDetail) { if (params == null || params.size() == 0) { shanTaiLogger.error(String.format("闪态回调接口接收参数为NULL,参数map=>", params)); } // 于2022-11-30新增:用于记录参数 StringBuffer sb = new StringBuffer(); // 完 String userId = null; String partnerThirdOrderId = null; String orderId = null; try { MultiValueMap stringMultiValueMap = new LinkedMultiValueMap<>(); for (Map.Entry entry : params.entrySet()) { if (entry.getValue() != null) { List value = Arrays.asList(entry.getValue()); // shanTaiLogger.info("闪态支付回调参数名:" + entry.getKey() + " 值:" + value); // 于2022-11-30新增: sb.append("," + entry.getKey() + ":" + value.get(0)); stringMultiValueMap.put(entry.getKey(), new ArrayList<>(value)); if ("userId".equals(entry.getKey()) || "partnerThirdOrderId".equals(entry.getKey()) || "orderId".equals(entry.getKey())) { if ("userId".equals(entry.getKey())) { userId = value.get(0); } else if ("partnerThirdOrderId".equals(entry.getKey())) { partnerThirdOrderId = value.get(0); } else { orderId = value.get(0); } } } else { // shanTaiLogger.info("闪态支付回调参数名:" + entry.getKey() + " 值:" + null); sb.append("," + entry.getKey() + ":" + null); stringMultiValueMap.put(entry.getKey(), null); } } shanTaiLogger.info("闪态支付回调参数:{}", sb); List signParam = stringMultiValueMap.get("sign"); String signValue = ""; if (signParam != null) { signValue = signParam.get(0); } stringMultiValueMap.remove("sign"); String signStr = stringMultiValueMap.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(Map.Entry::getValue) .filter(l -> !l.isEmpty()) .map(l -> l.get(0)) .filter(StringUtils::isNotEmpty) .collect(Collectors.joining("", appKey, "")); String sign = Base64.getEncoder().encodeToString(DigestUtils.sha256(signStr)); if (sign.equals(signValue)) { //系统内订单状态更新 // orderId = Objects.requireNonNull(stringMultiValueMap.get("orderId")).get(0); // partnerThirdOrderId = Objects.requireNonNull(stringMultiValueMap.get("partnerThirdOrderId")).get(0); // // // 于2022-11-30新增: // userId = Objects.requireNonNull(stringMultiValueMap.get("userId")).get(0); String type = Objects.requireNonNull(stringMultiValueMap.get("type")).get(0); VipCardOrder vipCardOrder = null; if (StringUtils.isNotBlank(partnerThirdOrderId)) { vipCardOrder = vipCardOrderMapper.selectOne(new LambdaQueryWrapper() .eq(VipCardOrder::getPartnerThirdOrderId, partnerThirdOrderId)); } else if (StringUtils.isNotBlank(orderId)) { vipCardOrder = vipCardOrderMapper.selectOne(new LambdaQueryWrapper() .eq(VipCardOrder::getOrderId, orderId)); } if (vipCardOrder == null) { callbackPayRecord(userId, partnerThirdOrderId, orderId, "闪态支付回调参数没有订单号:" + sb); shanTaiLogger.error("闪态支付回调参数没有 partnerThirdOrderId 和 orderId:{}", sb); return; } String systemStatus = parseSystemStatus(type); if (VipCardOrderEnum.STATUS_INVALID.getCode().equals(systemStatus)) { callbackPayRecord(userId, partnerThirdOrderId, orderId, "订单回调类型非法:" + sb); shanTaiLogger.error("闪态支付回调订单类型非法,回调类型:" + type + ",对应参数:{}", sb); } if (vipCardOrder != null) { String oldStatus = vipCardOrder.getStatus(); vipCardOrder.setStatus(systemStatus); vipCardOrder.setOrderId(orderId); if (!systemStatus.equals(oldStatus) && !VipCardOrderEnum.STATUS_END.getCode().equalsIgnoreCase(oldStatus)) { vipCardOrderMapper.update(null, Wrappers.lambdaUpdate() .set(VipCardOrder::getStatus, systemStatus) .set(VipCardOrder::getOrderId, orderId) .eq(VipCardOrder::getPartnerThirdOrderId, partnerThirdOrderId)); if (VipCardOrderEnum.STATUS_END.getCode().equals(systemStatus)) { VipCard card = vipCardService.getOne(Wrappers.lambdaQuery() .eq(VipCard::getCardId, vipCardOrder.getCardId()).last(" limit 1 ")); if (card == null) { callbackPayRecord(userId, partnerThirdOrderId, orderId, "闪态支付对应会员卡不存在:" + sb); shanTaiLogger.error("闪态支付回调失败,对应会员卡不存在,原始数据:" + vipCardOrder); return; // throw new CommonException("对应会员卡不存在"); } VipEffectiveTimeVo vipEffectiveTimeVo = customerUserService.calculateExpiredDate(vipCardOrder.getUserId(), card.getValidDate(), null, null); customerUserService.updateVipEffectiveTime(vipCardOrder, vipEffectiveTimeVo); shanTaiLogger.info("闪态支付回调支付成功,参数map:{}", sb); callbackPayRecord(userId, partnerThirdOrderId, orderId, null); } } } else { callbackPayRecord(userId, partnerThirdOrderId, orderId, "闪态支付对应订单不存在:" + sb.toString()); shanTaiLogger.error("闪态支付回调失败,对应订单不存在,对应参数:" + sb.toString()); // throw new CommonException("对应订单不存在"); } } else { // shanTaiLogger.error(String.format("闪态回调接口签名异常,参数map=>", sb.toString())); callbackPayRecord(userId, partnerThirdOrderId, orderId, "闪态支付回调签名异常:" + sb); shanTaiLogger.error("闪态支付回调签名异常,参数map:{}", sb); } } catch (Exception e) { // shanTaiLogger.error(String.format("闪态回调接口异常,参数map=>", sb.toString())); callbackPayRecord(userId, partnerThirdOrderId, orderId, "闪态支付回调出异常:" + sb); shanTaiLogger.error("闪态支付回调出异常,参数map:{};异常错误信息:{}", sb, e); } } private void callbackPayRecord(String userIdStr, String partnerThirdOrderId, String orderId, String errorStr) { if (StringUtils.isBlank(userIdStr)) { return; } Long userId = Long.parseLong(userIdStr); String outTradeNo = StringUtils.isNotBlank(partnerThirdOrderId) ? partnerThirdOrderId : orderId; PayRecord payRecord = new PayRecord(); LocalDateTime payDate = LocalDateTime.now(); payRecord.setPayDate(payDate); payRecord.setUserId(userId); payRecord.setPayType("se"); payRecord.setPayStatus(errorStr == null ? 3 : 2); payRecord.setPayError(errorStr == null ? "闪态回调支付成功" : errorStr); payRecord.setPayErrorCode(errorStr == null ? "666666" : "888888"); payRecord.setOutTradeNo(outTradeNo); payRecordImpl(payRecord); } @Override public GetOrderStatusVo getOrderStatus(String payOrderId) { String accessToken = getAccessToken(); HttpResponse response = HttpRequest.get(apiUrl + "/card/order/" + payOrderId + "/status") .contentType(ContentType.FORM_URLENCODED.getValue()) .header("authorization", accessToken) .execute(); if (response.getStatus() != HttpStatus.HTTP_OK) { shanTaiLogger.error("闪态查询订单失败,调用结果:" + response.body()); throw new CommonException("查询订单失败"); } String body = response.body(); shanTaiLogger.info("闪态查询订单原始转换前返回数据:{}", body); GetOrderStatusVo orderStatusVo; try { orderStatusVo = JSON.parseObject(body, GetOrderStatusVo.class); shanTaiLogger.info("闪态查询订单原始转换后返回数据:{}", body); } catch (Exception e) { shanTaiLogger.info("闪态确认支付原始返回数据转换失败"); e.printStackTrace(); return null; } return orderStatusVo; } @Override public boolean checkBeforePayment(Long userId) { ShanTaiSignRecord signRecord = null; List signRecords = shanTaiSignRecordService.list(Wrappers.lambdaQuery(ShanTaiSignRecord.class). eq(ShanTaiSignRecord::getCustomerUserId, userId).orderByDesc(ShanTaiSignRecord::getCreationDate)); if (!signRecords.isEmpty()) { signRecord = signRecords.get(0); } return signRecord != null && SignStatusEnum.SUCCESS.getCode().equals(signRecord.getSignResult()); } @Override public ShanTaiCheckVo checkProtocolSignBySt(HttpServletRequest request) { String token = request.getHeader("Authorization"); UserDetail user = UserUtil.getUser(token); if (user == null || user.getId() == null) { throw new CommonException("Token无效"); } CustomerUser customerUser = customerUserService.getById(user.getId()); if (customerUser == null) { throw new CommonException("用户不存在"); } ShanTaiCheckVo checkVo = new ShanTaiCheckVo(); ShanTaiSignRecord signRecord = null; List signRecords = shanTaiSignRecordService.list(Wrappers.lambdaQuery(ShanTaiSignRecord.class). eq(ShanTaiSignRecord::getCustomerUserId, customerUser.getId()).orderByDesc(ShanTaiSignRecord::getCreationDate)); if (!signRecords.isEmpty()) { signRecord = signRecords.get(0); } Customer customer = customerMapper.getLatestCustomerRecord(customerUser.getPhone()); if (signRecord != null && SignStatusEnum.SUCCESS.getCode().equals(signRecord.getSignResult())) { checkVo.setSign(true); checkVo.setSignCardNumber(signRecord.getSignCardNumber()); checkVo.setSignIdNo(signRecord.getSignIdNo()); checkVo.setSignName(signRecord.getSignName()); checkVo.setSignPhone(signRecord.getSignPhone()); } else { checkVo.setSign(false); if (customer != null) { checkVo.setSignName(customer.getName()); checkVo.setSignIdNo(customer.getIdCard()); } } if (customer != null) { checkVo.setBankName(customer.getBankName()); checkVo.setBankCode(customer.getBankCode()); } return checkVo; } public static String parseSystemStatus(String type) { if (ShanTaiOrderEnum.PAPER_OK.getCode().equals(type)) { return VipCardOrderEnum.STATUS_END.getCode(); } else if (ShanTaiOrderEnum.OK.getCode().equals(type) || ShanTaiOrderEnum.PAPER_AUTH.getCode().equals(type)) { return VipCardOrderEnum.STATUS_WAIT.getCode(); } else if (ShanTaiOrderEnum.CLOSE.getCode().equals(type)) { return VipCardOrderEnum.STATUS_CLOSE.getCode(); } else { return VipCardOrderEnum.STATUS_INVALID.getCode(); } } public static String parseSelectSystemStatus(String type) { if (ShanTaiSelectOrderEnum.CLOSE.getCode().equals(type)) { return VipCardOrderEnum.STATUS_CLOSE.getCode(); } else if (ShanTaiSelectOrderEnum.INIT.getCode().equals(type) || ShanTaiSelectOrderEnum.DELIVER.getCode().equals(type)) { return VipCardOrderEnum.STATUS_WAIT.getCode(); } else { return VipCardOrderEnum.STATUS_END.getCode(); } } private CustomerUser getUser(String phone) { LambdaQueryWrapper customerUserWrapper = new LambdaQueryWrapper<>(); customerUserWrapper.eq(CustomerUser::getPhone, phone).eq(CustomerUser::getDeleteFlag, 0); CustomerUser customerUser = customerUserMapper.selectOne(customerUserWrapper); if (customerUser == null) { throw new CommonException("用户不存在"); } return customerUser; } @Override public String getEquityUrl(CustomerUser customerUser) { List shanTaiSignRecords = shanTaiSignRecordService.list(Wrappers.lambdaQuery(ShanTaiSignRecord.class).eq(ShanTaiSignRecord::getCustomerUserId, customerUser.getId()).eq(ShanTaiSignRecord::getSignResult, "SUCCESS").orderByDesc(ShanTaiSignRecord::getCreationDate).last("LIMIT 1")); if (!shanTaiSignRecords.isEmpty()) { ShanTaiSignRecord shanTaiSignRecord = shanTaiSignRecords.get(0); String accessToken = getAccessToken(); String userToken = getUserToken(shanTaiSignRecord.getSignPhone(), shanTaiSignRecord.getCustomerUserId().toString(), accessToken); if (apiUrl.contains("dev")) { return apiUrl + "/gotoBuy/630713b501b02a246df9d164?_token=" + userToken; } else { return apiUrl + "/gotoBuy/6323e89439132e1df8beea9a?_token=" + userToken; } } return null; } /** * 使用会员通知 * * @return 响应信息 */ @Override public Integer useEquityNotify(UseEquityNotifyParams params) { if (Objects.isNull(params.getThirdUserId())) throw new CommonException("thirdUserId不存在"); shanTaiLogger.info("使用会员权益回调__服务器名:{},参数:{}", serverName.getServerName(), JSON.toJSONString(params)); String domain = null; //域名 int result = HttpStatus.HTTP_OK; //响应码 VipCardOrder vipCardOrder; //判断来源,如果是读取秋畅的配置文件,说明是闪态支付来源于本服务器,其他的话,要做转发 if (params.getThirdUserId().endsWith(ServerNameEnum.TEST.getValue())) { //海南bj2 domain = "https://bj2.e086.net/api/v2/shanTai/useEquityForward"; } else if (params.getThirdUserId().endsWith(ServerNameEnum.ZH.getValue())) { domain = "https://skfq.yamiloantech.com/api/v2/shanTai/useEquityForward"; } else if (params.getThirdUserId().endsWith(ServerNameEnum.WH.getValue())) { domain = "https://skfq.shenzhenweihong.com/api/v2/shanTai/useEquityForward"; } else if (params.getThirdUserId().endsWith(ServerNameEnum.DLD.getValue())) { //秋畅服务器,无需转发,直接处理即可 this.useEquityForward(params.getThirdUserId()); return result; } if (Objects.nonNull(domain)) { vipCardOrder = new VipCardOrder(); vipCardOrder.setPartnerThirdOrderId(params.getThirdUserId()); String param = "partnerThirdOrderId=" + params.getThirdUserId(); String to = HttpUtil.encodeParams(param, StandardCharsets.UTF_8); HttpResponse response = HttpRequest.post(domain) .contentType(ContentType.FORM_URLENCODED.getValue()) .body(to).execute(); if (!Objects.equals(response.getStatus(), HttpStatus.HTTP_OK)) { result = HttpStatus.HTTP_INTERNAL_ERROR; } } return result; } @Override public Integer useEquityForward(String partnerThirdOrderId) { VipCardOrder order = vipCardOrderMapper.selectOne(Wrappers.lambdaQuery(VipCardOrder.class).eq(VipCardOrder::getPartnerThirdOrderId, partnerThirdOrderId)); if (Objects.isNull(order)) throw new CommonException("订单不存在"); order.setIsUsedEquity(1); return vipCardOrderMapper.update(order, Wrappers.lambdaUpdate(VipCardOrder.class).eq(VipCardOrder::getPartnerThirdOrderId, order.getPartnerThirdOrderId())); } @Resource private PlatformTransactionManager transactionManager;// 引入 (平台)事务管理器,Spring 事务策略的核心。 // 于2022-11-17号 private final IPayRecordService payRecordService; /** * 于2022-11-18新增:录入支付记录表 */ @Async public void payRecordImpl(PayRecord payRecord) { // 发起一个新事务 DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);//新发起一个事务 TransactionStatus defStatus = transactionManager.getTransaction(def);// 获得事务状态 payRecordService.save(payRecord); transactionManager.commit(defStatus);// 手动提交事务 } }