package com.fs.his.service.impl;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fs.common.annotation.DataScope;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.ip.IpUtils;
import com.fs.company.domain.Company;
import com.fs.company.domain.CompanyDivItem;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyConfigMapper;
import com.fs.company.param.FsStoreStatisticsParam;
import com.fs.company.service.ICompanyConfigService;
import com.fs.company.service.ICompanyDivItemService;
import com.fs.company.service.ICompanyService;
import com.fs.company.service.ICompanyUserService;
import com.fs.company.vo.FsStorePaymentStatisticsVO;
import com.fs.config.cloud.CloudHostProper;
import com.fs.core.config.WxMaConfiguration;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.course.config.RedPacketConfig;
import com.fs.course.service.IFsCourseRedPacketLogService;
import com.fs.course.service.IFsUserCourseOrderService;
import com.fs.course.service.IFsUserVipOrderService;
import com.fs.his.domain.*;
import com.fs.his.dto.PayConfigDTO;
import com.fs.his.enums.PaymentMethodEnum;
import com.fs.his.mapper.*;
import com.fs.his.param.FsStorePaymentParam;
import com.fs.his.param.PayOrderParam;
import com.fs.his.param.WxSendRedPacketParam;
import com.fs.his.service.IFsInquiryOrderService;

import com.fs.his.param.WxSendRedPacketParam;
import com.fs.his.service.IFsInquiryOrderService;
import com.fs.his.service.IFsPackageOrderService;
import com.fs.his.service.IFsStoreOrderService;
import com.fs.his.service.IFsStorePaymentService;
import com.fs.his.utils.PhoneUtil;
import com.fs.his.vo.FsStorePaymentExcelVO;
import com.fs.his.vo.FsStorePaymentVO;
import com.fs.hisStore.domain.FsStorePaymentScrm;
import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
import com.fs.hisStore.param.FsStorePaymentGetWxaCodeParam;
import com.fs.hisStore.param.FsStorePaymentPayParam;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import com.fs.system.service.ISysConfigService;
import com.fs.tzBankPay.TzBankService.TzBankService;
import com.fs.tzBankPay.doman.*;
import com.fs.ybPay.domain.CreateWxOrderResult;
import com.fs.ybPay.domain.OrderResult;
import com.fs.ybPay.dto.OrderQueryDTO;
import com.fs.ybPay.dto.RefundDTO;
import com.fs.ybPay.dto.WxJspayDTO;
import com.fs.ybPay.service.IPayService;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.transfer.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.TransferService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.gson.Gson;
import com.hc.openapi.tool.fastjson.JSON;
import me.chanjar.weixin.common.error.WxErrorException;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;

/**
 * 支付明细Service业务层处理
 *
 * @author fs
 * @date 2023-08-11
 */
@Service
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private FsStorePaymentMapper fsStorePaymentMapper;
    @Autowired
    private FsStorePaymentScrmMapper fsStorePaymentScrmMapper;
    @Autowired
    private TzBankService tzBankService;
    @Autowired
    private IFsInquiryOrderService inquiryOrderService;
    @Autowired
    private IFsStoreOrderService storeOrderService;
    @Autowired
    private IFsPackageOrderService packageOrderService;
    @Autowired
    private IPayService ybPayService;
    @Autowired
    private HuiFuService huiFuService;
    @Autowired
    private IFsUserCourseOrderService courseOrderService;
    @Autowired
    private IFsUserVipOrderService vipOrderService;
    @Autowired
    SysConfigMapper sysConfigMapper;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    FsExportTaskMapper fsExportTaskMapper;
    @Autowired
    private IFsCourseRedPacketLogService redPacketLogService;
    @Autowired
    private CompanyConfigMapper companyConfigMapper;
    @Autowired
    private FsUserMapper userMapper;
    @Autowired
    private FsUserWxMapper userWxMapper;
    @Autowired
    private ICompanyUserService companyUserService;
    @Autowired
    private ICompanyService companyService;

    @Autowired
    private CloudHostProper cloudHostProper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    @Qualifier("redisTemplateForBigDecimal")
    private RedisTemplate<String,BigDecimal> redisTemplate;

    @Autowired
    @Qualifier("redisTemplateForInteger")
    private RedisTemplate<String,Integer> redisTemplateInteger;
    /**
     * 红包领取数量限制 默认一个用户当天最多只能领取10个
     */
    @Value("${RED_PACKET_LIMIT_COUNT:10}")
    private Integer RED_PACKET_LIMIT_COUNT;
    @Autowired
    private ISysConfigService sysConfigService;

    /**
     * 是否开启红包账户扣减
     */
    @Value("${enableRedPackAccount:0}")
    private String ENABLE_RED_PACK_ACCOUNT;

    @Autowired
    private ICompanyConfigService companyConfigService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedPacketLogMapper redPacketLogMapper;

    @Autowired
    private ICompanyDivItemService companyDivItemService;

    @Value("${cloud_host.company_name}")
    private String signProjectName;

    /**
     * 红包账户锁
     */
    private static final String REDPACKET_POOL_LOCK = "redpacket_pool_lock";
    /**
     * 红包锁
     */
    private static final String REDPACKET_LOCK = "redpacket_lock:%d";

    /**
     * 公司红包金额
     */
    private static final String REDPACKET_COMPANY_MONEY = "redpacket_money";

    /**
     * 用户领取红包限制
     */
    private static final String REDPACKET_USER_LIMIT = "redpacket_user_limit:%s:%d";



    /**
     * 查询支付明细
     *
     * @param paymentId 支付明细主键
     * @return 支付明细
     */
    @Override
    public FsStorePayment selectFsStorePaymentByPaymentId(Long paymentId) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
    }

    /**
     * 查询支付明细列表
     *
     * @param fsStorePayment 支付明细
     * @return 支付明细
     */
    @Override
    public List<FsStorePayment> selectFsStorePaymentList(FsStorePayment fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentList(fsStorePayment);
    }

    /**
     * 新增支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int insertFsStorePayment(FsStorePayment fsStorePayment) {
        fsStorePayment.setCreateTime(DateUtils.getNowDate());
        return fsStorePaymentMapper.insertFsStorePayment(fsStorePayment);
    }

    /**
     * 修改支付明细
     *
     * @param fsStorePayment 支付明细
     * @return 结果
     */
    @Override
    public int updateFsStorePayment(FsStorePayment fsStorePayment) {
        return fsStorePaymentMapper.updateFsStorePayment(fsStorePayment);
    }

    /**
     * 批量删除支付明细
     *
     * @param paymentIds 需要删除的支付明细主键
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentByPaymentIds(Long[] paymentIds) {
        return fsStorePaymentMapper.deleteFsStorePaymentByPaymentIds(paymentIds);
    }

    /**
     * 删除支付明细信息
     *
     * @param paymentId 支付明细主键
     * @return 结果
     */
    @Override
    public int deleteFsStorePaymentByPaymentId(Long paymentId) {
        return fsStorePaymentMapper.deleteFsStorePaymentByPaymentId(paymentId);
    }

    @Override
    public List<FsStorePaymentVO> selectFsStorePaymentListVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentListVO(fsStorePayment);
    }

    @Override
    public FsStorePaymentVO selectFsStorePaymentByPaymentIdVO(Long paymentId) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentIdVO(paymentId);
    }

    @Override
    public List<FsStorePaymentStatisticsVO> selectFsStorePaymentStatisticsList(FsStoreStatisticsParam param) {
        return fsStorePaymentMapper.selectFsStorePaymentStatisticsList(param);
    }

    @Override
    public List<JSONObject> selectFsStorePaymentCounts(Map<String, Object> toMap) {
        return fsStorePaymentMapper.selectFsStorePaymentCounts(toMap);
    }

    @Override
    public Long selectFsStorePaymentCount(int type, Long companyId) {
        return fsStorePaymentMapper.selectFsStorePaymentCount(type, companyId);
    }

    @Override
    public List<FsStorePaymentExcelVO> selectFsStorePaymentExcelVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentExcelVO(fsStorePayment);
    }

    @Override
    public String updateFsStorePaymentByDecryptForm(Long paymentId) {
        FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
        logger.info("手动查询单号:" + paymentId + ":" + fsStorePayment);
        if (fsStorePayment.getPayMode().equals("tz")) {
            payQueryOrder payQueryOrder = new payQueryOrder();
            payQueryOrder.setOrderFlowNo(fsStorePayment.getTradeNo());
            TzBankResult<QueryOrderResult> result = tzBankService.queryOrder(payQueryOrder);
            logger.info("手动查询内容:" + paymentId + ":" + result);
            if (result.getRetType().equals("S") && result.getBody().getStatus().equals("90")) {
                QueryOrderResult body = result.getBody();
                logger.info("手动回调内容:" + body);
                if (fsStorePayment.getBusinessType() == 1) {
                    inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1,null,null);
                } else if (fsStorePayment.getBusinessType() == 2) {
                    storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1,null,null);
                } else if (fsStorePayment.getBusinessType() == 3) {
                    packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), body.getPayType(), 1,null,null);
                }else if (fsStorePayment.getBusinessType() == 4) {
                    courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,null,null);
                }else if (fsStorePayment.getBusinessType() == 5) {
                    vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,null,null);
                }
            }
        }
        if (fsStorePayment.getPayMode().equals("yb")) {
            OrderQueryDTO o = new OrderQueryDTO();
            o.setUpOrderId(fsStorePayment.getTradeNo());
            OrderResult orderResult = ybPayService.getOrder(o);

            if ("0".equals(orderResult.getState())) {
                if (orderResult.getStatus().equals("100")) {
                    logger.info("手动查询内容:" + paymentId + ":" + orderResult);
                    if (orderResult.getStatus().equals("100")) {
                        if (fsStorePayment.getBusinessType() == 1) {
                            inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,null,null);
                        } else if (fsStorePayment.getBusinessType() == 2) {
                            storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,null,null);
                        } else if (fsStorePayment.getBusinessType() == 3) {
                            packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,null,null);
                        }else if (fsStorePayment.getBusinessType() == 4) {
                            courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,null,null);
                        }else if (fsStorePayment.getBusinessType() == 5) {
                            vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,null,null);
                        }
                    }
                }
            }
        }
        if (fsStorePayment.getPayMode().equals("hf")) {
            V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
            request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(fsStorePayment.getCreateTime()));
            request.setOrgHfSeqId(fsStorePayment.getTradeNo());
            HuiFuQueryOrderResult queryOrderResult = null;
            try {
                queryOrderResult = huiFuService.queryOrder(request);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            logger.info("汇付返回"+queryOrderResult);
            if ("00000000".equals(queryOrderResult.getResp_code())) {
                if (queryOrderResult.getTrans_stat().equals("S")) {
                    logger.info("手动查询内容:" + paymentId + ":" + request);
                        if (fsStorePayment.getBusinessType() == 1) {
                            inquiryOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,queryOrderResult.getOut_trans_id(),queryOrderResult.getParty_order_id());
                        } else if (fsStorePayment.getBusinessType() == 2) {
                            storeOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,queryOrderResult.getOut_trans_id(),queryOrderResult.getParty_order_id());
                        } else if (fsStorePayment.getBusinessType() == 3) {
                            packageOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "14", 1,queryOrderResult.getOut_trans_id(),queryOrderResult.getParty_order_id());
                        }  else if (fsStorePayment.getBusinessType() == 4) {
                            courseOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,queryOrderResult.getOut_trans_id(),queryOrderResult.getParty_order_id());
                        }else if (fsStorePayment.getBusinessType() == 5) {
                            vipOrderService.payConfirm("", fsStorePayment.getPayCode(), fsStorePayment.getTradeNo(), "", 1,queryOrderResult.getOut_trans_id(),queryOrderResult.getParty_order_id());
                        }

                }
            }
        }
        return "同步完成";
}
    @Autowired
    IPayService payService;
    @Override
    public R refundFsStorePayment(Long paymentId) {
        FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
        if(fsStorePayment!=null){
            String orderType="";
            if (fsStorePayment.getBusinessType()==1){
                orderType="inquiry";
            }else if (fsStorePayment.getBusinessType()==2){
                orderType="store";
            }else if (fsStorePayment.getBusinessType()==3){
                orderType="package";
            }else if (fsStorePayment.getBusinessType()==4){
                orderType="course";
            }else if (fsStorePayment.getBusinessType()==5){
                orderType="appvip";
            } else if (fsStorePayment.getBusinessType()==7){
                orderType="payment";
            }

            if(fsStorePayment.getPayMode().equals("wx")){
                WxPayConfig payConfig = new WxPayConfig();
                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setKeyPath(wxPayProperties.getKeyPath());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                wxPayService.setConfig(payConfig);
                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
                refundRequest.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
                refundRequest.setOutRefundNo(orderType+"-"+fsStorePayment.getPayCode());
                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
                try {
                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
                    if(refundQueryResult!=null&&refundQueryResult.getResultCode().equals("SUCCESS")){
                        FsStorePayment paymentMap=new FsStorePayment();
                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                        paymentMap.setStatus(-1);
                        paymentMap.setRefundTime(DateUtils.getNowDate());
                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    }
                    else {
                        throw new CustomException("退款请求失败"+refundQueryResult.getReturnMsg());
                    }
                } catch (WxPayException e) {
                    throw new CustomException("退款请求失败"+e.getReturnMsg());
                }
            }
            else if(fsStorePayment.getPayMode().equals("yb")){
                //易宝
                RefundDTO refundDTO=new RefundDTO();
                refundDTO.setRefundMoney(fsStorePayment.getPayMoney().toString());
                refundDTO.setLowRefundNo(orderType+"-"+fsStorePayment.getPayCode());
                refundDTO.setUpOrderId(fsStorePayment.getTradeNo());
                com.fs.ybPay.domain.RefundResult result=payService.refund(refundDTO);
                logger.info("订单退款返回结果:退款订单id:"+paymentId+result);
                if(result.getState().equals("5")){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                }else {
                    throw new CustomException("退款请求失败"+result.getMessage());
                }
            } else if(fsStorePayment.getPayMode().equals("tz")){
                RefundParam tzBankResult = new RefundParam();
                // 使用set方法为对象的字段赋值
                //商户原支付订单号
                tzBankResult.setOldPayOutOrderNo(orderType+fsStorePayment.getPayCode());
                // 商户退款订单号 对接平台系统里自己生成的退款订单号
                tzBankResult.setRefundOrderNo(orderType+fsStorePayment.getPayCode());
                // 交易发送时间 yyyyMMddHHmmss
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                tzBankResult.setTrxSendTime(sdf.format(new Date()));
                // 退款金额
                tzBankResult.setRefundOrdTransAmt(fsStorePayment.getPayMoney().doubleValue());
                TzBankResult<com.fs.tzBankPay.doman.RefundResult> result = tzBankService.refund(tzBankResult);
                logger.info("订单退款返回结果:退款订单id:"+paymentId+result);
                if(result.getBody().getRefundOrdStatus().equals("90")||result.getBody().getRefundOrdStatus().equals("60")){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                }else {
                    throw new CustomException("退款请求失败"+result.getRetMsg());
                }
            }
            else if(fsStorePayment.getPayMode().equals("hf")){
                V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                request.setOrdAmt(fsStorePayment.getPayMoney().toString());
                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(fsStorePayment.getCreateTime()));
                request.setReqSeqId("refund-"+fsStorePayment.getPayCode());
                Map<String, Object> extendInfoMap = new HashMap<>();
                extendInfoMap.put("org_req_seq_id", orderType+"-"+fsStorePayment.getPayCode());
                request.setExtendInfo(extendInfoMap);
                //处理分账退款
                //1.判断是否是全额退款
                CompanyDivItem companyDivItem = null;
                try {
                    companyDivItem = HuiFuUtils.doRefundDiv(fsStorePayment.getPayMoney(), fsStorePayment.getPayMoney(), fsStorePayment, extendInfoMap);
                } catch (Exception e) {
                    logger.error("-----------------分账退款处理失败{}", e.getMessage());
                }
                HuiFuRefundResult refund = huiFuService.refund(request);
                logger.info("订单退款返回结果:"+paymentId+""+refund);
                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
                    FsStorePayment paymentMap=new FsStorePayment();
                    paymentMap.setPaymentId(fsStorePayment.getPaymentId());
                    paymentMap.setStatus(-1);
                    paymentMap.setRefundTime(DateUtils.getNowDate());
                    paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                    try {
                        //处理分账退款明细表
                        if (companyDivItem !=null && companyDivItem.getId() != null) {
                            companyDivItem.setIsRefund(1);
                            companyDivItemService.updateCompanyDivItem(companyDivItem);
                        }
                    } catch (Exception e) {
                        logger.error("-----------------分账退款明细处理失败{}", e.getMessage());
                    }
                }else {
                    throw new CustomException("退款请求失败"+refund.getResp_desc());
                }
            }
        }
        return R.ok();
    }

    @Override
    public FsStorePayment selectFsStorePaymentByPaymentCode(String payCode) {
        return fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
    }


    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public R sendRedPacket(WxSendRedPacketParam param) {
        IFsStorePaymentService service = (IFsStorePaymentService) AopContext.currentProxy();

        if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
            return service.sendRedPacketDeduction(param);
        } else {
            return service.sendRedPacketLimit(param);
        }
    }


    @Override
    public R sendRedPacketLimit(WxSendRedPacketParam param){
        FsUser user = param.getUser();

        if(user == null) {
            throw new IllegalArgumentException("[发送红包] 用户id为必传参数！");
        }
        Long userId = user.getUserId();

        String key = String.format(REDPACKET_LOCK,userId);
        RLock lock = redissonClient.getLock(key);

        try{
            boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);

//            if (!locked) {
//                logger.error("获取锁失败");
//                return R.error("[红包领取] 系统繁忙，请重试！");
//            }


            // 判断当前用户是否限流
            String today = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
            String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, userId);
            Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);


            // 首次领取
            if(userCount == null) {
                userCount = 0;
                long expireSeconds = getExpireSeconds();
                redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
            }

            if(userCount >= RED_PACKET_LIMIT_COUNT){
                logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",userId);
                return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制！");
            }

            String json;
            RedPacketConfig config = new RedPacketConfig();
            // 根据红包模式获取配置
            switch (param.getRedPacketMode()){
                case 1:
                    json = configService.selectConfigByKey("redPacket.config");
                    config = JSONUtil.toBean(json, RedPacketConfig.class);
                    break;
                case 2:
                    json = companyConfigService.selectRedPacketConfigByKey(param.getCompanyId());
                    config = JSONUtil.toBean(json, RedPacketConfig.class);
                    break;
                default:
                    throw new UnsupportedOperationException("当前红包模式不支持!");
            }
            //H5的用公众号的appid发，小程序的用小程序的appid来发
            if (param.getSource()==2){
                // 传参appId为空时，仍然使用配置里面的
                String appId = StringUtils.isBlank(param.getAppId()) ? config.getMiniappId() : param.getAppId();
                config.setAppId(appId);
            }
            logger.info("最终传参 {}",config);
            //组合返回参数
            R result = new R();
            // 根据 isNew 判断使用哪种发红包方式
            if (config.getIsNew() != null && config.getIsNew() == 1) {
                result = sendRedPacketV3Internal(param, config);
            } else {
                result= sendRedPacketLegacyInternal(param, config);
            }
            result.put("mchId", config.getMchId());
            result.put("isNew",config.getIsNew());
            logger.info("红包返回：{}",result);

            // 用户领取红包次数+1
            redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
            return result;
        }catch (Exception e){
            logger.error("领取红包失败原因：{}", ExceptionUtils.getMessage(e),e);
            if (e instanceof WxPayException && "济南联志健康".equals(signProjectName)) {
                WxPayException wxPayException = (WxPayException) e;
                String customErrorMsg = wxPayException.getCustomErrorMsg();
                if (null != customErrorMsg && customErrorMsg.startsWith("商户运营账户资金不足")) {
                    return R.error("[红包领取] 账户余额不足，请联系管理员！");
                }
            }
            throw new RuntimeException(e);
        }finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 开启红包账户扣减-发红包
     */
    @Override
    public R sendRedPacketDeduction(WxSendRedPacketParam param){
        //---------------发红包前先判断润天账户余额是否足够---------
        RLock lock = redissonClient.getLock(REDPACKET_POOL_LOCK);
        RedPacketLog redPacketLog = null;

        try{
            boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);

            if (!locked) {
                logger.error("获取锁失败");
                return R.error("[红包领取] 系统繁忙，请重试！");
            }

            FsUser user = param.getUser();
            BigDecimal amount = param.getAmount();

            if(user == null) {
                throw new IllegalArgumentException("[发送红包] 用户id为必传参数！");
            }
            Long userId = user.getUserId();

            // 判断当前用户是否限流
            String today = LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
            String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, userId);
            Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);


            // 首次领取
            if(userCount == null) {
                userCount = 0;
                long expireSeconds = getExpireSeconds();
                redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
            }

            if(userCount >= RED_PACKET_LIMIT_COUNT){
                logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",userId);
                return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制！");
            }


            BigDecimal companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);

            if(ObjectUtils.isNull(companyMoney)){
                SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("company.money");
                if(ObjectUtils.isNull(sysConfig)){
                    throw new IllegalArgumentException("润天公司账户余额不能为空！请检查配置！");
                }
                String configValue = sysConfig.getConfigValue();
                companyMoney = new BigDecimal(configValue);
                logger.info("缓存公司余额为空，从数据库读取 companyMoney: {}",companyMoney);
            }

            if (companyMoney.compareTo(BigDecimal.ZERO) <= 0) {
                logger.info("润天账户余额: {} 不足!", companyMoney);
                return R.error("[红包领取] 账户余额不足，请联系管理员！");
            }

            redPacketLog = new RedPacketLog();
            redPacketLog.setRedPacketMode(param.getRedPacketMode());
            redPacketLog.setAmount(param.getAmount());
            redPacketLog.setAppId(param.getAppId());
            redPacketLog.setCompanyId(param.getCompanyId());
            redPacketLog.setCreateTime(LocalDateTime.now());
            redPacketLog.setUserId(userId);
            redPacketLog.setAccBalanceBefore(companyMoney);
            redPacketLog.setSource(param.getSource());

            String json;
            RedPacketConfig config = new RedPacketConfig();
            // 根据红包模式获取配置
            switch (param.getRedPacketMode()){
                case 1:
                    json = configService.selectConfigByKey("redPacket.config");
                    config = JSONUtil.toBean(json, RedPacketConfig.class);
                    break;
                case 2:
                    json = companyConfigService.selectRedPacketConfigByKey(param.getCompanyId());
                    config = JSONUtil.toBean(json, RedPacketConfig.class);
                    break;
                default:
                    throw new UnsupportedOperationException("当前红包模式不支持!");
            }
            //H5的用公众号的appid发，小程序的用小程序的appid来发
            if (param.getSource()==2){
                // 传参appId为空时，仍然使用配置里面的
                String appId = StringUtils.isBlank(param.getAppId()) ? config.getMiniappId() : param.getAppId();
                config.setAppId(appId);
            }
            logger.info("最终传参 {}",config);
            //组合返回参数
            R result = new R();
            // 根据 isNew 判断使用哪种发红包方式
            if (config.getIsNew() != null && config.getIsNew() == 1) {
                result = sendRedPacketV3Internal(param, config);
            } else {
                result= sendRedPacketLegacyInternal(param, config);
            }
            result.put("mchId",config.getMchId()+"");
            result.put("isNew",config.getIsNew());
            logger.info("红包返回：{}",result);

            // 更新账户余额
            logger.info("[更新账户余额] 当前余额{} 更新后余额{}",companyMoney.toPlainString(),companyMoney.subtract(amount).toPlainString());

            companyMoney = companyMoney.subtract(amount);
            redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);

            redPacketLog.setAccBalanceAfter(companyMoney);
            redPacketLog.setUpdateTime(LocalDateTime.now());
            redPacketLog.setStatus(1);


            // 用户领取红包次数+1
            redisTemplateInteger.opsForValue().increment(userLimitKey, 1);

            return result;
        }catch (Exception e){
            logger.error("领取红包失败原因：{}", ExceptionUtils.getMessage(e),e);
            if(redPacketLog != null) {
                redPacketLog.setStatus(2);
                redPacketLog.setErrorMsg(ExceptionUtils.getMessage(e));
            }
            throw new RuntimeException(e);
        }finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
            if(redPacketLog != null) {
                redPacketLogMapper.insert(redPacketLog);
            }
        }
    }

    private static long getExpireSeconds() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        // 计算从现在到明天凌晨的秒数
        return (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }
    // 内部方法：处理新版本的发红包逻辑
    private R sendRedPacketV3Internal(WxSendRedPacketParam param, RedPacketConfig config) {

        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config, payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBillsRequest request = new TransferBillsRequest();
        request.setAppid(config.getAppId());
        request.setOpenid(param.getOpenId());

        String code =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(code)){
            return R.error("订单生成失败，请重试");
        }
//        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBillNo("fsCourse" + code);

        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount() != null ? param.getAmount().toString() : "0.1");
        request.setTransferAmount(amount);
        request.setTransferRemark("活动奖励");
        request.setUserRecvPerception("活动奖励");
        request.setNotifyUrl(config.getNotifyUrl());
        request.setTransferSceneId("1000");

        // 设置场景信息
        List<TransferBillsRequest.TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<>();
        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
        info1.setInfoType("活动名称");
        info1.setInfoContent("新会员有礼");
        transferSceneReportInfos.add(info1);

        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
        info2.setInfoType("奖励说明");
        info2.setInfoContent("注册会员抽奖一等奖");
        transferSceneReportInfos.add(info2);
        request.setTransferSceneReportInfos(transferSceneReportInfos);


        try {
            TransferBillsResult transferBillsResult = transferService.transferBills(request);
            logger.info("商家转账支付完成:[msg:{}]", transferBillsResult);
            return R.ok("发送红包成功").put("data", transferBillsResult);
        } catch (Exception e) {
            logger.error("商家转账支付失败:参数: {} ：原因: {}",JSON.toJSONString(param), e.getMessage(),e);
            throw new RuntimeException(e);
        }
    }

    // 内部方法：处理旧版本的发红包逻辑
    private R sendRedPacketLegacyInternal(WxSendRedPacketParam param, RedPacketConfig config) {
        //如果服务号的配置存在，小程序红包接口可以使用服务号来发红包，重新赋值
        //仅老商户支持
        if (param.getUser().getMpOpenId()!=null && StringUtils.isNotEmpty(param.getMpAppId())){
            config.setAppId(param.getMpAppId());
            param.setOpenId(param.getUser().getMpOpenId());
        }
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config, payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBatchesRequest request = new TransferBatchesRequest();
        request.setAppid(config.getAppId());


        // todo 如果未配置负载均衡请还原原本的单号方式
//        String code = IdUtil.getSnowflake(0, 0).nextIdStr();
        String code =  OrderCodeUtils.getOrderSn();
        if(StringUtils.isEmpty(code)){
            return R.error("红包单号生成失败，请重试");
        }
        request.setOutBatchNo("fsCourse"+cloudHostProper.getProjectCode() + code);
        request.setBatchRemark("课堂答题奖励");
        request.setBatchName("课堂答题奖励");
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount().toString());
        request.setTotalAmount(amount);
        request.setTotalNum(1);
        request.setNotifyUrl(config.getNotifyUrl());

        ArrayList<TransferBatchesRequest.TransferDetail> transferDetailList = new ArrayList<>();
        TransferBatchesRequest.TransferDetail transferDetail = new TransferBatchesRequest.TransferDetail();
        transferDetail.setOpenid(param.getOpenId());
        String code1 = IdUtil.getSnowflake(0, 0).nextIdStr();
        transferDetail.setOutDetailNo("fsCourse"+cloudHostProper.getProjectCode() + code1);
        transferDetail.setTransferAmount(amount);
        transferDetail.setTransferRemark("恭喜同学，认真听课，奖励你一朵小红花!");
        transferDetailList.add(transferDetail);
        request.setTransferDetailList(transferDetailList);

        try {
            TransferBatchesResult transferBatchesResult = transferService.transferBatches(request);
            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo()).put("batchId", transferBatchesResult.getBatchId());
        } catch (Exception e) {
            logger.error("商家转账支付失败:参数: {} ：原因: {}",JSON.toJSONString(param), e.getMessage(),e);
            throw new RuntimeException(e);
        }
    }


    @Override
    public String transferNotify(String notifyData, HttpServletRequest request) {
        logger.info("zyp \n【收到转账回调】：{}",notifyData);
        try {
            String json = configService.selectConfigByKey("redPacket.config");
            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
            //创建微信订单
            WxPayConfig payConfig = new WxPayConfig();
            BeanUtils.copyProperties(config,payConfig);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            SignatureHeader signatureHeader = new SignatureHeader();
            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
            WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
            logger.info("到零钱回调：{}",result.getResult());
            if (result.getResult().getBatchStatus().equals("FINISHED") && result.getResult().getFailNum()==0) {
                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo(),result.getResult().getBatchId());
                logger.info("result:{}",r);
                if (r.get("code").equals(200)){
                    return WxPayNotifyResponse.success("处理成功");
                }else {
                    return WxPayNotifyResponse.fail("");
                }
            }else {
                return WxPayNotifyResponse.fail("");
            }
        } catch (WxPayException e) {
            logger.error("zyp \n【转账回调异常】：{}", e.getReturnMsg());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    /**
     * 分公司配置回调地址
     * @param companyId
     * @param notifyData
     * @param request
     * @return
     */
    @Override
    public String TransferNotifyWithCompanyId(Long companyId,String notifyData, HttpServletRequest request) {
        logger.info("分公司回调::companyId:{}",companyId);
        logger.info("zyp \n【收到转账回调::分公司】：{}",notifyData);
        try {
            String json = companyConfigMapper.selectRedPacketConfigByKey(companyId);
//            String json = configService.selectConfigByKey("redPacket.config");
            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
            //创建微信订单
            WxPayConfig payConfig = new WxPayConfig();
            BeanUtils.copyProperties(config,payConfig);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            SignatureHeader signatureHeader = new SignatureHeader();
            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
            WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
            logger.info("到零钱回调::分公司：{}",result.getResult());
            if (result.getResult().getBatchStatus().equals("FINISHED") && result.getResult().getFailNum()==0) {
                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo(),result.getResult().getBatchId());
                logger.info("result:{}",r);
                if (r.get("code").equals(200)){
                    return WxPayNotifyResponse.success("处理成功");
                }else {
                    return WxPayNotifyResponse.fail("");
                }
            }else {
                return WxPayNotifyResponse.fail("");
            }
        } catch (WxPayException e) {
            logger.error("zyp \n【转账回调异常】：{}", e.getReturnMsg());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    @Override
    public Boolean isEntityNull(FsStorePaymentParam param) {
        if (param == null) {
            return true; // 整个实体对象为null
        }

        Class<? extends FsStorePaymentParam> entityClass = param.getClass();
        Field[] fields = entityClass.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(param);
                if (value != null) {
                    return false; // 实体对象中有字段不为null
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return true; // 实体对象内所有字段为null
    }

    @Override
    public Long selectFsStorePaymentExcelVOCount(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentExcelVOCount(fsStorePayment);
    }


    @Override
    public R sendRedPacketV3(WxSendRedPacketParam param) {
        String json = configService.selectConfigByKey("redPacket.config");
        RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);

        //创建微信订单
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config,payConfig);
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        //商家转账请求
        TransferBillsRequest request = new TransferBillsRequest();
        request.setAppid(config.getAppId());
        request.setOpenid(param.getOpenId());

//        String code =  OrderCodeUtils.getH5RedPacketOrderSn();
//        if(StringUtils.isEmpty(code)){
//            return R.error("订单生成失败，请重试");
//        }
        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBillNo("fsCourse"+code);
        //转账金额
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount()!=null ? param.getAmount().toString() : "0.1");
        request.setTransferAmount(amount);
        request.setTransferRemark("活动奖励");
        //用户感知
        request.setUserRecvPerception("活动奖励");
        request.setNotifyUrl(config.getNotifyUrl());
        request.setTransferSceneId("1000");
        List<TransferBillsRequest.TransferSceneReportInfo> transferSceneReportInfos = new ArrayList<>();
        // 添加第一条数据
        TransferBillsRequest.TransferSceneReportInfo info1 = new TransferBillsRequest.TransferSceneReportInfo();
        info1.setInfoType("活动名称");
        info1.setInfoContent("新会员有礼");
        transferSceneReportInfos.add(info1);

        // 添加第二条数据
        TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo();
        info2.setInfoType("奖励说明");
        info2.setInfoContent("注册会员抽奖一等奖");
        transferSceneReportInfos.add(info2);
        request.setTransferSceneReportInfos(transferSceneReportInfos);

        //发起商家转账API(新)
        TransferBillsResult transferBillsResult=null;
        try {
            transferBillsResult = transferService.transferBills(request);
            logger.info("商家转账支付完成:[msg:{}]",transferBillsResult);
            return R.ok("发送红包成功").put("data",transferBillsResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.info("商家转账支付失败：[msg:{}]",e.getMessage());
            return R.error("发送失败");
        }
    }


    @Override
    public String v3TransferNotify(String notifyData, HttpServletRequest request) {
        logger.info("zyp \n【收到转账回调V3】：{}",notifyData);
        try {
            String json = configService.selectConfigByKey("redPacket.config");
            RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
            //创建微信订单
            WxPayConfig payConfig = new WxPayConfig();
            BeanUtils.copyProperties(config,payConfig);
            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(payConfig);
            SignatureHeader signatureHeader = new SignatureHeader();
            signatureHeader.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
            signatureHeader.setNonce(request.getHeader("Wechatpay-Nonce"));
            signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
            signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
            TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
            logger.info("到零钱回调1：{}",result.getResult());
            if (result.getResult().getState().equals("SUCCESS")) {
                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo(),result.getResult().getTransferBillNo());
                logger.info("result:{}",r);
                if (r.get("code").equals(200)){
                    return WxPayNotifyResponse.success("处理成功");
                }else {
                    return WxPayNotifyResponse.fail("");
                }
            }else {
                return WxPayNotifyResponse.fail("");
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.error("zyp \n【转账回调异常】：{}", e.getReturnMsg());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    @Override
    @Transactional
    public R sendRedPacketTest(WxSendRedPacketParam param) {

        String json = configService.selectConfigByKey("redPacket.config");
        RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
        //创建微信订单
        WxPayConfig payConfig = new WxPayConfig();
        BeanUtils.copyProperties(config,payConfig);
        payConfig.setAppId("wxc3f0a952b7bc2b94");
        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);
        TransferService transferService = wxPayService.getTransferService();

        TransferBatchesRequest request = new TransferBatchesRequest();

//        request.setAppid(config.getAppId());
        request.setAppid("wxc3f0a952b7bc2b94");
//        String code =  OrderCodeUtils.getOrderSn();
//        if(StringUtils.isEmpty(code)){
//            return R.error("订单生成失败，请重试");
//        }
        String code = String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        request.setOutBatchNo("fsCourse"+code);
        request.setBatchRemark("课堂答题奖励");
        request.setBatchName("课堂答题奖励");
        Integer amount = WxPayUnifiedOrderRequest.yuanToFen(param.getAmount()!=null ? param.getAmount().toString() : "0.1");
        request.setTotalAmount(amount);
        request.setTotalNum(1);
        request.setNotifyUrl(config.getNotifyUrl());
        ArrayList<TransferBatchesRequest.TransferDetail> transferDetailList = new ArrayList<>();
        TransferBatchesRequest.TransferDetail transferDetail = new TransferBatchesRequest.TransferDetail();
        transferDetail.setOpenid(param.getOpenId());
        String code1 =  String.valueOf(IdUtil.getSnowflake(0, 0).nextId());
        transferDetail.setOutDetailNo("fsCourse"+code1);
        transferDetail.setTransferAmount(amount);
        transferDetail.setTransferRemark("恭喜同学，认真听课，奖励你一朵小红花!");
        transferDetailList.add(transferDetail);
        request.setTransferDetailList(transferDetailList);
        TransferBatchesResult transferBatchesResult=null;
        try {
            transferBatchesResult = transferService.transferBatches(request);
            logger.info("商家转账支付完成:[msg:{}]",transferBatchesResult);
            return R.ok("发送红包成功").put("orderCode",transferBatchesResult.getOutBatchNo());
        } catch (WxPayException e) {
            e.printStackTrace();
            logger.info("商家转账支付失败：[msg:{}]",e.getMessage());
            return R.error("发送失败");
        }
    }

    @Override
    @DataScope(deptAlias = "cu",userAlias = "cu")
    public List<FsStorePaymentVO> selectFsStorePaymentListQueryVO(FsStorePaymentParam fsStorePayment) {
        return fsStorePaymentMapper.selectFsStorePaymentListQueryVO(fsStorePayment);
    }

    /**
     * 发起支付
     * @param payOrderParam 入参
     * @return R
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public R processPayment(PayOrderParam payOrderParam) {
        logger.info("发起支付 payOrderParam: {}", JSON.toJSONString(payOrderParam));

        if (payOrderParam.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new CustomException("支付金额不正确");
        }

        FsUser user = userMapper.selectFsUserById(payOrderParam.getUserId());
        if (Objects.isNull(user)){
            throw new CustomException("用户不存在");
        }

        String json = configService.selectConfigByKey("his.pay");
        logger.debug("支付配置 his.pay: {}", json);
        FsPayConfig payConfig = JSONUtil.toBean(json, FsPayConfig.class);

        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
            String openId = getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig);
            if (StringUtils.isBlank(openId)){
                throw new CustomException("用户OPENID不存在");
            }
        }

        // 创建记录
        FsStorePayment storePayment = createStorePayment(payConfig, user, payOrderParam);

        // 根据配置类型创建第三方支付订单
        return createThirdPartyPayment(payConfig, storePayment, user, payOrderParam);
    }

    /**
     * 发起预支付
     */
    private R createThirdPartyPayment(FsPayConfig payConfig, FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam) {
        switch (payConfig.getType()) {
            case "wx":
                return createWxPayment(storePayment, user, payOrderParam, payConfig);
            case "yb":
                return createYbPayment(storePayment, user, payOrderParam, payConfig);
            case "tz":
                return createTzPayment(storePayment, user, payOrderParam, payConfig);
            case "hf":
                return createHfPayment(storePayment, user, payOrderParam, payConfig);
            default:
                throw new CustomException("不支持的支付方式");
        }
    }

    /**
     * 汇付
     */
    private R createHfPayment(FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
        logger.debug("创建汇付订单");

        HuiFuCreateOrder order = new HuiFuCreateOrder();
        order.setTradeType(getHfTradeType(payOrderParam.getPaymentMethod()));
        order.setReqSeqId(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
        order.setTransAmt(storePayment.getPayMoney().toString());
        order.setGoodsDesc(payOrderParam.getBusinessType().getDesc());

        // 微信支付需要设置openid
        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
            order.setOpenid(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
        }

        HuifuCreateOrderResult result = huiFuService.createOrder(order);
        logger.debug("汇付支付创建结果: {}", result);

        updateStorePaymentTradeNo(storePayment.getPaymentId(), result.getHf_seq_id());
        return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
    }

    /**
     * 获取汇付交易类型
     */
    private String getHfTradeType(PaymentMethodEnum paymentMethod) {
        switch (paymentMethod) {
            case MINIAPP_WECHAT:
                return "T_MINIAPP";
            case H5_WECHAT:
                return "T_JSAPI";
            case ALIPAY:
            case H5_ALIPAY:
                return "A_NATIVE";
            default:
                throw new CustomException("不支持的支付方式");
        }
    }

    /**
     * 台州银行
     */
    private R createTzPayment(FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
        PayCreateOrder payOrder = buildTzPayOrder(storePayment, user, payOrderParam, payConfig);
        TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(payOrder);

        updateStorePaymentTradeNo(storePayment.getPaymentId(), result.getBody().getOrderFlowNo());
        return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
    }

    /**
     * 构建台州银行支付
     */
    private PayCreateOrder buildTzPayOrder(FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
        PayCreateOrder payOrder = new PayCreateOrder();
        payOrder.setOrderNo(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
        payOrder.setTrxAmt(storePayment.getPayMoney().doubleValue());
        payOrder.setBusinessCstNo(payOrderParam.getUserId().toString());
        payOrder.setGoodsInfo(payOrderParam.getBusinessType().getDesc());
        payOrder.setOrderType(payOrderParam.getBusinessType().getCode());
        payOrder.setOrderId(payOrderParam.getOrderId().toString());

        // 设置支付方式
        setTzPaymentType(payOrder, payOrderParam.getPaymentMethod());

        // 设置用户信息
        String phone = getPhoneNumber(user);
        payOrder.setPayerName("微信用户" + phone);

        if (payOrderParam.getPaymentMethod() == PaymentMethodEnum.MINIAPP_WECHAT) {
            payOrder.setPayerMobileNo(getDecryptedPhone(user));
        }

        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
            payOrder.setOpenId(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
        }

        return payOrder;
    }

    /**
     * 获取解密后的手机号
     */
    private String getDecryptedPhone(FsUser user) {
        if (user.getPhone() != null) {
            if (user.getPhone().length() > 11) {
                return PhoneUtil.decryptPhone(user.getPhone());
            } else {
                return user.getPhone();
            }
        }
        return null;
    }

    /**
     * 获取手机号后4位
     */
    private String getPhoneNumber(FsUser user) {
        if (user.getPhone() != null && user.getPhone().length() > 4) {
            return user.getPhone().substring(user.getPhone().length() - 4);
        }
        return "";
    }

    /**
     * 设置支付类型
     */
    private void setTzPaymentType(PayCreateOrder payOrder, PaymentMethodEnum paymentMethod) {
        switch (paymentMethod) {
            case ALIPAY:
            case H5_ALIPAY:
                payOrder.setPayType(Collections.singletonList(PayType.ALIPAY_BARCODE_PAYMENT.getCode()));
                break;
            case H5_WECHAT:
                payOrder.setPayType(Collections.singletonList(PayType.WECHAT_PUBLIC_ACCOUNT.getCode()));
                break;
            default:
                // 小程序微信支付不需要设置payType
                break;
        }
    }

    /**
     * 易宝支付
     */
    private R createYbPayment(FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
        PaymentMethodEnum paymentMethod = payOrderParam.getPaymentMethod();
        if (paymentMethod == PaymentMethodEnum.ALIPAY || paymentMethod == PaymentMethodEnum.H5_ALIPAY
                || paymentMethod == PaymentMethodEnum.H5_WECHAT) {
            throw new CustomException("支付暂不可用!");
        }

        WxJspayDTO payDto = new WxJspayDTO();
        payDto.setPayMoney(storePayment.getPayMoney().toString());
        payDto.setLowOrderId(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
        payDto.setBody(payOrderParam.getBusinessType().getDesc());
        payDto.setIsMinipg("1");
        payDto.setOpenId(getOpenIdForPaymentMethod(user, paymentMethod, payConfig));
        payDto.setAttach("");
        payDto.setStoreid("0");

        CreateWxOrderResult wxOrder = payService.createWxOrder(payDto);
        logger.info("易宝支付返回: {}", wxOrder);

        if ("100".equals(wxOrder.getStatus())) {
            updateStorePaymentTradeNo(storePayment.getPaymentId(), wxOrder.getUpOrderId());
            return R.ok().put("isPay", 0).put("data", wxOrder).put("type", "yb");
        } else {
            throw new CustomException("支付失败");
        }
    }

    /**
     * 更新支付订单交易号
     */
    private void updateStorePaymentTradeNo(Long paymentId, String tradeNo) {
        FsStorePayment updatePayment = new FsStorePayment();
        updatePayment.setPaymentId(paymentId);
        updatePayment.setTradeNo(tradeNo);
        fsStorePaymentMapper.updateFsStorePayment(updatePayment);
    }

    /**
     * 微信支付
     */
    private R createWxPayment(FsStorePayment storePayment, FsUser user, PayOrderParam payOrderParam, FsPayConfig payConfig) {
        PaymentMethodEnum paymentMethod = payOrderParam.getPaymentMethod();
        if (paymentMethod != PaymentMethodEnum.MINIAPP_WECHAT) {
            logger.debug("微信支付 PaymentMethod: {}", paymentMethod.name());
            throw new CustomException("不支持的支付方式");
        }

        WxPayConfig wxPayConfig = buildWxPayConfig(payConfig);
        wxPayService.setConfig(wxPayConfig);

        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setOpenid(getOpenIdForPaymentMethod(user, paymentMethod, payConfig));
        orderRequest.setBody(payOrderParam.getBusinessType().getDesc());
        orderRequest.setOutTradeNo(payOrderParam.getBusinessType().getPrefix() + "-" + storePayment.getPayCode());
        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
        orderRequest.setTradeType("JSAPI");
        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));

        try {
            WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
            return R.ok().put("data", orderResult).put("type", "wx").put("isPay", 0);
        } catch (WxPayException e) {
            logger.error("微信支付发起失败: {}", e.getMessage(), e);
            throw new CustomException("支付失败: " + e.getMessage());
        }
    }

    /**
     * 构建微信支付配置
     */
    private WxPayConfig buildWxPayConfig(FsPayConfig fsPayConfig) {
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setAppId(fsPayConfig.getAppId());
        payConfig.setMchId(fsPayConfig.getWxMchId());
        payConfig.setMchKey(fsPayConfig.getWxMchKey());
        payConfig.setSubAppId(StringUtils.trimToNull(null));
        payConfig.setSubMchId(StringUtils.trimToNull(null));
        payConfig.setKeyPath(null);
        payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
        return payConfig;
    }

    /**
     * 判断是否微信支付
     * @param method 支付类型
     * @return boolean
     */
    private boolean isWechatPayment(PaymentMethodEnum method) {
        return method == PaymentMethodEnum.MINIAPP_WECHAT || method == PaymentMethodEnum.H5_WECHAT;
    }

    /**
     * 根据支付方式获取对应的openId
     */
    private String getOpenIdForPaymentMethod(FsUser user, PaymentMethodEnum method, FsPayConfig payConfig) {
        String openId;
        switch (method) {
            case MINIAPP_WECHAT:
                openId = user.getMaOpenId();
                break;
            case H5_WECHAT:
                openId = user.getMpOpenId();
                break;
            default:
                openId = null;
        }

        if (StringUtils.isBlank(openId)) {
            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                    .eq(FsUserWx::getFsUserId, user.getUserId())
                    .eq(FsUserWx::getAppId, payConfig.getAppId());
            FsUserWx fsUserWx = userWxMapper.selectOne(queryWrapper);
            if (Objects.nonNull(fsUserWx)) {
                openId = fsUserWx.getOpenId();
            }
        }

        return openId;
    }

    /**
     * 创建支付订单
     */
    private FsStorePayment createStorePayment(FsPayConfig payConfig, FsUser user, PayOrderParam payOrderParam) {
        String payCode = OrderCodeUtils.getOrderSn();
        if (StringUtils.isEmpty(payCode)) {
            throw new CustomException("订单生成失败，请重试");
        }

        FsStorePayment storePayment = new FsStorePayment();
        storePayment.setStatus(0);
        storePayment.setPayMode(payConfig.getType());
        storePayment.setBusinessCode(payOrderParam.getOrderCode());
        storePayment.setPayCode(payCode);
        storePayment.setPayMoney(payOrderParam.getAmount());
        storePayment.setCreateTime(new Date());
        storePayment.setPayTypeCode(payOrderParam.getPaymentMethod().getDesc());
        storePayment.setBusinessType(payOrderParam.getBusinessType().getCode());
        storePayment.setCompanyId(payOrderParam.getCompanyId());
        storePayment.setCompanyUserId(payOrderParam.getCompanyUserId());
        storePayment.setRemark(payOrderParam.getBusinessType().getDesc());
        storePayment.setStoreId(payOrderParam.getStoreId());
        storePayment.setUserId(user.getUserId());
        storePayment.setBusinessId(payOrderParam.getOrderId().toString());

        // 设置openId（如果是微信支付）
        if (isWechatPayment(payOrderParam.getPaymentMethod())) {
            storePayment.setOpenId(getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig));
        }

        if (fsStorePaymentMapper.insertFsStorePayment(storePayment) <= 0) {
            throw new CustomException("支付订单创建失败");
        }

        return storePayment;
    }


    @Override
    public R getWxaCodeByPayment(FsStorePaymentGetWxaCodeParam param)  {
        final WxMaService wxMaService = WxMaConfiguration.getMaService(param.getAppId());
        String scene;
        //判断销售id
        if (param.getCompanyUserId() == null){
            scene = "companyId="+ param.getCompanyId();
        }else {
            scene = "companyId="+ param.getCompanyId()+"&"+"companyUserId="+ param.getCompanyUserId();
        }
        byte[] file;
        try {
            file = wxMaService.getQrcodeService().createWxaCodeBytes(
                    "pages_user/user/pay?companyId="+param.getCompanyId(),
                    "release",
                    430,
                    true,
                    null,
                    true);

            // 上传图片到存储桶
            String suffix = ".png";
            CloudStorageService storage = OSSFactory.build();
            String url;
            try {
                url = storage.uploadSuffix(file, suffix);
            }  catch (Exception e) {
                // 记录错误日志
                logger.error("生成图片失败:{}",e.getMessage(),e);
                return R.error("生成图片失败");
            }

            redisCache.setCacheObject("company-wxa-code:"+param.getCompanyId()+":"+param.getAppId(),url);
            // 返回成功信息
            return R.ok().put("url",url);

        } catch (WxErrorException e) {
            logger.error(e.getMessage(), e);
            return R.error("微信接口调用失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public String payConfirm(String payCode, String tradeNo, String bankTransactionId, String bankSerialNo) {
        try {
            //更新订单状态
            FsStorePayment storePayment=fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
            if(!storePayment.getStatus().equals(0)){
                return "";
            }
            storePayment.setStatus(1);
            storePayment.setPayTime(new Date());
            storePayment.setTradeNo(tradeNo);
            storePayment.setBankSerialNo(bankSerialNo);
            storePayment.setBankTransactionId(bankTransactionId);
            fsStorePaymentMapper.updateFsStorePayment(storePayment);
            //增加佣金
//        if(storePayment.getCompanyId()!=null&&storePayment.getCompanyId()>0){
//            companyService.addCompanyPaymentMoney(storePayment);
//        }
        } catch (Exception e) {
            //更新订单状态
            FsStorePaymentScrm storePayment=fsStorePaymentScrmMapper.selectFsStorePaymentByPaymentCode(payCode);
            if(!storePayment.getStatus().equals(0)){
                return "";
            }
            storePayment.setStatus(1);
            storePayment.setPayTime(new Date());
            storePayment.setTradeNo(tradeNo);
            storePayment.setBankSerialNo(bankSerialNo);
            storePayment.setBankTransactionId(bankTransactionId);
            fsStorePaymentScrmMapper.updateFsStorePayment(storePayment);
        }
        return "SUCCESS";
    }

    @Override
    public void synchronizePayStatus() {
        FsStorePayment queryParam = new FsStorePayment();
        queryParam.setStatus(0);//未支付
        queryParam.setBeginTime(DateUtils.addDateDays(-1));
        queryParam.setEndTime(DateUtils.getDate());
        List<FsStorePayment> list = selectFsStorePaymentList(queryParam);
        if (list != null && !list.isEmpty()) {
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            for (FsStorePayment fsStorePayment : list) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    updateFsStorePaymentByDecryptForm(fsStorePayment.getPaymentId());
                    logger.info("定时任务:同步支付状态,payment_id：{}",fsStorePayment.getPaymentId());
                });
                futures.add(future);
            }
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        }
    }

    @Override
    public List<FsStorePayment> selectAllPayment() {
        return fsStorePaymentMapper.selectAllPayment();
    }

    @Override
    public R paymentByWxaCode(FsStorePaymentPayParam param) {
        FsUser user = userMapper.selectFsUserById(param.getUserId());
        if (user==null){
            return R.error("用户不存在！");
        }

        String json = configService.selectConfigByKey("his.pay");
        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
        String openId = null;
        String appId = param.getAppId();
        if (StringUtils.isNotBlank(appId)) {
            //查询fs_user_wx的openId
            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                    .eq(FsUserWx::getFsUserId, param.getUserId())
                    .eq(FsUserWx::getAppId, appId);
            FsUserWx fsUserWx = userWxMapper.selectOne(queryWrapper);
            if (fsUserWx != null) {
                openId = fsUserWx.getOpenId();
            }
        } else {
            appId = payConfigDTO.getAppId();
            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
            if (StringUtils.isBlank(openId)){
                Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                        .eq(FsUserWx::getFsUserId, param.getUserId())
                        .eq(FsUserWx::getAppId, appId);
                FsUserWx fsUserWx = userWxMapper.selectOne(queryWrapper);
                if (Objects.nonNull(fsUserWx)){
                    openId = fsUserWx.getOpenId();
                }
            }
        }

        Company company = companyService.selectCompanyById(param.getCompanyId());
        if (company==null || company.getStatus()==0){
            return R.error("服务商不存在，或已被停用！");
        }
        if(param.getPayMoney().compareTo(new BigDecimal(0.0))<1){
            return R.error("支付金额必须大于0");
        }
        if (param.getCompanyUserId()!=null){
            CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
            if(companyUser == null || companyUser.getStatus().equals("1")){
                return R.error("注册失败客服已停用，或不存在！");
            }
        }


        //生成支付流水
        String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
        FsStorePayment storePayment=new FsStorePayment();
        storePayment.setCompanyId(param.getCompanyId());
        //判断销售是否存在
        if (param.getCompanyUserId()!=null){
            storePayment.setCompanyUserId(param.getCompanyUserId());
        }
        storePayment.setStatus(0);
        storePayment.setPayCode(orderSn);
        storePayment.setPayMoney(param.getPayMoney());
        storePayment.setCreateTime(new Date());
        storePayment.setPayTypeCode("weixin");
        storePayment.setBusinessType(7);//微信收款
        storePayment.setRemark("商城收款订单支付");
        storePayment.setOpenId(openId);
        storePayment.setUserId(user.getUserId());
        storePayment.setPayMode("hf");//目前微信收款仅支持汇付
        fsStorePaymentMapper.insertFsStorePayment(storePayment);

        //汇付支付
        HuiFuCreateOrder o = new HuiFuCreateOrder();
        o.setTradeType("T_MINIAPP");
        o.setOpenid(openId);
        o.setReqSeqId("payment-"+storePayment.getPayCode());
        o.setTransAmt(storePayment.getPayMoney().toString());
        o.setGoodsDesc("商城订单支付");
        o.setAppId(appId);
        //公司分账
        try {
            HuiFuUtils.doDiv(o,company.getCompanyId());
            //存储分账明细
            HuiFuUtils.saveDivItem(o, storePayment.getPayCode(), storePayment.getPayCode());
        } catch (Exception e) {
            logger.error("-------------微信收款分账出错：{}", e.getMessage());
        }
        HuifuCreateOrderResult result = huiFuService.createOrder(o);
        if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
            FsStorePayment mt=new FsStorePayment();
            mt.setPaymentId(storePayment.getPaymentId());
            mt.setTradeNo(result.getHf_seq_id());
            mt.setAppId(appId);
            fsStorePaymentMapper.updateFsStorePayment(mt);
            Map<String, Object> resultMap = com.alibaba.fastjson.JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
            String s = (String) resultMap.get("package");
            resultMap.put("packageValue",s);
            return R.ok().put("result",resultMap);
        }
        else{
            return R.error(result.getResp_desc());
        }
    }

}
