|
|
@@ -11,14 +11,19 @@ import com.zhongshu.card.client.model.payment.ExpenseRefundParam;
|
|
|
import com.zhongshu.card.client.type.LogsLevel;
|
|
|
import com.zhongshu.card.client.type.MessageType;
|
|
|
import com.zhongshu.card.client.type.RefundState;
|
|
|
+import com.zhongshu.card.client.utils.DateUtils;
|
|
|
import com.zhongshu.card.client.utils.PayExceptionToShowUtil;
|
|
|
import com.zhongshu.card.server.core.dao.payment.ExpenseFlowDao;
|
|
|
+import com.zhongshu.card.server.core.dao.payment.PaymentProcessDao;
|
|
|
import com.zhongshu.card.server.core.domain.payment.ExpenseFlow;
|
|
|
+import com.zhongshu.card.server.core.domain.payment.PaymentProcess;
|
|
|
import com.zhongshu.card.server.core.domain.schedule.ScheduleTaskConfig;
|
|
|
import com.zhongshu.card.server.core.service.base.SuperService;
|
|
|
import com.zhongshu.card.server.core.service.orgManager.ProjectBindOrgServiceImpl;
|
|
|
import com.zhongshu.card.server.core.service.pay.BalancePayService;
|
|
|
+import com.zhongshu.card.server.core.service.pay.ChinaumsSenselessPayService;
|
|
|
import com.zhongshu.card.server.core.service.pay.SettleService;
|
|
|
+import com.zhongshu.card.server.core.service.paySetting.PayOrderSettingService;
|
|
|
import com.zhongshu.card.server.core.service.user.OperationLogsService;
|
|
|
import com.zhongshu.card.server.core.util.NextNoUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
@@ -31,6 +36,8 @@ import java.math.BigDecimal;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Set;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -50,12 +57,21 @@ public class PayCallService extends SuperService {
|
|
|
@Autowired
|
|
|
ExpenseFlowDao expenseFlowDao;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private PaymentProcessDao paymentProcessDao;
|
|
|
+
|
|
|
@Autowired
|
|
|
private ProjectBindOrgServiceImpl projectBindOrgService;
|
|
|
|
|
|
@Autowired
|
|
|
private SettleService settleService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private PayOrderSettingService payOrderSettingService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ChinaumsSenselessPayService chinaumsSenselessPayService;
|
|
|
+
|
|
|
/**
|
|
|
* 统一调用支付服务
|
|
|
*
|
|
|
@@ -63,14 +79,66 @@ public class PayCallService extends SuperService {
|
|
|
* @return
|
|
|
*/
|
|
|
public ResultContent payOrder(ExpenseFlow entity) {
|
|
|
- PaymentType paymentType = entity.getPaymentType();
|
|
|
OrderState orderType = entity.getOrderType();
|
|
|
if (orderType != OrderState.WAIT_PAYMENT) {
|
|
|
return ResultContent.buildFail(String.format("订单不能支付:%s", orderType.getRemark()));
|
|
|
}
|
|
|
- // 判断支付渠道
|
|
|
- if (paymentType == PaymentType.UserWallet) {
|
|
|
- return balancePay(entity);
|
|
|
+ // 得到用户所有的支付渠道,依次尝试扣款
|
|
|
+ List<PaymentType> paymentTypes = payOrderSettingService.getUserPayment(entity.getUserId(), entity.getProjectOid());
|
|
|
+ if (ObjectUtils.isEmpty(paymentTypes)) {
|
|
|
+ String msg = "项目无支付渠道";
|
|
|
+ entity.setPaymentStatus("支付失败");
|
|
|
+ entity.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ entity.setPayRemark(msg);
|
|
|
+ entity.setOrderType(OrderState.PAID_ERROR);
|
|
|
+ entity.setIsPaid(Boolean.TRUE);
|
|
|
+ expenseFlowDao.save(entity);
|
|
|
+ return ResultContent.buildFail(msg);
|
|
|
+ }
|
|
|
+ log.info("开始支付: {} {}", entity.getPaymentNo(), paymentTypes);
|
|
|
+ int maxTime = 4 * 1000;
|
|
|
+ boolean b = false;
|
|
|
+ for (PaymentType paymentType : paymentTypes) {
|
|
|
+ entity = expenseFlowDao.findTopById(entity.getId());
|
|
|
+ entity.setPaymentType(paymentType);
|
|
|
+ entity.setPaymentWay(paymentType.getRemark());
|
|
|
+ if (paymentType == PaymentType.UserWallet) {
|
|
|
+ balancePay(entity);
|
|
|
+ } else if (paymentType == PaymentType.UnionFrictionlessPay) {
|
|
|
+ unionFrictionlessPay(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean isPaying = isPaying(entity.getPaymentNo(), paymentType);
|
|
|
+ if (isPaying) {
|
|
|
+ AtomicInteger atomicInteger = new AtomicInteger(0);
|
|
|
+ while (atomicInteger.get() <= maxTime) {
|
|
|
+ isPaying = isPaying(entity.getPaymentNo(), paymentType);
|
|
|
+ if (!isPaying) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ TimeUnit.MILLISECONDS.sleep(300);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ atomicInteger.addAndGet(300);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (entity.getIsPaySuccess() != null && entity.getIsPaySuccess()) {
|
|
|
+ b = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 所有的渠道都支付失败
|
|
|
+ if (!b) {
|
|
|
+ String msg = "支付失败";
|
|
|
+ entity.setPaymentStatus("支付失败");
|
|
|
+ entity.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ entity.setPayRemark(msg);
|
|
|
+ entity.setOrderType(OrderState.PAID_ERROR);
|
|
|
+ entity.setIsPaid(Boolean.TRUE);
|
|
|
+ expenseFlowDao.save(entity);
|
|
|
}
|
|
|
return ResultContent.buildSuccess();
|
|
|
}
|
|
|
@@ -86,8 +154,13 @@ public class PayCallService extends SuperService {
|
|
|
OperationLogsAddParam logsAddParam = initLog(entity.getUserId());
|
|
|
logsAddParam.setTitle(desc);
|
|
|
logsAddParam.setDataId(entity.getPaymentNo());
|
|
|
- entity.setPayStartTime(System.currentTimeMillis());
|
|
|
+ PaymentProcess paymentProcess = new PaymentProcess();
|
|
|
+ paymentProcess.setPaymentNo(entity.getPaymentNo());
|
|
|
+ paymentProcess.setExpenseFlow(entity);
|
|
|
+ paymentProcess.setPaymentType(PaymentType.UserWallet);
|
|
|
+ paymentProcess.setPayStartTime(System.currentTimeMillis());
|
|
|
|
|
|
+ entity.setPayStartTime(System.currentTimeMillis());
|
|
|
com.github.microservice.pay.client.ret.ResultContent<List<TransactionLogModel>> resultContent = balancePayService.balancePay(entity.getProjectOid(), entity.getShopOid(), entity.getUserId(), entity.getPayAmount(), entity.getPaymentNo(), entity.getRemark());
|
|
|
if (resultContent.getState() == ResultState.Success) {
|
|
|
// 关联参数
|
|
|
@@ -99,22 +172,35 @@ public class PayCallService extends SuperService {
|
|
|
entity.setPayRemark(msg);
|
|
|
entity.setOrderType(OrderState.HAVE_PAID);
|
|
|
|
|
|
+ paymentProcess.setIsPaySuccess(Boolean.TRUE);
|
|
|
+ paymentProcess.setPayRemark(msg);
|
|
|
// 日志
|
|
|
logsAddParam.setMessageType(MessageType.Info);
|
|
|
logsAddParam.setLevel(LogsLevel.Low);
|
|
|
logsAddParam.setContent(msg);
|
|
|
+
|
|
|
+ paymentProcess.setPayEndTime(System.currentTimeMillis());
|
|
|
+ paymentProcess.setPayMillis(paymentProcess.getPayEndTime() - paymentProcess.getPayStartTime());
|
|
|
+ paymentProcess.setTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
|
|
|
+ paymentProcessDao.save(paymentProcess);
|
|
|
} else {
|
|
|
String msg = resultContent.getMsg();
|
|
|
if (StringUtils.isNotEmpty(msg) && msg.contains("Connection reset")) {
|
|
|
msg = "调用支付中心失败";
|
|
|
} else {
|
|
|
String cls = resultContent.getException().getCls();
|
|
|
+ msg = PayExceptionToShowUtil.convertException(cls);
|
|
|
if (cls.contains("UncategorizedMongoDbException") && entity.getRepeatTime() <= 1) {
|
|
|
// 如果是并发引起的问题,则重复一次
|
|
|
entity.setRepeatTime(entity.getRepeatTime() + 1);
|
|
|
+ paymentProcess.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ paymentProcess.setPayRemark(msg);
|
|
|
+ paymentProcess.setPayEndTime(System.currentTimeMillis());
|
|
|
+ paymentProcess.setPayMillis(paymentProcess.getPayEndTime() - paymentProcess.getPayStartTime());
|
|
|
+ paymentProcess.setTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
|
|
|
+ paymentProcessDao.save(paymentProcess);
|
|
|
return balancePay(entity);
|
|
|
}
|
|
|
- msg = PayExceptionToShowUtil.convertException(cls);
|
|
|
}
|
|
|
if (StringUtils.isEmpty(msg)) {
|
|
|
msg = "支付中心失败";
|
|
|
@@ -123,19 +209,117 @@ public class PayCallService extends SuperService {
|
|
|
entity.setIsPaySuccess(Boolean.FALSE);
|
|
|
entity.setPayRemark(msg);
|
|
|
entity.setOrderType(OrderState.PAID_ERROR);
|
|
|
+
|
|
|
+ paymentProcess.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ paymentProcess.setPayRemark(msg);
|
|
|
+ // 日志
|
|
|
+ logsAddParam.setMessageType(MessageType.Warn);
|
|
|
+ logsAddParam.setLevel(LogsLevel.Middle);
|
|
|
+ logsAddParam.setContent(msg);
|
|
|
+ }
|
|
|
+ // 保存日志
|
|
|
+ operationLogsService.addLog(logsAddParam);
|
|
|
+
|
|
|
+ entity.setPayEndTime(System.currentTimeMillis());
|
|
|
+ entity.setPayMillis(entity.getPayEndTime() - entity.getPayStartTime());
|
|
|
+ expenseFlowDao.save(entity);
|
|
|
+
|
|
|
+ paymentProcess.setPayEndTime(System.currentTimeMillis());
|
|
|
+ paymentProcess.setPayMillis(paymentProcess.getPayEndTime() - paymentProcess.getPayStartTime());
|
|
|
+ paymentProcess.setTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
|
|
|
+ paymentProcessDao.save(paymentProcess);
|
|
|
+ return ResultContent.buildSuccess();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 银联 云闪付
|
|
|
+ *
|
|
|
+ * @param entity
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public ResultContent unionFrictionlessPay(ExpenseFlow entity) {
|
|
|
+ String desc = "消费";
|
|
|
+ OperationLogsAddParam logsAddParam = initLog(entity.getUserId());
|
|
|
+ logsAddParam.setTitle(desc);
|
|
|
+ logsAddParam.setDataId(entity.getPaymentNo());
|
|
|
+
|
|
|
+ PaymentProcess paymentProcess = new PaymentProcess();
|
|
|
+ paymentProcess.setPaymentNo(entity.getPaymentNo());
|
|
|
+ paymentProcess.setExpenseFlow(entity);
|
|
|
+ paymentProcess.setPaymentType(PaymentType.UnionFrictionlessPay);
|
|
|
+ paymentProcess.setPayStartTime(System.currentTimeMillis());
|
|
|
+ paymentProcess.setIsPaying(Boolean.TRUE); // 支付中
|
|
|
+
|
|
|
+ entity.setPayStartTime(System.currentTimeMillis());
|
|
|
+ com.github.microservice.net.ResultContent resultContent = chinaumsSenselessPayService.senselessPay(entity.getProjectOid(), entity.getShopOid(), entity.getUserId(), entity.getPayAmount(), entity.getPaymentNo(), entity.getRemark());
|
|
|
+ if (resultContent.getState() == com.github.microservice.net.ResultState.Success) {
|
|
|
+ // 关联参数
|
|
|
+ String msg = "支付中";
|
|
|
+ entity.setPaymentStatus(msg);
|
|
|
+ entity.setPayRemark(msg);
|
|
|
+ entity.setOrderType(OrderState.PAY_IN_PROGRESS);
|
|
|
+
|
|
|
+ // 日志
|
|
|
+ logsAddParam.setMessageType(MessageType.Info);
|
|
|
+ logsAddParam.setLevel(LogsLevel.Low);
|
|
|
+ logsAddParam.setContent(msg);
|
|
|
+ } else {
|
|
|
+ String msg = resultContent.getMsg();
|
|
|
+ if (StringUtils.isNotEmpty(msg) && msg.contains("Connection reset")) {
|
|
|
+ msg = "调用支付中心失败";
|
|
|
+ } else {
|
|
|
+ if (resultContent.getException() != null) {
|
|
|
+ String cls = resultContent.getException().getCls();
|
|
|
+ msg = PayExceptionToShowUtil.convertException(cls);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(msg)) {
|
|
|
+ msg = "支付中心失败";
|
|
|
+ }
|
|
|
+ entity.setPaymentStatus(msg);
|
|
|
+ entity.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ entity.setPayRemark(msg);
|
|
|
+ entity.setOrderType(OrderState.PAID_ERROR);
|
|
|
+
|
|
|
// 日志
|
|
|
logsAddParam.setMessageType(MessageType.Warn);
|
|
|
logsAddParam.setLevel(LogsLevel.Middle);
|
|
|
logsAddParam.setContent(msg);
|
|
|
+
|
|
|
+ // 支付记录
|
|
|
+ paymentProcess.setIsPaySuccess(Boolean.FALSE);
|
|
|
+ paymentProcess.setPayRemark(msg);
|
|
|
+ paymentProcess.setIsPaying(Boolean.FALSE);
|
|
|
}
|
|
|
// 保存日志
|
|
|
operationLogsService.addLog(logsAddParam);
|
|
|
|
|
|
entity.setPayEndTime(System.currentTimeMillis());
|
|
|
entity.setPayMillis(entity.getPayEndTime() - entity.getPayStartTime());
|
|
|
+ expenseFlowDao.save(entity);
|
|
|
+
|
|
|
+ paymentProcess.setPayEndTime(System.currentTimeMillis());
|
|
|
+ paymentProcess.setPayMillis(paymentProcess.getPayEndTime() - paymentProcess.getPayStartTime());
|
|
|
+ paymentProcess.setTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
|
|
|
+ paymentProcessDao.save(paymentProcess);
|
|
|
return ResultContent.buildSuccess();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 订单是否在支付中
|
|
|
+ *
|
|
|
+ * @param paymentNo
|
|
|
+ * @param paymentType
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean isPaying(String paymentNo, PaymentType paymentType) {
|
|
|
+ PaymentProcess paymentProcess = paymentProcessDao.findTopByPaymentNoAndPaymentTypeOrderByCreateTimeDesc(paymentNo, paymentType);
|
|
|
+ if (ObjectUtils.isNotEmpty(paymentProcess) && paymentProcess.getIsPaying() != null && paymentProcess.getIsPaying()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 查询余额
|
|
|
*
|