PayOrderServiceImpl.java 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  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. HashMap<String, Object> map = new HashMap<>();
  265. String mobile = collageMapper.getUserMobileByOrderId(orderId);
  266. List<String> mobileList = collageMapper.getMobilesByCollageId(collage.getId());
  267. mobileList.add(mobile);
  268. String content = "您的商品已拼团成功,请赶紧登录颜选美学小程序查看订单吧。";
  269. map.put("type", 1);
  270. map.put("content", content);
  271. String url = userUrl + "/tools/sms/send";
  272. try {
  273. for (String userMobile : mobileList) {
  274. map.put("mobile", userMobile);
  275. String result = HttpRequest.sendPost(url, map);
  276. log.info("【呵呵拼团成功短信派送】mobile:" + mobile + ",result:" + result);
  277. }
  278. } catch (Exception e) {
  279. e.printStackTrace();
  280. }
  281. }
  282. }
  283. }
  284. } else {
  285. //部分支付
  286. if ("11".equals(order.getStatus()) || "21".equals(order.getStatus())) {
  287. order.setStatus("21");
  288. } else if ("12".equals(order.getStatus()) || "22".equals(order.getStatus())) {
  289. order.setStatus("22");
  290. } else {
  291. order.setStatus("23");
  292. }
  293. order.setOnlinePayFlag("0");
  294. //(收款买家)收款状态:1待收款、2部分收款、3已收款
  295. order.setReceiptStatus("2");
  296. }
  297. //更新付款次数
  298. order.setPaySuccessCounter(order.getPaySuccessCounter() + 1);
  299. payOrderMapper.updateSelective(order);
  300. //保存收款记录
  301. String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
  302. CmDiscernReceiptPo discernReceipt = new CmDiscernReceiptPo();
  303. discernReceipt.setPayWay("1");
  304. discernReceipt.setPayType(payType);
  305. discernReceipt.setReceiptType("1");
  306. discernReceipt.setReceiptStatus("3");
  307. discernReceipt.setReceiptAmount(amount);
  308. discernReceipt.setConfirmType("4");
  309. discernReceipt.setRePayFlag("1");
  310. discernReceipt.setFormData(json.toJSONString());
  311. discernReceipt.setReceiptDate(curDateStr);
  312. discernReceipt.setConfirmDate(curDateStr);
  313. discernReceipt.setReviewDate(curDateStr);
  314. discernReceipt.setUpdateDate(curDateStr);
  315. discernReceipt.setDelFlag("0");
  316. payOrderMapper.insertDiscernReceipt(discernReceipt);
  317. CmReceiptOrderRelationPo relation = new CmReceiptOrderRelationPo();
  318. relation.setReceiptID(discernReceipt.getId().intValue());
  319. relation.setOrderID(order.getOrderId());
  320. relation.setAssociateAmount(amount);
  321. relation.setRelationType("2");
  322. relation.setMbOrderId(mbOrderId);
  323. relation.setOrderRequestNo(orderRequestNo);
  324. relation.setDelFlag("0");
  325. relation.setSplitStatus("0");
  326. payOrderMapper.insertOrderRelation(relation);
  327. log.info(">>>>>>>>>>>>>>>>>>>>>>>保存付款金额到收款记录," + amount);
  328. return "SUCCESS";
  329. }
  330. /**
  331. * 支付状态转换
  332. */
  333. private String getPayType(PaymentDto payment) {
  334. String payType = payment.getPayType();
  335. if ("ALIPAY_H5".equals(payType)) {
  336. //支付宝H5
  337. return "14";
  338. } else if ("JSAPI_WEIXIN".equals(payType)) {
  339. //微信公众号支付
  340. return "13";
  341. } else if ("MINIAPP_WEIXIN".equals(payType)) {
  342. //微信小程序支付
  343. return "15";
  344. } else if ("GATEWAY_UNIONPAY".equals(payType) && "ENTERPRISE".equals(payment.getUserType())) {
  345. //企业网银
  346. return "12";
  347. } else {
  348. //个人网银
  349. return "17";
  350. }
  351. }
  352. @Override
  353. public ResponseJson<String> payWhetherSuccess(Integer orderId, Integer paySuccessCounter) {
  354. OrderVo order = orderMapper.findOrder(orderId);
  355. if (order.getPaySuccessCounter().equals(paySuccessCounter)) {
  356. return ResponseJson.error(-2, "支付失败", null);
  357. } else if (order.getPaySuccessCounter() > paySuccessCounter) {
  358. return ResponseJson.success("支付成功");
  359. } else {
  360. return ResponseJson.error("支付异常>>>>>>>" + order, null);
  361. }
  362. }
  363. @Override
  364. public ResponseJson<JSONObject> findOrderStatus(String mbOrderId) {
  365. // 时间戳
  366. long time = System.currentTimeMillis() / 1000;
  367. JSONObject json = new JSONObject();
  368. json.put("merAccount", merAccount);
  369. json.put("mbOrderId", mbOrderId);
  370. json.put("time", time);
  371. String sign = PayUtils.buildSign(json, merKey);
  372. json.put("sign", sign);
  373. String data = "";
  374. try {
  375. data = PayUtils.buildDataPrivate(json, merKey);
  376. } catch (Exception e) {
  377. log.error("错误信息", e);
  378. }
  379. JSONObject result = PayUtils.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/order/query/v1_1", merAccount, data);
  380. String code = result.getString("code");
  381. if (!"000000".equals(code)) {
  382. String msg = result.getString("msg");
  383. log.info("第三方查询订单失败>>>>>>>msg:" + msg);
  384. return ResponseJson.error(msg, null);
  385. }
  386. return ResponseJson.success(result);
  387. }
  388. @Override
  389. public void delayedSplitting() {
  390. log.info("延时分账,每一小时执行一次");
  391. Calendar calendar = Calendar.getInstance();
  392. calendar.setTime(new Date());
  393. calendar.add(Calendar.DAY_OF_MONTH, -1);
  394. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  395. String currentTime = format.format(calendar.getTime());
  396. List<CmReceiptOrderRelationPo> orderRelations = payOrderMapper.findUnallocatedAccount(currentTime);
  397. if (orderRelations != null && orderRelations.size() > 0) {
  398. for (CmReceiptOrderRelationPo orderRelation : orderRelations) {
  399. log.info("订单id" + orderRelation.getOrderID() + ">>>进入延时分账");
  400. OrderVo order = orderMapper.findOrder(orderRelation.getOrderID());
  401. PaymentDto payment = new PaymentDto();
  402. payment.setPayAmount(MathUtil.mul(orderRelation.getAssociateAmount(), 100).intValue());
  403. List<SplitAccountVo> splitBillDetail = splitBillDetail(order, payment);
  404. String parameters = ledgerParameters(splitBillDetail, order.getOrderId());
  405. log.info("分账参数: " + parameters);
  406. //第三方分账接口
  407. JSONObject result = null;
  408. try {
  409. // 时间戳
  410. long time = System.currentTimeMillis() / 1000;
  411. JSONObject json = new JSONObject();
  412. json.put("merAccount", merAccount);
  413. json.put("orderId", orderRelation.getOrderRequestNo());
  414. json.put("requestNo", orderRelation.getOrderRequestNo());
  415. json.put("mbOrderId", orderRelation.getMbOrderId());
  416. json.put("time", time);
  417. json.put("splitBillDetail", parameters);
  418. json.put("notifyUrl", delayedSplittingUrl);
  419. log.info("回调接口>>>" + delayedSplittingUrl);
  420. String sign = PayUtils.buildSign(json, merKey);
  421. json.put("sign", sign);
  422. String data = PayUtils.buildDataPrivate(json, merKey);
  423. result = PayUtils.httpGet("https://platform.mhxxkj.com/paygateway/mbpay/splitOrder/v1", merAccount, data);
  424. } catch (Exception e) {
  425. log.error("错误信息", e);
  426. }
  427. if (result != null) {
  428. String code = result.getString("code");
  429. if (!"000000".equals(code)) {
  430. String msg = result.getString("msg");
  431. log.info("第三方延迟分账失败>>>>>>>msg:" + msg);
  432. } else {
  433. //保存分账记录
  434. for (SplitAccountVo splitAccount : splitBillDetail) {
  435. splitAccount.setMbOrderId(orderRelation.getMbOrderId());
  436. splitAccount.setOrderRequestNo(orderRelation.getOrderRequestNo());
  437. splitAccount.setPayStatus("1");
  438. payOrderMapper.insertSplitAccount(splitAccount);
  439. }
  440. log.info("此订单分账结束");
  441. }
  442. }
  443. }
  444. }
  445. }
  446. @Override
  447. public String delayedSplittingCallback(String data) {
  448. try {
  449. //公钥解密
  450. JSONObject json = PayUtils.decryptDataPublic(data, publicKey);
  451. log.info("公钥解密>>>>>>" + json);
  452. //公钥验签
  453. String signaa = json.getString("sign");
  454. json.remove("sign");
  455. String signbb = PayUtils.buildSign(json, publicKey);
  456. if (!signaa.equals(signbb)) {
  457. return "验签失败";
  458. }
  459. String mbOrderId = json.getString("mbOrderId");
  460. String status = json.getString("status");
  461. log.info("分账状态>>>" + status);
  462. if ("FAILED".equals(status)) {
  463. return "分账失败";
  464. }
  465. //修改收款分账状态
  466. payOrderMapper.updateBySplitStatus(mbOrderId);
  467. Integer orderId = null;
  468. List<SplitAccountVo> splitAccountList = payOrderMapper.findByMbOrderId(mbOrderId);
  469. if (splitAccountList != null && splitAccountList.size() > 0) {
  470. Integer shopOrderId = null;
  471. String shopOrderNo = "";
  472. for (SplitAccountVo account : splitAccountList) {
  473. log.info("保存应付付供应商>>>>" + account.getShopId());
  474. //本次付供应商金额(分账金额)
  475. BigDecimal splitAmount = account.getSplitAccount();
  476. orderId = account.getOrderId();
  477. Integer shopId = account.getShopId();
  478. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  479. String payStatus = "";
  480. for (ShopOrderVo shopOrder : shopOrderList) {
  481. if (shopId.equals(shopOrder.getShopId())) {
  482. shopOrderId = shopOrder.getShopOrderId();
  483. shopOrderNo = shopOrder.getShopOrderNo();
  484. //已付供应商金额
  485. BigDecimal paidAmount = payOrderMapper.findPaidShop(shopOrderId);
  486. BigDecimal paidShop = MathUtil.add(paidAmount, splitAmount);
  487. if (MathUtil.compare(shopOrder.getShouldPayShopAmount(), paidShop) == 0) {
  488. payStatus = "3";
  489. } else {
  490. payStatus = "2";
  491. }
  492. //修改子订单付款状态及付款金额
  493. payOrderMapper.updateShopOrderByPayStatus(shopOrderId, paidShop, payStatus);
  494. }
  495. }
  496. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  497. String currentTime = format.format(new Date());
  498. //保存付供应商记录
  499. CmPayShopPo payShop = new CmPayShopPo();
  500. payShop.setShopID(shopId);
  501. payShop.setName("线上支付分账");
  502. payShop.setTotalAmount(splitAmount);
  503. payShop.setWipePayment(BigDecimal.ZERO);
  504. payShop.setPayType("6");
  505. payShop.setStatus("1");
  506. payShop.setDelFlag("0");
  507. payShop.setApplyTime(currentTime);
  508. payShop.setReviewTime(currentTime);
  509. payShop.setPayTime(currentTime);
  510. payOrderMapper.insertPayShop(payShop);
  511. CmPayShopRecordPo shopRecord = new CmPayShopRecordPo();
  512. shopRecord.setShopID(shopId);
  513. shopRecord.setShopOrderID(shopOrderId);
  514. shopRecord.setShopOrderNo(shopOrderNo);
  515. shopRecord.setPayAmount(splitAmount);
  516. shopRecord.setWipePayment(BigDecimal.ZERO);
  517. shopRecord.setPayType("6");
  518. shopRecord.setPayTime(currentTime);
  519. shopRecord.setPayShopID(payShop.getId().intValue());
  520. shopRecord.setStatus("1");
  521. shopRecord.setDelFlag("0");
  522. payOrderMapper.insertPayShopRecord(shopRecord);
  523. }
  524. //修改主订单付款状态
  525. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  526. //子订单是否全部付款
  527. boolean isPay = true;
  528. for (ShopOrderVo shopOrder : shopOrderList) {
  529. if (!"3".equals(shopOrder.getPayStatus())) {
  530. isPay = false;
  531. }
  532. }
  533. if (isPay) {
  534. payOrderMapper.updateOrderByPayStatus(orderId, "3");
  535. } else {
  536. payOrderMapper.updateOrderByPayStatus(orderId, "2");
  537. }
  538. }
  539. } catch (Exception e) {
  540. log.error("分账异步通知异常", e);
  541. return "分账失败";
  542. }
  543. return "SUCCESS";
  544. }
  545. /**
  546. * 分账详情
  547. */
  548. private List<SplitAccountVo> splitBillDetail(OrderVo order, PaymentDto payment) {
  549. List<SplitAccountVo> list = new ArrayList<>();
  550. //本次支付金额,单位/元
  551. BigDecimal payAmount = MathUtil.div(payment.getPayAmount(), 100);
  552. //待分账总金额
  553. BigDecimal splitAmount = payAmount;
  554. //总手续费
  555. BigDecimal procedureFee = BigDecimal.ZERO;
  556. //手续费
  557. procedureFee = MathUtil.mul(payAmount, 0.0038, 2);
  558. if (MathUtil.compare(procedureFee, 0) == 0) {
  559. procedureFee = new BigDecimal("0.01");
  560. }
  561. splitAmount = MathUtil.sub(splitAmount, procedureFee);
  562. List<OrderProductVo> orderProductList = payOrderMapper.findAllOrderProduct(order.getOrderId());
  563. for (OrderProductVo orderProduct : orderProductList) {
  564. BigDecimal costPrice = MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum());
  565. //不含税能开发票
  566. if ("0".equals(orderProduct.getIncludedTax()) && !"3".equals(orderProduct.getInvoiceType())) {
  567. //应付总税费
  568. BigDecimal payableTax = MathUtil.mul(orderProduct.getSingleShouldPayTotalTax(), orderProduct.getNum());
  569. costPrice = MathUtil.add(costPrice, payableTax);
  570. }
  571. //判断是否支付过
  572. BigDecimal paidAmount = payOrderMapper.findPaidAmount(orderProduct.getOrderProductId());
  573. if (paidAmount == null || MathUtil.compare(paidAmount, costPrice) < 0) {
  574. if (paidAmount != null && MathUtil.compare(paidAmount, 0) > 0) {
  575. costPrice = MathUtil.sub(costPrice, paidAmount);
  576. }
  577. //待分账金额>=本次待分账金额
  578. if (MathUtil.compare(splitAmount, costPrice) > -1) {
  579. splitAmount = MathUtil.sub(splitAmount, costPrice);
  580. } else {
  581. costPrice = splitAmount;
  582. splitAmount = BigDecimal.ZERO;
  583. }
  584. String commercialCode = payOrderMapper.findCommercialCode(orderProduct.getShopId());
  585. SplitAccountVo splitAccount = new SplitAccountVo();
  586. splitAccount.setOrderId(order.getOrderId());
  587. splitAccount.setOrderProductId(orderProduct.getOrderProductId());
  588. splitAccount.setShopId(orderProduct.getShopId().intValue());
  589. splitAccount.setSplitAccount(costPrice);
  590. splitAccount.setProductType("1");
  591. if (StringUtils.isNotBlank(commercialCode)) {
  592. //供应商拥有子商户号
  593. splitAccount.setType("4");
  594. splitAccount.setSubUserNo(commercialCode);
  595. } else {
  596. if ("3".equals(orderProduct.getInvoiceType())) {
  597. //不能开票,则分账到私账-无票
  598. splitAccount.setType("2");
  599. splitAccount.setSubUserNo(privateAccountNo);
  600. } else if ("1".equals(orderProduct.getInvoiceType())) {
  601. //开增值税发票,则分账到公账-专票
  602. splitAccount.setType("1");
  603. splitAccount.setSubUserNo(publicAccountNo);
  604. } else if ("2".equals(orderProduct.getInvoiceType())) {
  605. //开普通发票,则分账到公账-普票
  606. splitAccount.setType("3");
  607. splitAccount.setSubUserNo(commonInvoiceNo);
  608. }
  609. }
  610. log.info("分账详情(成本):" + splitAccount);
  611. list.add(splitAccount);
  612. if (MathUtil.compare(splitAmount, 0) == 0) {
  613. break;
  614. }
  615. }
  616. }
  617. //付供应商运费,是以供应商为单位的
  618. if (MathUtil.compare(splitAmount, 0) > 0) {
  619. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(order.getOrderId());
  620. for (ShopOrderVo shopOrder : shopOrderList) {
  621. //运费
  622. BigDecimal shopPostFee = shopOrder.getShopPostFee();
  623. if (MathUtil.compare(shopPostFee, 0) > 0) {
  624. BigDecimal shipping = payOrderMapper.findShipping(order.getOrderId(), shopOrder.getShopId());
  625. shopPostFee = MathUtil.sub(shopPostFee, shipping);
  626. if (MathUtil.compare(splitAmount, shopPostFee) > -1) {
  627. splitAmount = MathUtil.sub(splitAmount, shopPostFee);
  628. } else {
  629. shopPostFee = splitAmount;
  630. splitAmount = BigDecimal.ZERO;
  631. }
  632. String commercialCode = payOrderMapper.findCommercialCode(Long.valueOf(shopOrder.getShopId()));
  633. SplitAccountVo splitAccount = new SplitAccountVo();
  634. splitAccount.setOrderId(order.getOrderId());
  635. splitAccount.setShopId(shopOrder.getShopId());
  636. splitAccount.setSplitAccount(shopPostFee);
  637. splitAccount.setProductType("2");
  638. if (StringUtils.isNotBlank(commercialCode)) {
  639. //供应商拥有子商户号
  640. splitAccount.setType("4");
  641. splitAccount.setSubUserNo(commercialCode);
  642. } else {
  643. //私账
  644. splitAccount.setType("2");
  645. splitAccount.setSubUserNo(privateAccountNo);
  646. }
  647. log.info("分账详情(付供应商运费):" + splitAccount);
  648. list.add(splitAccount);
  649. }
  650. }
  651. }
  652. //佣金,公账
  653. if (MathUtil.compare(splitAmount, 0) > 0) {
  654. SplitAccountVo splitAccount = new SplitAccountVo();
  655. splitAccount.setOrderId(order.getOrderId());
  656. splitAccount.setSplitAccount(splitAmount);
  657. splitAccount.setProductType("3");
  658. splitAccount.setType("1");
  659. splitAccount.setSubUserNo(publicAccountNo);
  660. log.info("分账详情(佣金):" + splitAccount);
  661. list.add(splitAccount);
  662. }
  663. return list;
  664. }
  665. /**
  666. * 整理第三方支付详情参数
  667. */
  668. private String ledgerParameters(List<SplitAccountVo> splitBillDetail, Integer orderId) {
  669. List<Map<String, String>> maps = new ArrayList<>();
  670. List<ShopOrderVo> shopOrderList = orderMapper.findAllShopOrder(orderId);
  671. //供应商子商户总金额
  672. for (ShopOrderVo shopOrder : shopOrderList) {
  673. BigDecimal shopTotalAmount = BigDecimal.ZERO;
  674. String subUserNo = "";
  675. for (SplitAccountVo account : splitBillDetail) {
  676. if ("4".equals(account.getType()) && shopOrder.getShopId().equals(account.getShopId())) {
  677. shopTotalAmount = MathUtil.add(shopTotalAmount, account.getSplitAccount());
  678. subUserNo = account.getSubUserNo();
  679. }
  680. }
  681. addMaps(maps, shopTotalAmount, subUserNo);
  682. }
  683. //公账-专票总金额,私账-无票总金额,公账-普票总金额
  684. BigDecimal totalAmount1 = BigDecimal.ZERO;
  685. BigDecimal totalAmount2 = BigDecimal.ZERO;
  686. BigDecimal totalAmount3 = BigDecimal.ZERO;
  687. for (SplitAccountVo account : splitBillDetail) {
  688. if ("1".equals(account.getType())) {
  689. totalAmount1 = MathUtil.add(totalAmount1, account.getSplitAccount());
  690. } else if ("2".equals(account.getType())) {
  691. totalAmount2 = MathUtil.add(totalAmount2, account.getSplitAccount());
  692. } else if ("3".equals(account.getType())) {
  693. totalAmount3 = MathUtil.add(totalAmount3, account.getSplitAccount());
  694. }
  695. }
  696. addMaps(maps, totalAmount1, publicAccountNo);
  697. addMaps(maps, totalAmount2, privateAccountNo);
  698. addMaps(maps, totalAmount3, commonInvoiceNo);
  699. return JSON.toJSONString(maps);
  700. }
  701. private void addMaps(List<Map<String, String>> maps, BigDecimal shopTotalAmount, String subUserNo) {
  702. if (MathUtil.compare(shopTotalAmount, 0) > 0) {
  703. Map<String, String> map = new HashMap<>(3);
  704. map.put("subUserNo", subUserNo);
  705. map.put("splitBillType", "2");
  706. map.put("splitBillValue", MathUtil.mul(shopTotalAmount, 100).toString());
  707. maps.add(map);
  708. }
  709. }
  710. }