PayOrderServiceImpl.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. package com.caimei.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.caimei.mapper.*;
  5. import com.caimei.model.ResponseJson;
  6. import com.caimei.model.dto.PaymentDto;
  7. import com.caimei.model.po.*;
  8. import com.caimei.model.vo.*;
  9. import com.caimei.service.PayOrderService;
  10. import com.caimei.util.HttpRequest;
  11. import com.caimei.util.MathUtil;
  12. import com.caimei.util.PayUtils;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.apache.commons.lang3.StringUtils;
  15. import org.springframework.beans.factory.annotation.Value;
  16. import org.springframework.stereotype.Service;
  17. import org.springframework.transaction.annotation.Transactional;
  18. import javax.annotation.Resource;
  19. import java.math.BigDecimal;
  20. import java.text.SimpleDateFormat;
  21. import java.util.*;
  22. /**
  23. * Description
  24. *
  25. * @author : plf
  26. * @date : 2020/5/9
  27. */
  28. @Service
  29. @Slf4j
  30. public class PayOrderServiceImpl implements PayOrderService {
  31. @Resource
  32. private PayOrderMapper payOrderMapper;
  33. @Resource
  34. private OrderMapper orderMapper;
  35. @Resource
  36. private CouponMapper couponMapper;
  37. @Resource
  38. private CollageMapper collageMapper;
  39. @Value("${caimei.delayedSplittingUrl}")
  40. private String delayedSplittingUrl;
  41. @Value("${caimei.userUrl}")
  42. private String userUrl;
  43. /**
  44. * 商户标识
  45. */
  46. String merAccount = "150a5459416b4046b9153c1cd442e397";
  47. /**
  48. * 私钥,商户密钥
  49. */
  50. String merKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIggpVq2S1JLH0szxurEgVTz4JTpoyO6/YreVP3xl2bcVj8ekVU+GBwLXNhokxOavgY116XxScinFPa/VoWhaVzyLTbvKz5B6yytuRc3OkSqdDj83jCk+mpmJ5UuCRQ3jesaZAxRpPLzLc99sPtD7xnzEd9UWG8Hlnm6ATmmEQhDAgMBAAECgYBPX+nLGRyWYaNfsFM+tVJMfN/pNMqhnPkWLkoUwPhtS/EmYOaRc+GPCLkcnu2Tstk2udKCuk0xqOs6bZs/1DygxzifYUltWFpqQ2gfmDMoOL4GOflXEHIpoSzSinXz8rjjlQU0wgkbNn6wV6Ao4Jxm5Rzmr9mvTKrAwsnY2eZnYQJBAP+Gj3rrJ7s5778jCramS7yLei2ljkHa/7P0MQsJ+B02/V5CFCh6qKZ2aaAQdk6Z7og5f641TrKX76QetDItSgsCQQCIYVdOdkC3+P6r7WYKXEJ8fdIrf2xyhcCAt9I4q+rcID+ZQ+UqzPoBuib/xpgBZVukDpj9BbIyObyStkvQsNWpAkBd6ADQ5pz6ZKdkMiecym6pAwVKwz4Nm8M/Si2/5dEGQ5BH1Lb9zV4vlvLofURNTKrp61+uES8z2TybryEAE77TAkAD8YSbwTGX4DxE7mVf8VD+1oiIN3QET7fEQQx0FQyCdvA/10W+GhU0jZRpGu30RGEE+mMUFeEUMLUyLNE+ZI6ZAkEA2t0rz4UpljOPms3yfxvzFnShBdshFZOy8kZRG/+OL9entaSOJ0gDmfeFBE9oWXwTj8aVasgbrBV1HjNfyb8WfA==";
  51. /**
  52. * 公钥
  53. */
  54. String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIIKVatktSSx9LM8bqxIFU8+CU6aMjuv2K3lT98Zdm3FY/HpFVPhgcC1zYaJMTmr4GNdel8UnIpxT2v1aFoWlc8i027ys+QessrbkXNzpEqnQ4/N4wpPpqZieVLgkUN43rGmQMUaTy8y3PfbD7Q+8Z8xHfVFhvB5Z5ugE5phEIQwIDAQAB";
  55. /**
  56. * 用户编号
  57. */
  58. String merNo = "10002106";
  59. /**
  60. * 公账-专票,子商户商编
  61. */
  62. String publicAccountNo = "20001793";
  63. /**
  64. * 公账-普票,子商户商编
  65. */
  66. String commonInvoiceNo = "20001754";
  67. /**
  68. * 私账-无票,子商户商编
  69. */
  70. String privateAccountNo = "20001924";
  71. /**
  72. * 获取线上支付开关状态
  73. *
  74. * @return
  75. */
  76. @Override
  77. public ResponseJson<Integer> getPayOnLineSwitch() {
  78. Integer status = payOrderMapper.getPayOnLineSwitch();
  79. return ResponseJson.success(status);
  80. }
  81. @Override
  82. public synchronized ResponseJson<JSONObject> pay(PaymentDto payment) {
  83. JSONObject result = null;
  84. OrderVo order = orderMapper.findOrder(payment.getOrderId());
  85. if (null == order) {
  86. return ResponseJson.error("订单不存在", null);
  87. }
  88. if ("0".equals(order.getStatus()) || "33".equals(order.getStatus()) || "4".equals(order.getStatus()) || "5".equals(order.getStatus())
  89. || "6".equals(order.getStatus()) || "7".equals(order.getStatus())) {
  90. return ResponseJson.error("订单状态错误", null);
  91. }
  92. log.info("本次付款金额>>>>>" + payment.getPayAmount());
  93. if (MathUtil.compare(MathUtil.mul(order.getPayableAmount(), 100), payment.getPayAmount()) < 0) {
  94. return ResponseJson.error("付款金额错误", null);
  95. }
  96. try {
  97. // 时间戳
  98. long time = System.currentTimeMillis() / 1000;
  99. JSONObject json = getPayParameter(payment, time);
  100. // 商户订单号
  101. String orderId = order.getOrderNo() + "T" + time;
  102. json.put("orderId", orderId);
  103. //商品名称
  104. String product = "采美订单" + order.getOrderNo();
  105. json.put("product", product);
  106. //支付类型
  107. String payType = getPayType(payment);
  108. String attach = order.getOrderId() + "," + payType;
  109. json.put("attach", attach);
  110. String sign = PayUtils.buildSign(json, merKey);
  111. json.put("sign", sign);
  112. String data = PayUtils.buildDataPrivate(json, merKey);
  113. result = PayUtils.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/order/v1", merAccount, data);
  114. } catch (Exception e) {
  115. log.error("错误信息", e);
  116. return ResponseJson.error("支付失败", null);
  117. }
  118. String code = result.getString("code");
  119. if (!"000000".equals(code)) {
  120. String msg = result.getString("msg");
  121. log.info("第三方支付失败>>>>>>>msg:" + msg);
  122. return ResponseJson.error(msg, null);
  123. }
  124. return ResponseJson.success(result);
  125. }
  126. /**
  127. * 设置第三方支付参数
  128. */
  129. private JSONObject getPayParameter(PaymentDto payment, long time) {
  130. JSONObject json = new JSONObject();
  131. json.put("merAccount", merAccount);
  132. json.put("merNo", merNo);
  133. json.put("time", time);
  134. //支付金额
  135. json.put("amount", payment.getPayAmount());
  136. json.put("payWay", payment.getPayWay());
  137. json.put("payType", payment.getPayType());
  138. json.put("userIp", payment.getClientIp());
  139. json.put("returnUrl", payment.getReturnUrl());
  140. json.put("notifyUrl", payment.getNotifyUrl());
  141. if (StringUtils.isNotBlank(payment.getBankCode())) {
  142. json.put("bankCode", payment.getBankCode());
  143. }
  144. if (StringUtils.isNotBlank(payment.getOpenid())) {
  145. json.put("openId", payment.getOpenid());
  146. }
  147. return json;
  148. }
  149. @Override
  150. @Transactional(rollbackFor = Exception.class)
  151. public String paymentCallback(String data) throws Exception {
  152. //公钥解密
  153. JSONObject json = PayUtils.decryptDataPublic(data, publicKey);
  154. log.info("公钥解密>>>>>>" + json);
  155. //公钥验签
  156. String signaa = json.getString("sign");
  157. json.remove("sign");
  158. String signbb = PayUtils.buildSign(json, publicKey);
  159. if (!signaa.equals(signbb)) {
  160. return "验签失败";
  161. }
  162. //订单状态
  163. String orderStatus = json.getString("orderStatus");
  164. //附加数据,下单时若有传输则原样返回,下单时为空,则不返回该数据
  165. String attach = json.getString("attach");
  166. //平台唯一流水号
  167. String mbOrderId = json.getString("mbOrderId");
  168. //商户唯一订单号
  169. String orderRequestNo = json.getString("orderId");
  170. //订单金额,以元为单位
  171. BigDecimal amount = json.getBigDecimal("amount");
  172. log.info("订单状态>>>>>>" + orderStatus);
  173. if ("FAILED".equals(orderStatus)) {
  174. return "支付失败";
  175. }
  176. String[] split = attach.split(",");
  177. //订单id
  178. Integer orderId = Integer.valueOf(split[0]);
  179. //支付类型
  180. String payType = split[1];
  181. OrderVo order = orderMapper.findOrder(orderId);
  182. //支付记录
  183. List<DiscernReceiptVo> discernReceiptList = payOrderMapper.getDiscernReceipt(order);
  184. BigDecimal receiptAmount = BigDecimal.ZERO;
  185. if (null != discernReceiptList && discernReceiptList.size() > 0) {
  186. for (DiscernReceiptVo discernReceipt : discernReceiptList) {
  187. receiptAmount = receiptAmount.add(discernReceipt.getAssociateAmount());
  188. }
  189. }
  190. //已付金额+本次支付金额
  191. receiptAmount = MathUtil.add(receiptAmount, amount);
  192. log.info("已付金额+本次支付金额>>>>>>>" + receiptAmount);
  193. if (MathUtil.compare(order.getPayableAmount(), receiptAmount) == 0) {
  194. /*
  195. * 订单全部支付
  196. * 0待确认,11待收待发,12待收部发,13待收全发,21部收待发,22部收部发,23部收全发,
  197. * 31已收待发,32已收部发,33已收全发,4交易完成,5订单完成,6已关闭,7交易全退
  198. */
  199. if ("11".equals(order.getStatus()) || "21".equals(order.getStatus())) {
  200. order.setStatus("31");
  201. } else if ("12".equals(order.getStatus()) || "22".equals(order.getStatus())) {
  202. order.setStatus("32");
  203. } else {
  204. order.setStatus("33");
  205. }
  206. order.setPayFlag("1");
  207. order.setOnlinePayFlag("0");
  208. //(收款买家)收款状态:1待收款、2部分收款、3已收款
  209. order.setReceiptStatus("3");
  210. log.info("订单全部支付,修改订单状态>>>>>>" + order.getStatus());
  211. /*
  212. * 保存好友消费券赠送记录
  213. */
  214. CouponSharePo couponShare = couponMapper.getCouponShareId(order.getUserId());
  215. if (null != couponShare) {
  216. List<Integer> couponIds = couponMapper.getCurrentCouponIds(5);
  217. couponIds.forEach(couponId->{
  218. couponShare.setShareCouponId(couponId);
  219. couponMapper.insertCouponShare(couponShare);
  220. BigDecimal couponAmount = couponMapper.getCouponAmount(couponId);
  221. HashMap<String, Object> map = new HashMap<>();
  222. String mobile = couponMapper.getUserMobile(couponShare.getShareUserId());
  223. String content = "恭喜您邀请的好友已成功消费一笔订单,现赠送" + couponAmount + "元优惠券到您的领券中心,请赶紧登录呵呵商城小程序领取下单吧。退订回T";
  224. map.put("type", 3);
  225. map.put("mobile", mobile);
  226. map.put("content", content);
  227. String url = userUrl + "/tools/sms/send";
  228. try {
  229. String result = HttpRequest.sendPost(url, map);
  230. log.info("【呵呵好友消费券派送】mobile:" + mobile + ",result:" + result);
  231. // 保存短信发送条数+count
  232. couponMapper.updateSmsSendCount(19, 1);
  233. } catch (Exception e) {
  234. e.printStackTrace();
  235. }
  236. });
  237. }
  238. // 拼团数据更新
  239. CmHeheCollagePo collage = collageMapper.getCollageByOrderId(orderId);
  240. if (null != collage) {
  241. if (1 == collage.getLaunchFlag()) {
  242. // 拼团发起人支付订单,正式建立拼团
  243. collage.setStatus(1);
  244. Date startTime = new Date();
  245. collage.setStartTime(startTime);
  246. Calendar calendar = Calendar.getInstance();
  247. calendar.setTime(startTime);
  248. calendar.add(Calendar.DAY_OF_MONTH, 1);
  249. collage.setEndTime(calendar.getTime());
  250. collageMapper.createCollage(collage);
  251. } else {
  252. // 已拼且已支付人数
  253. Integer memberNum = collageMapper.findCollageMemberNum(collage.getId());
  254. if (memberNum + 1 == collage.getMemberNum()) {
  255. // 拼团成功
  256. collage.setStatus(2);
  257. collage.setCompleteTime(new Date());
  258. collageMapper.completeCollage(collage);
  259. // 关闭其它未支付拼团订单
  260. List<Integer> orderIdList = collageMapper.findNoPayCollageOrderIds(collage.getId());
  261. orderIdList.forEach(noPayOrderId->{
  262. orderMapper.cancelOrder(noPayOrderId, "拼团完成关闭其它未支付拼团订单");
  263. });
  264. }
  265. }
  266. }
  267. } else {
  268. //部分支付
  269. if ("11".equals(order.getStatus()) || "21".equals(order.getStatus())) {
  270. order.setStatus("21");
  271. } else if ("12".equals(order.getStatus()) || "22".equals(order.getStatus())) {
  272. order.setStatus("22");
  273. } else {
  274. order.setStatus("23");
  275. }
  276. order.setOnlinePayFlag("0");
  277. //(收款买家)收款状态:1待收款、2部分收款、3已收款
  278. order.setReceiptStatus("2");
  279. }
  280. //更新付款次数
  281. order.setPaySuccessCounter(order.getPaySuccessCounter() + 1);
  282. payOrderMapper.updateSelective(order);
  283. //保存收款记录
  284. String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
  285. CmDiscernReceiptPo discernReceipt = new CmDiscernReceiptPo();
  286. discernReceipt.setPayWay("1");
  287. discernReceipt.setPayType(payType);
  288. discernReceipt.setReceiptType("1");
  289. discernReceipt.setReceiptStatus("3");
  290. discernReceipt.setReceiptAmount(amount);
  291. discernReceipt.setConfirmType("4");
  292. discernReceipt.setRePayFlag("1");
  293. discernReceipt.setFormData(json.toJSONString());
  294. discernReceipt.setReceiptDate(curDateStr);
  295. discernReceipt.setConfirmDate(curDateStr);
  296. discernReceipt.setReviewDate(curDateStr);
  297. discernReceipt.setUpdateDate(curDateStr);
  298. discernReceipt.setDelFlag("0");
  299. payOrderMapper.insertDiscernReceipt(discernReceipt);
  300. CmReceiptOrderRelationPo relation = new CmReceiptOrderRelationPo();
  301. relation.setReceiptID(discernReceipt.getId().intValue());
  302. relation.setOrderID(order.getOrderId());
  303. relation.setAssociateAmount(amount);
  304. relation.setRelationType("2");
  305. relation.setMbOrderId(mbOrderId);
  306. relation.setOrderRequestNo(orderRequestNo);
  307. relation.setDelFlag("0");
  308. relation.setSplitStatus("0");
  309. payOrderMapper.insertOrderRelation(relation);
  310. log.info(">>>>>>>>>>>>>>>>>>>>>>>保存付款金额到收款记录," + amount);
  311. return "SUCCESS";
  312. }
  313. /**
  314. * 支付状态转换
  315. */
  316. private String getPayType(PaymentDto payment) {
  317. String payType = payment.getPayType();
  318. if ("ALIPAY_H5".equals(payType)) {
  319. //支付宝H5
  320. return "14";
  321. } else if ("JSAPI_WEIXIN".equals(payType)) {
  322. //微信公众号支付
  323. return "13";
  324. } else if ("MINIAPP_WEIXIN".equals(payType)) {
  325. //微信小程序支付
  326. return "15";
  327. } else if ("GATEWAY_UNIONPAY".equals(payType) && "ENTERPRISE".equals(payment.getUserType())) {
  328. //企业网银
  329. return "12";
  330. } else {
  331. //个人网银
  332. return "17";
  333. }
  334. }
  335. @Override
  336. public ResponseJson<String> payWhetherSuccess(Integer orderId, Integer paySuccessCounter) {
  337. OrderVo order = orderMapper.findOrder(orderId);
  338. if (order.getPaySuccessCounter().equals(paySuccessCounter)) {
  339. return ResponseJson.error(-2, "支付失败", null);
  340. } else if (order.getPaySuccessCounter() > paySuccessCounter) {
  341. return ResponseJson.success("支付成功");
  342. } else {
  343. return ResponseJson.error("支付异常>>>>>>>" + order, null);
  344. }
  345. }
  346. @Override
  347. public ResponseJson<JSONObject> findOrderStatus(String mbOrderId) {
  348. // 时间戳
  349. long time = System.currentTimeMillis() / 1000;
  350. JSONObject json = new JSONObject();
  351. json.put("merAccount", merAccount);
  352. json.put("mbOrderId", mbOrderId);
  353. json.put("time", time);
  354. String sign = PayUtils.buildSign(json, merKey);
  355. json.put("sign", sign);
  356. String data = "";
  357. try {
  358. data = PayUtils.buildDataPrivate(json, merKey);
  359. } catch (Exception e) {
  360. log.error("错误信息", e);
  361. }
  362. JSONObject result = PayUtils.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/order/query/v1_1", merAccount, data);
  363. String code = result.getString("code");
  364. if (!"000000".equals(code)) {
  365. String msg = result.getString("msg");
  366. log.info("第三方查询订单失败>>>>>>>msg:" + msg);
  367. return ResponseJson.error(msg, null);
  368. }
  369. return ResponseJson.success(result);
  370. }
  371. @Override
  372. public void delayedSplitting() {
  373. log.info("延时分账,每一小时执行一次");
  374. Calendar calendar = Calendar.getInstance();
  375. calendar.setTime(new Date());
  376. calendar.add(Calendar.DAY_OF_MONTH, -1);
  377. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  378. String currentTime = format.format(calendar.getTime());
  379. List<CmReceiptOrderRelationPo> orderRelations = payOrderMapper.findUnallocatedAccount(currentTime);
  380. if (orderRelations != null && orderRelations.size() > 0) {
  381. for (CmReceiptOrderRelationPo orderRelation : orderRelations) {
  382. log.info("订单id" + orderRelation.getOrderID() + ">>>进入延时分账");
  383. OrderVo order = orderMapper.findOrder(orderRelation.getOrderID());
  384. PaymentDto payment = new PaymentDto();
  385. payment.setPayAmount(MathUtil.mul(orderRelation.getAssociateAmount(), 100).intValue());
  386. List<SplitAccountVo> splitBillDetail = splitBillDetail(order, payment);
  387. String parameters = ledgerParameters(splitBillDetail, order.getOrderId());
  388. log.info("分账参数: " + parameters);
  389. //第三方分账接口
  390. JSONObject result = null;
  391. try {
  392. // 时间戳
  393. long time = System.currentTimeMillis() / 1000;
  394. JSONObject json = new JSONObject();
  395. json.put("merAccount", merAccount);
  396. json.put("orderId", orderRelation.getOrderRequestNo());
  397. json.put("requestNo", orderRelation.getOrderRequestNo());
  398. json.put("mbOrderId", orderRelation.getMbOrderId());
  399. json.put("time", time);
  400. json.put("splitBillDetail", parameters);
  401. json.put("notifyUrl", delayedSplittingUrl);
  402. log.info("回调接口>>>" + delayedSplittingUrl);
  403. String sign = PayUtils.buildSign(json, merKey);
  404. json.put("sign", sign);
  405. String data = PayUtils.buildDataPrivate(json, merKey);
  406. result = PayUtils.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/splitOrder/v1", merAccount, data);
  407. } catch (Exception e) {
  408. log.error("错误信息", e);
  409. }
  410. if (result != null) {
  411. String code = result.getString("code");
  412. if (!"000000".equals(code)) {
  413. String msg = result.getString("msg");
  414. log.info("第三方延迟分账失败>>>>>>>msg:" + msg);
  415. } else {
  416. //保存分账记录
  417. for (SplitAccountVo splitAccount : splitBillDetail) {
  418. splitAccount.setMbOrderId(orderRelation.getMbOrderId());
  419. splitAccount.setOrderRequestNo(orderRelation.getOrderRequestNo());
  420. splitAccount.setPayStatus("1");
  421. payOrderMapper.insertSplitAccount(splitAccount);
  422. }
  423. log.info("此订单分账结束");
  424. }
  425. }
  426. }
  427. }
  428. }
  429. @Override
  430. public String delayedSplittingCallback(String data) {
  431. try {
  432. //公钥解密
  433. JSONObject json = PayUtils.decryptDataPublic(data, publicKey);
  434. log.info("公钥解密>>>>>>" + json);
  435. //公钥验签
  436. String signaa = json.getString("sign");
  437. json.remove("sign");
  438. String signbb = PayUtils.buildSign(json, publicKey);
  439. if (!signaa.equals(signbb)) {
  440. return "验签失败";
  441. }
  442. String mbOrderId = json.getString("mbOrderId");
  443. String status = json.getString("status");
  444. log.info("分账状态>>>" + status);
  445. if ("FAILED".equals(status)) {
  446. return "分账失败";
  447. }
  448. //修改收款分账状态
  449. payOrderMapper.updateBySplitStatus(mbOrderId);
  450. Integer orderId = null;
  451. List<SplitAccountVo> splitAccountList = payOrderMapper.findByMbOrderId(mbOrderId);
  452. if (splitAccountList != null && splitAccountList.size() > 0) {
  453. Integer shopOrderId = null;
  454. String shopOrderNo = "";
  455. for (SplitAccountVo account : splitAccountList) {
  456. log.info("保存应付付供应商>>>>" + account.getShopId());
  457. //本次付供应商金额(分账金额)
  458. BigDecimal splitAmount = account.getSplitAccount();
  459. orderId = account.getOrderId();
  460. Integer shopId = account.getShopId();
  461. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  462. String payStatus = "";
  463. for (ShopOrderVo shopOrder : shopOrderList) {
  464. if (shopId.equals(shopOrder.getShopId())) {
  465. shopOrderId = shopOrder.getShopOrderId();
  466. shopOrderNo = shopOrder.getShopOrderNo();
  467. //已付供应商金额
  468. BigDecimal paidAmount = payOrderMapper.findPaidShop(shopOrderId);
  469. BigDecimal paidShop = MathUtil.add(paidAmount, splitAmount);
  470. if (MathUtil.compare(shopOrder.getShouldPayShopAmount(), paidShop) == 0) {
  471. payStatus = "3";
  472. } else {
  473. payStatus = "2";
  474. }
  475. //修改子订单付款状态及付款金额
  476. payOrderMapper.updateShopOrderByPayStatus(shopOrderId, paidShop, payStatus);
  477. }
  478. }
  479. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  480. String currentTime = format.format(new Date());
  481. //保存付供应商记录
  482. CmPayShopPo payShop = new CmPayShopPo();
  483. payShop.setShopID(shopId);
  484. payShop.setName("线上支付分账");
  485. payShop.setTotalAmount(splitAmount);
  486. payShop.setWipePayment(BigDecimal.ZERO);
  487. payShop.setPayType("6");
  488. payShop.setStatus("1");
  489. payShop.setDelFlag("0");
  490. payShop.setApplyTime(currentTime);
  491. payShop.setReviewTime(currentTime);
  492. payShop.setPayTime(currentTime);
  493. payOrderMapper.insertPayShop(payShop);
  494. CmPayShopRecordPo shopRecord = new CmPayShopRecordPo();
  495. shopRecord.setShopID(shopId);
  496. shopRecord.setShopOrderID(shopOrderId);
  497. shopRecord.setShopOrderNo(shopOrderNo);
  498. shopRecord.setPayAmount(splitAmount);
  499. shopRecord.setWipePayment(BigDecimal.ZERO);
  500. shopRecord.setPayType("6");
  501. shopRecord.setPayTime(currentTime);
  502. shopRecord.setPayShopID(payShop.getId().intValue());
  503. shopRecord.setStatus("1");
  504. shopRecord.setDelFlag("0");
  505. payOrderMapper.insertPayShopRecord(shopRecord);
  506. }
  507. //修改主订单付款状态
  508. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  509. //子订单是否全部付款
  510. boolean isPay = true;
  511. for (ShopOrderVo shopOrder : shopOrderList) {
  512. if (!"3".equals(shopOrder.getPayStatus())) {
  513. isPay = false;
  514. }
  515. }
  516. if (isPay) {
  517. payOrderMapper.updateOrderByPayStatus(orderId, "3");
  518. } else {
  519. payOrderMapper.updateOrderByPayStatus(orderId, "2");
  520. }
  521. }
  522. } catch (Exception e) {
  523. log.error("分账异步通知异常", e);
  524. return "分账失败";
  525. }
  526. return "SUCCESS";
  527. }
  528. /**
  529. * 分账详情
  530. */
  531. private List<SplitAccountVo> splitBillDetail(OrderVo order, PaymentDto payment) {
  532. List<SplitAccountVo> list = new ArrayList<>();
  533. //本次支付金额,单位/元
  534. BigDecimal payAmount = MathUtil.div(payment.getPayAmount(), 100);
  535. //待分账总金额
  536. BigDecimal splitAmount = payAmount;
  537. //总手续费
  538. BigDecimal procedureFee = BigDecimal.ZERO;
  539. //手续费
  540. procedureFee = MathUtil.mul(payAmount, 0.0038, 2);
  541. if (MathUtil.compare(procedureFee, 0) == 0) {
  542. procedureFee = new BigDecimal("0.01");
  543. }
  544. splitAmount = MathUtil.sub(splitAmount, procedureFee);
  545. List<OrderProductVo> orderProductList = payOrderMapper.findAllOrderProduct(order.getOrderId());
  546. for (OrderProductVo orderProduct : orderProductList) {
  547. BigDecimal costPrice = MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum());
  548. //不含税能开发票
  549. if ("0".equals(orderProduct.getIncludedTax()) && !"3".equals(orderProduct.getInvoiceType())) {
  550. //应付总税费
  551. BigDecimal payableTax = MathUtil.mul(orderProduct.getSingleShouldPayTotalTax(), orderProduct.getNum());
  552. costPrice = MathUtil.add(costPrice, payableTax);
  553. }
  554. //判断是否支付过
  555. BigDecimal paidAmount = payOrderMapper.findPaidAmount(orderProduct.getOrderProductId());
  556. if (paidAmount == null || MathUtil.compare(paidAmount, costPrice) < 0) {
  557. if (paidAmount != null && MathUtil.compare(paidAmount, 0) > 0) {
  558. costPrice = MathUtil.sub(costPrice, paidAmount);
  559. }
  560. //待分账金额>=本次待分账金额
  561. if (MathUtil.compare(splitAmount, costPrice) > -1) {
  562. splitAmount = MathUtil.sub(splitAmount, costPrice);
  563. } else {
  564. costPrice = splitAmount;
  565. splitAmount = BigDecimal.ZERO;
  566. }
  567. String commercialCode = payOrderMapper.findCommercialCode(orderProduct.getShopId());
  568. SplitAccountVo splitAccount = new SplitAccountVo();
  569. splitAccount.setOrderId(order.getOrderId());
  570. splitAccount.setOrderProductId(orderProduct.getOrderProductId());
  571. splitAccount.setShopId(orderProduct.getShopId().intValue());
  572. splitAccount.setSplitAccount(costPrice);
  573. splitAccount.setProductType("1");
  574. if (StringUtils.isNotBlank(commercialCode)) {
  575. //供应商拥有子商户号
  576. splitAccount.setType("4");
  577. splitAccount.setSubUserNo(commercialCode);
  578. } else {
  579. if ("3".equals(orderProduct.getInvoiceType())) {
  580. //不能开票,则分账到私账-无票
  581. splitAccount.setType("2");
  582. splitAccount.setSubUserNo(privateAccountNo);
  583. } else if ("1".equals(orderProduct.getInvoiceType())) {
  584. //开增值税发票,则分账到公账-专票
  585. splitAccount.setType("1");
  586. splitAccount.setSubUserNo(publicAccountNo);
  587. } else if ("2".equals(orderProduct.getInvoiceType())) {
  588. //开普通发票,则分账到公账-普票
  589. splitAccount.setType("3");
  590. splitAccount.setSubUserNo(commonInvoiceNo);
  591. }
  592. }
  593. log.info("分账详情(成本):" + splitAccount);
  594. list.add(splitAccount);
  595. if (MathUtil.compare(splitAmount, 0) == 0) {
  596. break;
  597. }
  598. }
  599. }
  600. //付供应商运费,是以供应商为单位的
  601. if (MathUtil.compare(splitAmount, 0) > 0) {
  602. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(order.getOrderId());
  603. for (ShopOrderVo shopOrder : shopOrderList) {
  604. //运费
  605. BigDecimal shopPostFee = shopOrder.getShopPostFee();
  606. if (MathUtil.compare(shopPostFee, 0) > 0) {
  607. BigDecimal shipping = payOrderMapper.findShipping(order.getOrderId(), shopOrder.getShopId());
  608. shopPostFee = MathUtil.sub(shopPostFee, shipping);
  609. if (MathUtil.compare(splitAmount, shopPostFee) > -1) {
  610. splitAmount = MathUtil.sub(splitAmount, shopPostFee);
  611. } else {
  612. shopPostFee = splitAmount;
  613. splitAmount = BigDecimal.ZERO;
  614. }
  615. String commercialCode = payOrderMapper.findCommercialCode(Long.valueOf(shopOrder.getShopId()));
  616. SplitAccountVo splitAccount = new SplitAccountVo();
  617. splitAccount.setOrderId(order.getOrderId());
  618. splitAccount.setShopId(shopOrder.getShopId());
  619. splitAccount.setSplitAccount(shopPostFee);
  620. splitAccount.setProductType("2");
  621. if (StringUtils.isNotBlank(commercialCode)) {
  622. //供应商拥有子商户号
  623. splitAccount.setType("4");
  624. splitAccount.setSubUserNo(commercialCode);
  625. } else {
  626. //私账
  627. splitAccount.setType("2");
  628. splitAccount.setSubUserNo(privateAccountNo);
  629. }
  630. log.info("分账详情(付供应商运费):" + splitAccount);
  631. list.add(splitAccount);
  632. }
  633. }
  634. }
  635. //佣金,公账
  636. if (MathUtil.compare(splitAmount, 0) > 0) {
  637. SplitAccountVo splitAccount = new SplitAccountVo();
  638. splitAccount.setOrderId(order.getOrderId());
  639. splitAccount.setSplitAccount(splitAmount);
  640. splitAccount.setProductType("3");
  641. splitAccount.setType("1");
  642. splitAccount.setSubUserNo(publicAccountNo);
  643. log.info("分账详情(佣金):" + splitAccount);
  644. list.add(splitAccount);
  645. }
  646. return list;
  647. }
  648. /**
  649. * 整理第三方支付详情参数
  650. */
  651. private String ledgerParameters(List<SplitAccountVo> splitBillDetail, Integer orderId) {
  652. List<Map<String, String>> maps = new ArrayList<>();
  653. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  654. //供应商子商户总金额
  655. for (ShopOrderVo shopOrder : shopOrderList) {
  656. BigDecimal shopTotalAmount = BigDecimal.ZERO;
  657. String subUserNo = "";
  658. for (SplitAccountVo account : splitBillDetail) {
  659. if ("4".equals(account.getType()) && shopOrder.getShopId().equals(account.getShopId())) {
  660. shopTotalAmount = MathUtil.add(shopTotalAmount, account.getSplitAccount());
  661. subUserNo = account.getSubUserNo();
  662. }
  663. }
  664. addMaps(maps, shopTotalAmount, subUserNo);
  665. }
  666. //公账-专票总金额,私账-无票总金额,公账-普票总金额
  667. BigDecimal totalAmount1 = BigDecimal.ZERO;
  668. BigDecimal totalAmount2 = BigDecimal.ZERO;
  669. BigDecimal totalAmount3 = BigDecimal.ZERO;
  670. for (SplitAccountVo account : splitBillDetail) {
  671. if ("1".equals(account.getType())) {
  672. totalAmount1 = MathUtil.add(totalAmount1, account.getSplitAccount());
  673. } else if ("2".equals(account.getType())) {
  674. totalAmount2 = MathUtil.add(totalAmount2, account.getSplitAccount());
  675. } else if ("3".equals(account.getType())) {
  676. totalAmount3 = MathUtil.add(totalAmount3, account.getSplitAccount());
  677. }
  678. }
  679. addMaps(maps, totalAmount1, publicAccountNo);
  680. addMaps(maps, totalAmount2, privateAccountNo);
  681. addMaps(maps, totalAmount3, commonInvoiceNo);
  682. return JSON.toJSONString(maps);
  683. }
  684. private void addMaps(List<Map<String, String>> maps, BigDecimal shopTotalAmount, String subUserNo) {
  685. if (MathUtil.compare(shopTotalAmount, 0) > 0) {
  686. Map<String, String> map = new HashMap<>(3);
  687. map.put("subUserNo", subUserNo);
  688. map.put("splitBillType", "2");
  689. map.put("splitBillValue", MathUtil.mul(shopTotalAmount, 100).toString());
  690. maps.add(map);
  691. }
  692. }
  693. }