|
@@ -0,0 +1,1351 @@
|
|
|
+package com.caimei365.order.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.caimei365.order.components.HeliPayUtil;
|
|
|
+import com.caimei365.order.components.WeChatService;
|
|
|
+import com.caimei365.order.constant.Constant;
|
|
|
+import com.caimei365.order.mapper.BaseMapper;
|
|
|
+import com.caimei365.order.mapper.OrderCommonMapper;
|
|
|
+import com.caimei365.order.mapper.PayOrderMapper;
|
|
|
+import com.caimei365.order.model.ResponseJson;
|
|
|
+import com.caimei365.order.model.bo.PayParamBo;
|
|
|
+import com.caimei365.order.model.dto.HeliDto;
|
|
|
+import com.caimei365.order.model.enums.AccountPayOrderType;
|
|
|
+import com.caimei365.order.model.enums.AppPayType;
|
|
|
+import com.caimei365.order.model.enums.OrderStatus;
|
|
|
+import com.caimei365.order.model.enums.PayType;
|
|
|
+import com.caimei365.order.model.po.*;
|
|
|
+import com.caimei365.order.model.vo.*;
|
|
|
+import com.caimei365.order.service.HeliPayService;
|
|
|
+import com.caimei365.order.service.RemoteCallService;
|
|
|
+import com.caimei365.order.utils.MathUtil;
|
|
|
+import com.caimei365.order.utils.PayUtil;
|
|
|
+import com.caimei365.order.utils.helipay.Disguiser;
|
|
|
+import com.caimei365.order.utils.helipay.HttpClientService;
|
|
|
+import com.caimei365.order.utils.helipay.MyBeanUtils;
|
|
|
+import com.caimei365.order.utils.pay.RSAUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.httpclient.HttpStatus;
|
|
|
+import org.apache.commons.lang.ArrayUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.servlet.ModelAndView;
|
|
|
+import springfox.documentation.spring.web.json.Json;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.beans.IntrospectionException;
|
|
|
+import java.io.IOException;
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
+
|
|
|
+import okhttp3.*;
|
|
|
+
|
|
|
+import static com.caimei365.order.constant.Constant.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Description
|
|
|
+ *
|
|
|
+ * @author : zzj
|
|
|
+ * @date : 2021/11/11
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class HeliPayServiceImpl implements HeliPayService {
|
|
|
+
|
|
|
+ public static OkHttpClient client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(3, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(20, TimeUnit.SECONDS)
|
|
|
+ .build();
|
|
|
+ @Resource
|
|
|
+ private OrderCommonMapper orderCommonMapper;
|
|
|
+ @Resource
|
|
|
+ private HeliPayUtil heliPayUtil;
|
|
|
+ @Resource
|
|
|
+ private BaseMapper baseMapper;
|
|
|
+ @Resource
|
|
|
+ private PayOrderMapper payOrderMapper;
|
|
|
+ @Resource
|
|
|
+ private RemoteCallService remoteCallService;
|
|
|
+ @Resource
|
|
|
+ private WeChatService weChatService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 微信/支付宝扫码接口
|
|
|
+ * 交易类型 P1_bizType 是 String(20) AppPay 交易类型
|
|
|
+ * 商户订单号 P2_orderId 是 String(50) p_20170302185347 商户系统内部订单号,要求50字符以内,同一商户号下订单号唯一
|
|
|
+ * 商户编号 P3_customerNumber 是 String(15) C1800000002 合利宝分配的商户号
|
|
|
+ * 支付类型 P4_payType 是 String(15) SCAN:扫码(主扫)
|
|
|
+ * 交易金额 P5_orderAmount 是 Number(10,2) 0.01 订单金额,以元为单位,最小金额为0.01
|
|
|
+ * 币种类型 P6_currency 是 String(30) CNY CNY:人民币
|
|
|
+ * 授权码 P7_authcode 是 String(50) 1234567890 payType为刷卡(被扫)时传入一组字符串(付款码),主扫支付类型传入1即可.
|
|
|
+ * 客户端类型 P8_appType 是 String(20) ALIPAY:支付宝 WXPAY:微信
|
|
|
+ * 通知回调地址 P9_notifyUrl 否 String(300) http://wap.helipay.com/notify.php
|
|
|
+ * 异步接收合利宝支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
|
|
|
+ * 成功跳转URL P10_successToUrl 否 String(300) http://wap.helipay.com/success.php 支付完成后,展示支付结果的页面地址(暂不用)
|
|
|
+ * 商户IP P11_orderIp 是 String(20) 192.168.10.1 用户下单IP
|
|
|
+ * 商品名称 P12_goodsName 是 String(128) Iphone7 商品名称,账单上显示
|
|
|
+ * 商品详情 P13_goodsDetail 否 String(8000)商品的优惠活动: 单品优惠活动该字段必传,且必须按照规范上传,JSON字符串格式,详见附录【6.3单品优惠活动字段说明】
|
|
|
+ * 备注 P14_desc 否 String(100) 备注 订单备注信息,原样返回
|
|
|
+ * 公众号appId P16_appId 否 String(30) wxdeaaaa2311 刷卡时可传.(不参与签名)
|
|
|
+ * 签名 sign 是 String(40) d3382b9a9b08cefc1a79d276ec03d83a MD5 签名结果,详见“第 5 章 数字签名”
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public ResponseJson<JSONObject> payByWeChat(HeliDto heliDto, HttpHeaders headers) {
|
|
|
+ log.info("--------进入支付二维码创建接口----------");
|
|
|
+ try {
|
|
|
+ AppCreateOrderVo pay = new AppCreateOrderVo();
|
|
|
+ //合利宝主扫接口参数赋值
|
|
|
+ heliPayUtil.setValue(pay, heliDto, "order", headers);
|
|
|
+ if (!(StringUtils.equals(AppPayType.ALIPAY.name(), pay.getP8_appType())
|
|
|
+ && StringUtils.equals(PayType.SWIPE.name(), pay.getP4_payType()))) {
|
|
|
+ pay.setOpenId(null);
|
|
|
+ pay.setAuthConfirmMode(null);
|
|
|
+ }
|
|
|
+ Map<String, String> map = MyBeanUtils.convertBean(pay, new LinkedHashMap());
|
|
|
+ String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppCreateOrderVo.NEED_SIGN_PARAMS);
|
|
|
+ //密钥拼接
|
|
|
+ oriMessage += SPLIT + Constant.SAOMA;
|
|
|
+ log.info("签名原文串:" + oriMessage);
|
|
|
+ String sign = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ log.info("签名串:" + sign);
|
|
|
+ map.put("sign", sign);
|
|
|
+ log.info("发送参数:" + map);
|
|
|
+ Map<String, Object> resultMap = HttpClientService.getHttpResp(map, Constant.REQUEST_URL);
|
|
|
+ log.info("响应结果:" + resultMap);
|
|
|
+ if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
|
|
|
+ String resultMsg = (String) resultMap.get("response");
|
|
|
+ AppCreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppCreateOrderResponseVo.class);
|
|
|
+ String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppCreateOrderResponseVo.NEED_SIGN_PARAMS);
|
|
|
+ assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
|
|
|
+ log.info("组装返回结果签名串:" + assemblyRespOriSign);
|
|
|
+ String responseSign = orderResponseVo.getSign();
|
|
|
+ log.info("响应签名:" + responseSign);
|
|
|
+ String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(resultMsg);
|
|
|
+ if (checkSign.equals(responseSign) && "0000".equals(orderResponseVo.getRt2_retCode())) {
|
|
|
+ return ResponseJson.success("二维码创建成功", jsonObject);
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("二维码创建失败", jsonObject);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("创建二维码请求失败", null);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("创建二维码请求失败" + e);
|
|
|
+ return ResponseJson.error("创建二维码请求失败", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseJson<JSONObject> payOnline(HeliDto heliDto, HttpHeaders headers) {
|
|
|
+ log.info("--------进入公众号/小程序预创建订单接口----------");
|
|
|
+ try {
|
|
|
+ AppPayPublicCreateOrderVo pay = new AppPayPublicCreateOrderVo();
|
|
|
+ //合利宝主扫接口参数赋值
|
|
|
+ heliPayUtil.setOnlineValue(pay, heliDto, "order", headers);
|
|
|
+ if ("GZH".equals(heliDto.getPayType()) || "XCX".equals(heliDto.getPayType())) {
|
|
|
+ //公众号/小程序
|
|
|
+ String openId = getOpenId(heliDto, headers);
|
|
|
+ if (StringUtils.isEmpty(openId)) {
|
|
|
+ return ResponseJson.error("微信openId获取失败", null);
|
|
|
+ }
|
|
|
+ pay.setP8_openid(openId);
|
|
|
+ }
|
|
|
+ Map<String, String> map = MyBeanUtils.convertBean(pay, new LinkedHashMap());
|
|
|
+ String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppPayPublicCreateOrderVo.NEED_SIGN_PARAMS);
|
|
|
+ oriMessage += SPLIT + Constant.SAOMA;
|
|
|
+ log.info("签名原文串:" + oriMessage);
|
|
|
+ String sign = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ log.info("签名串:" + sign);
|
|
|
+ map.put("sign", sign);
|
|
|
+ log.info("发送参数:" + map);
|
|
|
+ Map<String, Object> resultMap = HttpClientService.getHttpResp(map, Constant.REQUEST_URL);
|
|
|
+ log.info("响应结果:" + resultMap);
|
|
|
+ if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
|
|
|
+ String resultMsg = (String) resultMap.get("response");
|
|
|
+ AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
|
|
|
+ String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppPayPublicOrderResponseVo.NEED_SIGN_PARAMS);
|
|
|
+ assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
|
|
|
+ log.info("组装返回结果签名串:" + assemblyRespOriSign);
|
|
|
+ String responseSign = orderResponseVo.getSign();
|
|
|
+ log.info("响应签名:" + responseSign);
|
|
|
+ String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
|
|
|
+ if (checkSign.equals(responseSign) && "0000".equals(orderResponseVo.getRt2_retCode())) {
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(resultMsg);
|
|
|
+ return ResponseJson.success("请求成功", jsonObject);
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("请求参数有误", JSONObject.parseObject(resultMsg));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("请求失败", null);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("交易失败" + e);
|
|
|
+ return ResponseJson.error("交易失败", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String paymentCallback(NotifyResponseVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
|
|
|
+ log.info("******************** 支付异步回调 start *******************");
|
|
|
+ // 签名验证
|
|
|
+ String sign = res.getSign();
|
|
|
+ log.info("回调签名" + sign);
|
|
|
+ String oriMessage = MyBeanUtils.getSigned(res, null);
|
|
|
+ String oriMessage1 = oriMessage + SPLIT + Constant.SAOMA;
|
|
|
+ String oriMessage2 = oriMessage + SPLIT + Constant.FENZHANG;
|
|
|
+ String oriMessage3 = oriMessage + SPLIT + Constant.XUNI;
|
|
|
+ String oriMessage4 = oriMessage + SPLIT + Constant.WANGYIN;
|
|
|
+ String checkSign1 = Disguiser.disguiseMD5(oriMessage1.trim());
|
|
|
+ String checkSign2 = Disguiser.disguiseMD5(oriMessage2.trim());
|
|
|
+ String checkSign3 = Disguiser.disguiseMD5(oriMessage3.trim());
|
|
|
+ String checkSign4 = Disguiser.disguiseMD5(oriMessage4.trim());
|
|
|
+ boolean b = sign.equals(checkSign1) || sign.equals(checkSign2) || sign.equals(checkSign3) || sign.equals(checkSign4);
|
|
|
+ if (!b) {
|
|
|
+ return "验签名失败!";
|
|
|
+ }
|
|
|
+ // 订单状态 INIT:已接收 DOING:处理中 SUCCESS:成功 FAIL:失败 CLOSE:关闭 CANCEL:撤销
|
|
|
+ String orderStatus = res.getRt4_status();
|
|
|
+ // 平台唯一流水号
|
|
|
+ String mbOrderId = res.getRt3_systemSerial();
|
|
|
+ // 商户唯一订单号
|
|
|
+ String orderRequestNo = res.getRt2_orderId();
|
|
|
+ // 订单金额,以元为单位
|
|
|
+ Double amount = Double.valueOf(res.getRt5_orderAmount());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>支付订单状态:" + orderStatus);
|
|
|
+ if (!"SUCCESS".equals(orderStatus)) {
|
|
|
+ return "支付失败";
|
|
|
+ }
|
|
|
+ String[] split = res.getRt8_desc().split(",");
|
|
|
+ //0位置订单id
|
|
|
+ Integer orderId = Integer.valueOf(split[0]);
|
|
|
+ //1位置支付类型
|
|
|
+ String payType = split[1];
|
|
|
+ // 订单信息
|
|
|
+ OrderVo order = orderCommonMapper.getOrderByOrderId(orderId);
|
|
|
+ if (null == order) {
|
|
|
+ return "订单不存在";
|
|
|
+ }
|
|
|
+ // 支付记录
|
|
|
+ List<DiscernReceiptVo> discernReceiptList = orderCommonMapper.getDiscernReceipt(order.getOrderId(), order.getShopOrderIds());
|
|
|
+ double receiptAmount = 0d;
|
|
|
+ if (null != discernReceiptList && discernReceiptList.size() > 0) {
|
|
|
+ for (DiscernReceiptVo discernReceipt : discernReceiptList) {
|
|
|
+ receiptAmount = MathUtil.add(receiptAmount, discernReceipt.getAssociateAmount()).doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ order.setReceiptAmount(MathUtil.add(receiptAmount, amount).doubleValue());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>已付金额+本次支付金额:" + order.getReceiptAmount());
|
|
|
+ Date date = new Date();
|
|
|
+ String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
|
|
|
+ if (MathUtil.compare(order.getPayableAmount(), order.getReceiptAmount()) == 0) {
|
|
|
+ /*
|
|
|
+ * 订单全部支付
|
|
|
+ * 0待确认,11待收待发,12待收部发,13待收全发,21部收待发,22部收部发,23部收全发,
|
|
|
+ * 31已收待发,32已收部发,33已收全发,4交易完成,5订单完成,6已关闭,7交易全退
|
|
|
+ */
|
|
|
+ if (OrderStatus.UNRECEIVED_AND_UNSHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_UNSHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(31);
|
|
|
+ } else if (OrderStatus.UNRECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(32);
|
|
|
+ } else {
|
|
|
+ order.setStatus(33);
|
|
|
+ }
|
|
|
+ order.setPayFlag(1);
|
|
|
+ order.setOnlinePayFlag(0);
|
|
|
+ //(收款买家)收款状态:1待收款、2部分收款、3已收款
|
|
|
+ order.setReceiptStatus(3);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>订单(全部支付),修改订单状态:" + order.getStatus() + ",orderId:" + orderId);
|
|
|
+ } else {
|
|
|
+ // 部分支付
|
|
|
+ if (OrderStatus.UNRECEIVED_AND_UNSHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_UNSHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(21);
|
|
|
+ } else if (OrderStatus.UNRECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(22);
|
|
|
+ } else {
|
|
|
+ order.setStatus(23);
|
|
|
+ }
|
|
|
+ order.setOnlinePayFlag(0);
|
|
|
+ //(收款买家)收款状态:1待收款、2部分收款、3已收款
|
|
|
+ order.setReceiptStatus(2);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>订单(部分支付),修改订单状态:" + order.getStatus() + ",orderId:" + orderId);
|
|
|
+ }
|
|
|
+ // 更新付款次数
|
|
|
+ Integer paySuccessCounter = (null == order.getPaySuccessCounter()) ? 1 : order.getPaySuccessCounter() + 1;
|
|
|
+ order.setPaySuccessCounter(paySuccessCounter);
|
|
|
+ order.setUpdateDate(curDateStr);
|
|
|
+ // 更新订单支付状态
|
|
|
+ payOrderMapper.updateOrderStatus(order);
|
|
|
+ // 修改支付链接状态
|
|
|
+ OrderPayLinkVo orderPayLink = payOrderMapper.getOrderPayLink(orderId, amount);
|
|
|
+ if (null != orderPayLink && ("12".equals(payType) || "17".equals(payType))) {
|
|
|
+ orderPayLink.setPayStatus(1);
|
|
|
+ payOrderMapper.updateOrderPayLinkStatus(orderPayLink);
|
|
|
+ }
|
|
|
+ // 保存收款记录
|
|
|
+ DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
|
|
|
+ discernReceipt.setPayWay(1);
|
|
|
+ discernReceipt.setPayType(Integer.valueOf(payType));
|
|
|
+ discernReceipt.setReceiptType(1);
|
|
|
+ discernReceipt.setReceiptStatus(3);
|
|
|
+ discernReceipt.setReceiptAmount(amount);
|
|
|
+ discernReceipt.setConfirmType(4);
|
|
|
+ discernReceipt.setRePayFlag(1);
|
|
|
+ discernReceipt.setFormData(JSONObject.toJSONString(res));
|
|
|
+ discernReceipt.setReceiptDate(curDateStr);
|
|
|
+ discernReceipt.setConfirmDate(curDateStr);
|
|
|
+ discernReceipt.setReviewDate(curDateStr);
|
|
|
+ discernReceipt.setUpdateDate(curDateStr);
|
|
|
+ discernReceipt.setDelFlag(0);
|
|
|
+ // 保存 收款记录
|
|
|
+ baseMapper.insertDiscernReceipt(discernReceipt);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>保存识别款项(insert[cm_discern_receipt])id:" + discernReceipt.getId() + ",orderId:" + orderId);
|
|
|
+ // 收款项和订单关系表
|
|
|
+ OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
|
|
|
+ relation.setReceiptId(discernReceipt.getId());
|
|
|
+ relation.setOrderId(orderId);
|
|
|
+ relation.setAssociateAmount(amount);
|
|
|
+ relation.setMbOrderId(mbOrderId);
|
|
|
+ relation.setOrderRequestNo(orderRequestNo);
|
|
|
+ relation.setSplitStatus(0);
|
|
|
+ relation.setRelationType(2);
|
|
|
+ relation.setDelFlag(0);
|
|
|
+ // 保存 收款项和订单关系
|
|
|
+ baseMapper.insertOrderReceiptRelation(relation);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>收款项和订单关系(insert[cm_receipt_order_relation])id:" + relation.getId() + ",orderId:" + orderId);
|
|
|
+
|
|
|
+ // 商品数据
|
|
|
+ List<OrderProductVo> orderProductList = orderCommonMapper.getOrderProductByOrderId(orderId);
|
|
|
+ // 判断是否是充值商品
|
|
|
+ int rechargeFlag = 0;
|
|
|
+ // 缴纳订金订单
|
|
|
+ int[] productId1 = {6060, 6061, 6062, 6063, 6064};
|
|
|
+ // 充值余额订单
|
|
|
+ int[] productId2 = {6065, 6066, 6067, 6068, 6069};
|
|
|
+ for (OrderProductVo product : orderProductList) {
|
|
|
+ if (ArrayUtils.contains(productId1, product.getProductId())) {
|
|
|
+ rechargeFlag = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (ArrayUtils.contains(productId2, product.getProductId())) {
|
|
|
+ rechargeFlag = 2;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (rechargeFlag > 0) {
|
|
|
+ // 账户余额
|
|
|
+ double oldUserMoney = baseMapper.getonlineMoney(order.getUserId());
|
|
|
+ double userMoney = MathUtil.add(oldUserMoney, amount).doubleValue();
|
|
|
+ // 可用余额
|
|
|
+ Double oldAvailableMoney = baseMapper.getAbleUserMoney(order.getUserId());
|
|
|
+ double availableMoney = MathUtil.add(oldAvailableMoney, amount).doubleValue();
|
|
|
+ //充值线上余额
|
|
|
+ payOrderMapper.updateOnlineMoneyByUserId(userMoney, availableMoney, order.getUserId());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>更新用户余额(update[user])userId:" + order.getUserId() + ",orderId:" + orderId);
|
|
|
+ //保存余额到余额收支记录
|
|
|
+ BalanceRecordPo balanceRecord = new BalanceRecordPo();
|
|
|
+ balanceRecord.setUserId(order.getUserId());
|
|
|
+ balanceRecord.setType(1);
|
|
|
+ if (rechargeFlag == 1) {
|
|
|
+ balanceRecord.setBalanceType(16);
|
|
|
+ } else {
|
|
|
+ balanceRecord.setBalanceType(17);
|
|
|
+ }
|
|
|
+ balanceRecord.setAddDate(new Date());
|
|
|
+ balanceRecord.setAmount(amount);
|
|
|
+ balanceRecord.setOrderId(orderId);
|
|
|
+ balanceRecord.setRemark("订单商品充值余额");
|
|
|
+ balanceRecord.setDelFlag(0);
|
|
|
+ // 保存 余额收支记录
|
|
|
+ baseMapper.insertBalanceRecord(balanceRecord);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>>>>>>>>>>>>>订单商品充值余额(insert[cm_user_balance_record])orderId:" + orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 线上支付与自主下单送豆(已全部收款),最后一笔线上支付成功后,赠送200采美豆
|
|
|
+ if (3 == order.getReceiptStatus() && 0 == order.getSecondHandOrderFlag()) {
|
|
|
+ UserBeansHistoryPo beansHistory = new UserBeansHistoryPo();
|
|
|
+ beansHistory.setUserId(order.getUserId());
|
|
|
+ beansHistory.setOrderId(orderId);
|
|
|
+ beansHistory.setBeansType(6);
|
|
|
+ beansHistory.setType(1);
|
|
|
+ beansHistory.setNum(200);
|
|
|
+ beansHistory.setPushStatus(0);
|
|
|
+ beansHistory.setAddTime(date);
|
|
|
+ beansHistory.setDelFlag(0);
|
|
|
+ // 保存 采美豆使用记录
|
|
|
+ baseMapper.insertBeansHistory(beansHistory);
|
|
|
+ // 用户采美豆
|
|
|
+ Integer userBeans = baseMapper.getUserBeans(order.getUserId());
|
|
|
+ // 更新用户剩余采美豆数量
|
|
|
+ userBeans = userBeans + beansHistory.getNum();
|
|
|
+
|
|
|
+ // 自主下单且没有促销活动送豆
|
|
|
+ Integer orderPromotionsId = payOrderMapper.getOrderPromotionsId(order.getOrderId());
|
|
|
+ if (1 == order.getOrderType() && null == orderPromotionsId) {
|
|
|
+ // 机构自主下单,根据订单总额的价格区间赠送采美豆数量规则
|
|
|
+ Double payTotalFee = order.getPayTotalFee();
|
|
|
+ int num;
|
|
|
+ if (MathUtil.compare(1000, payTotalFee) > -1) {
|
|
|
+ num = 0;
|
|
|
+ } else if (MathUtil.compare(5000, payTotalFee) > -1) {
|
|
|
+ num = 1000;
|
|
|
+ } else if (MathUtil.compare(10000, payTotalFee) > -1) {
|
|
|
+ num = 2500;
|
|
|
+ } else if (MathUtil.compare(25000, payTotalFee) > -1) {
|
|
|
+ num = 5000;
|
|
|
+ } else if (MathUtil.compare(100000, payTotalFee) > -1) {
|
|
|
+ num = 7500;
|
|
|
+ } else if (MathUtil.compare(250000, payTotalFee) > -1) {
|
|
|
+ num = 10000;
|
|
|
+ } else if (MathUtil.compare(500000, payTotalFee) > -1) {
|
|
|
+ num = 12500;
|
|
|
+ } else {
|
|
|
+ num = 20000;
|
|
|
+ }
|
|
|
+ // 超级会员用户标识
|
|
|
+ Integer svipUserId = baseMapper.getSvipUserIdByUserId(order.getUserId());
|
|
|
+ if (null != svipUserId && svipUserId.equals(order.getUserId())) {
|
|
|
+ // 超级会员用户采美豆翻倍
|
|
|
+ num = num * 2;
|
|
|
+ }
|
|
|
+ beansHistory.setBeansType(5);
|
|
|
+ beansHistory.setNum(num);
|
|
|
+ if (num > 0) {
|
|
|
+ // 保存 采美豆使用记录
|
|
|
+ baseMapper.insertBeansHistory(beansHistory);
|
|
|
+ // 更新用户剩余采美豆数量
|
|
|
+ userBeans = userBeans + beansHistory.getNum();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ baseMapper.updateUserBeans(beansHistory.getUserId(), userBeans);
|
|
|
+ log.info("【支付异步回调】>>>>>更新用户采美豆(update[user(userBeans:" + userBeans + ")]),userId:" + beansHistory.getUserId());
|
|
|
+ }
|
|
|
+ // 已支付短信推送 不是本地或者测试
|
|
|
+ boolean smsPushFlag = !orderRequestNo.contains("BETA") && !orderRequestNo.contains("DEV");
|
|
|
+ String bindMobile = baseMapper.getBindMobileByUserId(order.getUserId());
|
|
|
+ if (smsPushFlag && StringUtils.isNotBlank(bindMobile)) {
|
|
|
+ String shortLink = remoteCallService.getShortLink(8, 6, "https://www.caimei365.com/user/order/detail.html?orderId=" + orderId);
|
|
|
+ String content = "您已成功支付订单(订单编号:" + order.getOrderNo() + ")全部款项,支付总金额¥" + order.getPayTotalFee() + ",采美平台将立即安排发货。您可关注采美公众号或者访问采美微信小程序和网站查看订单。" +
|
|
|
+ "平台公众号:微信搜索“采美365网”; 微信小程序:微信搜索“采美采购商城”;网址:www.caimei365.com/t/" + shortLink;
|
|
|
+ boolean sendSms = remoteCallService.getSendSms(6, bindMobile, content);
|
|
|
+ if (!sendSms) {
|
|
|
+ log.info("取消订单推送失败,orderId>>>>" + orderId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "SUCCESS";
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseJson<String> link(HeliDto heliDto, HttpHeaders headers) {
|
|
|
+ log.info("--------进入线上支付接口----------");
|
|
|
+ // 订单信息
|
|
|
+ OrderVo order = orderCommonMapper.getOrderByOrderId(heliDto.getOrderId());
|
|
|
+ if (null == order) {
|
|
|
+ log.error("订单不存在");
|
|
|
+ return ResponseJson.error("订单不存在");
|
|
|
+ }
|
|
|
+ if (OrderStatus.UNCONFIRMED.getCode() == order.getStatus() ||
|
|
|
+ OrderStatus.RECEIVED_AND_FULL_SHIPPED.getCode() == order.getStatus() ||
|
|
|
+ OrderStatus.TRANSACTION_COMPLETED.getCode() == order.getStatus() ||
|
|
|
+ OrderStatus.ORDER_COMPLETED.getCode() == order.getStatus() ||
|
|
|
+ OrderStatus.CLOSED.getCode() == order.getStatus() ||
|
|
|
+ OrderStatus.FULL_RETURNED.getCode() == order.getStatus()) {
|
|
|
+ log.error("订单状态错误");
|
|
|
+ return ResponseJson.error("订单状态错误", null);
|
|
|
+ }
|
|
|
+ // 支付记录
|
|
|
+ List<DiscernReceiptVo> discernReceiptList = orderCommonMapper.getDiscernReceipt(order.getOrderId(), order.getShopOrderIds());
|
|
|
+ if (!discernReceiptList.isEmpty()) {
|
|
|
+ AtomicReference<Boolean> offlineFlag = new AtomicReference<>(false);
|
|
|
+ discernReceiptList.forEach(discernReceipt -> {
|
|
|
+ if (2 == discernReceipt.getPayWay()) {
|
|
|
+ offlineFlag.set(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (offlineFlag.get()) {
|
|
|
+ log.error("已经线下支付过,只能线下支付!");
|
|
|
+ return ResponseJson.error("已经线下支付过,只能线下支付!", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info(">>>>>>>>>>>>>>本次付款金额:" + heliDto.getPayAmount());
|
|
|
+ if (MathUtil.compare(MathUtil.mul(order.getPayableAmount(), 100), heliDto.getPayAmount()) < 0) {
|
|
|
+ log.error("付款金额错误!");
|
|
|
+ return ResponseJson.error("付款金额错误!", null);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ HeliOnlineVo heliOnlineVo = new HeliOnlineVo();
|
|
|
+ heliPayUtil.setLinkValue(heliOnlineVo, heliDto, "order", headers);
|
|
|
+ Map<String, String> map = MyBeanUtils.convertBean(heliOnlineVo, new LinkedHashMap());
|
|
|
+ String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, HeliOnlineVo.NEED_SIGN_PARAMS);
|
|
|
+ oriMessage += SPLIT + Constant.WANGYIN;
|
|
|
+ String sign = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ Map<String, String> sPara = new HashMap<String, String>();
|
|
|
+ sPara.put("P1_bizType", heliOnlineVo.getP1_bizType());
|
|
|
+ sPara.put("P2_orderId", heliOnlineVo.getP2_orderId());
|
|
|
+ sPara.put("P3_customerNumber", heliOnlineVo.getP3_customerNumber());
|
|
|
+ sPara.put("P4_orderAmount", heliOnlineVo.getP4_orderAmount());
|
|
|
+ sPara.put("P5_bankId", heliOnlineVo.getP5_bankId());
|
|
|
+ sPara.put("P6_business", heliOnlineVo.getP6_business());
|
|
|
+ sPara.put("P7_timestamp", heliOnlineVo.getP7_timestamp());
|
|
|
+ sPara.put("P8_goodsName", heliOnlineVo.getP8_goodsName());
|
|
|
+ sPara.put("P9_period", heliOnlineVo.getP9_period());
|
|
|
+ sPara.put("P10_periodUnit", heliOnlineVo.getP10_periodUnit());
|
|
|
+ sPara.put("P11_callbackUrl", heliOnlineVo.getP11_callbackUrl());
|
|
|
+ sPara.put("P12_serverCallbackUrl", heliOnlineVo.getP12_serverCallback());
|
|
|
+ sPara.put("P13_orderIp", heliOnlineVo.getP13_orderIp());
|
|
|
+ sPara.put("P14_onlineCardType", heliOnlineVo.getP14_onlineCardType());
|
|
|
+ sPara.put("P15_desc", heliOnlineVo.getP15_desc());
|
|
|
+ sPara.put("sign", sign);
|
|
|
+ StringBuffer sbHtml = new StringBuffer();
|
|
|
+ List<String> keys = new ArrayList<String>(sPara.keySet());
|
|
|
+ // post方式传递
|
|
|
+ sbHtml.append("<form id=\"onlineForm\" name=\"onlineForm\" action=\"").append(YL).append("\" method=\"post\">");
|
|
|
+ String name = "";
|
|
|
+ String value = "";
|
|
|
+ for (int i = 0; i < keys.size(); i++) {
|
|
|
+ name = (String) keys.get(i);
|
|
|
+ value = (String) sPara.get(name);
|
|
|
+ if (value != null && !"".equals(value)) {
|
|
|
+ sbHtml.append("<input type=\"hidden\" name=\"").append(name).append("\" value=\"" + value + "\"/>");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //submit按钮控件请不要含有name属性
|
|
|
+ sbHtml.append("<input type=\"submit\" value=\"确认付款\"></form>");
|
|
|
+ return ResponseJson.success(sbHtml.toString());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("错误信息", e);
|
|
|
+ return ResponseJson.error("支付失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getOpenId(HeliDto heliDto, HttpHeaders headers) {
|
|
|
+ PayParamBo payParam = new PayParamBo();
|
|
|
+ // payDto -> payParam
|
|
|
+ BeanUtils.copyProperties(heliDto, payParam);
|
|
|
+ // 微信线上支付
|
|
|
+ String openId = null;
|
|
|
+ if (null == payParam.getState()) {
|
|
|
+ // 小程序微信授权获取登录信息
|
|
|
+ ResponseJson<Map<String, Object>> appletsInfo = weChatService.getInfoMapByApplets(payParam.getCode(), headers, 1);
|
|
|
+ if (appletsInfo.getCode() == -1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Map<String, Object> infoData = appletsInfo.getData();
|
|
|
+ openId = (String) infoData.get(WeChatService.Keys.OPEN_ID);
|
|
|
+ if (StringUtils.isEmpty(openId)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ // 微信公众号,通过code获取微信用户信息
|
|
|
+ Map<String, Object> map = weChatService.getInfoMapByWeb(payParam.getCode(), "crm");
|
|
|
+ openId = (String) map.get(WeChatService.Keys.OPEN_ID);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("openId获取失败", e);
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(openId)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return openId;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void delayedSplitting(String callUrl) {
|
|
|
+ log.info("【延时分账】>>>>>>>>>>延时分账,每一小时执行一次");
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(new Date());
|
|
|
+ //todo 测试 不减时间,现在有就分账
|
|
|
+ //测试查5分钟前的单
|
|
|
+ calendar.add(Calendar.SECOND, -5);
|
|
|
+// calendar.add(Calendar.DAY_OF_MONTH, -1);
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ String currentTime = format.format(calendar.getTime());
|
|
|
+ // 查询未分账已支付收款 排除线上订金/充值订单
|
|
|
+ List<OrderReceiptRelationPo> orderRelations = payOrderMapper.getUndividedPaidReceipt(currentTime);
|
|
|
+ if (null != orderRelations && orderRelations.size() > 0) {
|
|
|
+ for (OrderReceiptRelationPo orderRelation : orderRelations) {
|
|
|
+ log.info("【延时分账】>>>>>>>>>>订单id:" + orderRelation.getOrderId() + "进入延时分账");
|
|
|
+ // 收款对应的订单信息
|
|
|
+ OrderVo order = orderCommonMapper.getOrderByOrderId(orderRelation.getOrderId());
|
|
|
+ PayParamBo payParam = new PayParamBo();
|
|
|
+ //支付金额
|
|
|
+ payParam.setPayAmount(MathUtil.mul(orderRelation.getAssociateAmount(), 100).intValue());
|
|
|
+ if (12 == orderRelation.getPayType()) {
|
|
|
+ // 网银支付
|
|
|
+ payParam.setPayWay("UNIONPAY");
|
|
|
+ }
|
|
|
+ if (17 == orderRelation.getPayType()) {
|
|
|
+ //b2c网银
|
|
|
+ payParam.setPayWay("B2C");
|
|
|
+ }
|
|
|
+ //微信0.65%手续费
|
|
|
+ if (8 == orderRelation.getPayType() || 13 == orderRelation.getPayType() || 15 == orderRelation.getPayType()) {
|
|
|
+ payParam.setPayWay("WX");
|
|
|
+ }
|
|
|
+ List<SplitAccountPo> splitBillDetail = setSplitAccountDetail(order, payParam);
|
|
|
+ List<Map<String, String>> maps = new ArrayList<>();
|
|
|
+ List<ShopOrderVo> shopOrderList = orderCommonMapper.getShopOrderListByOrderId(order.getOrderId());
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ double shopTotalAmount = 0.00;
|
|
|
+ String subUserNo = "";
|
|
|
+ for (SplitAccountPo account : splitBillDetail) {
|
|
|
+ //供应商有支付平台账户type=4
|
|
|
+ if (null != account.getType() && 4 == account.getType() && shopOrder.getShopId().equals(account.getShopId())) {
|
|
|
+ shopTotalAmount = MathUtil.add(shopTotalAmount, account.getSplitAccount()).doubleValue();
|
|
|
+ subUserNo = account.getSubUserNo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+// addMaps(maps, shopTotalAmount, subUserNo);
|
|
|
+ }
|
|
|
+ if (null == splitBillDetail || splitBillDetail.size() == 0) {
|
|
|
+ log.info("无满足条件分账单号");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //公账-专票总金额,私账-无票总金额,公账-普票总金额
|
|
|
+ //Type2,3奥泰,1,5信息
|
|
|
+ //todo 正式改
|
|
|
+ String sp1 = "";
|
|
|
+ BigDecimal totalAmount1 = BigDecimal.ZERO;
|
|
|
+ String sp2 = "";
|
|
|
+ BigDecimal totalAmount2 = BigDecimal.ZERO;
|
|
|
+ for (SplitAccountPo account : splitBillDetail) {
|
|
|
+ if (1 == account.getType() || 5 == account.getType()) {
|
|
|
+ totalAmount1 = MathUtil.add(totalAmount1, account.getSplitAccount());
|
|
|
+ sp1 = account.getSubUserNo();
|
|
|
+ }
|
|
|
+ if (2 == account.getType() || 3 == account.getType()) {
|
|
|
+ totalAmount2 = MathUtil.add(totalAmount2, account.getSplitAccount());
|
|
|
+ sp2 = account.getSubUserNo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ArrayList<AccountPayOrder.AccountPayOrderExt.SplitBillRule> splitBillRules = new ArrayList<>();
|
|
|
+ if (MathUtil.compare(totalAmount1, 0.01) > 0) {
|
|
|
+ AccountPayOrder.AccountPayOrderExt.SplitBillRule splitBillRule = new AccountPayOrder.AccountPayOrderExt.SplitBillRule();
|
|
|
+ splitBillRule.setSplitBillAmount(totalAmount1);
|
|
|
+ splitBillRule.setSplitBillMerchantNo(sp1);
|
|
|
+ splitBillRules.add(splitBillRule);
|
|
|
+ }
|
|
|
+ if (MathUtil.compare(totalAmount2, 0.01) > 0) {
|
|
|
+ AccountPayOrder.AccountPayOrderExt.SplitBillRule splitBillRule = new AccountPayOrder.AccountPayOrderExt.SplitBillRule();
|
|
|
+ splitBillRule.setSplitBillAmount(totalAmount2);
|
|
|
+ splitBillRule.setSplitBillMerchantNo(sp2);
|
|
|
+ splitBillRules.add(splitBillRule);
|
|
|
+ }
|
|
|
+ //第三方分账接口
|
|
|
+ try {
|
|
|
+ AccountPayOrder accountPayOrder = new AccountPayOrder();
|
|
|
+ accountPayOrder.setP1_bizType("AccountPaySub");
|
|
|
+ accountPayOrder.setP2_signType("MD5");
|
|
|
+ String format1 = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS").format(new Date());
|
|
|
+ accountPayOrder.setP3_timestamp(format1);
|
|
|
+ String substring = format1.substring(20);
|
|
|
+ // fz+当前微秒时间+原唯一订单号
|
|
|
+ accountPayOrder.setP4_orderId("FZ" + substring + orderRelation.getOrderRequestNo());
|
|
|
+ //todo 付款账户商编暂用网络
|
|
|
+ accountPayOrder.setP5_customerNumber(Constant.CUSTOMERNUM2);
|
|
|
+ AccountPayOrder.AccountPayOrderExt accountPayOrderExt = new AccountPayOrder.AccountPayOrderExt();
|
|
|
+ //收款账户商编 填写splitBillRules时候不填写MerchantNo,Amount并且即使填写这两个参数不生效!!
|
|
|
+// accountPayOrderExt.setInMerchantNo(splitMoneyVo.getName());
|
|
|
+ accountPayOrderExt.setOrderType(AccountPayOrderType.TRANSFER);
|
|
|
+// accountPayOrderExt.setAmount(splitMoneyVo.getSplitMoney());
|
|
|
+ accountPayOrderExt.setServerCallbackUrl(callUrl);
|
|
|
+ accountPayOrderExt.setGoodsName("分账");
|
|
|
+
|
|
|
+ if (null != splitBillRules && splitBillRules.size() > 0) {
|
|
|
+ accountPayOrderExt.setSplitBillRules(splitBillRules);
|
|
|
+ }
|
|
|
+ String ext = JSON.toJSONString(accountPayOrderExt);
|
|
|
+ log.info("分账规则串json串:" + ext);
|
|
|
+ accountPayOrder.setP6_ext(ext);
|
|
|
+ // 生成签名
|
|
|
+ StringBuilder builder = new StringBuilder();
|
|
|
+ builder.append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP1_bizType()).append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP2_signType()).append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP3_timestamp()).append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP4_orderId()).append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP5_customerNumber()).append(SPLIT)
|
|
|
+ .append(accountPayOrder.getP6_ext()).append(SPLIT)
|
|
|
+ .append(XUNI);
|
|
|
+ String sign = Disguiser.disguiseMD5(builder.toString().trim());
|
|
|
+ Map<String, String> bean = convertBean(accountPayOrder);
|
|
|
+ log.info("--------------------> 发送分账参数: " + bean);
|
|
|
+ Map<String, String> map = postForm(bean, Constant.FZ, sign, Map.class);
|
|
|
+ log.info("----------------分账返回数据: " + map.toString());
|
|
|
+ if (map != null) {
|
|
|
+ String code = map.get("rt5_retCode");
|
|
|
+ if (!"0000".equals(code)) {
|
|
|
+ String msg = map.get("rt6_retMsg");
|
|
|
+ log.info("【延时分账】>>>>>>>>>>第三方延迟分账失败>>>>>>>msg:" + msg);
|
|
|
+ } else {
|
|
|
+ for (SplitAccountPo splitAccount : splitBillDetail) {
|
|
|
+ splitAccount.setMbOrderId(orderRelation.getMbOrderId());
|
|
|
+ splitAccount.setOrderRequestNo(substring + orderRelation.getOrderRequestNo());
|
|
|
+ splitAccount.setPayStatus(1);
|
|
|
+ // 保存分账详情
|
|
|
+ payOrderMapper.insertSplitAccount(splitAccount);
|
|
|
+ }
|
|
|
+ log.info("【延时分账】>>>>>>>>>>此订单分账结束");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("【延时分账】>>>>>>>>>>错误信息", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String delayedSplittingCallback(AccountResVo data) {
|
|
|
+ log.info("延时分账异步回调参数-------------------》 " + data.toString());
|
|
|
+ try {
|
|
|
+ String oriMessage = MyBeanUtils.getSigned(data, null);
|
|
|
+ oriMessage = oriMessage + SPLIT + XUNI;
|
|
|
+ String checkSign = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ log.info("回调签名 :" + data.getSign());
|
|
|
+ log.info("checkSign : " + checkSign);
|
|
|
+ if (!checkSign.equals(data.getSign())) {
|
|
|
+ log.info("延时分账异步回调验签失败------------------");
|
|
|
+ return "验签失败";
|
|
|
+ }
|
|
|
+ //分账的时候防止相同订单号,前面加了FZ,切割掉2位还原
|
|
|
+ String orderRequestNo = data.getRt7_orderId().substring(5);
|
|
|
+ //切2位是splict account表orderRequestNo
|
|
|
+ String substring = data.getRt7_orderId().substring(2);
|
|
|
+ String status = data.getRt10_orderStatus();
|
|
|
+ log.info("【延时分账回调】>>>>>>>>>>分账状态:" + status);
|
|
|
+ if (!"SUCCESS".equals(status)) {
|
|
|
+ return "分账失败";
|
|
|
+ }
|
|
|
+ // 修改收款分账状态为1
|
|
|
+ payOrderMapper.updateBySplitStatus(orderRequestNo);
|
|
|
+
|
|
|
+ List<SplitAccountPo> splitAccountList = payOrderMapper.getSplitAccountList(substring);
|
|
|
+ if (splitAccountList != null && splitAccountList.size() > 0) {
|
|
|
+ Integer orderId = splitAccountList.get(0).getOrderId();
|
|
|
+ List<ShopOrderVo> shopOrderList = orderCommonMapper.getShopOrderListByOrderId(orderId);
|
|
|
+ Integer shopOrderId = null;
|
|
|
+ String shopOrderNo = "";
|
|
|
+ for (SplitAccountPo account : splitAccountList) {
|
|
|
+ log.info("【延时分账回调】>>>>>>>>>>保存应付付供应商:" + account.getShopId());
|
|
|
+ // 本次付供应商金额(分账金额)
|
|
|
+ Double splitAmount = account.getSplitAccount();
|
|
|
+ orderId = account.getOrderId();
|
|
|
+ Integer shopId = account.getShopId();
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ if (shopId.equals(shopOrder.getShopId())) {
|
|
|
+ shopOrderId = shopOrder.getShopOrderId();
|
|
|
+ shopOrderNo = shopOrder.getShopOrderNo();
|
|
|
+ // 已付供应商金额
|
|
|
+ Double paidAmount = payOrderMapper.getPaidShopAmount(shopOrderId);
|
|
|
+ Double paidShop = MathUtil.add(paidAmount, splitAmount).doubleValue();
|
|
|
+ shopOrder.setPayedShopAmount(paidShop);
|
|
|
+ if (MathUtil.compare(shopOrder.getShouldPayShopAmount(), paidShop) == 0) {
|
|
|
+ shopOrder.setPayStatus(3);
|
|
|
+ } else {
|
|
|
+ shopOrder.setPayStatus(2);
|
|
|
+ }
|
|
|
+ // 修改子订单付款状态及付款金额
|
|
|
+ payOrderMapper.updateShopOrderByPayStatus(shopOrderId, paidShop, shopOrder.getPayStatus());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ String currentTime = format.format(new Date());
|
|
|
+ // 保存付款单表
|
|
|
+ //todo 线上余额分账保存balancePayFee
|
|
|
+ PayShopPo payShop = new PayShopPo();
|
|
|
+ payShop.setShopId(shopId);
|
|
|
+ payShop.setName("线上支付分账");
|
|
|
+ payShop.setTotalAmount(splitAmount);
|
|
|
+ payShop.setWipePayment(0d);
|
|
|
+ payShop.setPayType(6);
|
|
|
+ payShop.setStatus(1);
|
|
|
+ payShop.setDelFlag(0);
|
|
|
+ payShop.setApplyTime(currentTime);
|
|
|
+ payShop.setReviewTime(currentTime);
|
|
|
+ payShop.setPayTime(currentTime);
|
|
|
+ payOrderMapper.insertPayShop(payShop);
|
|
|
+ // 保存 付供应商记录
|
|
|
+ PayShopRecordPo shopRecord = new PayShopRecordPo();
|
|
|
+ shopRecord.setShopId(shopId);
|
|
|
+ shopRecord.setShopOrderId(shopOrderId);
|
|
|
+ shopRecord.setShopOrderNo(shopOrderNo);
|
|
|
+ shopRecord.setPayAmount(splitAmount);
|
|
|
+ shopRecord.setWipePayment(0d);
|
|
|
+ shopRecord.setPayType(6);
|
|
|
+ shopRecord.setPayTime(currentTime);
|
|
|
+ shopRecord.setPayShopId(payShop.getId());
|
|
|
+ shopRecord.setStatus(1);
|
|
|
+ shopRecord.setDelFlag(0);
|
|
|
+ payOrderMapper.insertPayShopRecord(shopRecord);
|
|
|
+ }
|
|
|
+ // 子订单是否全部付款
|
|
|
+ boolean isPay = true;
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ if (3 != shopOrder.getPayStatus()) {
|
|
|
+ isPay = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 修改主订单付款状态
|
|
|
+ if (isPay) {
|
|
|
+ payOrderMapper.updateOrderByPayStatus(orderId, 3);
|
|
|
+ } else {
|
|
|
+ payOrderMapper.updateOrderByPayStatus(orderId, 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("【延时分账回调】>>>>>>>>>>分账异步通知异常", e);
|
|
|
+ return "分账失败";
|
|
|
+ }
|
|
|
+ return "SUCCESS";
|
|
|
+ }
|
|
|
+
|
|
|
+ //银行通道码获取
|
|
|
+ @Override
|
|
|
+ public ResponseJson<JSONObject> bankCode() {
|
|
|
+ List<BankCodeVo> banks = payOrderMapper.findBankCode();
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("list", banks);
|
|
|
+ return ResponseJson.success("获取成功", jsonObject);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResponseJson<JSONObject> getPayOrderResult(String mbOrderId) {
|
|
|
+ log.info("--------进入交易订单查询接口----------");
|
|
|
+ QueryOrderVo queryOrderVo = new QueryOrderVo();
|
|
|
+ queryOrderVo.setP1_bizType("AppPayQuery");
|
|
|
+ queryOrderVo.setP2_orderId(mbOrderId);
|
|
|
+ //todo 换收款账户
|
|
|
+ queryOrderVo.setP3_customerNumber(Constant.CUSTOMERNUM2);
|
|
|
+ try {
|
|
|
+ Map<String, String> map = MyBeanUtils.convertBean(queryOrderVo, new LinkedHashMap());
|
|
|
+ String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, QueryOrderVo.NEED_SIGN_PARAMS);
|
|
|
+ //区分网银和其他产品
|
|
|
+ String payType = baseMapper.findType(mbOrderId);
|
|
|
+ if ("12".equals(payType) || "17".equals(payType)) {
|
|
|
+ oriMessage += Constant.SPLIT + Constant.WANGYIN;
|
|
|
+ } else {
|
|
|
+ oriMessage += Constant.SPLIT + Constant.SAOMA;
|
|
|
+ }
|
|
|
+ log.info("签名原文串:" + oriMessage);
|
|
|
+ String sign = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ log.info("签名串:" + sign);
|
|
|
+ map.put("sign", sign);
|
|
|
+ log.info("发送参数:" + map);
|
|
|
+ Map<String, Object> resultMap = HttpClientService.getHttpResp(map, Constant.REQUEST_URL);
|
|
|
+ log.info("响应结果:" + resultMap);
|
|
|
+ if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
|
|
|
+ String resultMsg = (String) resultMap.get("response");
|
|
|
+ QueryOrderResponseVo queryOrderResponseVo = JSONObject.parseObject(resultMsg, QueryOrderResponseVo.class);
|
|
|
+ String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(queryOrderResponseVo, QueryOrderResponseVo.NEED_SIGN_PARAMS);
|
|
|
+ log.info("组装返回结果签名串:" + assemblyRespOriSign);
|
|
|
+ if ("12".equals(payType) || "17".equals(payType)) {
|
|
|
+ assemblyRespOriSign += Constant.SPLIT + Constant.WANGYIN;
|
|
|
+ } else {
|
|
|
+ assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
|
|
|
+ }
|
|
|
+ String responseSign = queryOrderResponseVo.getSign();
|
|
|
+ log.info("响应签名:" + responseSign);
|
|
|
+ String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
|
|
|
+ if (checkSign.equals(responseSign)) {
|
|
|
+ if ("0000".equals(queryOrderResponseVo.getRt2_retCode())) {
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(resultMsg, JSONObject.class);
|
|
|
+ return ResponseJson.success("查询成功", jsonObject);
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("验签失败", null);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("验签失败", null);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return ResponseJson.error("请求失败", null);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ return ResponseJson.error("查询失败", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String unionCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
|
|
|
+ log.info("******************** 网银支付异步回调 start *******************");
|
|
|
+ // 签名验证
|
|
|
+ String sign = res.getSign();
|
|
|
+ log.info("回调签名" + sign);
|
|
|
+ String oriMessage = MyBeanUtils.getSignedByPresetParameter(res, UnionResVo.NEED_SIGN_PARAMS);
|
|
|
+ oriMessage += Constant.SPLIT + Constant.WANGYIN;
|
|
|
+ String checkSign2 = Disguiser.disguiseMD5(oriMessage.trim());
|
|
|
+ if (!sign.equals(checkSign2)) {
|
|
|
+ log.error("网银支付异步回调验签失败------------------------------------");
|
|
|
+ return "验签名失败!";
|
|
|
+ }
|
|
|
+ // INIT:未支付
|
|
|
+ //SUCCESS:已支付
|
|
|
+ //CANCELLED:已取消
|
|
|
+ String orderStatus = res.getRt11_orderStatus();
|
|
|
+ // 平台唯一流水号
|
|
|
+ String mbOrderId = res.getRt12_serialNumber();
|
|
|
+ // 商户唯一订单号
|
|
|
+ String orderRequestNo = res.getRt5_orderId();
|
|
|
+ // 订单金额,以元为单位
|
|
|
+ Double amount = Double.valueOf(res.getRt6_orderAmount());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>支付订单状态:" + orderStatus);
|
|
|
+ if (!"SUCCESS".equals(orderStatus)) {
|
|
|
+ return "支付失败";
|
|
|
+ }
|
|
|
+ String[] split = res.getRt13_desc().split(",");
|
|
|
+ //0位置订单id
|
|
|
+ Integer orderId = Integer.valueOf(split[0]);
|
|
|
+ //1位置支付类型
|
|
|
+ String payType = split[1];
|
|
|
+ // 订单信息
|
|
|
+ OrderVo order = orderCommonMapper.getOrderByOrderId(orderId);
|
|
|
+ if (null == order) {
|
|
|
+ return "订单不存在";
|
|
|
+ }
|
|
|
+ // 支付记录
|
|
|
+ List<DiscernReceiptVo> discernReceiptList = orderCommonMapper.getDiscernReceipt(order.getOrderId(), order.getShopOrderIds());
|
|
|
+ double receiptAmount = 0d;
|
|
|
+ if (null != discernReceiptList && discernReceiptList.size() > 0) {
|
|
|
+ for (DiscernReceiptVo discernReceipt : discernReceiptList) {
|
|
|
+ receiptAmount = MathUtil.add(receiptAmount, discernReceipt.getAssociateAmount()).doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ order.setReceiptAmount(MathUtil.add(receiptAmount, amount).doubleValue());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>已付金额+本次支付金额:" + order.getReceiptAmount());
|
|
|
+ Date date = new Date();
|
|
|
+ String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
|
|
|
+ if (MathUtil.compare(order.getPayableAmount(), order.getReceiptAmount()) == 0) {
|
|
|
+ /*
|
|
|
+ * 订单全部支付
|
|
|
+ * 0待确认,11待收待发,12待收部发,13待收全发,21部收待发,22部收部发,23部收全发,
|
|
|
+ * 31已收待发,32已收部发,33已收全发,4交易完成,5订单完成,6已关闭,7交易全退
|
|
|
+ */
|
|
|
+ if (OrderStatus.UNRECEIVED_AND_UNSHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_UNSHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(31);
|
|
|
+ } else if (OrderStatus.UNRECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(32);
|
|
|
+ } else {
|
|
|
+ order.setStatus(33);
|
|
|
+ }
|
|
|
+ order.setPayFlag(1);
|
|
|
+ order.setOnlinePayFlag(0);
|
|
|
+ //(收款买家)收款状态:1待收款、2部分收款、3已收款
|
|
|
+ order.setReceiptStatus(3);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>订单(全部支付),修改订单状态:" + order.getStatus() + ",orderId:" + orderId);
|
|
|
+ } else {
|
|
|
+ // 部分支付
|
|
|
+ if (OrderStatus.UNRECEIVED_AND_UNSHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_UNSHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(21);
|
|
|
+ } else if (OrderStatus.UNRECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus() || OrderStatus.PART_RECEIVED_AND_PART_SHIPPED.getCode() == order.getStatus()) {
|
|
|
+ order.setStatus(22);
|
|
|
+ } else {
|
|
|
+ order.setStatus(23);
|
|
|
+ }
|
|
|
+ order.setOnlinePayFlag(0);
|
|
|
+ //(收款买家)收款状态:1待收款、2部分收款、3已收款
|
|
|
+ order.setReceiptStatus(2);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>订单(部分支付),修改订单状态:" + order.getStatus() + ",orderId:" + orderId);
|
|
|
+ }
|
|
|
+ // 更新付款次数
|
|
|
+ Integer paySuccessCounter = (null == order.getPaySuccessCounter()) ? 1 : order.getPaySuccessCounter() + 1;
|
|
|
+ order.setPaySuccessCounter(paySuccessCounter);
|
|
|
+ order.setUpdateDate(curDateStr);
|
|
|
+ // 更新订单支付状态
|
|
|
+ payOrderMapper.updateOrderStatus(order);
|
|
|
+ // 修改支付链接状态
|
|
|
+ OrderPayLinkVo orderPayLink = payOrderMapper.getOrderPayLink(orderId, amount);
|
|
|
+ if (null != orderPayLink && ("12".equals(payType) || "17".equals(payType))) {
|
|
|
+ orderPayLink.setPayStatus(1);
|
|
|
+ payOrderMapper.updateOrderPayLinkStatus(orderPayLink);
|
|
|
+ }
|
|
|
+ // 保存收款记录
|
|
|
+ DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
|
|
|
+ discernReceipt.setPayWay(1);
|
|
|
+ discernReceipt.setPayType(Integer.valueOf(payType));
|
|
|
+ discernReceipt.setReceiptType(1);
|
|
|
+ discernReceipt.setReceiptStatus(3);
|
|
|
+ discernReceipt.setReceiptAmount(amount);
|
|
|
+ discernReceipt.setConfirmType(4);
|
|
|
+ discernReceipt.setRePayFlag(1);
|
|
|
+ discernReceipt.setFormData(JSONObject.toJSONString(res));
|
|
|
+ discernReceipt.setReceiptDate(curDateStr);
|
|
|
+ discernReceipt.setConfirmDate(curDateStr);
|
|
|
+ discernReceipt.setReviewDate(curDateStr);
|
|
|
+ discernReceipt.setUpdateDate(curDateStr);
|
|
|
+ discernReceipt.setDelFlag(0);
|
|
|
+ // 保存 收款记录
|
|
|
+ baseMapper.insertDiscernReceipt(discernReceipt);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>保存识别款项(insert[cm_discern_receipt])id:" + discernReceipt.getId() + ",orderId:" + orderId);
|
|
|
+ // 收款项和订单关系表
|
|
|
+ OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
|
|
|
+ relation.setReceiptId(discernReceipt.getId());
|
|
|
+ relation.setOrderId(orderId);
|
|
|
+ relation.setAssociateAmount(amount);
|
|
|
+ relation.setMbOrderId(mbOrderId);
|
|
|
+ relation.setOrderRequestNo(orderRequestNo);
|
|
|
+ relation.setSplitStatus(0);
|
|
|
+ relation.setRelationType(2);
|
|
|
+ relation.setDelFlag(0);
|
|
|
+ // 保存 收款项和订单关系
|
|
|
+ baseMapper.insertOrderReceiptRelation(relation);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>收款项和订单关系(insert[cm_receipt_order_relation])id:" + relation.getId() + ",orderId:" + orderId);
|
|
|
+
|
|
|
+ // 商品数据
|
|
|
+ List<OrderProductVo> orderProductList = orderCommonMapper.getOrderProductByOrderId(orderId);
|
|
|
+ // 判断是否是充值商品
|
|
|
+ int rechargeFlag = 0;
|
|
|
+ // 缴纳订金订单
|
|
|
+ int[] productId1 = {6060, 6061, 6062, 6063, 6064};
|
|
|
+ // 充值余额订单
|
|
|
+ int[] productId2 = {6065, 6066, 6067, 6068, 6069};
|
|
|
+ for (OrderProductVo product : orderProductList) {
|
|
|
+ if (ArrayUtils.contains(productId1, product.getProductId())) {
|
|
|
+ rechargeFlag = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (ArrayUtils.contains(productId2, product.getProductId())) {
|
|
|
+ rechargeFlag = 2;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (rechargeFlag > 0) {
|
|
|
+ // 账户线上余额
|
|
|
+ double oldUserMoney = baseMapper.getonlineMoney(order.getUserId());
|
|
|
+ double userMoney = MathUtil.add(oldUserMoney, amount).doubleValue();
|
|
|
+ // 可用余额
|
|
|
+ Double oldAvailableMoney = baseMapper.getAbleUserMoney(order.getUserId());
|
|
|
+ double availableMoney = MathUtil.add(oldAvailableMoney, amount).doubleValue();
|
|
|
+ // 充值线上
|
|
|
+ payOrderMapper.updateOnlineMoneyByUserId(userMoney, availableMoney, order.getUserId());
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>更新用户余额(update[user])userId:" + order.getUserId() + ",orderId:" + orderId);
|
|
|
+ //保存余额到余额收支记录
|
|
|
+ BalanceRecordPo balanceRecord = new BalanceRecordPo();
|
|
|
+ balanceRecord.setUserId(order.getUserId());
|
|
|
+ balanceRecord.setType(1);
|
|
|
+ if (rechargeFlag == 1) {
|
|
|
+ balanceRecord.setBalanceType(16);
|
|
|
+ } else {
|
|
|
+ balanceRecord.setBalanceType(17);
|
|
|
+ }
|
|
|
+ balanceRecord.setAddDate(new Date());
|
|
|
+ balanceRecord.setAmount(amount);
|
|
|
+ balanceRecord.setOrderId(orderId);
|
|
|
+ balanceRecord.setRemark("订单商品充值余额");
|
|
|
+ balanceRecord.setDelFlag(0);
|
|
|
+ // 保存 余额收支记录
|
|
|
+ baseMapper.insertBalanceRecord(balanceRecord);
|
|
|
+ log.info("【支付异步回调】>>>>>>>>>>>>>>>>>>>>>>>>>>订单商品充值余额(insert[cm_user_balance_record])orderId:" + orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 线上支付与自主下单送豆(已全部收款),最后一笔线上支付成功后,赠送200采美豆
|
|
|
+ if (3 == order.getReceiptStatus() && 0 == order.getSecondHandOrderFlag()) {
|
|
|
+ UserBeansHistoryPo beansHistory = new UserBeansHistoryPo();
|
|
|
+ beansHistory.setUserId(order.getUserId());
|
|
|
+ beansHistory.setOrderId(orderId);
|
|
|
+ beansHistory.setBeansType(6);
|
|
|
+ beansHistory.setType(1);
|
|
|
+ beansHistory.setNum(200);
|
|
|
+ beansHistory.setPushStatus(0);
|
|
|
+ beansHistory.setAddTime(date);
|
|
|
+ beansHistory.setDelFlag(0);
|
|
|
+ // 保存 采美豆使用记录
|
|
|
+ baseMapper.insertBeansHistory(beansHistory);
|
|
|
+ // 用户采美豆
|
|
|
+ Integer userBeans = baseMapper.getUserBeans(order.getUserId());
|
|
|
+ // 更新用户剩余采美豆数量
|
|
|
+ userBeans = userBeans + beansHistory.getNum();
|
|
|
+
|
|
|
+ // 自主下单且没有促销活动送豆
|
|
|
+ Integer orderPromotionsId = payOrderMapper.getOrderPromotionsId(order.getOrderId());
|
|
|
+ if (1 == order.getOrderType() && null == orderPromotionsId) {
|
|
|
+ // 机构自主下单,根据订单总额的价格区间赠送采美豆数量规则
|
|
|
+ Double payTotalFee = order.getPayTotalFee();
|
|
|
+ int num;
|
|
|
+ if (MathUtil.compare(1000, payTotalFee) > -1) {
|
|
|
+ num = 0;
|
|
|
+ } else if (MathUtil.compare(5000, payTotalFee) > -1) {
|
|
|
+ num = 1000;
|
|
|
+ } else if (MathUtil.compare(10000, payTotalFee) > -1) {
|
|
|
+ num = 2500;
|
|
|
+ } else if (MathUtil.compare(25000, payTotalFee) > -1) {
|
|
|
+ num = 5000;
|
|
|
+ } else if (MathUtil.compare(100000, payTotalFee) > -1) {
|
|
|
+ num = 7500;
|
|
|
+ } else if (MathUtil.compare(250000, payTotalFee) > -1) {
|
|
|
+ num = 10000;
|
|
|
+ } else if (MathUtil.compare(500000, payTotalFee) > -1) {
|
|
|
+ num = 12500;
|
|
|
+ } else {
|
|
|
+ num = 20000;
|
|
|
+ }
|
|
|
+ // 超级会员用户标识
|
|
|
+ Integer svipUserId = baseMapper.getSvipUserIdByUserId(order.getUserId());
|
|
|
+ if (null != svipUserId && svipUserId.equals(order.getUserId())) {
|
|
|
+ // 超级会员用户采美豆翻倍
|
|
|
+ num = num * 2;
|
|
|
+ }
|
|
|
+ beansHistory.setBeansType(5);
|
|
|
+ beansHistory.setNum(num);
|
|
|
+ if (num > 0) {
|
|
|
+ // 保存 采美豆使用记录
|
|
|
+ baseMapper.insertBeansHistory(beansHistory);
|
|
|
+ // 更新用户剩余采美豆数量
|
|
|
+ userBeans = userBeans + beansHistory.getNum();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ baseMapper.updateUserBeans(beansHistory.getUserId(), userBeans);
|
|
|
+ log.info("【支付异步回调】>>>>>更新用户采美豆(update[user(userBeans:" + userBeans + ")]),userId:" + beansHistory.getUserId());
|
|
|
+ }
|
|
|
+ // 已支付短信推送 不是本地或者测试
|
|
|
+ boolean smsPushFlag = !orderRequestNo.contains("BETA") && !orderRequestNo.contains("DEV");
|
|
|
+ String bindMobile = baseMapper.getBindMobileByUserId(order.getUserId());
|
|
|
+ if (smsPushFlag && StringUtils.isNotBlank(bindMobile)) {
|
|
|
+ String shortLink = remoteCallService.getShortLink(8, 6, "https://www.caimei365.com/user/order/detail.html?orderId=" + orderId);
|
|
|
+ String content = "您已成功支付订单(订单编号:" + order.getOrderNo() + ")全部款项,支付总金额¥" + order.getPayTotalFee() + ",采美平台将立即安排发货。您可关注采美公众号或者访问采美微信小程序和网站查看订单。" +
|
|
|
+ "平台公众号:微信搜索“采美365网”; 微信小程序:微信搜索“采美采购商城”;网址:www.caimei365.com/t/" + shortLink;
|
|
|
+ boolean sendSms = remoteCallService.getSendSms(6, bindMobile, content);
|
|
|
+ if (!sendSms) {
|
|
|
+ log.info("取消订单推送失败,orderId>>>>" + orderId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "SUCCESS";
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T> T postForm(Map<String, String> params, String url, String sign, Class<T> clazz) {
|
|
|
+ FormBody.Builder builder = new FormBody.Builder();
|
|
|
+ for (Map.Entry<String, String> entry : params.entrySet()) {
|
|
|
+ builder.add(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ builder.add("sign", sign);
|
|
|
+
|
|
|
+ Request request = new Request.Builder() // okHttp post
|
|
|
+ .url(url)
|
|
|
+ .post(builder.build())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ Response response = null;
|
|
|
+ try {
|
|
|
+ response = client.newCall(request).execute();
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new IllegalStateException("请求出错", e);
|
|
|
+ }
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ try {
|
|
|
+ log.info(response.body().string());
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ throw new RuntimeException("请求失败了: http response code: " + response.code());
|
|
|
+ }
|
|
|
+
|
|
|
+ ResponseBody body = response.body();
|
|
|
+ String content = null;
|
|
|
+ try {
|
|
|
+ content = body.string();
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new IllegalStateException("IO异常", e);
|
|
|
+ }
|
|
|
+ JSONObject res = JSON.parseObject(content);
|
|
|
+ if (!res.getBooleanValue("rt4_success")) {
|
|
|
+ log.error("error: " + res.getString("rt6_retMsg"));
|
|
|
+ }
|
|
|
+ /** rt4_success 为 true,需验签 **/
|
|
|
+ return res.toJavaObject(clazz);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Map<String, String> convertBean(Object bean) {
|
|
|
+ Class clazz = bean.getClass();
|
|
|
+ Field[] fields = clazz.getDeclaredFields();
|
|
|
+ for (Field f : fields) {
|
|
|
+ f.setAccessible(true);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Map<String, String> retMap = new LinkedHashMap<>();
|
|
|
+ for (Field f : fields) {
|
|
|
+ String key = f.toString().substring(f.toString().lastIndexOf(".") + 1);
|
|
|
+ Object value = f.get(bean);
|
|
|
+ if (value == null) {
|
|
|
+ value = "";
|
|
|
+ }
|
|
|
+ retMap.put(key, (String) value);
|
|
|
+ }
|
|
|
+ return retMap;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("分账", e);
|
|
|
+ throw new IllegalStateException("分账异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分账详情
|
|
|
+ */
|
|
|
+ private List<SplitAccountPo> setSplitAccountDetail(OrderVo order, PayParamBo payParam) {
|
|
|
+ List<SplitAccountPo> list = new ArrayList<>();
|
|
|
+ // 本次支付金额,单位/元
|
|
|
+ double payAmount = MathUtil.div(payParam.getPayAmount(), 100).doubleValue();
|
|
|
+ // 待分账总金额
|
|
|
+ double splitAmount = payAmount;
|
|
|
+ // 总手续费
|
|
|
+ double procedureFee;
|
|
|
+ if ("UNIONPAY".equals(payParam.getPayWay())) {
|
|
|
+ procedureFee = 10.00;
|
|
|
+ } else if ("B2C".equals(payParam.getPayWay())) {
|
|
|
+ //b2c 0.2%
|
|
|
+ procedureFee = MathUtil.mul(payAmount, 0.002, 2).doubleValue();
|
|
|
+ //b2c最低手续费0.1
|
|
|
+ if (procedureFee < 0.1) {
|
|
|
+ procedureFee = 0.1;
|
|
|
+ }
|
|
|
+ } else if ("WX".equals(payParam.getPayWay())) {
|
|
|
+ //微信0.65%
|
|
|
+ procedureFee = MathUtil.mul(payAmount, 0.0065, 2).doubleValue();
|
|
|
+ } else {
|
|
|
+ //手续费 其他0.25%
|
|
|
+ procedureFee = MathUtil.mul(payAmount, 0.0025, 2).doubleValue();
|
|
|
+ }
|
|
|
+ if (MathUtil.compare(procedureFee, 0.01) <= 0) {
|
|
|
+ procedureFee = 0.01;
|
|
|
+ }
|
|
|
+ //减去收款手续费
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, procedureFee).doubleValue();
|
|
|
+ //分账手续费0.1%
|
|
|
+ Double amount = Math.max(MathUtil.mul(splitAmount, 0.001, 2).doubleValue(), 0.01);
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, amount).doubleValue();
|
|
|
+ if (splitAmount <= 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 商品数据
|
|
|
+ List<OrderProductVo> orderProductList = orderCommonMapper.getOrderProductByOrderId(order.getOrderId());
|
|
|
+ for (OrderProductVo orderProduct : orderProductList) {
|
|
|
+ //成本价*数量
|
|
|
+ double costPrice = MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum()).doubleValue();
|
|
|
+ // 不含税能开发票
|
|
|
+ if (Integer.valueOf(0).equals(orderProduct.getIncludedTax()) && !Integer.valueOf(3).equals(orderProduct.getInvoiceType())) {
|
|
|
+ //应付总税费
|
|
|
+ Double payableTax = MathUtil.mul(orderProduct.getSingleShouldPayTotalTax(), orderProduct.getNum()).doubleValue();
|
|
|
+ //成本+税费
|
|
|
+ costPrice = MathUtil.add(costPrice, payableTax).doubleValue();
|
|
|
+ }
|
|
|
+ // 判断是否支付过
|
|
|
+ Double paidAmount = payOrderMapper.getOrderProductPaidAmount(orderProduct.getOrderProductId());
|
|
|
+ // 支付过金额大于0
|
|
|
+ if (paidAmount != null && MathUtil.compare(paidAmount, 0) > 0) {
|
|
|
+ //成本-支付过的金额
|
|
|
+ costPrice = MathUtil.sub(costPrice, paidAmount).doubleValue();
|
|
|
+ }
|
|
|
+ // 没支付过或者支付过的金额-成本<0(成本还没分够)
|
|
|
+ if (paidAmount == null || MathUtil.compare(paidAmount, costPrice) < 0) {
|
|
|
+ // 待分账金额>=本次待分账金额(还要分账的成本)
|
|
|
+ if (MathUtil.compare(splitAmount, costPrice) > 0) {
|
|
|
+ // 待分账金额=待分账金额-成本
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, costPrice).doubleValue();
|
|
|
+ log.info("待分账金额大于成本 splitAmount = splitAmount-costPrice --------->splitAmount= " + splitAmount);
|
|
|
+ } else {
|
|
|
+ // 待分账金额小于成本
|
|
|
+ log.info("待分账金额小于成本 costPrice = splitAmount --------->splitAmount= " + splitAmount);
|
|
|
+ costPrice = splitAmount;
|
|
|
+ splitAmount = 0.00;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //todo 子商户有商编暂不考虑
|
|
|
+ //分账对象
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setOrderProductId(orderProduct.getOrderProductId());
|
|
|
+ splitAccount.setShopId(orderProduct.getShopId());
|
|
|
+ //成本设置给分账金额
|
|
|
+ splitAccount.setSplitAccount(costPrice);
|
|
|
+ splitAccount.setProductType(1);
|
|
|
+ if (1 == orderProduct.getInvoiceType()) {
|
|
|
+ // 开增值税发票,则分账到公账-专票
|
|
|
+ splitAccount.setType(1);
|
|
|
+ //todo 专票测试暂入信息
|
|
|
+ splitAccount.setSubUserNo(CUSTOMERNUM);
|
|
|
+ } else if (2 == orderProduct.getInvoiceType()) {
|
|
|
+ // 开普通发票,则分账到公账-普票
|
|
|
+ splitAccount.setType(3);
|
|
|
+ //todo 公账-普票 暂入奥泰
|
|
|
+ splitAccount.setSubUserNo(CUSTOMERNUM3);
|
|
|
+ } else {
|
|
|
+ // 未知或不能开票,则分账到私账
|
|
|
+ splitAccount.setType(2);
|
|
|
+ //todo 私账测试暂入奥泰
|
|
|
+ splitAccount.setSubUserNo(CUSTOMERNUM3);
|
|
|
+ }
|
|
|
+ if (splitAccount.getSplitAccount() > 0) {
|
|
|
+ list.add(splitAccount);
|
|
|
+ log.info("============设置成本分账详情对象: " + splitAccount.toString());
|
|
|
+ }
|
|
|
+ //没钱了就break
|
|
|
+ if (MathUtil.compare(splitAmount, 0) == 0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 还有钱就付供应商运费
|
|
|
+ // 付供应商运费,是以供应商为单位的
|
|
|
+ if (MathUtil.compare(splitAmount, 0) > 0) {
|
|
|
+ List<ShopOrderVo> shopOrderList = orderCommonMapper.getShopOrderListByOrderId(order.getOrderId());
|
|
|
+ for (ShopOrderVo shopOrder : shopOrderList) {
|
|
|
+ // 运费
|
|
|
+ Double shopPostFee = shopOrder.getShopPostFee();
|
|
|
+ if (MathUtil.compare(shopPostFee, 0) > 0) {
|
|
|
+ // 查询已支付运费
|
|
|
+ Double shipping = payOrderMapper.getPaidShipping(order.getOrderId(), shopOrder.getShopId());
|
|
|
+ shopPostFee = MathUtil.sub(shopPostFee, shipping).doubleValue();
|
|
|
+ if (MathUtil.compare(splitAmount, shopPostFee) > -1) {
|
|
|
+ //减去运费
|
|
|
+ splitAmount = MathUtil.sub(splitAmount, shopPostFee).doubleValue();
|
|
|
+ } else {
|
|
|
+ //钱不够运费就分剩余
|
|
|
+ shopPostFee = splitAmount;
|
|
|
+ splitAmount = 0.00;
|
|
|
+ }
|
|
|
+ //todo 暂不考虑供应商有商户号,有分给供应商,没有进私账
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setShopId(shopOrder.getShopId());
|
|
|
+ splitAccount.setSplitAccount(shopPostFee);
|
|
|
+ splitAccount.setProductType(2);
|
|
|
+ splitAccount.setType(2);
|
|
|
+ //todo 私账-无票,子商户商编 测试暂入奥泰
|
|
|
+ splitAccount.setSubUserNo(CUSTOMERNUM3);
|
|
|
+ if (splitAccount.getSplitAccount() > 0) {
|
|
|
+ log.info("============设置付供应商运费分账详情对象: " + splitAccount.toString());
|
|
|
+ list.add(splitAccount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如果还有钱则为佣金,分到采美网络
|
|
|
+ if (MathUtil.compare(splitAmount, 0) > 0) {
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
+ splitAccount.setOrderId(order.getOrderId());
|
|
|
+ splitAccount.setSplitAccount(splitAmount);
|
|
|
+ splitAccount.setProductType(3);
|
|
|
+ splitAccount.setType(5);
|
|
|
+ //todo 佣金应入采美网络,测试暂入信息
|
|
|
+ splitAccount.setSubUserNo(Constant.CUSTOMERNUM);
|
|
|
+ if (splitAccount.getSplitAccount() > 0) {
|
|
|
+ log.info("============设置佣金分账详情对象: " + splitAccount.toString());
|
|
|
+ list.add(splitAccount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|