@@ -0,0 +1,124 @@ | |||
package com.qtzl.alterSales.dao.entity.second; | |||
import com.txffp.api.core.dao.entity.AbstractInsertTimeEntity; | |||
import javax.persistence.Column; | |||
import javax.persistence.Entity; | |||
import javax.persistence.Table; | |||
/** | |||
* 通行流水推送配置(AflPaccountPushConfig)实体类 | |||
* | |||
* @author shuiqilin | |||
* @since 2024-08-06 10:33:51 | |||
*/ | |||
@Entity | |||
@Table(name = "AFL_PACCOUNT_PUSH_CONFIG") | |||
public class AflPaccountPushConfig extends AbstractInsertTimeEntity { | |||
/** | |||
* 公司名称 | |||
*/ | |||
private String companyName; | |||
/** | |||
* 渠道方ID | |||
*/ | |||
private String agentId; | |||
/** | |||
* 流水推送地址 | |||
*/ | |||
private String pushUrl; | |||
/** | |||
* 接口ID | |||
*/ | |||
private String ifCode; | |||
/** | |||
* 是否开启推送 0否 1是 | |||
*/ | |||
private Integer isOnPush; | |||
/** | |||
* 来源方ID | |||
*/ | |||
private String appid; | |||
/** | |||
* sm3Key | |||
*/ | |||
private String sm3Key; | |||
/** | |||
* sm4Key | |||
*/ | |||
private String sm4Key; | |||
@Column(name = "COMPANY_NAME") | |||
public String getCompanyName() { | |||
return companyName; | |||
} | |||
public void setCompanyName(String companyName) { | |||
this.companyName = companyName; | |||
} | |||
@Column(name = "AGENT_ID") | |||
public String getAgentId() { | |||
return agentId; | |||
} | |||
public void setAgentId(String agentId) { | |||
this.agentId = agentId; | |||
} | |||
@Column(name = "PUSH_URL") | |||
public String getPushUrl() { | |||
return pushUrl; | |||
} | |||
public void setPushUrl(String pushUrl) { | |||
this.pushUrl = pushUrl; | |||
} | |||
@Column(name = "IF_CODE") | |||
public String getIfCode() { | |||
return ifCode; | |||
} | |||
public void setIfCode(String ifCode) { | |||
this.ifCode = ifCode; | |||
} | |||
@Column(name = "IS_ON_PUSH") | |||
public Integer getIsOnPush() { | |||
return isOnPush; | |||
} | |||
public void setIsOnPush(Integer isOnPush) { | |||
this.isOnPush = isOnPush; | |||
} | |||
@Column(name = "APPID") | |||
public String getAppid() { | |||
return appid; | |||
} | |||
public void setAppid(String appid) { | |||
this.appid = appid; | |||
} | |||
@Column(name = "SM3_KEY") | |||
public String getSm3Key() { | |||
return sm3Key; | |||
} | |||
public void setSm3Key(String sm3Key) { | |||
this.sm3Key = sm3Key; | |||
} | |||
@Column(name = "SM4_KEY") | |||
public String getSm4Key() { | |||
return sm4Key; | |||
} | |||
public void setSm4Key(String sm4Key) { | |||
this.sm4Key = sm4Key; | |||
} | |||
} | |||
@@ -0,0 +1,26 @@ | |||
package com.qtzl.alterSales.dao.repo.jpa.second; | |||
import com.qtzl.alterSales.dao.entity.second.AflMchConfig; | |||
import com.qtzl.alterSales.dao.entity.second.AflPaccountPushConfig; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
import org.springframework.data.jpa.repository.Query; | |||
/*** | |||
* <p> | |||
* 通行流水推送配置 repo | |||
* </p> | |||
* @author hou yi | |||
* {@code @date} 2024/4/19 22:10 | |||
**/ | |||
public interface AflPaccountPushConfigRepo extends JpaRepository<AflMchConfig, String> { | |||
/*** | |||
* 根据渠道方ID查询配置 | |||
* @param agentId 子商户号 | |||
* @return 、 | |||
*/ | |||
@Query("FROM AflPaccountPushConfig WHERE agentId = ?1") | |||
AflPaccountPushConfig findByAgentId(String agentId); | |||
} |
@@ -0,0 +1,21 @@ | |||
package com.qtzl.alterSales.manager.handler; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import com.qtzl.alterSales.manager.vo.AflPaccountPushConfigVo; | |||
/*** | |||
* <p> | |||
* 通行流水推送配置 | |||
* </p> | |||
* @author hou yi | |||
* {@code @date} 2024/4/19 22:19 | |||
**/ | |||
public interface AflPaccountPushConfigManager { | |||
/*** | |||
* 根据渠道方ID查询配置信息 | |||
* @param agentId 渠道方ID | |||
* @return 、 | |||
*/ | |||
AflPaccountPushConfigVo findByAgentId(String agentId); | |||
} |
@@ -0,0 +1,66 @@ | |||
package com.qtzl.alterSales.manager.handler; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import com.alibaba.fastjson2.JSON; | |||
import com.alibaba.fastjson2.JSONObject; | |||
import com.qtzl.alterSales.dao.entity.second.AflPaccountPushConfig; | |||
import com.qtzl.alterSales.dao.repo.jpa.second.AflPaccountPushConfigRepo; | |||
import com.qtzl.alterSales.manager.tools.RedisUtils; | |||
import com.qtzl.alterSales.manager.vo.AflPaccountPushConfigVo; | |||
import com.txffp.api.core.manager.tools.AESTools; | |||
import org.apache.commons.lang3.ObjectUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.stereotype.Service; | |||
import javax.annotation.Resource; | |||
/** | |||
* @author shuiqilin | |||
* @version 1.0 | |||
* @date 2024/8/6 上午 10:45 | |||
*/ | |||
@Service | |||
public class AflPaccountPushConfigManagerImpl implements AflPaccountPushConfigManager { | |||
private static final Logger log = LoggerFactory.getLogger(AflPaccountPushConfigManagerImpl.class); | |||
@Resource | |||
private AflPaccountPushConfigRepo aflPaccountPushConfigRepo; | |||
@Resource | |||
private RedisUtils redisUtils; | |||
/*** 请勿更改*/ | |||
private static final String PACCOUNT_PUSH_AES_KEY = "qtzl2024xzxtpush"; | |||
private static final String PACCOUNT_PUSH_CONFIG = "PACCOUNT_PUSH_CONFIG_"; | |||
@Override | |||
public AflPaccountPushConfigVo findByAgentId(String agentId){ | |||
if (StringUtils.isEmpty(agentId)) { | |||
log.error("通行流水推送配置查询未指定渠道方id"); | |||
return null; | |||
} | |||
String redisKey = PACCOUNT_PUSH_CONFIG + agentId; | |||
final Object object = redisUtils.get(redisKey); | |||
if (!ObjectUtils.isEmpty(object)) { | |||
return JSONObject.parseObject((String) object, AflPaccountPushConfigVo.class); | |||
} | |||
final AflPaccountPushConfig paccountPushConfig = aflPaccountPushConfigRepo.findByAgentId(agentId); | |||
if (null == paccountPushConfig) { | |||
return null; | |||
} | |||
// 相关参数解密 | |||
decryption(paccountPushConfig); | |||
// | |||
final AflPaccountPushConfigVo paccountPushConfigVo = new AflPaccountPushConfigVo(); | |||
BeanUtil.copyProperties(paccountPushConfig, paccountPushConfigVo); | |||
redisUtils.set(redisKey, JSON.toJSONString(paccountPushConfigVo)); | |||
return paccountPushConfigVo; | |||
} | |||
private void decryption(AflPaccountPushConfig paccountPushConfig) { | |||
// 解密 | |||
paccountPushConfig.setSm3Key(AESTools.decrypt(paccountPushConfig.getSm3Key(), PACCOUNT_PUSH_AES_KEY)); | |||
paccountPushConfig.setSm4Key(AESTools.decrypt(paccountPushConfig.getSm4Key(), PACCOUNT_PUSH_AES_KEY)); | |||
} | |||
} |
@@ -17,12 +17,14 @@ import com.qtzl.alterSales.dao.repo.jpa.second.AflWechatSignRepo; | |||
import com.qtzl.alterSales.manager.enums.AflApPayOrderStatus; | |||
import com.qtzl.alterSales.manager.enums.BlacklistOpType; | |||
import com.qtzl.alterSales.manager.enums.WechatAttachEnum; | |||
import com.qtzl.alterSales.manager.handler.AflPaccountPushConfigManager; | |||
import com.qtzl.alterSales.manager.model.protocol.UcServiceError; | |||
import com.qtzl.alterSales.manager.model.protocol.sales.ChoiceBillsPayRequest; | |||
import com.qtzl.alterSales.manager.model.protocol.wechat.partnerpayments.JsapiV3Manager; | |||
import com.qtzl.alterSales.manager.rabbit.RabbitUnifiedProduction; | |||
import com.qtzl.alterSales.manager.tools.RedisUtils; | |||
import com.qtzl.alterSales.manager.vo.AflMchConfigVo; | |||
import com.qtzl.alterSales.manager.vo.AflPaccountPushConfigVo; | |||
import com.qtzl.alterSales.manager.vo.ChoiceBillsPayVo; | |||
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayWithRequestPaymentResponse; | |||
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; | |||
@@ -51,7 +53,10 @@ import java.util.stream.Collectors; | |||
public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationService { | |||
private static final Logger log = LoggerFactory.getLogger(ChoiceBillsOperationServiceImpl.class); | |||
// 请不要改这个key | |||
private static final String REDIS_KEY = "PAY_FAIL_"; | |||
@Resource | |||
AflPaccountRefundCountService aflPaccountRefundCountService; | |||
@Resource | |||
private AflBlackInfoManager blackInfoManager; | |||
@Resource | |||
@@ -77,12 +82,9 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
@Resource | |||
private AflWechatSignRepo aflWechatSignRepo; | |||
@Resource | |||
AflPaccountRefundCountService aflPaccountRefundCountService; | |||
@Resource | |||
private RabbitUnifiedProduction rabbitUnifiedProduction; | |||
// 请不要改这个key | |||
private static final String REDIS_KEY = "PAY_FAIL_"; | |||
@Resource | |||
private AflPaccountPushConfigManager paccountPushConfigManager; | |||
@Override | |||
public ChoiceBillsPayVo choiceBillsPay(ChoiceBillsPayRequest request) throws ServiceHandleException { | |||
@@ -119,16 +121,19 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
} | |||
} | |||
final String vehicleId = vehicleIds.iterator().next(); | |||
String orderNo = "AFLBQ" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + (int) ((Math.random() * 9 + 1) * Math.pow(10, 5)); | |||
String orderNo = | |||
"AFLBQ" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + (int) ((Math.random() * 9 + 1) * Math.pow(10, 5)); | |||
final long totalFee = payList.stream().mapToLong(FssPaccountPay::getReceiptAmt).sum(); | |||
final AflMchConfigVo mchConfig = getMchInfoEnum(vehicleId); | |||
// 写入补扣微信支付订单表 | |||
final AflApPayOrder payOrder = new AflApPayOrder(orderNo, mchConfig.getSubMchId(), request.getOpenId(), request.getIdType(), request.getIdNum(), vehicleId, | |||
final AflApPayOrder payOrder = new AflApPayOrder(orderNo, mchConfig.getSubMchId(), request.getOpenId(), | |||
request.getIdType(), request.getIdNum(), vehicleId, | |||
payList.size(), totalFee, AflApPayOrderStatus.TO_BE_PAID); | |||
List<AflApPayOrderRel> orderRel = Lists.newArrayList(); | |||
for (FssPaccountPay pay : payList) { | |||
final LocalDateTime firstInsertTime = wechatBillPayApplyRepo.getFirstInsertTime(pay.getPayId()); | |||
final WechatBillPayApply payApply = null == firstInsertTime ? null : wechatBillPayApplyRepo.findByPayIdAndInsertTime(pay.getPayId(), firstInsertTime); | |||
final WechatBillPayApply payApply = null == firstInsertTime ? null : | |||
wechatBillPayApplyRepo.findByPayIdAndInsertTime(pay.getPayId(), firstInsertTime); | |||
if (null != payApply && AflApPayOrderStatus.SUCCESS.getStatus().equals(payApply.getResultCode()) && StringUtils.isEmpty(payApply.getTradeState())) { | |||
throw UcServiceError.BUSINESS_VALIDATE_ERR.toHandleException("系统轮扣等待微信结果中,为避免重复扣费,请稍后重试"); | |||
} | |||
@@ -188,7 +193,8 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
redisUtils.del(REDIS_KEY + payId); | |||
} | |||
} | |||
final Transaction transaction = jsapiV3Manager.jsApiQueryByOutTradeNo(payOrder.getOrderNo(), mchConfigManager.findBySubMchId(payOrder.getSubMchId())); | |||
final Transaction transaction = jsapiV3Manager.jsApiQueryByOutTradeNo(payOrder.getOrderNo(), | |||
mchConfigManager.findBySubMchId(payOrder.getSubMchId())); | |||
if (Transaction.TradeStateEnum.PAYERROR.equals(transaction.getTradeState())) { | |||
// 支付失败 | |||
payOrder.setTransactionId(transaction.getTransactionId()); | |||
@@ -216,17 +222,26 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
//进行统计累加已收款金额 | |||
aflPaccountRefundCountService.saveFind(pay); | |||
} catch (Exception e) { | |||
log.error("进行统计累加已收款金额失败... payId:{},{}", pay.getPayId(),e.getMessage()); | |||
log.error("进行统计累加已收款金额失败... payId:{},{}", pay.getPayId(), e.getMessage()); | |||
} | |||
pay.setStatus(1); | |||
pay.setMsg("请款成功"); | |||
pay.setWxPayStatus(1); | |||
pay.setWxPayTime(payTime); | |||
pay.setWxOrderId(payOrder.getOrderNo()); | |||
//加入队列,等待扣款结果通知 | |||
rabbitUnifiedProduction.delayFssPaccountpayPushQueue(pay.getPayId(), 180000,0); | |||
try { | |||
//加入队列前,判断是否推送 | |||
final AflPaccountPushConfigVo paccountPushConfig = paccountPushConfigManager. | |||
findByAgentId(pay.getAgentId()); | |||
if (ObjectUtil.isNotNull(paccountPushConfig) && paccountPushConfig.getIsOnPush().equals(1)) { | |||
//加入队列,等待扣款结果通知 | |||
rabbitUnifiedProduction.delayFssPaccountpayPushQueue(pay.getPayId(), 180000, 0); | |||
} else { | |||
log.info("该渠道未开启流水推送,不加入队列... payId:{}", pay.getPayId()); | |||
} | |||
} catch (Exception e) { | |||
log.error("加入推送流水队列失败... payId:{},{}", pay.getPayId(), e.getMessage()); | |||
} | |||
supplementaryPayOrderService.paySuccessNotify(pay.getPayId(), payTime, payOrder.getOrderNo()); | |||
}); | |||
accountPayRepo.saveAll(accountPayList); | |||
@@ -243,7 +258,8 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
final List<String> orderList = accountPayList.stream().map(FssPaccountPay::getOrderId).toList(); | |||
final List<String> payIdList = accountPayList.stream().map(FssPaccountPay::getcPayId).toList(); | |||
blackInfoManager.execute(agreementNum, BlacklistOpType.OUT, "所有流水补扣成功,对该协议返白", String.join("、", orderList), String.join("、", payIdList), | |||
blackInfoManager.execute(agreementNum, BlacklistOpType.OUT, "所有流水补扣成功,对该协议返白", String.join("、", | |||
orderList), String.join("、", payIdList), | |||
null, null, null); | |||
} | |||
} | |||
@@ -251,7 +267,8 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
private AflMchConfigVo getMchInfoEnum(String vehicleId) throws ServiceHandleException { | |||
// | |||
final String[] split = vehicleId.split("_"); | |||
final AflWechatSign wechatSign = aflWechatSignRepo.findByPlateNumAndPlateColor(split[0], Integer.parseInt(split[1])); | |||
final AflWechatSign wechatSign = aflWechatSignRepo.findByPlateNumAndPlateColor(split[0], | |||
Integer.parseInt(split[1])); | |||
if (null == wechatSign) { | |||
return mchConfigManager.findBySubMchId("1648725759"); | |||
} |
@@ -4,10 +4,12 @@ import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import com.alibaba.fastjson.JSON; | |||
import com.google.common.collect.Lists; | |||
import com.qtzl.alterSales.dao.entity.primary.AflApPayOrder; | |||
import com.qtzl.alterSales.dao.entity.primary.FssPaccountPay; | |||
import com.qtzl.alterSales.dao.entity.primary.WechatBillPayApply; | |||
import com.qtzl.alterSales.dao.entity.primary.WechatBillPaySuccess; | |||
import com.qtzl.alterSales.dao.entity.second.AflPaccountRefundCount; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.AflApPayOrderRepo; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.AflSupplementaryPayOrderRepo; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.FssPaccountPayRepo; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.FssPaccountRefundRepo; | |||
@@ -60,6 +62,8 @@ public class FssPaccountPayServiceImpl implements FssPaccountPayService { | |||
@Resource | |||
private WechatBillPaySuccessRepo successRepo; | |||
@Resource | |||
private AflApPayOrderRepo apPayOrderRepo; | |||
@Override | |||
@@ -233,6 +237,11 @@ public class FssPaccountPayServiceImpl implements FssPaccountPayService { | |||
WechatBillPaySuccess paySuccess = successRepo.findByOutTradeNo(fssPaccountPay.getWxOrderId()); | |||
if (null != paySuccess) { | |||
response.setTransactionId(paySuccess.getTransactionId()); | |||
} else { | |||
AflApPayOrder aflApPayOrder = apPayOrderRepo.findByOrderNo(fssPaccountPay.getWxOrderId()); | |||
if (null != aflApPayOrder) { | |||
response.setTransactionId(aflApPayOrder.getTransactionId()); | |||
} | |||
} | |||
} | |||
return response; |
@@ -0,0 +1,108 @@ | |||
package com.qtzl.alterSales.manager.vo; | |||
/** | |||
* 通行流水推送配置(AflPaccountPushConfig)vo | |||
* | |||
* @author shuiqilin | |||
* @since 2024-08-06 10:33:51 | |||
*/ | |||
public class AflPaccountPushConfigVo { | |||
/** | |||
* 公司名称 | |||
*/ | |||
private String companyName; | |||
/** | |||
* 渠道方ID | |||
*/ | |||
private String agentId; | |||
/** | |||
* 流水推送地址 | |||
*/ | |||
private String pushUrl; | |||
/** | |||
* 接口ID | |||
*/ | |||
private String ifCode; | |||
/** | |||
* 是否开启推送 0否 1是 | |||
*/ | |||
private Integer isOnPush; | |||
/** | |||
* 来源方ID | |||
*/ | |||
private String appid; | |||
/** | |||
* sm3Key | |||
*/ | |||
private String sm3Key; | |||
/** | |||
* sm4Key | |||
*/ | |||
private String sm4Key; | |||
public String getCompanyName() { | |||
return companyName; | |||
} | |||
public void setCompanyName(String companyName) { | |||
this.companyName = companyName; | |||
} | |||
public String getAgentId() { | |||
return agentId; | |||
} | |||
public void setAgentId(String agentId) { | |||
this.agentId = agentId; | |||
} | |||
public String getPushUrl() { | |||
return pushUrl; | |||
} | |||
public void setPushUrl(String pushUrl) { | |||
this.pushUrl = pushUrl; | |||
} | |||
public String getIfCode() { | |||
return ifCode; | |||
} | |||
public void setIfCode(String ifCode) { | |||
this.ifCode = ifCode; | |||
} | |||
public Integer getIsOnPush() { | |||
return isOnPush; | |||
} | |||
public void setIsOnPush(Integer isOnPush) { | |||
this.isOnPush = isOnPush; | |||
} | |||
public String getAppid() { | |||
return appid; | |||
} | |||
public void setAppid(String appid) { | |||
this.appid = appid; | |||
} | |||
public String getSm3Key() { | |||
return sm3Key; | |||
} | |||
public void setSm3Key(String sm3Key) { | |||
this.sm3Key = sm3Key; | |||
} | |||
public String getSm4Key() { | |||
return sm4Key; | |||
} | |||
public void setSm4Key(String sm4Key) { | |||
this.sm4Key = sm4Key; | |||
} | |||
} | |||