Browse Source

合利宝支付接口

zhijiezhao 3 years ago
parent
commit
64e09238a7

+ 280 - 0
src/main/java/com/caimei365/order/components/HeliPayUtil.java

@@ -0,0 +1,280 @@
+package com.caimei365.order.components;
+
+import com.alibaba.fastjson.JSON;
+import com.caimei365.order.constant.Constant;
+import com.caimei365.order.mapper.OrderCommonMapper;
+import com.caimei365.order.mapper.PayOrderMapper;
+import com.caimei365.order.model.bo.VipRecordBo;
+import com.caimei365.order.model.dto.HeliDto;
+import com.caimei365.order.model.dto.PaySecondDto;
+import com.caimei365.order.model.enums.BizType;
+import com.caimei365.order.model.vo.*;
+import com.caimei365.order.utils.MathUtil;
+import com.caimei365.order.utils.PayUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+@Slf4j
+@Service
+public class HeliPayUtil {
+
+    @Resource
+    private PayOrderMapper payOrderMapper;
+    @Resource
+    private OrderCommonMapper orderCommonMapper;
+    @Value("${pay.second-notify-url}")
+    private String secondHandUrl;
+    @Value("${pay.vip-notify-url}")
+    private String superVipUrl;
+    @Value("${wx.mini-app-id}")
+    private String miniAppId;
+    @Value("${pay.notify-url}")
+    private String notifyUrl;
+    @Value("${pay.union-url}")
+    private String unionPay;
+    @Value("${pay.vip-union-url}")
+    private String vipUnionPay;
+    @Value("${pay.second-union-url}")
+    private String secondUnionPay;
+
+    private final String publicCode="wx91c4152b60ca91a3";
+
+    //小程序/公众号线上公用方法 p8 openid在自己方法传
+    public AppPayPublicCreateOrderVo setOnlineValue(AppPayPublicCreateOrderVo pay, HeliDto heliDto, String payFlag, HttpHeaders headers) {
+        String orderId = "";
+        // 时间戳
+        long time = System.currentTimeMillis() / 1000;
+        String environment = "";
+        if (secondHandUrl.contains("18002")) {
+            environment = "DEV";
+        } else if (secondHandUrl.contains("core-b")) {
+            environment = "BETA";
+        }
+        if ("second".equals(payFlag)) {
+            //二手支付固定100
+            pay.setP9_orderAmount("100");
+            //二手
+            orderId = heliDto.getProductId() + "T" + time + environment;
+            pay.setP12_notifyUrl(secondHandUrl);
+            String product = "采美订单" + orderId;
+            pay.setP15_goodsName(product);
+            //备注
+            pay.setP18_desc(heliDto.getProductId().toString() + "," + BizType.getNumByType(heliDto.getPayType()));
+            //收款账号
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            //立即分账,固定金额
+            pay.setSplitBillType("FIXED_AMOUNT");
+            //分账对象
+            PaySplitVo paySplitVo = new PaySplitVo();
+            //todo 分账账户邮箱 二手进信息
+            //交易分账规则串必须包含两个参数,分别是分账商户的合法邮箱splitBillMerchantEmail和对应分账合法金额splitBillAmount,
+            //分账金额单位:元,最多保留两位小数,分账规则串中不可以重复出现同一邮箱,分账规则串中不可以传分账发起方自己;
+            paySplitVo.setSplitBillMerchantEmail(Constant.XX_MAIL);
+            //手续费0.25% 支付金额*(1-0.25%)
+            paySplitVo.setSplitBillAmount("99.75");
+            String s = JSON.toJSONString(new ArrayList<PaySplitVo>().add(paySplitVo));
+            pay.setRuleJson(s);
+        } else if ("vip".equals(payFlag)) {
+            VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+            Double price = payOrderMapper.getVipPackagePriceById(record.getPackageId());
+            //会员
+            orderId = record.getUserId() + "R" + heliDto.getVipRecordId() + "V" + record.getPackageId() + "T" + time + environment;
+            pay.setP9_orderAmount(price.toString());
+            pay.setP12_notifyUrl(superVipUrl);
+            String product = "采美订单" + orderId;
+            pay.setP15_goodsName(product);
+            String attach = record.getPackageId() + "," + record.getUserId() + "," + heliDto.getVipRecordId() + "," + BizType.getNumByType(heliDto.getPayType());
+            pay.setP18_desc(attach);
+            //收款账号
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            //立即分账,固定金额
+            pay.setSplitBillType("FIXED_AMOUNT");
+            //分账对象
+            PaySplitVo paySplitVo = new PaySplitVo();
+            //todo 分账账户邮箱 超级会员默认进信息
+            //交易分账规则串必须包含两个参数,分别是分账商户的合法邮箱splitBillMerchantEmail和对应分账合法金额splitBillAmount,
+            //分账金额单位:元,最多保留两位小数,分账规则串中不可以重复出现同一邮箱,分账规则串中不可以传分账发起方自己;
+            paySplitVo.setSplitBillMerchantEmail(Constant.XX_MAIL);
+            //手续费0.25% 支付金额*(1-0.25%)
+            paySplitVo.setSplitBillAmount(MathUtil.mul(price,0.9975).toString());
+            String s = JSON.toJSONString(new ArrayList<PaySplitVo>().add(paySplitVo));
+            pay.setRuleJson(s);
+        } else if ("order".equals(payFlag)) {
+            //普通订单
+            //todo 账号待定
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            OrderVo order = orderCommonMapper.getOrderByOrderId(heliDto.getOrderId());
+            orderId = order.getOrderNo() + "T" + time + environment;
+            pay.setP9_orderAmount(heliDto.getPayAmount().toString());
+            pay.setP12_notifyUrl(notifyUrl);
+            String product = "采美订单" + order.getOrderNo();
+            pay.setP15_goodsName(product);
+            String attach = order.getOrderId() + "," + BizType.getNumByType(heliDto.getPayType());
+            pay.setP18_desc(attach);
+        }
+        pay.setP1_bizType(BizType.getP1ByType(heliDto.getPayType()));
+        pay.setP2_orderId(orderId);
+        pay.setP4_payType(BizType.getP4ByType(heliDto.getPayType()));
+        pay.setP10_currency("CNY");
+        pay.setP14_orderIp(headers.getFirst("X-CLIENT-IP"));
+        pay.setP11_appType("WXPAY");
+        //成功后跳转地址
+        pay.setP13_successToUrl(heliDto.getReturnUrl());
+        if ("GZH".equals(heliDto.getPayType())) {
+            //公众号appid
+            pay.setP5_appid(publicCode);
+        } else if ("XCX".equals(heliDto.getPayType())) {
+            //小程序appid
+            pay.setP5_appid(miniAppId);
+        }
+        return pay;
+    }
+
+    //pc支付宝,微信二维码设值
+    public AppCreateOrderVo setValue(AppCreateOrderVo pay, HeliDto heliDto, String payFlag, HttpHeaders headers) {
+        String orderId = "";
+        // 时间戳
+        long time = System.currentTimeMillis() / 1000;
+        String environment = "";
+        if (secondHandUrl.contains("18002")) {
+            environment = "DEV";
+        } else if (secondHandUrl.contains("core-b")) {
+            environment = "BETA";
+        }
+        if ("second".equals(payFlag)) {
+            pay.setP5_orderAmount("100");
+            pay.setP9_notifyUrl(secondHandUrl);
+            orderId = heliDto.getProductId() + "T" + time + environment;
+            String product = "采美订单" + orderId;
+            pay.setP12_goodsName(product);
+            pay.setP14_desc(heliDto.getProductId().toString() + "," + BizType.getNumByType(heliDto.getPayType()));
+            //网络收款,分账进信息
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            PaySplitVo paySplitVo = new PaySplitVo();
+            //todo 分账规则穿给分账账户邮箱 二手进信息
+            //交易分账规则串必须包含两个参数,分别是分账商户的合法邮箱splitBillMerchantEmail和对应分账合法金额splitBillAmount,
+            //分账金额单位:元,最多保留两位小数,分账规则串中不可以重复出现同一邮箱,分账规则串中不可以传分账发起方自己;
+            paySplitVo.setSplitBillMerchantEmail(Constant.XX_MAIL);
+            //手续费0.25% 100*(1-0.25%)
+            paySplitVo.setSplitBillAmount("99.75");
+            String s = JSON.toJSONString(new ArrayList<PaySplitVo>().add(paySplitVo));
+            pay.setRuleJson(s);
+            pay.setSplitBillType("FIXED_AMOUNT");
+        }else if ("vip".equals(payFlag)) {
+            VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+            Double price = payOrderMapper.getVipPackagePriceById(record.getPackageId());
+            pay.setP5_orderAmount(price.toString());
+            pay.setP9_notifyUrl(superVipUrl);
+            orderId = record.getUserId() + "R" + heliDto.getVipRecordId() + "V" + record.getPackageId() + "T" + time + environment;
+            String product = "采美订单" + orderId;
+            pay.setP12_goodsName(product);
+            String attach = record.getPackageId() + "," + record.getUserId() + "," + heliDto.getVipRecordId() + "," + BizType.getNumByType(heliDto.getPayType());
+            pay.setP14_desc(attach);
+            //收款账号
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            PaySplitVo paySplitVo = new PaySplitVo();
+            //进信息
+            paySplitVo.setSplitBillMerchantEmail(Constant.XX_MAIL);
+            //价格*0.9975
+            paySplitVo.setSplitBillAmount(MathUtil.mul(price,0.9975).toString());
+            String s = JSON.toJSONString(new ArrayList<PaySplitVo>().add(paySplitVo));
+            pay.setRuleJson(s);
+            pay.setSplitBillType("FIXED_AMOUNT");
+        }else if ("order".equals(payFlag)) {
+            pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+            OrderVo order = orderCommonMapper.getOrderByOrderId(heliDto.getOrderId());
+            orderId = order.getOrderNo() + "T" + time + environment;
+            pay.setP5_orderAmount(heliDto.getPayAmount().toString());
+            pay.setP9_notifyUrl(notifyUrl);
+            String product = "采美订单" + order.getOrderNo();
+            pay.setP12_goodsName(product);
+            String attach = order.getOrderId() + "," + BizType.getNumByType(heliDto.getPayType());
+            pay.setP14_desc(attach);
+        }
+        pay.setP1_bizType(BizType.getP1ByType(heliDto.getPayType()));
+        pay.setP2_orderId(orderId);
+        pay.setP4_payType("SCAN");
+        pay.setP6_currency("CNY");
+        pay.setP7_authcode("1");
+        //pc二维码apptype不是微信就是支付宝
+        String appType="WXEWM".equals(heliDto.getPayType())?"WXPAY":"ALIPAY";
+        pay.setP8_appType(appType);
+        pay.setP10_successToUrl(heliDto.getReturnUrl());
+        pay.setP11_orderIp(headers.getFirst("X-CLIENT-IP"));
+        return pay;
+    }
+
+    public HeliOnlineVo setLinkValue(HeliOnlineVo pay, HeliDto heliDto, String payFlag, HttpHeaders headers) {
+        try {
+            String orderId = "";
+            // 时间戳
+            long time = System.currentTimeMillis() / 1000;
+            String environment = "";
+            if (secondHandUrl.contains("18002")) {
+                environment = "DEV";
+            } else if (secondHandUrl.contains("core-b")) {
+                environment = "BETA";
+            }
+            if ("second".equals(payFlag)) {
+                pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+                pay.setP4_orderAmount("100");
+                pay.setP12_serverCallback(secondUnionPay);
+                orderId = heliDto.getProductId() + "T" + time + environment;
+                String product = "采美订单" + orderId;
+                URLEncoder.encode(product,"UTF-8");
+                pay.setP8_goodsName(product);
+                String desc=heliDto.getProductId().toString() + "," + BizType.getNumByType(heliDto.getUserType());
+                URLEncoder.encode(desc,"UTF-8");
+                pay.setP15_desc(desc);
+            }else if ("vip".equals(payFlag)) {
+                pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+                VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+                Double price = payOrderMapper.getVipPackagePriceById(record.getPackageId());
+                pay.setP4_orderAmount(price.toString());
+                pay.setP12_serverCallback(vipUnionPay);
+                orderId = record.getUserId() + "R" + heliDto.getVipRecordId() + "V" + record.getPackageId() + "T" + time + environment;
+                String product = "采美订单" + orderId;
+                URLEncoder.encode(product,"UTF-8");
+                pay.setP8_goodsName(product);
+                String attach = record.getPackageId() + "," + record.getUserId() + "," + heliDto.getVipRecordId() + "," + BizType.getNumByType(heliDto.getUserType());
+                URLEncoder.encode(attach,"UTF-8");
+                pay.setP15_desc(attach);
+            }else if ("order".equals(payFlag)) {
+                pay.setP3_customerNumber(Constant.CUSTOMERNUM2);
+                OrderVo order = orderCommonMapper.getOrderByOrderId(heliDto.getOrderId());
+                orderId = order.getOrderNo() + "T" + time + environment;
+                pay.setP4_orderAmount(heliDto.getPayAmount().toString());
+                pay.setP12_serverCallback(unionPay);
+                String product = "采美订单" + order.getOrderNo();
+                URLEncoder.encode(product,"UTF-8");
+                pay.setP8_goodsName(product);
+                String attach = order.getOrderId() + "," + BizType.getNumByType(heliDto.getUserType());
+                URLEncoder.encode(attach,"UTF-8");
+                pay.setP15_desc(attach);
+            }
+            pay.setP1_bizType("OnlinePay");
+            pay.setP2_orderId(orderId);
+            pay.setP5_bankId(heliDto.getBankCode());
+            pay.setP6_business(heliDto.getUserType());
+            pay.setP7_timestamp(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
+            pay.setP9_period("1");
+            pay.setP10_periodUnit("hour");
+            pay.setP11_callbackUrl(heliDto.getReturnUrl());
+            pay.setP13_orderIp(headers.getFirst("X-CLIENT-IP"));
+            pay.setP14_onlineCardType("DEBIT");
+//            pay.setP17_signatureType("MD5");
+        } catch (UnsupportedEncodingException e) {
+            log.error("网银支付设值错误=================>"+e);
+        }
+        return pay;
+    }
+}

+ 49 - 0
src/main/java/com/caimei365/order/constant/Constant.java

@@ -0,0 +1,49 @@
+package com.caimei365.order.constant;
+
+
+/**
+ * 常量类
+ * @author Administrator
+ */
+public class Constant {
+
+
+    //todo 子商户E商编
+    //专票 信息 测试佣金暂入信息  308785626@qq.com vip/二手暂入信息
+    public static final String CUSTOMERNUM = "E1807059160";
+
+    public static final String XX_MAIL="308785626@qq.com";
+
+    //收款商编 网络   xun.zhang@caimei365.com
+    public static final String CUSTOMERNUM2 = "E1807062884";
+
+    public static final String WL_MAIL="xun.zhang@caimei365.com";
+
+    //普票 奥泰 测试私账暂进奥泰   caimei365@yeah.net
+    public static final String CUSTOMERNUM3 = "E1807085606";
+
+    public static final String AT_MAIL="caimei365@yeah.net";
+
+    public static final String SPLIT = "&";
+
+    public static final String DOMAIN_NAME = "http://pay.trx.helipay.com/";
+    //网银地址http://pay.trx.helipay.com/trx/online/interface.action
+    public static final String YL="http://pay.trx.helipay.com/trx/online/interface.action";
+    //分账地址
+    public static final String FZ="http://pay.trx.helipay.com/trx/accountPay/interface.action";
+
+    //微信/支付宝扫码/小程序公众号支付
+    public static final String SAOMA="1iHnZaalUNAVcfcbKdh6n86Z0yUHtM6f";
+    //网银
+    public static final String WANGYIN="CZiCbGrgFYQMldVkQnzbFQeQkn6mp25w";
+    //虚拟账户支付
+    public static final String XUNI="8VmdRSXMIOfUo7aEq1iYs2XEWgGZpBQc";
+    //分账
+    public static final String FENZHANG="2hATS0A4IoxdudGxNkGRNOt6aFSdOd8Q";
+
+    /**
+     * 扫码接口地址
+     */
+    public static final String REQUEST_URL = DOMAIN_NAME + "trx/app/interface.action";
+
+}

+ 259 - 0
src/main/java/com/caimei365/order/controller/HeliPayApi.java

@@ -0,0 +1,259 @@
+package com.caimei365.order.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei365.order.model.ResponseJson;
+import com.caimei365.order.model.dto.HeliDto;
+import com.caimei365.order.model.dto.PayDto;
+import com.caimei365.order.model.dto.PayLinkDto;
+import com.caimei365.order.model.vo.AccountResVo;
+import com.caimei365.order.model.vo.NotifyResponseVo;
+import com.caimei365.order.model.vo.UnionResVo;
+import com.caimei365.order.service.HeliPayService;
+import com.caimei365.order.service.PayOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.bind.annotation.*;
+
+
+import javax.servlet.http.HttpServletResponse;
+import java.beans.IntrospectionException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+
+/**
+ * Description
+ *
+ * @author : zzj
+ * @date : 2021/11/11
+ */
+@Api(tags = "合利宝支付API")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/order/pay")
+public class HeliPayApi {
+
+    private final HeliPayService heliPayService;
+    private final PayOrderService payOrderService;
+
+    /**
+     * 订单支付前效验付款规则
+     */
+    @ApiOperation("订单支付前效验付款规则(旧:/order/paymentValidation)")
+    @ApiImplicitParam(required = false, name = "orderId", value = "订单Id")
+    @GetMapping("/check")
+    public ResponseJson<Map<String, Object>> paymentValidation(Integer orderId) {
+        if (null == orderId) {
+            return ResponseJson.error("订单Id不能为空!", null);
+        }
+        return payOrderService.payBeforeCheck(orderId);
+    }
+
+    /**
+     * 订单支付,余额抵扣
+     *
+     * @param payDto {
+     *               orderId      订单ID
+     *               }
+     */
+    @ApiOperation("订单支付,余额抵扣(旧:/order/balanceDeduction)")
+    @PostMapping("/balance/deduction")
+    public ResponseJson<Map<String, Object>> balanceDeduction(PayDto payDto) {
+        if (null == payDto.getOrderId()) {
+            return ResponseJson.error("订单Id不能为空!", null);
+        }
+        return payOrderService.balanceDeduction(payDto.getOrderId());
+    }
+
+    /**
+     * 获取线上支付全局开关状态
+     */
+    @ApiOperation("获取线上支付全局开关状态(旧:/PayOrder/onLineSwitch)")
+    @GetMapping("/online/switch")
+    public ResponseJson<Integer> getPayOnLineSwitch() {
+        return payOrderService.getPayOnLineSwitch();
+    }
+
+    /**
+     * 收银台数据显示
+     */
+    @ApiOperation("收银台数据(旧:/PayOrder/checkoutCounter)")
+    @ApiImplicitParam(required = false, name = "orderId", value = "订单Id")
+    @GetMapping("/checkout/counter")
+    public ResponseJson<Map<String, Object>> getCheckoutCounter(Integer orderId) {
+        if (null == orderId) {
+            return ResponseJson.error("订单Id不能为空!", null);
+        }
+        return payOrderService.getCheckoutCounter(orderId);
+    }
+
+
+    /**
+     * 生成网银支付链接
+     *
+     * @param payLinkDto {
+     *                   orderId       订单ID
+     *                   vipRecordId   会员购买记录Id
+     *                   }
+     */
+    @ApiOperation("生成网银支付链接(旧:/PayOrder/payLink)")
+    @PostMapping("/link")
+    public ResponseJson<String> getPayLink(PayLinkDto payLinkDto) {
+        if (null == payLinkDto.getOrderId() && null == payLinkDto.getVipRecordId()) {
+            return ResponseJson.error("订单Id和会员购买记录Id不能同时为空!", null);
+        }
+        if (null != payLinkDto.getOrderId() && null != payLinkDto.getVipRecordId()) {
+            return ResponseJson.error("订单Id和会员购买记录Id不能同时出现!", null);
+        }
+        return payOrderService.getPayLink(payLinkDto);
+    }
+
+    /**
+     * 支付链接重定向到页面
+     *
+     * @param linkLogo 链接标识
+     */
+    @ApiOperation("支付链接重定向到页面(旧:/PayOrder/jumpPage)")
+    @ApiImplicitParam(required = false, name = "linkLogo", value = "链接标识")
+    @GetMapping("/link/jump")
+    public void jumpPayPage(String linkLogo, HttpServletResponse response) throws IOException {
+        payOrderService.jumpPayPage(linkLogo, response);
+    }
+
+    /**
+     * 重定向页面的支付数据
+     */
+    @ApiOperation("重定向页面的支付数据(旧:/PayOrder/linkData)")
+    @GetMapping("/link/data")
+    public ResponseJson<Map<String, Object>> linkPayData(String linkLogo) {
+        if (StringUtils.isBlank(linkLogo)) {
+            return ResponseJson.error("链接标识不能为空!", null);
+        }
+        return payOrderService.linkPayData(linkLogo);
+    }
+
+    /**
+     * 判断此次支付是否完成
+     *
+     * @param orderId           订单id
+     * @param paySuccessCounter 付款次数
+     */
+    @ApiOperation("判断此次支付是否完成(旧:/PayOrder/payWhetherSuccess)")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = false, name = "orderId", value = "订单id"),
+            @ApiImplicitParam(required = false, name = "paySuccessCounter", value = "付款次数")
+    })
+    @GetMapping("/result/check")
+    public ResponseJson<String> payWhetherSuccess(Integer orderId, Integer paySuccessCounter) {
+        if (null == orderId) {
+            return ResponseJson.error("订单Id不能为空!", null);
+        }
+        if (null == paySuccessCounter) {
+            return ResponseJson.error("付款次数不能为空!", null);
+        }
+        return payOrderService.payWhetherSuccess(orderId, paySuccessCounter);
+    }
+
+    /**
+     * 查询本次支付订单结果
+     *
+     * @param mbOrderId 平台唯一流水号
+     */
+    @ApiOperation("查询本次支付订单结果(旧:/PayOrder/findOrderStatus)")
+    @ApiImplicitParam(required = false, name = "mbOrderId", value = "平台唯一流水号")
+    @GetMapping("/result/json")
+    public ResponseJson<JSONObject> getPayOrderResult(String mbOrderId) {
+        if (null == mbOrderId) {
+            return ResponseJson.error("平台唯一流水号不能为空!", null);
+        }
+        return heliPayService.getPayOrderResult(mbOrderId);
+    }
+
+    /**
+     * 合利宝pc微信支付宝二维码
+     */
+    @ApiOperation("合利宝pc微信/支付宝扫码支付")
+    @PostMapping("/scan/pay")
+    public ResponseJson<JSONObject> payByWeChat(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        return heliPayService.payByWeChat(heliDto, headers);
+    }
+
+    /**
+     * 合利宝公众号/小程序支付
+     */
+    @ApiOperation("合利宝微信小程序/公众号支付")
+    @PostMapping("/online")
+    public ResponseJson<JSONObject> payOnline(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        return heliPayService.payOnline(heliDto, headers);
+    }
+
+    /**
+     * 合利宝网银支付
+     */
+    @ApiOperation("合利宝网银支付")
+    @PostMapping("/union")
+    public ResponseJson<String> link(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getOrderId()) {
+            return ResponseJson.error("订单Id不能为空!", null);
+        }
+        if (null == heliDto.getPayAmount() || Double.valueOf(heliDto.getPayAmount()) <= 0.1) {
+            return ResponseJson.error("支付金额不正确!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getReturnUrl())) {
+            return ResponseJson.error("回调地址不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getBankCode())) {
+            return ResponseJson.error("银行编码不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getUserType())) {
+            return ResponseJson.error("银行用户类型不能为空!", null);
+        }
+        return heliPayService.link(heliDto, headers);
+    }
+
+    /**
+     * 支付异步通知回调
+     */
+    @ApiOperation("支付异步通知回调(旧:/PayOrder/paymentCallback)")
+    @PostMapping("/callback")
+    public String paymentCallback(NotifyResponseVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (res == null) {
+            return "回调参数失败";
+        }
+        return heliPayService.paymentCallback(res);
+    }
+
+    @ApiOperation("网银支付异步通知回调")
+    @PostMapping("/union/callback")
+    public String unionCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (res == null) {
+            return "回调参数失败";
+        }
+        return heliPayService.unionCallback(res);
+    }
+
+    /**
+     * 延时分账异步通知回调
+     */
+    @ApiOperation("延时分账异步通知回调(旧:/PayOrder/delayedSplittingCallback)")
+    @PostMapping("/delay/split/callback")
+    public String delayedSplittingCallback(AccountResVo data) {
+        if (null == data) {
+            return "回调参数失败";
+        }
+        return heliPayService.delayedSplittingCallback(data);
+    }
+
+    @ApiOperation("银行通道码获取")
+    @GetMapping("/bankcode")
+    public ResponseJson<JSONObject> bankcode() {
+        return heliPayService.bankCode();
+    }
+
+}

+ 203 - 0
src/main/java/com/caimei365/order/controller/HeliPayNonOrderApi.java

@@ -0,0 +1,203 @@
+package com.caimei365.order.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei365.order.model.ResponseJson;
+import com.caimei365.order.model.dto.HeliDto;
+import com.caimei365.order.model.dto.PaySecondDto;
+import com.caimei365.order.model.dto.PayVipDto;
+import com.caimei365.order.model.vo.NotifyResponseVo;
+import com.caimei365.order.model.vo.UnionResVo;
+import com.caimei365.order.service.HeliPayNonOrderService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.bind.annotation.*;
+
+import java.beans.IntrospectionException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * @author zzj
+ * 合利宝非订单
+ */
+@Api(tags = "其他(非订单)支付API")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/order/pay")
+public class HeliPayNonOrderApi {
+
+    private final HeliPayNonOrderService payNonOrderService;
+
+    /**
+     * 二手发布-微信线上支付
+     *
+     * @param heliDto {
+     *                productId      二手发布商品id
+     *                returnUrl     页面回调地址
+     *                code          微信小程序code
+     *                state         微信公众号state参数
+     *                }
+     */
+    @ApiOperation("二手发布-微信线上支付(旧:/PayOrder/appletsSecondHandPay)(/PayOrder/secondHandPay[WEIXIN])")
+    @PostMapping("/second/wechat")
+    public ResponseJson<JSONObject> paySecondByWeChat(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getProductId()) {
+            return ResponseJson.error("二手商品Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getCode())) {
+            return ResponseJson.error("微信code不能为空!", null);
+        }
+        return payNonOrderService.paySecondByWeChat(heliDto, headers);
+    }
+
+    /**
+     * 二手发布-微信/支付宝二维码
+     *
+     * @param heliDto {
+     *                productId      二手发布商品id
+     *                returnUrl     页面回调地址
+     *                }
+     */
+    @ApiOperation("二手发布-支付宝线上支付(旧:/PayOrder/secondHandPay[ALIPAY])")
+    @PostMapping("/second/scan")
+    public ResponseJson<JSONObject> paySecondByAlipay(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getProductId()) {
+            return ResponseJson.error("二手商品Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getReturnUrl())) {
+            return ResponseJson.error("回调地址不能为空!", null);
+        }
+        return payNonOrderService.paySecondByAlipay(heliDto, headers);
+    }
+
+    /**
+     * 二手发布-支付回调
+     */
+    @ApiOperation("二手发布-支付回调(旧:/PayOrder/secondHandPayCallBack)")
+    @PostMapping("/second/callback")
+    public String paymentSecondCallback(NotifyResponseVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (null == res) {
+            return "回调参数失败";
+        }
+        return payNonOrderService.paymentSecondCallback(res);
+    }
+
+    /**
+     * 二手发布-网银支付回调
+     */
+    @ApiOperation("二手发布-网银支付回调")
+    @PostMapping("/second/callback/union")
+    public String paymentSecondCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (null == res) {
+            return "回调参数失败";
+        }
+        return payNonOrderService.unionSecondCallback(res);
+    }
+
+    @ApiOperation("升级超级会员-网银线上支付")
+    @PostMapping("/vip/union")
+    public ResponseJson<String> paySuperVipByUnionPay(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getVipRecordId()) {
+            return ResponseJson.error("会员购买记录Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getReturnUrl())) {
+            return ResponseJson.error("回调地址不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getBankCode())) {
+            return ResponseJson.error("银行编码不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getUserType())) {
+            return ResponseJson.error("银行用户类型不能为空!", null);
+        }
+        return payNonOrderService.unionPay(heliDto, headers);
+    }
+
+    @ApiOperation("二手发布-网银线上支付(旧:/PayOrder/secondHandPay[UNIONPAY])")
+    @PostMapping("/second/union")
+    public ResponseJson<String> paySecondByUnionPay(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getProductId()) {
+            return ResponseJson.error("二手商品Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getReturnUrl())) {
+            return ResponseJson.error("回调地址不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getBankCode())) {
+            return ResponseJson.error("银行编码不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getUserType())) {
+            return ResponseJson.error("银行用户类型不能为空!", null);
+        }
+        return payNonOrderService.unionPaySecond(heliDto, headers);
+    }
+
+    /**
+     * 升级超级会员-微信线上支付
+     *
+     * @param heliDto {
+     *                vipRecordId   会员购买记录Id
+     *                returnUrl     页面回调地址
+     *                code          微信小程序code
+     *                state         微信公众号state参数
+     *                }
+     */
+    @ApiOperation("升级超级会员-微信线上支付")
+    @PostMapping("/vip/wechat")
+    public ResponseJson<JSONObject> paySuperVipByWeChat(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getVipRecordId()) {
+            return ResponseJson.error("会员购买记录Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getCode())) {
+            return ResponseJson.error("微信code不能为空!", null);
+        }
+        return payNonOrderService.paySuperVipByWeChat(heliDto, headers);
+    }
+
+    /**
+     * 升级超级会员-微信/支付宝二维码
+     *
+     * @param heliDto {
+     *                vipRecordId   会员购买记录Id
+     *                returnUrl     页面回调地址
+     *                }
+     */
+    @ApiOperation("升级超级会员-支付宝线上支付")
+    @PostMapping("/vip/scan")
+    public ResponseJson<JSONObject> paySuperVipByAlipay(HeliDto heliDto, @RequestHeader HttpHeaders headers) {
+        if (null == heliDto.getVipRecordId()) {
+            return ResponseJson.error("会员购买记录Id不能为空!", null);
+        }
+        if (StringUtils.isEmpty(heliDto.getReturnUrl())) {
+            return ResponseJson.error("回调地址不能为空!", null);
+        }
+        return payNonOrderService.paySuperVipByAlipay(heliDto, headers);
+    }
+
+    /**
+     * 升级超级会员-支付回调
+     */
+    @ApiOperation("升级超级会员-支付回调")
+    @PostMapping("/vip/callback")
+    public String paymentSuperVipCallback(NotifyResponseVo data) throws NoSuchAlgorithmException, InvalidKeySpecException, IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (null == data) {
+            return "回调参数失败";
+        }
+        return payNonOrderService.paymentSuperVipCallback(data);
+    }
+
+    /**
+     * 升级超级会员-网银支付回调
+     */
+    @ApiOperation("升级超级会员-网银支付回调")
+    @PostMapping("/vip/callback/union")
+    public String paymentSuperVipCallback(UnionResVo data) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        if (null == data) {
+            return "回调参数失败";
+        }
+        return payNonOrderService.unionVipCallback(data);
+    }
+
+}

+ 78 - 0
src/main/java/com/caimei365/order/service/HeliPayNonOrderService.java

@@ -0,0 +1,78 @@
+package com.caimei365.order.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei365.order.model.ResponseJson;
+import com.caimei365.order.model.dto.HeliDto;
+import com.caimei365.order.model.dto.PaySecondDto;
+import com.caimei365.order.model.dto.PayVipDto;
+import com.caimei365.order.model.vo.NotifyResponseVo;
+import com.caimei365.order.model.vo.UnionResVo;
+import org.springframework.http.HttpHeaders;
+
+import java.beans.IntrospectionException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+public interface HeliPayNonOrderService {
+    /**
+     * 二手发布微信线上支付
+     * @param heliDto {
+     *               productId      二手发布商品id
+     *               returnUrl     页面回调地址
+     *               code          微信小程序code
+     *               state         微信公众号state参数
+     * }
+     */
+    ResponseJson<JSONObject> paySecondByWeChat(HeliDto heliDto, HttpHeaders headers);
+    /**
+     * 二手发布支付宝线上支付
+     * @param heliDto {
+     *               productId      二手发布商品id
+     *               returnUrl     页面回调地址
+     * }
+     */
+    ResponseJson<JSONObject> paySecondByAlipay(HeliDto heliDto, HttpHeaders headers);
+
+    /**
+     * 二手发布支付回调
+     */
+    String paymentSecondCallback(NotifyResponseVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException;
+
+    /**
+     * 升级超级会员-微信线上支付
+     * @param heliDto {
+     *               vipRecordId   会员购买记录Id
+     *               returnUrl     页面回调地址
+     *               code          微信小程序code
+     *               state         微信公众号state参数
+     * }
+     */
+    ResponseJson<JSONObject> paySuperVipByWeChat(HeliDto heliDto, HttpHeaders headers);
+    /**
+     * 升级超级会员-支付宝线上支付
+     * @param heliDto {
+     *               vipRecordId   会员购买记录Id
+     *               returnUrl     页面回调地址
+     * }
+     */
+    ResponseJson<JSONObject> paySuperVipByAlipay(HeliDto heliDto, HttpHeaders headers);
+
+    /**
+     * 升级超级会员-支付回调
+     */
+    String paymentSuperVipCallback(NotifyResponseVo data) throws NoSuchAlgorithmException, InvalidKeySpecException, IntrospectionException, InvocationTargetException, IllegalAccessException;
+
+    ResponseJson<String> unionPay(HeliDto heliDto, HttpHeaders headers);
+
+    ResponseJson<String> unionPaySecond(HeliDto heliDto, HttpHeaders headers);
+
+    /**
+     * 升级超级会员-网银支付回调
+     */
+    String unionVipCallback(UnionResVo data) throws IntrospectionException, InvocationTargetException, IllegalAccessException;
+    /**
+     * 二手发布-网银支付回调
+     */
+    String unionSecondCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException;
+}

+ 53 - 0
src/main/java/com/caimei365/order/service/HeliPayService.java

@@ -0,0 +1,53 @@
+package com.caimei365.order.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei365.order.model.ResponseJson;
+import com.caimei365.order.model.dto.HeliDto;
+import com.caimei365.order.model.dto.PayDto;
+import com.caimei365.order.model.vo.AccountResVo;
+import com.caimei365.order.model.vo.AppCreateOrderVo;
+import com.caimei365.order.model.vo.NotifyResponseVo;
+import com.caimei365.order.model.vo.UnionResVo;
+import org.springframework.http.HttpHeaders;
+
+import javax.servlet.http.HttpServletRequest;
+import java.beans.IntrospectionException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * Description
+ *
+ * @author : zzj
+ * @date : 2021/11/11
+ */
+public interface HeliPayService {
+    ResponseJson<JSONObject> payByWeChat(HeliDto heliDto, HttpHeaders headers);
+
+    ResponseJson<JSONObject> payOnline(HeliDto heliDto, HttpHeaders headers);
+    /**
+     * 回调
+     */
+    String paymentCallback(NotifyResponseVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException;
+
+    ResponseJson<String> link(HeliDto heliDto, HttpHeaders headers);
+
+    /**
+     * 延时分账
+     */
+    void delayedSplitting(String callUrl);
+    /**
+     * 延时分账异步回调
+     */
+    String delayedSplittingCallback(AccountResVo data);
+
+    ResponseJson<JSONObject> bankCode();
+
+    ResponseJson<JSONObject> getPayOrderResult(String mbOrderId);
+    /**
+     * 银联回调
+     */
+    String unionCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException;
+
+}

+ 1123 - 0
src/main/java/com/caimei365/order/service/impl/HeliPayNonOrderServiceImpl.java

@@ -0,0 +1,1123 @@
+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.PayOrderMapper;
+import com.caimei365.order.model.ResponseJson;
+import com.caimei365.order.model.bo.PayParamBo;
+import com.caimei365.order.model.bo.VipRecordBo;
+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.DiscernReceiptPo;
+import com.caimei365.order.model.po.OrderReceiptRelationPo;
+import com.caimei365.order.model.po.SplitAccountPo;
+import com.caimei365.order.model.po.UserVipPo;
+import com.caimei365.order.model.vo.*;
+import com.caimei365.order.service.HeliPayNonOrderService;
+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 lombok.extern.slf4j.Slf4j;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.beans.IntrospectionException;
+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.atomic.AtomicReference;
+
+import static com.caimei365.order.constant.Constant.SPLIT;
+import static com.caimei365.order.constant.Constant.YL;
+
+
+@Slf4j
+@Service
+public class HeliPayNonOrderServiceImpl implements HeliPayNonOrderService {
+    @Resource
+    private HeliPayUtil heliPayUtil;
+    @Resource
+    private BaseMapper baseMapper;
+    @Resource
+    private PayOrderMapper payOrderMapper;
+    @Resource
+    private WeChatService weChatService;
+    @Resource
+    private RemoteCallService remoteCallService;
+
+    /**
+     * 二手发布 小程序/公众号
+     *
+     * @param heliDto {
+     *                productId      二手发布商品id
+     *                returnUrl     页面回调地址
+     *                code          微信小程序code
+     *                state         微信公众号state参数
+     *                }
+     * @param headers
+     */
+    @Override
+    public ResponseJson<JSONObject> paySecondByWeChat(HeliDto heliDto, HttpHeaders headers) {
+        log.info("--------进入二手发布公众号/小程序预创建订单接口----------");
+        try {
+            AppPayPublicCreateOrderVo pay = new AppPayPublicCreateOrderVo();
+            //公众号,小程序获取openid
+            if ("GZH".equals(heliDto.getPayType()) || "XCX".equals(heliDto.getPayType())) {
+                PayParamBo tempParam = new PayParamBo();
+                BeanUtils.copyProperties(heliDto, tempParam);
+                ResponseJson<PayParamBo> jsonParam = getWeChatResponseJson(tempParam, headers);
+                if (-1 == jsonParam.getCode()) {
+                    return ResponseJson.error(jsonParam.getMsg(), null);
+                }
+                PayParamBo payParam = jsonParam.getData();
+                pay.setP8_openid(payParam.getOpenId());
+            }
+            //合利宝主扫接口参数赋值
+            heliPayUtil.setOnlineValue(pay, heliDto, "second", headers);
+            Map<String, String> map = MyBeanUtils.convertBean(pay, new LinkedHashMap());
+            String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppPayPublicCreateOrderVo.NEED_SIGN_PARAMS);
+            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");
+                AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
+                String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppPayPublicOrderResponseVo.NEED_SIGN_PARAMS);
+                log.info("组装返回结果签名串:" + assemblyRespOriSign);
+                assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
+                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);
+                    saveWXSplit(heliDto, orderResponseVo);
+                    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);
+        }
+    }
+
+    private void saveWXSplit(HeliDto heliDto, AppPayPublicOrderResponseVo orderResponseVo) {
+        // 保存二手发布分账参数
+        SplitAccountPo splitAccount = new SplitAccountPo();
+        splitAccount.setProductId(heliDto.getProductId());
+        // 二手交易供应商
+        splitAccount.setShopId(1252);
+        splitAccount.setProductType(4);
+        splitAccount.setType(2);
+        splitAccount.setSplitAccount(99.75);
+        splitAccount.setMbOrderId(orderResponseVo.getRt6_serialNumber());
+        splitAccount.setOrderRequestNo(orderResponseVo.getRt5_orderId());
+        splitAccount.setPayStatus(0);
+        // 保存分账详情
+        payOrderMapper.insertSplitAccount(splitAccount);
+    }
+
+    /**
+     * 微信线上支付-获取微信支付信息
+     *
+     * @param payParam 支付参数
+     * @param headers  HttpHeaders
+     * @return payParam获取微信支付信息
+     */
+    private ResponseJson<PayParamBo> getWeChatResponseJson(PayParamBo payParam, HttpHeaders headers) {
+        // 微信线上支付
+        payParam.setPayWay("WEIXIN");
+        String openId = null;
+        if (null == payParam.getState()) {
+            // 小程序微信授权获取登录信息
+            ResponseJson<Map<String, Object>> appletsInfo = weChatService.getInfoMapByApplets(payParam.getCode(), headers, 1);
+            if (appletsInfo.getCode() == -1) {
+                return ResponseJson.error(appletsInfo.getMsg(), null);
+            }
+            Map<String, Object> infoData = appletsInfo.getData();
+            openId = (String) infoData.get(WeChatService.Keys.OPEN_ID);
+            if (StringUtils.isEmpty(openId)) {
+                return ResponseJson.error("微信小程序获取openId失败!", null);
+            }
+            //小程序微信快捷支付
+            payParam.setPayType("MINIAPP_WEIXIN");
+        } 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("try-catch:", e);
+            }
+            if (StringUtils.isEmpty(openId)) {
+                return ResponseJson.error("微信公众号获取openId失败!", null);
+            }
+            //pc微信扫码支付,微信公众号支付
+            payParam.setPayType("JSAPI_WEIXIN");
+        }
+        payParam.setOpenId(openId);
+        return ResponseJson.success(payParam);
+    }
+
+    /**
+     * 二手发布 支付宝/微信扫码支付
+     *
+     * @param heliDto {
+     *                productId      二手发布商品id
+     *                returnUrl     页面回调地址
+     *                }
+     * @param headers HttpHeaders
+     */
+    @Override
+    public ResponseJson<JSONObject> paySecondByAlipay(HeliDto heliDto, HttpHeaders headers) {
+        log.info("--------进入二手发布支付二维码创建接口----------");
+        try {
+            AppCreateOrderVo pay = new AppCreateOrderVo();
+            //合利宝主扫接口参数赋值
+            heliPayUtil.setValue(pay, heliDto, "second", 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 += 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");
+                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())) {
+                    //保存分账参数
+                    saveSplit(heliDto, orderResponseVo);
+                    return ResponseJson.success("二维码创建成功", jsonObject);
+                } else {
+                    return ResponseJson.error("二维码创建失败", jsonObject);
+                }
+            } else {
+                return ResponseJson.error("创建二维码请求失败", null);
+            }
+        } catch (Exception e) {
+            log.error("创建二维码请求失败" + e);
+            return ResponseJson.error("创建二维码请求失败", null);
+        }
+    }
+
+    //保存二手发布分账参数
+    private void saveSplit(HeliDto heliDto, AppCreateOrderResponseVo orderResponseVo) {
+        // 保存二手发布分账参数
+        SplitAccountPo splitAccount = new SplitAccountPo();
+        splitAccount.setProductId(heliDto.getProductId());
+        // 二手交易供应商
+        splitAccount.setShopId(1252);
+        splitAccount.setProductType(4);
+        splitAccount.setType(2);
+        splitAccount.setSplitAccount(99.75);
+        splitAccount.setMbOrderId(orderResponseVo.getRt6_serialNumber());
+        splitAccount.setOrderRequestNo(orderResponseVo.getRt5_orderId());
+        splitAccount.setPayStatus(0);
+        // 保存分账详情
+        payOrderMapper.insertSplitAccount(splitAccount);
+    }
+
+    /**
+     * 二手发布支付回调
+     */
+    @Override
+    public String paymentSecondCallback(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 + Constant.SPLIT + Constant.SAOMA;
+        String oriMessage2 = oriMessage + Constant.SPLIT + Constant.FENZHANG;
+        String oriMessage3 = oriMessage + Constant.SPLIT + Constant.XUNI;
+        String oriMessage4 = oriMessage + Constant.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 "验签失败!";
+        }
+        // 订单状态
+        String orderStatus = res.getRt4_status();
+        // 平台唯一流水号
+        String mbOrderId = res.getRt3_systemSerial();
+        // 附加数据,下单时若有传输则原样返回,下单时为空,则不返回该数据
+        String attach = res.getRt8_desc();
+        // 订单金额,以元为单位
+        Double amount = Double.valueOf(res.getRt5_orderAmount());
+        String payFormData = JSON.toJSONString(res);
+        log.info("【二手发布支付异步回调】>>>>>>>>>>>>>>支付订单状态:" + orderStatus);
+        if (!"SUCCESS".equals(orderStatus)) {
+            return "支付失败";
+        }
+        log.info("【二手发布支付异步回调】>>>>>>>>>>>>>>本次支付金额:" + amount);
+        String[] split = attach.split(",");
+        // 订单id
+        Integer productId = Integer.valueOf(split[0]);
+        // 支付类型
+        String payType = split[1];
+        payOrderMapper.updateSeconHandDetail(productId, payType, amount, payFormData);
+        //修改分账付款状态
+        payOrderMapper.updateSplitAccountByPay(mbOrderId);
+        //存收款列表
+        Date date = new Date();
+        String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
+        String payTyp = PayUtil.getPayTypeId(payType, split[2]);
+        // 保存收款记录
+        DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
+        discernReceipt.setPayWay(1);
+        discernReceipt.setPayType(Integer.valueOf(payTyp));
+        discernReceipt.setReceiptType(7);
+        discernReceipt.setReceiptStatus(3);
+        discernReceipt.setReceiptAmount(amount);
+        discernReceipt.setConfirmType(4);
+        discernReceipt.setRePayFlag(1);
+        discernReceipt.setFormData(payFormData);
+        discernReceipt.setReceiptDate(curDateStr);
+        discernReceipt.setConfirmDate(curDateStr);
+        discernReceipt.setReviewDate(curDateStr);
+        discernReceipt.setUpdateDate(curDateStr);
+        discernReceipt.setDelFlag(0);
+        // 保存 收款记录
+        baseMapper.insertDiscernReceipt(discernReceipt);
+        // 收款项和订单关系表
+        OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
+        relation.setReceiptId(discernReceipt.getId());
+        relation.setAssociateAmount(amount);
+        relation.setMbOrderId(mbOrderId);
+        relation.setSplitStatus(1);
+        relation.setRelationType(4);
+        relation.setDelFlag(0);
+        //二手商品id
+        relation.setProductId(productId);
+        // 保存 收款项和订单关系
+        baseMapper.insertOrderReceiptRelation(relation);
+        return "SUCCESS";
+    }
+
+    /**
+     * 设置支付基础参数
+     */
+    private JSONObject getPayJsonObject(PayParamBo payParam, HttpHeaders headers, long time) {
+        // 用户IP地址
+        String userIp = headers.getFirst("X-CLIENT-IP");
+        JSONObject json = new JSONObject();
+        json.put("merAccount", PayUtil.merAccount);
+        json.put("merNo", PayUtil.merNo);
+        json.put("time", time);
+        //支付金额
+        json.put("amount", payParam.getPayAmount());
+        json.put("payWay", payParam.getPayWay());
+        json.put("payType", payParam.getPayType());
+        json.put("userIp", userIp);
+        json.put("returnUrl", payParam.getReturnUrl());
+        json.put("notifyUrl", payParam.getNotifyUrl());
+        if (StringUtils.isNotBlank(payParam.getBankCode())) {
+            json.put("bankCode", payParam.getBankCode());
+        }
+        if (StringUtils.isNotBlank(payParam.getUserType())) {
+            json.put("userType", payParam.getUserType());
+        }
+        if (StringUtils.isNotBlank(payParam.getOpenId())) {
+            json.put("openId", payParam.getOpenId());
+        }
+        return json;
+    }
+
+    /**
+     * 升级超级会员-微信线上支付
+     *
+     * @param heliDto {
+     *                vipRecordId   会员购买记录Id
+     *                returnUrl     页面回调地址
+     *                code          微信小程序code
+     *                state         微信公众号state参数
+     *                }
+     * @param headers
+     */
+    @Override
+    public ResponseJson<JSONObject> paySuperVipByWeChat(HeliDto heliDto, HttpHeaders headers) {
+        log.info("--------进入超级会员公众号/小程序预创建订单接口----------");
+        try {
+            AppPayPublicCreateOrderVo pay = new AppPayPublicCreateOrderVo();
+            //微信给openid
+            if ("GZX".equals(heliDto.getPayType()) || "XCX".equals(heliDto.getPayType())) {
+                PayParamBo tempParam = new PayParamBo();
+                BeanUtils.copyProperties(heliDto, tempParam);
+                ResponseJson<PayParamBo> jsonParam = getWeChatResponseJson(tempParam, headers);
+                if (-1 == jsonParam.getCode()) {
+                    return ResponseJson.error(jsonParam.getMsg(), null);
+                }
+                PayParamBo payParam = jsonParam.getData();
+                pay.setP8_openid(payParam.getOpenId());
+            }
+            // 获取会员套餐记录
+            VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+            if (null == record) {
+                log.info("【升级超级会员-微信线上支付】该笔记录异常,记录Id:" + heliDto.getVipRecordId());
+                return ResponseJson.error("该笔记录异常!", null);
+            }
+            if (null != record.getPayStatus() && 1 == record.getPayStatus()) {
+                return ResponseJson.error("该笔记录已支付,请勿重复支付!", null);
+            }
+            //合利宝接口参数赋值
+            heliPayUtil.setOnlineValue(pay, heliDto, "vip", headers);
+            Map<String, String> map = MyBeanUtils.convertBean(pay, new LinkedHashMap());
+            String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppPayPublicCreateOrderVo.NEED_SIGN_PARAMS);
+            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");
+                AppPayPublicOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppPayPublicOrderResponseVo.class);
+                String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppPayPublicOrderResponseVo.NEED_SIGN_PARAMS);
+                log.info("组装返回结果签名串:" + assemblyRespOriSign);
+                assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
+                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);
+                    // 保存升级超级会员分账参数
+                    SplitAccountPo splitAccount = new SplitAccountPo();
+                    splitAccount.setVipRecordId(heliDto.getVipRecordId());
+                    // 超级会员 公账-专票
+                    splitAccount.setType(1);
+                    // 待分账总金额
+                    double splitAmount = record.getPrice();
+                    // 总手续费
+                    double procedureFee;
+                    //手续费
+                    procedureFee = MathUtil.mul(splitAmount, 0.0025, 2).doubleValue();
+                    if (MathUtil.compare(procedureFee, 0) == 0) {
+                        procedureFee = 0.01;
+                    }
+                    splitAmount = MathUtil.sub(splitAmount, procedureFee).doubleValue();
+                    splitAccount.setSplitAccount(splitAmount);
+                    splitAccount.setMbOrderId(orderResponseVo.getRt6_serialNumber());
+                    splitAccount.setOrderRequestNo(orderResponseVo.getRt5_orderId());
+                    splitAccount.setPayStatus(0);
+                    // 保存分账详情
+                    payOrderMapper.insertSplitAccount(splitAccount);
+                    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);
+        }
+    }
+
+    //超级会员pc二维码
+    @Override
+    public ResponseJson<JSONObject> paySuperVipByAlipay(HeliDto heliDto, HttpHeaders headers) {
+        // 获取会员套餐记录
+        VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+        if (null != record.getPayStatus() && 1 == record.getPayStatus()) {
+            return ResponseJson.error("该笔记录已支付,请勿重复支付!", null);
+        }
+        try {
+            AppCreateOrderVo pay = new AppCreateOrderVo();
+            //合利宝主扫接口参数赋值
+            heliPayUtil.setValue(pay, heliDto, "vip", 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 += 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");
+                AppCreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppCreateOrderResponseVo.class);
+                String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppCreateOrderResponseVo.NEED_SIGN_PARAMS);
+                log.info("组装返回结果签名串:" + assemblyRespOriSign);
+                assemblyRespOriSign += Constant.SPLIT + Constant.SAOMA;
+                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())) {
+                    //保存分账参数
+                    SplitAccountPo splitAccount = new SplitAccountPo();
+                    splitAccount.setVipRecordId(heliDto.getVipRecordId());
+                    // 超级会员 公账-专票
+                    splitAccount.setType(1);
+                    // 待分账总金额
+                    double splitAmount = record.getPrice();
+                    // 总手续费
+                    double procedureFee;
+                    //手续费
+                    procedureFee = MathUtil.mul(splitAmount, 0.0025, 2).doubleValue();
+                    if (MathUtil.compare(procedureFee, 0) == 0) {
+                        procedureFee = 0.01;
+                    }
+                    splitAmount = MathUtil.sub(splitAmount, procedureFee).doubleValue();
+                    splitAccount.setSplitAccount(splitAmount);
+                    splitAccount.setMbOrderId(orderResponseVo.getRt6_serialNumber());
+                    splitAccount.setOrderRequestNo(orderResponseVo.getRt5_orderId());
+                    splitAccount.setPayStatus(0);
+                    // 保存分账详情
+                    payOrderMapper.insertSplitAccount(splitAccount);
+                    return ResponseJson.success("二维码创建成功", jsonObject);
+                } else {
+                    return ResponseJson.error("二维码创建失败", jsonObject);
+                }
+            } else {
+                return ResponseJson.error("创建二维码请求失败", null);
+            }
+        } catch (Exception e) {
+            log.error("创建二维码请求失败" + e);
+            return ResponseJson.error("创建二维码请求失败", null);
+        }
+    }
+
+
+    /**
+     * 升级超级会员-支付回调
+     *
+     * @param res
+     */
+    @Override
+    public String paymentSuperVipCallback(NotifyResponseVo res) throws NoSuchAlgorithmException, InvalidKeySpecException, IntrospectionException, InvocationTargetException, IllegalAccessException {
+        log.info("******************** 升级超级会员异步回调 start *******************");
+        String sign = res.getSign();
+        log.info("回调签名" + sign);
+        // 公钥验签
+        String oriMessage = MyBeanUtils.getSigned(res, null);
+        String oriMessage1 = oriMessage + Constant.SPLIT + Constant.SAOMA;
+        String oriMessage2 = oriMessage + Constant.SPLIT + Constant.FENZHANG;
+        String oriMessage3 = oriMessage + Constant.SPLIT + Constant.XUNI;
+        String oriMessage4 = oriMessage + Constant.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 "验签失败!";
+        }
+        // 订单状态
+        String orderStatus = res.getRt4_status();
+        // 平台唯一流水号
+        String mbOrderId = res.getRt3_systemSerial();
+        // 商户唯一订单号
+        String orderRequestNo = res.getRt2_orderId();
+        // 金额,以元为单位
+        Double amount = Double.valueOf(res.getRt5_orderAmount());
+        String payFormData = JSON.toJSONString(res);
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>支付订单状态:" + orderStatus);
+        if (!"SUCCESS".equals(orderStatus)) {
+            return "支付失败";
+        }
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>>>>本次支付金额:" + amount);
+        // 附加数据,支付时若有传输则原样返回(vipId,userId,recordId,payType),下单时为空,则不返回该数据
+        String attach = res.getRt8_desc();
+        String[] split = attach.split(",");
+        int vipId = 0;
+        int userId = 0;
+        int recordId = 0;
+        int payType = 0;
+        try {
+            // 会员套餐Id
+            vipId = Integer.parseInt(split[0]);
+            // 用户Id
+            userId = Integer.parseInt(split[1]);
+            // 购买历史记录Id
+            recordId = Integer.parseInt(split[2]);
+            // 支付方式
+            payType = Integer.parseInt(split[3]);
+        } catch (NumberFormatException e) {
+            log.info("【升级超级会员异步回调】>>>>>>>>>>>>>>获取回调参数解析失败!");
+        }
+        //超级会员数据库修改
+        UserVipPo userVip = new UserVipPo();
+        UserVipPo dbUserVip = payOrderMapper.getUserVipInfo(userId);
+        Date beginTime = new Date();
+        if (null != dbUserVip && null != dbUserVip.getEndTime()) {
+            // 有效期内续费
+            beginTime = dbUserVip.getEndTime();
+            userVip.setId(dbUserVip.getId());
+        }
+        userVip.setUserId(userId);
+        userVip.setUpdateTime(new Date());
+        userVip.setBeginTime(beginTime);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(beginTime);
+        // 超级会员套餐时长(月)
+        Integer mouth = payOrderMapper.getVipPackageDurationById(vipId);
+        cal.add(Calendar.MONTH, mouth);
+        userVip.setEndTime(cal.getTime());
+        userVip.setDelFlag(0);
+        if (null != userVip.getId()) {
+            // 更新会员信息
+            payOrderMapper.updateUserVipInfo(userVip);
+        } else {
+            // 新增会员信息
+            payOrderMapper.insertUserVipInfo(userVip);
+        }
+        // 修改会员历史记录支付状态
+        VipRecordBo record = payOrderMapper.getVipPackageRecord(recordId);
+        record.setPayStatus(1);
+        record.setBeginTime(beginTime);
+        record.setEndTime(cal.getTime());
+        record.setPayWay(1);
+        record.setPayType(payType);
+        record.setPayTime(new Date());
+        payOrderMapper.updateVipPackageRecord(record);
+        // 修改支付链接状态
+        OrderPayLinkVo orderPayLink = payOrderMapper.getVipPayLink(recordId, amount);
+        if (null != orderPayLink && (12 == payType || 17 == payType)) {
+            orderPayLink.setPayStatus(1);
+            payOrderMapper.updateOrderPayLinkStatus(orderPayLink);
+        }
+        Date date = new Date();
+        String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
+        // 保存收款记录
+        DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
+        discernReceipt.setPayWay(1);
+        discernReceipt.setPayType(record.getPayType());
+        discernReceipt.setReceiptType(6);
+        discernReceipt.setReceiptStatus(3);
+        discernReceipt.setReceiptAmount(amount);
+        discernReceipt.setConfirmType(4);
+        discernReceipt.setRePayFlag(1);
+        discernReceipt.setFormData(payFormData);
+        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() + ",vipRecordId:" + recordId);
+        // 收款项和订单关系表
+        OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
+        relation.setReceiptId(discernReceipt.getId());
+        relation.setVipRecordId(recordId);
+        relation.setAssociateAmount(amount);
+        relation.setMbOrderId(mbOrderId);
+        relation.setOrderRequestNo(orderRequestNo);
+        relation.setSplitStatus(1);
+        relation.setRelationType(3);
+        relation.setDelFlag(0);
+        // 保存 收款项和订单关系
+        baseMapper.insertOrderReceiptRelation(relation);
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>收款项和购买历史关系(insert[cm_receipt_order_relation])id:" + relation.getId() + ",vipRecordId:" + recordId);
+        //修改分账付款状态
+        payOrderMapper.updateSplitAccountByPay(mbOrderId);
+        //已支付推送
+        boolean smsPushFlag = !orderRequestNo.contains("BETA") && !orderRequestNo.contains("DEV");
+        String bindMobile = baseMapper.getBindMobileByUserId(userId);
+        if (smsPushFlag && StringUtils.isNotBlank(bindMobile)) {
+            String shortLink = remoteCallService.getShortLink(8, 2, "https://www.caimei365.com/user/member.html?userId=" + userId);
+            String content = "恭喜您成功开通采美平台超级会员,为期" + mouth + "个月,快戳采美网站链接www.caimei365.com/t/" + shortLink + "或微信搜索“采美采购商城”小程序登录采美平台畅享会员特权吧。关注公众号“采美365网”可获取更多优惠和精彩资讯。退订回T";
+            boolean sendSms = remoteCallService.getSendSms(2, bindMobile, content);
+            if (!sendSms) {
+                log.info("购买会员短信推送失败");
+            }
+        }
+        return "SUCCESS";
+    }
+
+    @Override
+    public ResponseJson<String> unionPay(HeliDto heliDto, HttpHeaders headers) {
+        VipRecordBo record = payOrderMapper.getVipPackageRecord(heliDto.getVipRecordId());
+        if (null != record.getPayStatus() && 1 == record.getPayStatus()) {
+            return ResponseJson.error("该笔记录已支付,请勿重复支付!", null);
+        }
+        try {
+            log.info("--------进入超级会员网银线上支付接口----------");
+            HeliOnlineVo heliOnlineVo = new HeliOnlineVo();
+            heliPayUtil.setLinkValue(heliOnlineVo, heliDto, "vip", 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>");
+
+            // 保存升级超级会员分账参数
+            SplitAccountPo splitAccount = new SplitAccountPo();
+            splitAccount.setVipRecordId(heliDto.getVipRecordId());
+            // 超级会员 公账-专票
+            splitAccount.setType(1);
+            // 待分账总金额
+            Double splitAmount = Double.valueOf(heliOnlineVo.getP4_orderAmount());
+            //b2b10块 b2c0.2%
+            if ("B2B".equals(heliDto.getUserType())) {
+                splitAmount = MathUtil.sub(splitAmount, 10).doubleValue();
+            } else {
+                splitAmount = MathUtil.mul(splitAmount, 0.998).doubleValue();
+            }
+            splitAccount.setSplitAccount(splitAmount);
+            //流水号暂存唯一订单id
+            splitAccount.setMbOrderId(heliOnlineVo.getP2_orderId());
+            splitAccount.setOrderRequestNo(heliOnlineVo.getP2_orderId());
+            splitAccount.setPayStatus(0);
+            // 保存分账详情
+            payOrderMapper.insertSplitAccount(splitAccount);
+            return ResponseJson.success(sbHtml.toString());
+        } catch (Exception e) {
+            log.error("错误信息", e);
+            return ResponseJson.error("支付失败!", null);
+        }
+    }
+
+    @Override
+    public ResponseJson<String> unionPaySecond(HeliDto heliDto, HttpHeaders headers) {
+        log.info("--------进入二手上架费网银线上支付接口----------");
+        try {
+            HeliOnlineVo heliOnlineVo = new HeliOnlineVo();
+            heliPayUtil.setLinkValue(heliOnlineVo, heliDto, "second", 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 + "\"/>");
+                }
+            }
+            // 保存二手发布分账参数
+            SplitAccountPo splitAccount = new SplitAccountPo();
+            splitAccount.setOrderId(heliDto.getOrderId());
+            splitAccount.setProductId(heliDto.getProductId());
+            // 二手交易供应商
+            splitAccount.setShopId(1252);
+            splitAccount.setProductType(4);
+            splitAccount.setType(2);
+            //b2b10块 b2c0.2%
+            if ("B2B".equals(heliDto.getUserType())) {
+                splitAccount.setSplitAccount(90.00);
+            } else {
+                splitAccount.setSplitAccount(99.8);
+            }
+            //没有立即回调 流水号暂存唯一订单id
+            splitAccount.setMbOrderId(heliOnlineVo.getP2_orderId());
+            splitAccount.setOrderRequestNo(heliOnlineVo.getP2_orderId());
+            splitAccount.setPayStatus(0);
+            // 保存分账详情
+            payOrderMapper.insertSplitAccount(splitAccount);
+            //submit按钮控件请不要含有name属性
+            sbHtml.append("<input type=\"submit\" value=\"确认付款\"></form>");
+            return ResponseJson.success(sbHtml.toString());
+        } catch (Exception e) {
+            log.error("错误信息", e);
+            return ResponseJson.error("支付失败!", null);
+        }
+    }
+
+    @Override
+    public String unionVipCallback(UnionResVo data) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        log.info("******************** 升级超级会员网银支付异步回调 start *******************");
+        String sign = data.getSign();
+        log.info("回调签名" + sign);
+        // 公钥验签
+        String oriMessage = MyBeanUtils.getSigned(data, null);
+        String oriMessage1 = oriMessage + Constant.SPLIT + Constant.SAOMA;
+        String oriMessage2 = oriMessage + Constant.SPLIT + Constant.FENZHANG;
+        String oriMessage3 = oriMessage + Constant.SPLIT + Constant.XUNI;
+        String oriMessage4 = oriMessage + Constant.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 "验签失败!";
+        }
+        // 订单状态
+        String orderStatus = data.getRt11_orderStatus();
+        // 平台唯一流水号
+        String mbOrderId = data.getRt12_serialNumber();
+        // 商户唯一订单号
+        String orderRequestNo = data.getRt5_orderId();
+        // 金额,以元为单位
+        Double amount = Double.valueOf(data.getRt6_orderAmount());
+        String payFormData = JSON.toJSONString(data);
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>支付订单状态:" + orderStatus);
+        if (!"SUCCESS".equals(orderStatus)) {
+            return "支付失败";
+        }
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>>>>本次支付金额:" + amount);
+        // 附加数据,支付时若有传输则原样返回(vipId,userId,recordId,payType),下单时为空,则不返回该数据
+        String attach = data.getRt13_desc();
+        String[] split = attach.split(",");
+        int vipId = 0;
+        int userId = 0;
+        int recordId = 0;
+        int payType = 0;
+        try {
+            // 会员套餐Id
+            vipId = Integer.parseInt(split[0]);
+            // 用户Id
+            userId = Integer.parseInt(split[1]);
+            // 购买历史记录Id
+            recordId = Integer.parseInt(split[2]);
+            // 支付方式
+            payType = Integer.parseInt(split[3]);
+        } catch (NumberFormatException e) {
+            log.info("【升级超级会员异步回调】>>>>>>>>>>>>>>获取回调参数解析失败!");
+        }
+        //超级会员数据库修改
+        UserVipPo userVip = new UserVipPo();
+        UserVipPo dbUserVip = payOrderMapper.getUserVipInfo(userId);
+        Date beginTime = new Date();
+        if (null != dbUserVip && null != dbUserVip.getEndTime()) {
+            // 有效期内续费
+            beginTime = dbUserVip.getEndTime();
+            userVip.setId(dbUserVip.getId());
+        }
+        userVip.setUserId(userId);
+        userVip.setUpdateTime(new Date());
+        userVip.setBeginTime(beginTime);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(beginTime);
+        // 超级会员套餐时长(月)
+        Integer mouth = payOrderMapper.getVipPackageDurationById(vipId);
+        cal.add(Calendar.MONTH, mouth);
+        userVip.setEndTime(cal.getTime());
+        userVip.setDelFlag(0);
+        if (null != userVip.getId()) {
+            // 更新会员信息
+            payOrderMapper.updateUserVipInfo(userVip);
+        } else {
+            // 新增会员信息
+            payOrderMapper.insertUserVipInfo(userVip);
+        }
+        // 修改会员历史记录支付状态
+        VipRecordBo record = payOrderMapper.getVipPackageRecord(recordId);
+        record.setPayStatus(1);
+        record.setBeginTime(beginTime);
+        record.setEndTime(cal.getTime());
+        record.setPayWay(1);
+        record.setPayType(payType);
+        record.setPayTime(new Date());
+        payOrderMapper.updateVipPackageRecord(record);
+        // 修改支付链接状态
+        OrderPayLinkVo orderPayLink = payOrderMapper.getVipPayLink(recordId, amount);
+        if (null != orderPayLink && (12 == payType || 17 == payType)) {
+            orderPayLink.setPayStatus(1);
+            payOrderMapper.updateOrderPayLinkStatus(orderPayLink);
+        }
+        Date date = new Date();
+        String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
+        // 保存收款记录
+        DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
+        discernReceipt.setPayWay(1);
+        discernReceipt.setPayType(record.getPayType());
+        discernReceipt.setReceiptType(6);
+        discernReceipt.setReceiptStatus(3);
+        discernReceipt.setReceiptAmount(amount);
+        discernReceipt.setConfirmType(4);
+        discernReceipt.setRePayFlag(1);
+        discernReceipt.setFormData(payFormData);
+        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() + ",vipRecordId:" + recordId);
+        // 收款项和订单关系表
+        OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
+        relation.setReceiptId(discernReceipt.getId());
+        relation.setVipRecordId(recordId);
+        relation.setAssociateAmount(amount);
+        relation.setMbOrderId(mbOrderId);
+        relation.setOrderRequestNo(orderRequestNo);
+        relation.setSplitStatus(1);
+        relation.setRelationType(3);
+        relation.setDelFlag(0);
+        // 保存 收款项和订单关系
+        baseMapper.insertOrderReceiptRelation(relation);
+        log.info("【升级超级会员异步回调】>>>>>>>>>>>收款项和购买历史关系(insert[cm_receipt_order_relation])id:" + relation.getId() + ",vipRecordId:" + recordId);
+        //已支付推送
+        boolean smsPushFlag = !orderRequestNo.contains("BETA") && !orderRequestNo.contains("DEV");
+        String bindMobile = baseMapper.getBindMobileByUserId(userId);
+        if (smsPushFlag && StringUtils.isNotBlank(bindMobile)) {
+            String shortLink = remoteCallService.getShortLink(8, 2, "https://www.caimei365.com/user/member.html?userId=" + userId);
+            String content = "恭喜您成功开通采美平台超级会员,为期" + mouth + "个月,快戳采美网站链接www.caimei365.com/t/" + shortLink + "或微信搜索“采美采购商城”小程序登录采美平台畅享会员特权吧。关注公众号“采美365网”可获取更多优惠和精彩资讯。退订回T";
+            boolean sendSms = remoteCallService.getSendSms(2, bindMobile, content);
+            if (!sendSms) {
+                log.info("购买会员短信推送失败");
+            }
+        }
+        //修改分账付款状态
+        //合利宝无立即回调,这里用唯一订单id查,然后把真实mborderid存进去
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        //12企业17个人
+        if ("12".equals(payType)) {
+            //vipprice-(vipprice-10手续费)*(1-0.1%)分账手续费
+            totalAmount = MathUtil.mul(MathUtil.sub(amount, 10), 0.999);
+        } else if ("17".equals(payType)) {
+            //vipprice-(vipprice-0.2%*vipprice手续费)*(1-0.1%)
+            totalAmount = MathUtil.mul(MathUtil.mul(amount, 0.998), 0.999);
+        } else {
+            log.info("二手网银分账类型参数payType错误======================》" + payType);
+            return "SUCCESS";
+        }
+        split(data.getRt5_orderId(), totalAmount);
+        return "SUCCESS";
+    }
+
+    @Override
+    public String unionSecondCallback(UnionResVo res) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
+        log.info("******************** 二手发布网银支付异步回调 start *******************");
+        String sign = res.getSign();
+        log.info("回调签名" + sign);
+        // 公钥验签
+        String oriMessage = MyBeanUtils.getSigned(res, null);
+        String oriMessage1 = oriMessage + Constant.SPLIT + Constant.SAOMA;
+        String oriMessage2 = oriMessage + Constant.SPLIT + Constant.FENZHANG;
+        String oriMessage3 = oriMessage + Constant.SPLIT + Constant.XUNI;
+        String oriMessage4 = oriMessage + Constant.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 "验签失败!";
+        }
+        // 订单状态
+        String orderStatus = res.getRt11_orderStatus();
+        // 平台唯一流水号
+        String mbOrderId = res.getRt12_serialNumber();
+        // 附加数据,下单时若有传输则原样返回,下单时为空,则不返回该数据
+        String attach = res.getRt13_desc();
+        // 订单金额,以元为单位
+        Double amount = Double.valueOf(res.getRt6_orderAmount());
+        String payFormData = JSON.toJSONString(res);
+        log.info("【二手发布支付异步回调】>>>>>>>>>>>>>>支付订单状态:" + orderStatus);
+        if (!"SUCCESS".equals(orderStatus)) {
+            return "支付失败";
+        }
+        log.info("【二手发布支付异步回调】>>>>>>>>>>>>>>本次支付金额:" + amount);
+        String[] split = attach.split(",");
+        // 订单id
+        Integer productId = Integer.valueOf(split[0]);
+        // 支付类型
+        String payType = split[1];
+        payOrderMapper.updateSeconHandDetail(productId, payType, amount, payFormData);
+        //存收款列表
+        Date date = new Date();
+        String curDateStr = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(date);
+//        String payTyp = PayUtil.getPayTypeId(payType, split[2]);
+        // 保存收款记录
+        DiscernReceiptPo discernReceipt = new DiscernReceiptPo();
+        discernReceipt.setPayWay(1);
+        discernReceipt.setPayType(Integer.valueOf(payType));
+        discernReceipt.setReceiptType(7);
+        discernReceipt.setReceiptStatus(3);
+        discernReceipt.setReceiptAmount(amount);
+        discernReceipt.setConfirmType(4);
+        discernReceipt.setRePayFlag(1);
+        discernReceipt.setFormData(payFormData);
+        discernReceipt.setReceiptDate(curDateStr);
+        discernReceipt.setConfirmDate(curDateStr);
+        discernReceipt.setReviewDate(curDateStr);
+        discernReceipt.setUpdateDate(curDateStr);
+        discernReceipt.setDelFlag(0);
+        // 保存 收款记录
+        baseMapper.insertDiscernReceipt(discernReceipt);
+        // 收款项和订单关系表
+        OrderReceiptRelationPo relation = new OrderReceiptRelationPo();
+        relation.setReceiptId(discernReceipt.getId());
+        relation.setAssociateAmount(amount);
+        relation.setMbOrderId(mbOrderId);
+        relation.setSplitStatus(1);
+        relation.setRelationType(4);
+        relation.setDelFlag(0);
+        //二手商品id
+        relation.setProductId(productId);
+        // 保存 收款项和订单关系
+        baseMapper.insertOrderReceiptRelation(relation);
+        //修改分账付款状态
+        //合利宝无立即回调,这里用唯一订单id查,然后把真实mborderid存进去
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        //12企业17个人
+        if ("12".equals(payType)) {
+            //100-(100-10手续费)*0.1%分账手续费
+            totalAmount = MathUtil.mul(90, 0.999);
+        } else if ("17".equals(payType)) {
+            //100-(100-0.2%*100手续费)*0.1%
+            totalAmount = MathUtil.mul(99.8, 0.999);
+        } else {
+            log.info("二手网银分账类型参数payType错误======================》" + payType);
+            return "SUCCESS";
+        }
+        split(res.getRt5_orderId(), totalAmount);
+        return "SUCCESS";
+    }
+
+    void split(String orderId, BigDecimal totalAmount) {
+        log.info("超级会员/二手发布网银支付回调分账开始================================分账金额 》 " + totalAmount);
+        try {
+            AccountPayOrder accountPayOrder = new AccountPayOrder();
+            accountPayOrder.setP1_bizType("AccountPaySub");
+            accountPayOrder.setP2_signType("MD5");
+            accountPayOrder.setP3_timestamp(new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS").format(new Date()));
+            // fz+原唯一订单号
+            accountPayOrder.setP4_orderId("FZ" + orderId);
+            //付款账户商编
+            accountPayOrder.setP5_customerNumber(Constant.CUSTOMERNUM2);
+            AccountPayOrder.AccountPayOrderExt accountPayOrderExt = new AccountPayOrder.AccountPayOrderExt();
+            //收款账户商编
+            accountPayOrderExt.setInMerchantNo(Constant.CUSTOMERNUM);
+            accountPayOrderExt.setOrderType(AccountPayOrderType.TRANSFER);
+            accountPayOrderExt.setAmount(totalAmount);
+            //todo 二手/vip的网银支付无法立即分账,这里放在支付回调里面分账,暂不设置回调
+            //accountPayOrderExt.setServerCallbackUrl(callUrl);
+            accountPayOrderExt.setGoodsName("分账");
+            String ext = JSON.toJSONString(accountPayOrderExt);
+            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(Constant.FENZHANG);
+            String sign = Disguiser.disguiseMD5(builder.toString());
+            Map<String, String> bean = HeliPayServiceImpl.convertBean(accountPayOrder);
+            Map<String, String> map = HeliPayServiceImpl.postForm(bean, Constant.FZ, sign, Map.class);
+            if (map != null) {
+                String code = map.get("rt5_retCode");
+                if (!"0000".equals(code)) {
+                    String msg = map.get("rt6_retMsg");
+                    log.info("【二手/vip网银立即分账失败】>>>>>>>>>>立即分账失败>>>>>>>msg:" + msg);
+                } else {
+                    //分账成功改变分账状态
+                    payOrderMapper.updateSplitAccount(map.get("rt9_serialNumber"), orderId);
+                    log.info("【二手/vip网银立即分账成功】>>>>>>>>>>此订单分账结束");
+                }
+            }
+        } catch (Exception e) {
+            log.error("【二手/vip网银立即分账失败】>>>>>>>>>>错误信息", e);
+        }
+    }
+}
+

+ 1351 - 0
src/main/java/com/caimei365/order/service/impl/HeliPayServiceImpl.java

@@ -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;
+    }
+
+}