|
@@ -1,5 +1,6 @@
|
|
|
package com.caimei365.order.service.impl;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.caimei365.order.components.OrderCommonService;
|
|
|
import com.caimei365.order.components.ProductService;
|
|
@@ -36,6 +37,7 @@ import java.security.NoSuchAlgorithmException;
|
|
|
import java.security.spec.InvalidKeySpecException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
/**
|
|
@@ -61,13 +63,13 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
private WeChatService weChatService;
|
|
|
@Resource
|
|
|
private RemoteCallService remoteCallService;
|
|
|
- @Value("${caimei.redirectLink}")
|
|
|
+ @Value("${pay.redirect-link}")
|
|
|
private String redirectLink;
|
|
|
- @Value("${caimei.linkPage}")
|
|
|
+ @Value("${pay.link-page}")
|
|
|
private String linkPage;
|
|
|
- @Value("${caimei.notifyUrl}")
|
|
|
+ @Value("${pay.notify-url}")
|
|
|
private String notifyUrl;
|
|
|
- @Value("${caimei.secondHandUrl}")
|
|
|
+ @Value("${pay.second-notify-url}")
|
|
|
private String secondHandUrl;
|
|
|
|
|
|
/**
|
|
@@ -231,7 +233,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
List<DiscernReceiptVo> discernReceiptList = orderCommonMapper.getDiscernReceipt(order.getOrderId(), order.getShopOrderIds());
|
|
|
if (!discernReceiptList.isEmpty()) {
|
|
|
AtomicDouble receiptAmount = new AtomicDouble(0d);
|
|
|
- AtomicReference<Boolean> offlineFlag = new AtomicReference<>(false);
|
|
|
+ AtomicBoolean offlineFlag = new AtomicBoolean(false);
|
|
|
discernReceiptList.forEach(discernReceipt -> {
|
|
|
if (2 == discernReceipt.getPayWay()) {
|
|
|
offlineFlag.set(true);
|
|
@@ -432,7 +434,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
* payAmount 支付金额,单位分,必须大于2
|
|
|
* returnUrl 页面回调地址
|
|
|
* }
|
|
|
- * @param headers
|
|
|
+ * @param headers HttpHeaders
|
|
|
*/
|
|
|
@Override
|
|
|
public ResponseJson<JSONObject> payByAlipay(PayDto payDto, HttpHeaders headers) {
|
|
@@ -457,7 +459,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
* bankCode 银行编码(银联支付使用)
|
|
|
* userType 用户类型(银联支付使用)企业:ENTERPRISE,个人:USER
|
|
|
* }
|
|
|
- * @param headers
|
|
|
+ * @param headers HttpHeaders
|
|
|
*/
|
|
|
@Override
|
|
|
public ResponseJson<JSONObject> payByUnionPay(PayDto payDto, HttpHeaders headers) {
|
|
@@ -502,7 +504,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
return ResponseJson.error("付款金额错误!", null);
|
|
|
}
|
|
|
// 定义支付请求结果
|
|
|
- JSONObject result = null;
|
|
|
+ JSONObject result;
|
|
|
try {
|
|
|
// 时间戳
|
|
|
long time = System.currentTimeMillis() / 1000;
|
|
@@ -512,7 +514,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
json.put("merAccount", PayUtil.merAccount);
|
|
|
json.put("merNo", PayUtil.merNo);
|
|
|
json.put("time", time);
|
|
|
- //支付金额
|
|
|
+ // 支付金额
|
|
|
json.put("amount", payParam.getPayAmount());
|
|
|
json.put("payWay", payParam.getPayWay());
|
|
|
json.put("payType", payParam.getPayType());
|
|
@@ -571,7 +573,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
log.info("******************** 支付异步回调 start *******************");
|
|
|
// 公钥解密
|
|
|
JSONObject json = PayUtil.publicKeyDecrypt(data, PayUtil.publicKey);
|
|
|
- log.info("公钥解密>>>>>>" + json);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>公钥解密:" + json);
|
|
|
// 公钥验签
|
|
|
String signaa = json.getString("sign");
|
|
|
json.remove("sign");
|
|
@@ -696,7 +698,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
// 商品数据
|
|
|
List<OrderProductVo> orderProductList = orderCommonMapper.getOrderProductByOrderId(orderId);
|
|
|
// 判断是否是充值商品
|
|
|
- Integer rechargeFlag = 0;
|
|
|
+ int rechargeFlag = 0;
|
|
|
// 缴纳订金订单
|
|
|
int[] productId1 = {6060, 6061, 6062, 6063, 6064};
|
|
|
// 充值余额订单
|
|
@@ -1097,6 +1099,244 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
return "SUCCESS";
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 延时分账
|
|
|
+ *
|
|
|
+ * @param callUrl 回调地址
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void delayedSplitting(String callUrl) {
|
|
|
+ log.info("【延时分账】>>>>>>>>>>延时分账,每一小时执行一次");
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(new Date());
|
|
|
+ calendar.add(Calendar.DAY_OF_MONTH, -1);
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ String currentTime = format.format(calendar.getTime());
|
|
|
+ // 查询未分账已支付收款
|
|
|
+ List<OrderReceiptRelationPo> orderRelations = payOrderMapper.getUndividedPaidReceipt(currentTime);
|
|
|
+ if (orderRelations != null && orderRelations.size() > 0) {
|
|
|
+ for (OrderReceiptRelationPo orderRelation : orderRelations) {
|
|
|
+ log.info("【延时分账】>>>>>>>>>>订单id:" + orderRelation.getOrderId() + ",进入延时分账");
|
|
|
+ // 订单信息
|
|
|
+ OrderVo order = payOrderMapper.getOrderByOrderId(orderRelation.getOrderId());
|
|
|
+ PayParamBo payParam = new PayParamBo();
|
|
|
+ payParam.setPayAmount(MathUtil.mul(orderRelation.getAssociateAmount(), 100).intValue());
|
|
|
+ if (12 == orderRelation.getPayType()) {
|
|
|
+ // 网银支付
|
|
|
+ payParam.setPayWay("UNIONPAY");
|
|
|
+ }
|
|
|
+ List<SplitAccountPo> splitBillDetail = setSplitAccountDetail(order, payParam);
|
|
|
+ List<Map<String, String>> maps = new ArrayList<>();
|
|
|
+ List<ShopOrderVo> shopOrderList = payOrderMapper.getShopOrderListByOrderId(order.getOrderId());
|
|
|
+ //供应商子商户总金额
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ double shopTotalAmount = 0.00;
|
|
|
+ String subUserNo = "";
|
|
|
+ for (SplitAccountPo account : splitBillDetail) {
|
|
|
+ if (4 == account.getType() && shopOrder.getShopId().equals(account.getShopId())) {
|
|
|
+ shopTotalAmount = MathUtil.add(shopTotalAmount, account.getSplitAccount()).doubleValue();
|
|
|
+ subUserNo = account.getSubUserNo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ addMaps(maps, shopTotalAmount, subUserNo);
|
|
|
+ }
|
|
|
+ //公账-专票总金额,私账-无票总金额,公账-普票总金额
|
|
|
+ double totalAmount1 = 0.00;
|
|
|
+ double totalAmount2 = 0.00;
|
|
|
+ double totalAmount3 = 0.00;
|
|
|
+ for (SplitAccountPo account : splitBillDetail) {
|
|
|
+ if (1 == account.getType()) {
|
|
|
+ totalAmount1 = MathUtil.add(totalAmount1, account.getSplitAccount()).doubleValue();
|
|
|
+ } else if (2 == account.getType()) {
|
|
|
+ totalAmount2 = MathUtil.add(totalAmount2, account.getSplitAccount()).doubleValue();
|
|
|
+ } else if (3 == account.getType()) {
|
|
|
+ totalAmount3 = MathUtil.add(totalAmount3, account.getSplitAccount()).doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ addMaps(maps, totalAmount1, PayUtil.publicAccountNo);
|
|
|
+ addMaps(maps, totalAmount2, PayUtil.privateAccountNo);
|
|
|
+ addMaps(maps, totalAmount3, PayUtil.commonInvoiceNo);
|
|
|
+ String parameters = JSON.toJSONString(maps);
|
|
|
+ log.info("【延时分账】>>>>>>>>>>分账参数: " + parameters);
|
|
|
+
|
|
|
+ //第三方分账接口
|
|
|
+ JSONObject result = null;
|
|
|
+ try {
|
|
|
+ // 时间戳
|
|
|
+ long time = System.currentTimeMillis() / 1000;
|
|
|
+ JSONObject json = new JSONObject();
|
|
|
+ json.put("merAccount", PayUtil.merAccount);
|
|
|
+ json.put("orderId", orderRelation.getOrderRequestNo());
|
|
|
+ json.put("requestNo", orderRelation.getOrderRequestNo());
|
|
|
+ json.put("mbOrderId", orderRelation.getMbOrderId());
|
|
|
+ json.put("time", time);
|
|
|
+ json.put("splitBillDetail", parameters);
|
|
|
+ json.put("notifyUrl", notifyUrl);
|
|
|
+ log.info("回调接口>>>" + notifyUrl);
|
|
|
+ String sign = PayUtil.getPaySign(json, PayUtil.merKey);
|
|
|
+ json.put("sign", sign);
|
|
|
+ String data = PayUtil.privateKeyEncrypt(json, PayUtil.merKey);
|
|
|
+ result = PayUtil.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/splitOrder/v1", PayUtil.merAccount, data);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("【延时分账】>>>>>>>>>>错误信息", e);
|
|
|
+ }
|
|
|
+ if (result != null) {
|
|
|
+ String code = result.getString("code");
|
|
|
+ if (!"000000".equals(code)) {
|
|
|
+ String msg = result.getString("msg");
|
|
|
+ log.info("【延时分账】>>>>>>>>>>第三方延迟分账失败>>>>>>>msg:" + msg);
|
|
|
+ } else {
|
|
|
+ for (SplitAccountPo splitAccount : splitBillDetail) {
|
|
|
+ splitAccount.setMbOrderId(orderRelation.getMbOrderId());
|
|
|
+ splitAccount.setOrderRequestNo(orderRelation.getOrderRequestNo());
|
|
|
+ splitAccount.setPayStatus(1);
|
|
|
+ // 保存分账详情
|
|
|
+ payOrderMapper.insertSplitAccount(splitAccount);
|
|
|
+ }
|
|
|
+ log.info("【延时分账】>>>>>>>>>>此订单分账结束");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分账参数添加
|
|
|
+ */
|
|
|
+ private void addMaps(List<Map<String, String>> maps, Double shopTotalAmount, String subUserNo) {
|
|
|
+ if (MathUtil.compare(shopTotalAmount, 0) > 0) {
|
|
|
+ Map<String, String> map = new HashMap<>(3);
|
|
|
+ map.put("subUserNo", subUserNo);
|
|
|
+ map.put("splitBillType", "2");
|
|
|
+ map.put("splitBillValue", MathUtil.mul(shopTotalAmount, 100).toString());
|
|
|
+ maps.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分账详情
|
|
|
+ */
|
|
|
+ private List<SplitAccountPo> setSplitAccountDetail(OrderVo order, PayParamBo payParam) {
|
|
|
+ List<SplitAccountPo> list = new ArrayList<>();
|
|
|
+ // 本次支付金额,单位/元
|
|
|
+ double payAmount = MathUtil.div(payParam.getPayAmount(), 100).doubleValue();
|
|
|
+ // 待分账总金额
|
|
|
+ double splitAmount = payAmount;
|
|
|
+ // 总手续费
|
|
|
+ double procedureFee = 0.00;
|
|
|
+ if ("UNIONPAY".equals(payParam.getPayWay())) {
|
|
|
+ procedureFee = 8.00;
|
|
|
+ } else {
|
|
|
+ //手续费
|
|
|
+ procedureFee = MathUtil.mul(payAmount, 0.0038, 2).doubleValue();
|
|
|
+ if (MathUtil.compare(procedureFee, 0) == 0) {
|
|
|
+ procedureFee = 0.01;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, procedureFee).doubleValue();
|
|
|
+ // 商品数据
|
|
|
+ List<OrderProductVo> orderProductList = orderCommonMapper.getOrderProductByOrderId(order.getOrderId());
|
|
|
+ for (OrderProductVo orderProduct : orderProductList) {
|
|
|
+ double costPrice = MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum()).doubleValue();
|
|
|
+ // 不含税能开发票
|
|
|
+ if (0 == orderProduct.getIncludedTax() && 3 != orderProduct.getInvoiceType()) {
|
|
|
+ //应付总税费
|
|
|
+ Double payableTax = MathUtil.mul(orderProduct.getSingleShouldPayTotalTax(), orderProduct.getNum()).doubleValue();
|
|
|
+ costPrice = MathUtil.add(costPrice, payableTax).doubleValue();
|
|
|
+ }
|
|
|
+ // 判断是否支付过
|
|
|
+ Double paidAmount = payOrderMapper.getOrderProductPaidAmount(orderProduct.getOrderProductId());
|
|
|
+ if (paidAmount != null && MathUtil.compare(paidAmount, 0) > 0) {
|
|
|
+ costPrice = MathUtil.sub(costPrice, paidAmount).doubleValue();
|
|
|
+ }
|
|
|
+ if (paidAmount == null || MathUtil.compare(paidAmount, costPrice) < 0) {
|
|
|
+ // 待分账金额>=本次待分账金额
|
|
|
+ if (MathUtil.compare(splitAmount, costPrice) > -1) {
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, costPrice).doubleValue();
|
|
|
+ } else {
|
|
|
+ costPrice = splitAmount;
|
|
|
+ splitAmount = 0.00;
|
|
|
+ }
|
|
|
+ String commercialCode = payOrderMapper.getShopCommercialCode(orderProduct.getShopId());
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setOrderProductId(orderProduct.getOrderProductId());
|
|
|
+ splitAccount.setShopId(orderProduct.getShopId());
|
|
|
+ splitAccount.setSplitAccount(costPrice);
|
|
|
+ splitAccount.setProductType(1);
|
|
|
+ if (StringUtils.isNotBlank(commercialCode)) {
|
|
|
+ // 供应商拥有子商户号
|
|
|
+ splitAccount.setType(4);
|
|
|
+ splitAccount.setSubUserNo(commercialCode);
|
|
|
+ } else {
|
|
|
+ if (3 == orderProduct.getInvoiceType()) {
|
|
|
+ // 不能开票,则分账到私账-无票
|
|
|
+ splitAccount.setType(2);
|
|
|
+ splitAccount.setSubUserNo(PayUtil.privateAccountNo);
|
|
|
+ } else if (1 == orderProduct.getInvoiceType()) {
|
|
|
+ // 开增值税发票,则分账到公账-专票
|
|
|
+ splitAccount.setType(1);
|
|
|
+ splitAccount.setSubUserNo(PayUtil.publicAccountNo);
|
|
|
+ } else if (2 == orderProduct.getInvoiceType()) {
|
|
|
+ // 开普通发票,则分账到公账-普票
|
|
|
+ splitAccount.setType(3);
|
|
|
+ splitAccount.setSubUserNo(PayUtil.commonInvoiceNo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ list.add(splitAccount);
|
|
|
+ if (MathUtil.compare(splitAmount, 0) == 0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 付供应商运费,是以供应商为单位的
|
|
|
+ if (MathUtil.compare(splitAmount, 0) > 0) {
|
|
|
+ List<ShopOrderVo> shopOrderList = payOrderMapper.getShopOrderListByOrderId(order.getOrderId());
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ // 运费
|
|
|
+ Double shopPostFee = shopOrder.getShopPostFee();
|
|
|
+ if (MathUtil.compare(shopPostFee, 0) > 0) {
|
|
|
+ // 查询已支付运费
|
|
|
+ Double shipping = payOrderMapper.getPaidShipping(order.getOrderId(), shopOrder.getShopId());
|
|
|
+ shopPostFee = MathUtil.sub(shopPostFee, shipping).doubleValue();
|
|
|
+ if (MathUtil.compare(splitAmount, shopPostFee) > -1) {
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, shopPostFee).doubleValue();
|
|
|
+ } else {
|
|
|
+ shopPostFee = splitAmount;
|
|
|
+ splitAmount = 0.00;
|
|
|
+ }
|
|
|
+ String commercialCode = payOrderMapper.getShopCommercialCode(shopOrder.getShopId());
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setShopId(shopOrder.getShopId());
|
|
|
+ splitAccount.setSplitAccount(shopPostFee);
|
|
|
+ splitAccount.setProductType(2);
|
|
|
+ if (StringUtils.isNotBlank(commercialCode)) {
|
|
|
+ //供应商拥有子商户号
|
|
|
+ splitAccount.setType(4);
|
|
|
+ splitAccount.setSubUserNo(commercialCode);
|
|
|
+ } else {
|
|
|
+ //私账
|
|
|
+ splitAccount.setType(2);
|
|
|
+ splitAccount.setSubUserNo(PayUtil.privateAccountNo);
|
|
|
+ }
|
|
|
+ list.add(splitAccount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //佣金,公账
|
|
|
+ if (MathUtil.compare(splitAmount, 0) > 0) {
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setSplitAccount(splitAmount);
|
|
|
+ splitAccount.setProductType(3);
|
|
|
+ splitAccount.setType(1);
|
|
|
+ splitAccount.setSubUserNo(PayUtil.publicAccountNo);
|
|
|
+ list.add(splitAccount);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 延时分账异步通知回调
|
|
|
*/
|
|
@@ -1181,11 +1421,12 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|
|
shopRecord.setDelFlag(0);
|
|
|
payOrderMapper.insertPayShopRecord(shopRecord);
|
|
|
}
|
|
|
- //子订单是否全部付款
|
|
|
+ // 子订单是否全部付款
|
|
|
boolean isPay = true;
|
|
|
for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
if (3 != shopOrder.getPayStatus()) {
|
|
|
isPay = false;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
// 修改主订单付款状态
|