PayOrderServiceImpl.java 34 KB

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