package com.cyksj.service.register.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.Xmls;
import com.cyksj.config.WeChatConfig;
import com.cyksj.config.zfb.AliPayClientFactory;
import com.cyksj.config.zfb.BaseZfbConfig;
import com.cyksj.config.zfb.ZfbProductCode;
import com.cyksj.dto.RedisKey;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.AppleAutoRegisterDataMapper;
import com.cyksj.mapper.RegisterOrderDonMapper;
import com.cyksj.mapper.SpotifyUnLimitRecordMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.channel.ShopConfigMapper;
import com.cyksj.mapper.manage.coupon.CouponMapper;
import com.cyksj.model.dto.AliPayParams;
import com.cyksj.model.dto.H5JsPayParams;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.request.RegisterReq;
import com.cyksj.model.request.AlipayOrderDonReq;
import com.cyksj.model.request.OrderAttach;
import com.cyksj.model.request.OrderRefundReq;
import com.cyksj.model.views.CouponUserView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.mange.coupon.CouponCommonService;
import com.cyksj.service.pay.AliPayCommonService;
import com.cyksj.service.register.RegisterOrderDonService;
import com.cyksj.service.register.SpotifyService;
import com.cyksj.service.sys.SysConfigService;
import com.cyksj.service.wechat.WeChatService;
import com.cyksj.task.JobManager;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author chan
 * @date 2022/11/7 2:39 PM
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RegisterOrderDonServiceImpl extends ServiceImpl<RegisterOrderDonMapper ,RegisterOrderDon> implements RegisterOrderDonService {

    private static final Sequence SEQUENCE = new Sequence(0);

    private static final String REGISTER_PRICE_KEY = "register_price";

    private final SpotifyService spotifyService;

    private final RedisService redisService;

    private final WeChatService weChatService;

    private final WeChatConfig weChatConfig;

    private final SysConfigService sysConfigService;

    private final UserMapper userMapper;

    private final AppleAutoRegisterDataMapper appleAutoRegisterDataMapper;

    private final JobManager jobManager;

    private final RegisterOrderDonMapper registerOrderDonMapper;

    private final CouponMapper couponMapper;

    private final CouponCommonService couponCommonService;

    private final SpotifyUnLimitRecordMapper spotifyUnLimitRecordMapper;

    private final BeanSearcher beanSearcher;

    private final ShopConfigMapper shopConfigMapper;

    private final AliPayCommonService aliPayCommonService;

    private static final Long EXPIRY_TIME = 1000 * 60 * 5L;

    /**
     * 判断是否免费
     * @author chan
     * @date 2022-11-07 3:34 PM
     */
    @Override
    public boolean isFree(long userId, String platform, String code) {
        if (StringUtils.isBlank(code)) {
            return false;
        }
        int count = count(Wrappers.lambdaQuery(RegisterOrderDon.class)
                .eq(RegisterOrderDon::getUserId, userId)
                .notIn(RegisterOrderDon::getStatus, List.of(RegisterOrderDon.Status.noPayment, RegisterOrderDon.Status.error))
                .eq(RegisterOrderDon::getIsFree, true));
        if(count > 0){
            throw BusinessRuntimeException.getInstance("您已使用过注册码进行注册过啦，如需再次注册请清除注册码再提交哦");
        }
        SysConfig sysConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "spotify_free_code"));
        if (sysConfig == null) {
            return false;
        }else {
            if (JSONUtil.isJsonArray(sysConfig.getSysValue())) {
                List<String> list = JSONUtil.parseArray(sysConfig.getSysValue()).toList(String.class);
                return list.contains(code);
            }else {
                return false;
            }
        }
    }

    /**
     * 保存注册资料
     * @author chan
     * @date 2022-11-07 3:34 PM
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public RegisterOrderDon saveOrder(long userId, RegisterReq req, boolean isFree) throws Exception {
        RegisterOrderDon orderDon = new RegisterOrderDon();
        User user = userMapper.selectById(userId);
        BeanUtil.copyProperties(req,orderDon);
        SysConfig register_price = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "register_price").last("limit 1"));
        Map<String, Integer> map = Jsons.toMap(register_price.getSysValue());
        orderDon.setOrderNo(SEQUENCE.nextId() + "");
        orderDon.setUserId(userId);
        orderDon.setOpenId(user.getOpenId());
        orderDon.setIsFree(isFree);
        orderDon.setMoney(isFree ? BigDecimal.ZERO : BigDecimal.valueOf(("apple".equals(req.getPlatform()) && "auto".equals(req.getAppleRegisterType())) ? map.get("appleAuto") : map.get(req.getPlatform())));
        orderDon.setStatus(isFree ? RegisterOrderDon.Status.hasPayment : RegisterOrderDon.Status.noPayment);
        String shopId = sysConfigService.getDefaultShopConfigByType("zfb");
        orderDon.setShopId(shopId);
        save(orderDon);
        //apple
        handleAppleIdAuto(userId, req, orderDon);
        return orderDon;
    }

    /**
     *  Apple ID自动注册
     */
    private void handleAppleIdAuto(long userId, RegisterReq req, RegisterOrderDon orderDon) {
        if ("apple".equals(req.getPlatform()) && "auto".equals(req.getAppleRegisterType())) {
            //是否有未支付的国家或区域的订单
            Integer exists = appleAutoRegisterDataMapper.checkNoPayOrder(userId, req.getCountryOrArea());
            if (exists != null) {
                throw BusinessRuntimeException.getInstance(String.format("您有%s随机生成Apple ID未支付的订单", req.getCountryOrArea().getDesc()));
            }
            if (req.getCountryOrArea() == null) {
                throw BusinessRuntimeException.getInstance("请选择对应的国家或地区");
            }
            //查看是否有空余账号
            AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getCountryOrArea, req.getCountryOrArea()).eq(AppleAutoRegisterData::getStatus, false).select(AppleAutoRegisterData::getId).last("limit 1"));
            if (appleAutoRegisterData == null) {
                throw BusinessRuntimeException.getInstance("自动生成Apple ID库存不足");
            }
            appleAutoRegisterData.setUserId(userId);
            appleAutoRegisterData.setStatus(true);
            appleAutoRegisterData.setOrderId(orderDon.getId());
            int update = appleAutoRegisterDataMapper.update(appleAutoRegisterData, Wrappers.lambdaUpdate(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getStatus, false).eq(AppleAutoRegisterData::getId, appleAutoRegisterData.getId()));
            if (update != 1) {
                throw BusinessRuntimeException.getInstance("系统异常,请重新操作");
            }
            jobManager.addJob(EXPIRY_TIME, () -> {
                updateAppleAutoStatus(orderDon.getId());
            });
        }
    }

    @Override
    public void updateAppleAutoStatus(Long orderId) {
        log.info("校验appleID自动注册订单 orderId:{}", orderId);
        RegisterOrderDon registerOrderDon = this.getById(orderId);
        if (registerOrderDon != null && RegisterOrderDon.Status.noPayment == registerOrderDon.getStatus()) {
            AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, orderId).last("limit 1"));
            if (appleAutoRegisterData != null) {
                appleAutoRegisterData.setStatus(false);
                appleAutoRegisterData.setUserId(0l);
                appleAutoRegisterData.setOrderId(0l);
                appleAutoRegisterDataMapper.updateById(appleAutoRegisterData);
                log.info("未支付appleID自动注册订单:{},修改appleID使用状态", orderId);
            }
            //订单关闭
            registerOrderDon.setStatus(RegisterOrderDon.Status.close);
            registerOrderDonMapper.updateById(registerOrderDon);
        }
    }

	@Override
	public CouponUserView spotifyUnLimit(SpotifyUnLimitRecord spotifyUnLimitRecord) {
		Boolean isFlag = false;
		Long spotifyUnLimitCouponId = null;
		//是否配置了优惠券
		SysConfig spotify_unLimit_cid = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "spotify_unLimit_cid").last("limit 1"));
		if (spotify_unLimit_cid != null && StrUtil.isNotBlank(spotify_unLimit_cid.getSysValue())) {
			spotifyUnLimitCouponId = Long.parseLong(spotify_unLimit_cid.getSysValue());
			Coupon coupon = couponMapper.selectById(spotifyUnLimitCouponId);
			if (coupon != null) {
				isFlag = couponCommonService.sendCouponToUser(spotifyUnLimitRecord.getUserId(), spotifyUnLimitCouponId, null, null, null, CouponUser.Channel.manual);
			}
		}
		//14天内是否重复提交过该账号
        SpotifyUnLimitRecord exists = spotifyUnLimitRecordMapper.selectOne(Wrappers.lambdaQuery(SpotifyUnLimitRecord.class)
                .eq(SpotifyUnLimitRecord::getUserId, spotifyUnLimitRecord.getUserId())
                .eq(SpotifyUnLimitRecord::getAccount, spotifyUnLimitRecord.getAccount())
                .last("limit 1"));
        if (exists != null && exists.getUpdateTime().after(DateUtil.offsetDay(DateTime.now(), -14))) {
            throw BusinessRuntimeException.getInstance("您已提交过,请勿重复提交");
        }
        if (exists != null) {
            spotifyUnLimitRecord.setId(exists.getId());
            spotifyUnLimitRecord.setIsSend(false);
            spotifyUnLimitRecordMapper.updateById(spotifyUnLimitRecord);
        } else {
            try {
                spotifyUnLimitRecordMapper.insert(spotifyUnLimitRecord);
            } catch (DuplicateKeyException e) {
                log.info("用户:{}重复提交解除限制spotify账号:{}", spotifyUnLimitRecord.getUserId(), spotifyUnLimitRecord.getAccount());
            }
        }
		return isFlag ? beanSearcher.searchFirst(CouponUserView.class, MapUtils.builder()
				.field(CouponUserView::getUserId, spotifyUnLimitRecord.getUserId()).op(Operator.Equal)
				.field(CouponUserView::getCouponId, spotifyUnLimitCouponId).op(Operator.Equal)
				.build()) : null;
	}

    @Override
    public CouponUserView getAvailableSpotifyCoupon(long userId) {
        SysConfig spotify_register_success_cid = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "spotify_register_success_cid").last("limit 1"));
        CouponUserView couponUserView = null;
        if (spotify_register_success_cid != null && StrUtil.isNotBlank(spotify_register_success_cid.getSysValue())) {
            DateTime now = DateTime.now();
            Long spotifyRegisterSucCid = Long.parseLong(spotify_register_success_cid.getSysValue());
            couponUserView = beanSearcher.searchFirst(CouponUserView.class, MapUtils.builder()
                    .field(CouponUserView::getUserId, userId).op(Operator.Equal)
                    .field(CouponUserView::getCouponId, spotifyRegisterSucCid).op(Operator.Equal)
                    .field(CouponUserView::getCouponUserStatus, CouponUser.Status.unused.name()).op(Operator.Equal)
                    .field(CouponUserView::getValidStartTime, now).op(Operator.LessThan)
                    .field(Coupon::getValidEndTime, now).op(Operator.GreaterThan)
                    .build());
        }
        return couponUserView;
    }

    @Override
    public void unifiedRefund(OrderRefundReq refundReq) throws Exception {
        Long orderId = refundReq.getOrderId();
        RegisterOrderDon registerOrderDon = this.getById(orderId);
        if (registerOrderDon == null) throw BusinessRuntimeException.getInstance("订单不存在");
        if (registerOrderDon.getStatus() == RegisterOrderDon.Status.refund) throw BusinessRuntimeException.getInstance("该订单已退款");

        if (registerOrderDon.getStatus() != RegisterOrderDon.Status.error && registerOrderDon.getStatus() != RegisterOrderDon.Status.hasPayment) {
            throw BusinessRuntimeException.getInstance("该订单状态不允许退款");
        }
        if (registerOrderDon.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
            throw BusinessRuntimeException.getInstance("该订单金额为0,无需退款");
        }
        if (!redisService.setNx(String.format("%s", refundReq.getOrderId()), refundReq.getOrderId(), 10l)) {
            throw BusinessRuntimeException.getInstance("请勿重复点击,正在退款中..");
        }
        RegisterOrderDon.Type type = registerOrderDon.getType();
        if (type == RegisterOrderDon.Type.WeChat) {
            wxRefund(refundReq, registerOrderDon);
        }
        if (type == RegisterOrderDon.Type.ALI_PAY) {
            zfbRefund(refundReq, registerOrderDon);
        }
    }

    @Override
    public AliPayParams zfbUnifiedPay(AlipayOrderDonReq re) throws Exception {
        String productCode = StrUtil.EMPTY;
        if (re.getType() == 1) {
            productCode = ZfbProductCode.MOBILE_WEB.getProductCode();
        }
        if (re.getType() == 2) {
            productCode = ZfbProductCode.PC_WEB.getProductCode();
        }
        return aliPayCommonService.unifiedPayRegister(re.getOrderId(), productCode, re.getPayMode(), re.getReturnUrl());
    }

    @Override
    public void aliPayNotify(Map<String, String> params) throws Exception {
        //调用SDK验证签名
        String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
        OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
        Long oderId = orderAttach.getO();
        RegisterOrderDon orderDon = getById(oderId);
        if (null == orderDon) {
            throw BusinessRuntimeException.getInstance("订单不存在.");
        }
        String appId = params.get("app_id");
        boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
        if (!signVerified) {
            log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
            throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
        }
        String transactionId = params.get("trade_no");
        String payTimeStr = params.get("gmt_payment");
        if (!orderDon.getStatus().equals(RegisterOrderDon.Status.noPayment) && !orderDon.getStatus().equals(RegisterOrderDon.Status.close)) {
            log.info("支付宝已回调，重复修改状态 id:{}", orderDon.getId());
            return;
        }

        // 更改订单状态
        orderDon.setTransactionId(transactionId);
        orderDon.setStatus(RegisterOrderDon.Status.hasPayment);
        AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, orderDon.getId()).eq(AppleAutoRegisterData::getStatus, true));
        if (appleAutoRegisterData != null) {
            orderDon.setStatus(RegisterOrderDon.Status.complete);
        }
        if (StrUtil.isNotBlank(payTimeStr)) {
            orderDon.setPayTime(DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss"));
        }
        this.updateById(orderDon);
    }

    @Override
    public H5JsPayParams pay(Long orderId) throws Exception {
        log.info("注册 账号调起微信支付[start] orderId:{}", orderId);
        RegisterOrderDon orderDon = this.getById(orderId);
        if (orderDon.getStatus() == RegisterOrderDon.Status.close) {
            throw BusinessRuntimeException.getInstance("订单已关闭");
        }
        OrderAttach attach = new OrderAttach();
        attach.setO(orderDon.getId());

        //获取支付默认商户
        String shopId = sysConfigService.getDefaultShopConfigByType("wx");

        String toWechatAttach = Codec.DoBase64.custom()
                .setData(Jsons.toJson(attach)).encodeAsText();

        H5JsPayParams params = weChatService.getJsPayParams(
                weChatConfig.getAppid(),
                shopId,
                orderDon.getOpenId(),
                orderDon.getMoney().intValue(),
                orderDon.getOrderNo(),
                weChatConfig.getNotifyDomain() + "applets/register/prepay/notify",
                toWechatAttach,
                "注册服务",
                "JSAPI",
                null
        );

        log.info("微信支付成功[end]");
        return params;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void prepayNotify(Map<String, String> map) throws Exception {
        /* 此处处理订单等业务逻辑 */
        // 获取订单 和 微信订单号 和 支付的金额

        String attach = Codec.DoBase64.custom().setData(map.get("attach")).decodeAsText();

        OrderAttach orderAttach = Jsons.parseObject(attach, OrderAttach.class);

        final Long oid = orderAttach.getO();

        //final Long shareId = orderAttach.getShared();

        RegisterOrderDon order = this.getById(oid);

        if (null == order) {
            throw BusinessRuntimeException.getInstance("订单不存在.");
        }
        String appId = map.get("mch_id");

        // 校验签名
        boolean f = weChatService.checkSignWithMd5(map, shopConfigMapper.getByAppId(appId).getSecret());
        if (!f) {
            log.error("回调数据：{}", map);
            throw BusinessRuntimeException.getInstance("支付成功回调, 校验签名失败.");
        }

        String transactionId = map.get("transaction_id");

        if (order.getStatus().equals(RegisterOrderDon.Status.hasPayment)) {
            log.info("已回调，重复修改状态 id:{}", order.getId());
            return;
        }

        // 更改订单状态
        order.setTransactionId(transactionId);
        order.setStatus(RegisterOrderDon.Status.hasPayment);
        AppleAutoRegisterData appleAutoRegisterData = appleAutoRegisterDataMapper.selectOne(Wrappers.lambdaQuery(AppleAutoRegisterData.class).eq(AppleAutoRegisterData::getOrderId, order.getId()).eq(AppleAutoRegisterData::getStatus, true));
        if (appleAutoRegisterData != null) {
            order.setStatus(RegisterOrderDon.Status.complete);
        }

        order.setPayTime(DateUtil.parse(map.get("time_end"), "yyyyMMddHHmmss"));

        if (StringUtils.isBlank(order.getOpenId())) {
            order.setOpenId(map.get("openid"));
        }


        this.updateById(order);
    }

    @Override
    public Result<String> wxRefund(OrderRefundReq refundReq,RegisterOrderDon registerOrderDon) throws Exception {
        long time = System.currentTimeMillis();
        //退款订单号
        String outRefundNo = Codec.DoDigest.custom()
                .setAlgorithm(Codec.DoDigest.Algorithm.MD5)
                .setStringData(time + String.valueOf(registerOrderDon.getId()))
                .toHexString();
        if (refundReq.getRefundMoney() == null) {
            refundReq.setRefundMoney(registerOrderDon.getMoney());
        }
        weChatService.refundWxOrder(weChatConfig.getAppid(),
                Optional.ofNullable(registerOrderDon.getShopId()).orElse(ShopConfig.WX_DEFAULT_APP_ID),
                registerOrderDon.getTransactionId(),
                outRefundNo,
                registerOrderDon.getMoney(),
                refundReq.getRefundMoney(),
                weChatConfig.getNotifyDomain() + "manage/register/wx/refund/notify");
        //修改订单状态
        registerOrderDon.setStatus(RegisterOrderDon.Status.refund);
        registerOrderDon.setRefundMoney(refundReq.getRefundMoney());
        this.updateById(registerOrderDon);
        return GatewayResponse.SUCCESS.newBuilder().toResult("退款成功");
    }

    @Override
    public void wxRefundNotify(Map<String, String> map) throws Exception {
        // 对退款数据 解密
        String md5Key = Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(shopConfigMapper.getByAppId(map.get("mch_id")).getSecret()).toHexString();
        String reqInfoXml = Codec.DoCipher.custom().setAlgorithm(Codec.DoCipher.Trans.AES_ECB_PKCS7Padding).setBase64Data(map.get("req_info")).setStringKey(md5Key).ofDecrypt().toText();
        log.info("=== 退款数据解密: \n {}", reqInfoXml);
        Map<String, String> reqInfoMap = Xmls.toMap(reqInfoXml);
        // 退款失败
        if (StrUtil.equals("CHANGE", reqInfoMap.get("refund_status"))) {
            throw BusinessRuntimeException.getInstance("退款异常.");
        } else if (StrUtil.equals("REFUNDCLOSE", reqInfoMap.get("refund_status"))) {
            throw BusinessRuntimeException.getInstance("退款关闭.");
        }
        /* 此处处理业务逻辑 */
        String outRefundNo = reqInfoMap.get("out_refund_no");
        String transactionId = reqInfoMap.get("transaction_id");
        RegisterOrderDon registerOrderDon = this.getOne(Wrappers.lambdaQuery(RegisterOrderDon.class).eq(RegisterOrderDon::getTransactionId, transactionId).last("limit 1"));
        if (registerOrderDon == null) {
            log.error("退款回调,transactionId:{}订单不存在", transactionId);
        }
        if (registerOrderDon.getStatus() != RegisterOrderDon.Status.refund) {
            registerOrderDon.setStatus(RegisterOrderDon.Status.refund);
            this.updateById(registerOrderDon);
        }
        log.info("微信退款: 退款单号[{}] 退款成功.", outRefundNo);
    }

    public void zfbRefund(OrderRefundReq refundReq, RegisterOrderDon registerOrderDon) throws Exception {
        AlipayTradeRefundResponse response;
        //支付宝退款
        AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(registerOrderDon.getShopId()).orElse(ShopConfig.ZFB_DEFAULT_APP_ID));
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        //支付宝交易号
        model.setTradeNo(registerOrderDon.getTransactionId());
        if (refundReq.getRefundMoney() == null) {
            refundReq.setRefundMoney(registerOrderDon.getMoney());
        }
        model.setRefundAmount(refundReq.getRefundMoney().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).toString());
        model.setQueryOptions(List.of("gmt_refund_pay"));
        long time = System.currentTimeMillis();
        //退款订单号
        String outRefundNo = Codec.DoDigest.custom()
                .setAlgorithm(Codec.DoDigest.Algorithm.MD5)
                .setStringData(time + String.valueOf(registerOrderDon.getId()))
                .toHexString();
        //退款请求号
        model.setOutRequestNo(outRefundNo);
        request.setBizModel(model);
        String shopId = registerOrderDon.getShopId();
        ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, registerOrderDon.getShopId()));
        if (shopId != null && shopConfig != null && shopConfig.getIsCert()) {
            response = alipayClient.certificateExecute(request);
        } else {
            response = alipayClient.execute(request);
        }
        if (!response.isSuccess()) throw BusinessRuntimeException.getInstance("退款失败,e:{0}", response.getSubMsg());
        registerOrderDon.setStatus(RegisterOrderDon.Status.refund);
        registerOrderDon.setRefundMoney(refundReq.getRefundMoney());
        registerOrderDonMapper.updateById(registerOrderDon);
    }
}
