package com.slodon.b2b2c.controller.seller.seller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.XmlUtil;
import com.alipay.api.internal.util.AlipaySignature;
import com.gexin.fastjson.JSON;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.slodon.b2b2c.core.constant.PayConst;
import com.slodon.b2b2c.core.constant.StoreConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.WxPayCallbackVO;
import com.slodon.b2b2c.core.util.XmlUtils;
import com.slodon.b2b2c.model.seller.StoreApplyModel;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.seller.example.StoreApplyExample;
import com.slodon.b2b2c.seller.pojo.StoreApply;
import com.slodon.b2b2c.starter.entity.*;
import com.slodon.b2b2c.starter.entity.cpcn.TxRefundRequest;
import com.slodon.b2b2c.starter.pay.SlodonPay;
import com.slodon.b2b2c.util.PayPropertiesUtil;
import cpcn.institution.tools.util.Base64;
import cpcn.institution.tools.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import payment.api.notice.Notice5018Request;
import payment.api.notice.NoticeRequest;
import payment.api.notice.NoticeResponse;
import payment.api.util.GUIDGenerator;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * seller入驻支付回调接口
 * @author slodon
 */
@Slf4j
@RestController
@RequestMapping("v3/seller/seller/registerPayCallback")
public class RegisterPayCallbackController extends BaseController {

    @Resource
    private StoreApplyModel storeApplyModel;
    @Resource
    private StoreModel storeModel;
    @Resource
    private PayPropertiesUtil payPropertiesUtil;
    @Resource
    private SlodonPay slodonPay;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 微信返回  fail 失败，success 成功
     */
    private static final String RETURN_CODE_SUCCESS = "SUCCESS";
    private static final String RETURN_MSG_OK = "OK";
    private static final String RETURN_CODE_FAIL = "FAIL";

    /**
     * 支付宝支付回调
     *
     * @param request request
     * @param response response
     */
    @PostMapping("ali")
    public void alipayNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            //获取支付宝POST过来反馈信息
            Map<String, String> params = new HashMap<>(16);
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            //调用SDK,验证签名
            AliPayProperties aliPayProperties = payPropertiesUtil.getAliPayProperties();
            //证书验签
            boolean signVerified = AlipaySignature.rsaCertCheckV1(params, aliPayProperties.aliPayPublicCertPath, aliPayProperties.inputCharset, aliPayProperties.signType);
            if (signVerified) {
                //验证成功
                // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
                //获取支付宝的通知返回参数，可参考技术文档中页面跳转异步通知参数列表(以下仅供参考)//
                //商户订单号
                String outTradeNo = params.get("out_trade_no");
                //支付宝交易号
                String tradeNo = params.get("trade_no");
                //交易金额
                String totalAmount = params.get("total_amount");
                //交易状态
                String tradeStatus = params.get("trade_status");
                //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                if ("TRADE_FINISHED".equals(tradeStatus)) {
                    log.debug("订单已完成");
                    //请不要修改或删除
                    response.getWriter().println(RETURN_CODE_SUCCESS);
                } else if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    log.debug("支付成功");
                    //获取注册信息
                    StoreApplyExample storeApplyExample = new StoreApplyExample();
                    storeApplyExample.setPaySn(outTradeNo);
                    List<StoreApply> storeApplyList = storeApplyModel.getStoreApplyList(storeApplyExample, null);
                    if (CollectionUtils.isEmpty(storeApplyList)) {
                        log.error("[storeApplyModel][getStoreApplyList]支付信息获取失败:" + outTradeNo);
                        response.getWriter().println(RETURN_CODE_FAIL);
                    }
                    StoreApply storeApplyDb = storeApplyList.get(0);

                    if (StoreConst.STATE_4_STORE_OPEN == storeApplyDb.getState()) {
                        //订单已支付，执行退款操作
                        if (storeApplyDb.getPaymentCode().contains(PayConst.METHOD_ALIPAY.toUpperCase())) {
                            //重复回调，不处理，直接返回成功
                            response.getWriter().println(RETURN_CODE_SUCCESS);
                            return;
                        }
                        //其他方式已支付，如余额、微信，执行退款
                        this.aliRefund(storeApplyDb.getPaySn(), storeApplyDb.getTradeSn(), new BigDecimal(totalAmount));
                        response.getWriter().println(RETURN_CODE_SUCCESS);
                        return;
                    }
                    // 1-开启测试, 0-关闭测试
                    if ("1".equals(stringRedisTemplate.opsForValue().get("pay_test_enable"))) {
                        //不校验支付额
                    } else {
                        if (!totalAmount.equals(storeApplyDb.getPayAmount().toString())) {
                            log.error("续签支付金额不一致paySn:" + outTradeNo);
                            response.getWriter().println(RETURN_CODE_FAIL);
                            //续签金额不一致不往下执行
                            return;
                        }
                    }

                    //支付成功，新增店铺
                    StoreApply storeApply = new StoreApply();
                    storeApply.setApplyId(storeApplyDb.getApplyId());
                    storeApply.setVendorId(storeApplyDb.getVendorId());
                    storeApply.setStoreName(storeApplyDb.getStoreName());
                    storeApply.setApplyYear(storeApplyDb.getApplyYear());
                    storeApply.setStoreGradeId(storeApplyDb.getStoreGradeId());
                    storeApply.setTradeSn(tradeNo);
                    storeApply.setPaymentName("支付宝支付");
                    storeApply.setPaymentCode("alipay");
                    storeModel.openStore(storeApply);
                } else {
                    response.getWriter().println(RETURN_CODE_FAIL);
                }
                response.getWriter().println(RETURN_CODE_SUCCESS);
            } else {
                response.getWriter().println(RETURN_CODE_FAIL);
            }
        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.getWriter().println(RETURN_CODE_FAIL);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    /**
     * 微信支付回调
     *
     */
    @PostMapping("wx")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        log.debug("-----------------------------------------------------------------------------");
        log.debug("微信通知开始");
        log.debug("-----------------------------------------------------------------------------");
        ServletInputStream in;
        try {
            // post 过来的xml
            in = request.getInputStream();
            //转换微信post过来的xml内容
            String notifyData = IoUtil.read(in, StandardCharsets.UTF_8);

            WxPayCallbackVO vo = XmlUtils.convertToObject(notifyData, WxPayCallbackVO.class);
            //格式为payType_codeSource
            String attach = vo.getAttach();
            String wxPayType = attach.split("_")[0];
            Integer codeSource = null;
            if (wxPayType.equalsIgnoreCase(PayConst.WX_TYPE_JSAPI)) {
                codeSource = Integer.parseInt(attach.split("_")[1]);
            }

            //微信支付配置
            WxPayProperties wxPayProperties = payPropertiesUtil.getWxPayProperties(wxPayType);
            WxPayServiceImpl wxPayService = new WxPayServiceImpl();
            WxPayConfig wxPayConfig = new WxPayConfig();
            wxPayConfig.setAppId(StringUtils.trimToNull(wxPayProperties.getAppId()));
            wxPayConfig.setMchId(StringUtils.trimToNull(wxPayProperties.getMchId()));
            wxPayConfig.setMchKey(StringUtils.trimToNull(wxPayProperties.getMchKey()));
            wxPayService.setConfig(wxPayConfig);
            //处理xml
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(notifyData);
            //验证签名
            notifyResult.checkResult(wxPayService, notifyResult.getSignType(), true);

            String outTradeNo = notifyResult.getOutTradeNo();
            //格式为paySn_payType，截取paySn
            String paySn = outTradeNo.split("_")[0];
            String payType = outTradeNo.split("_")[1];

            // 签名正确
            // 进行处理。
            // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
            //安全校验(比较订单金额)
            StoreApplyExample storeApplyExample = new StoreApplyExample();
            storeApplyExample.setPaySn(paySn);
            List<StoreApply> storeApplyList = storeApplyModel.getStoreApplyList(storeApplyExample, null);
            if (CollectionUtils.isEmpty(storeApplyList)) {
                log.error("[storeApplyModel][getStoreApplyList]支付信息获取失败:" + notifyResult.getOutTradeNo());
                response.getWriter().println(RETURN_CODE_FAIL);
            }
            StoreApply storeApplyDb = storeApplyList.get(0);
            if (StoreConst.STATE_4_STORE_OPEN == storeApplyDb.getState()) {
                //订单已支付
                if (storeApplyDb.getPaymentCode().contains(PayConst.METHOD_WX.toUpperCase()) &&
                        storeApplyDb.getPaymentCode().contains(payType)) {
                    //同一客户端重复回调，不做处理
                    sendMsg(response);
                    return;
                }
                //不同客户端重复支付，执行退款
                this.wxRefund(paySn, storeApplyDb.getTradeSn(), payType, notifyResult.getTotalFee());
                sendMsg(response);
                return;
            }
            // 1-开启测试, 0-关闭测试
            if ("1".equals(stringRedisTemplate.opsForValue().get("pay_test_enable"))) {
                //不校验支付额
            } else {
                int payAmount = storeApplyDb.getPayAmount().multiply(new BigDecimal(100)).intValue();
                if (payAmount != notifyResult.getTotalFee()) {
                    log.error("订单支付金额不一致paySn:" + notifyResult.getOutTradeNo());
                    response.getWriter().println(RETURN_CODE_FAIL);
                    return;
                }
            }

            //支付成功，新增店铺
            StoreApply storeApply = new StoreApply();
            storeApply.setApplyId(storeApplyDb.getApplyId());
            storeApply.setVendorId(storeApplyDb.getVendorId());
            storeApply.setStoreName(storeApplyDb.getStoreName());
            storeApply.setApplyYear(storeApplyDb.getApplyYear());
            storeApply.setStoreGradeId(storeApplyDb.getStoreGradeId());
            storeApply.setTradeSn(notifyResult.getTransactionId());
            storeApply.setPaymentName("微信支付");
            storeApply.setPaymentCode("wx");
            storeModel.openStore(storeApply);

            //返回微信应答报文
            sendMsg(response);

        } catch (Exception e) {
            log.error("未知异常", e);
        }
    }

    /**
     * 订单支付payPal回调
     *
     */
    @PostMapping("payPal")
    public void payPalPayCallback(HttpServletRequest request, HttpServletResponse response) {
        log.debug("-----------------------------------------------------------------------------");
        log.debug("payPal通知开始");
        log.debug("-----------------------------------------------------------------------------");
        try {
            String paymentId = request.getParameter("paymentId");
            String payerId = request.getParameter("PayerID");

            PayPalProperties payPalProperties = payPropertiesUtil.getPayPalProperties();
            APIContext apiContext = new APIContext(payPalProperties.getClientId(), payPalProperties.getSecret(), payPalProperties.getMode());

            Payment payment = new Payment();
            payment.setId(paymentId);
            PaymentExecution paymentExecute = new PaymentExecution();
            paymentExecute.setPayerId(payerId);
            Payment paymentResponse = payment.execute(apiContext, paymentExecute);
            log.info("回调信息：" + paymentResponse);
            if ("approved".equals(paymentResponse.getState())) {
                Transaction transaction = paymentResponse.getTransactions().get(0);
                RelatedResources resources = transaction.getRelatedResources().get(0);
                Amount amount = transaction.getAmount();
                String saleId = resources.getSale().getId();
                String totalAmount = amount.getTotal();
                String paySn = transaction.getCustom();

                //获取注册信息
                StoreApplyExample storeApplyExample = new StoreApplyExample();
                storeApplyExample.setPaySn(paySn);
                List<StoreApply> storeApplyList = storeApplyModel.getStoreApplyList(storeApplyExample, null);
                if (CollectionUtils.isEmpty(storeApplyList)) {
                    log.error("[storeApplyModel][getStoreApplyList]支付信息获取失败:" + paySn);
                    response.getWriter().println(RETURN_CODE_FAIL);
                }
                StoreApply storeApplyDb = storeApplyList.get(0);

                if (StoreConst.STATE_4_STORE_OPEN == storeApplyDb.getState()) {
                    //订单已支付，执行退款操作
                    if (storeApplyDb.getPaymentCode().contains(PayConst.METHOD_ALIPAY.toUpperCase())) {
                        //重复回调，不处理，直接返回成功
                        response.getWriter().println(RETURN_CODE_SUCCESS);
                        return;
                    }
                    //其他方式已支付，如余额、微信，执行退款
                    this.payPalRefund(storeApplyDb.getPaySn(), storeApplyDb.getTradeSn(), new BigDecimal(totalAmount));
                    response.getWriter().println(RETURN_CODE_SUCCESS);
                    return;
                }
                // 1-开启测试, 0-关闭测试
                if ("1".equals(stringRedisTemplate.opsForValue().get("pay_test_enable"))) {
                    //不校验支付额
                } else {
                    if (!totalAmount.equals(storeApplyDb.getPayAmount().toString())) {
                        log.error("续签支付金额不一致paySn:" + paySn);
                        response.getWriter().println(RETURN_CODE_FAIL);
                        //续签金额不一致不往下执行
                        return;
                    }
                }

                //支付成功，新增店铺
                StoreApply storeApply = new StoreApply();
                storeApply.setApplyId(storeApplyDb.getApplyId());
                storeApply.setVendorId(storeApplyDb.getVendorId());
                storeApply.setStoreName(storeApplyDb.getStoreName());
                storeApply.setApplyYear(storeApplyDb.getApplyYear());
                storeApply.setStoreGradeId(storeApplyDb.getStoreGradeId());
                storeApply.setTradeSn(saleId);
                storeApply.setPaymentName("PayPal支付");
                storeApply.setPaymentCode("paypal");
                storeModel.openStore(storeApply);
            } else {
                log.error("回调状态state：{}", paymentResponse.getState());
                log.error("回调失败原因failed_transactions：{}", paymentResponse.getFailureReason());
                response.getWriter().println(RETURN_CODE_FAIL);
            }
            response.getWriter().println(RETURN_CODE_SUCCESS);
        } catch (Exception e) {
            log.error("未知异常", e);
        }
    }

    /**
     * 订单支付中金回调
     */
    @PostMapping("zj")
    public void txPayCallback(HttpServletRequest request, HttpServletResponse response) {
        log.debug("=========================================");
        log.debug("中金支付回调开始");
        log.debug(JSON.toJSONString(request.getParameterMap()));
        log.debug("=========================================");

        try {
            // 1 获得参数message和signature
            String message = request.getParameter("message");
            String signature = request.getParameter("signature");
            String isDgEnv=request.getParameter("isDgEnv");
            String digitalEnvelope=request.getParameter("digitalEnvelope");
            String signAlgorithm=request.getParameter("signAlgorithm");
            String signSN=request.getParameter("signSN");
            String encryptSN=request.getParameter("encryptSN");

            // 2 生成交易结果对象
            NoticeRequest noticeRequest;
            if("YES".equals(isDgEnv)) {
                //数字信封解密验签
                noticeRequest = new NoticeRequest(message, signature,digitalEnvelope,signSN,encryptSN,signAlgorithm);
            }else {
                //非数字信封解密验签
                if(StringUtil.isNotEmpty(signSN)) {
                    message = message +","+signSN+","+signAlgorithm;
                }
                noticeRequest = new NoticeRequest(message, signature);
            }

            Notice5018Request nr = new Notice5018Request(noticeRequest.getDocument());
            log.debug("=========================================");
            log.debug(JSON.toJSONString(nr));
            log.debug("=========================================");

            /*
            支付状态:
            10=未支付
            20=支付处理中
            30=支付成功
            40=支付失败
            50=订单关闭
             */
            String status = nr.getStatus();
            if ("30".equals(status)){
                //只处理支付成功的情况
                String paySn = nr.getOrderNo();
                paySn = paySn.substring(0,paySn.length()-6);

                StoreApplyExample storeApplyExample = new StoreApplyExample();
                storeApplyExample.setPaySn(paySn);
                List<StoreApply> storeApplyList = storeApplyModel.getStoreApplyList(storeApplyExample, null);
                if (CollectionUtils.isEmpty(storeApplyList)) {
                    //无申请信息
                    PrintWriter out = response.getWriter();
                    this.response(out);
                    out.flush();
                    out.close();
                    return;
                }
                StoreApply storeApplyDb = storeApplyList.get(0);
                BigDecimal payAmount = new BigDecimal(nr.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);//回调金额
                if (StoreConst.STATE_4_STORE_OPEN == storeApplyDb.getState()) {
                    //订单已支付
                    if (nr.getTxSN().equals(storeApplyDb.getTradeSn())){
                        //重复回调
                        PrintWriter out = response.getWriter();
                        this.response(out);
                        out.flush();
                        out.close();
                        return;
                    }
                    //其他方式支付，执行退款
                    this.zjRefund(payAmount,paySn,nr.getTxSN());
                    PrintWriter out = response.getWriter();
                    this.response(out);
                    out.flush();
                    out.close();
                    return;
                }
                if (!nr.getTxSN().equals(storeApplyDb.getTradeSn())){
                    //支付流水号不同，废弃的支付流水号
                    this.zjRefund(payAmount,paySn,nr.getTxSN());
                    PrintWriter out = response.getWriter();
                    this.response(out);
                    out.flush();
                    out.close();
                    return;
                }
                // 1-开启测试, 0-关闭测试
                if ("1".equals(stringRedisTemplate.opsForValue().get("pay_test_enable"))) {
                    //不校验支付额
                } else {
                    if (payAmount.compareTo(storeApplyDb.getPayAmount()) != 0) {
                        log.error("订单支付金额不一致paySn:" + paySn);
                        PrintWriter out = response.getWriter();
                        this.response(out);
                        out.flush();
                        out.close();
                        return;
                    }
                }

                String qrPaymentType = nr.getQRPaymentType();//10微信，20-支付宝
                //支付成功，新增店铺
                StoreApply storeApply = new StoreApply();
                storeApply.setApplyId(storeApplyDb.getApplyId());
                storeApply.setVendorId(storeApplyDb.getVendorId());
                storeApply.setStoreName(storeApplyDb.getStoreName());
                storeApply.setApplyYear(storeApplyDb.getApplyYear());
                storeApply.setStoreGradeId(storeApplyDb.getStoreGradeId());
                storeApply.setTradeSn(nr.getTxSN());
                storeApply.setPaymentName("10".equals(qrPaymentType) ? PayConst.NAME_WX : PayConst.NAME_ALIPAY);
                storeApply.setPaymentCode("10".equals(qrPaymentType) ? PayConst.METHOD_ZJ_WX : PayConst.METHOD_ZJ_ALI);
                storeModel.openStore(storeApply);
            }
            PrintWriter out = response.getWriter();
            this.response(out);
            out.flush();
            out.close();
        }catch (Exception e){
            log.error("中金支付回调异常：" , e);

        }
    }

    /**
     * 给支付平台发送回调成功信息，发送后支付平台不再进行回调
     * @param out 响应
     */
    private void response(PrintWriter out){
        String xmlString = new NoticeResponse().getMessage();
        String base64String = new String(Base64.encode(xmlString.getBytes(StandardCharsets.UTF_8)));
        out.print(base64String);
    }

    /**
     * 中金支付退款
     * @param refundAmount 退款金额
     * @param refundSn 退款单号
     * @param paymentTxSn 支付时的交易流水号
     */
    public void zjRefund(BigDecimal refundAmount, String refundSn, String paymentTxSn) throws Exception {
        TxRefundRequest txRefundRequest = new TxRefundRequest();
        txRefundRequest.setInstitutionId(stringRedisTemplate.opsForValue().get("zj_pay_institution_id"));
        txRefundRequest.setTxSn(GUIDGenerator.genGUID());
        txRefundRequest.setPaymentTxSn(paymentTxSn);
        txRefundRequest.setRemark("");

        SlodonRefundRequest refundRequest = new SlodonRefundRequest();
        refundRequest.setRefundSn(refundSn);
        refundRequest.setRefundAmount(refundAmount);
        refundRequest.setTxRefundRequest(txRefundRequest);
        slodonPay.refund(refundRequest, PayConst.METHOD_ZJ);
    }

    /**
     * 给微信反回应答报文，防止重复回调
     *
     */
    private void sendMsg(HttpServletResponse response) {
        LinkedHashMap<String, String> responseMap = new LinkedHashMap<>();
        responseMap.put("return_code", RETURN_CODE_SUCCESS);
        responseMap.put("return_msg", RETURN_MSG_OK);
        String mapToXml = XmlUtil.mapToXmlStr(responseMap);
        response.setContentType("text/html;charset=utf-8");
        try (PrintWriter out = response.getWriter()) {
            out.print(mapToXml);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 执行微信退款
     *
     * @param refundSn 退款单号
     * @param tradeSn  交易流水号
     * @param payType  支付类型
     * @param totalFee 支付金额，单位分
     */
    private void wxRefund(String refundSn, String tradeSn, String payType, Integer totalFee) {
        SlodonRefundRequest refundRequest = new SlodonRefundRequest();

        //微信退款
        refundRequest.setWxPayProperties(payPropertiesUtil.getWxPayProperties(payType));
        //微信需要设置原支付金额
        BigDecimal payAmount = new BigDecimal(totalFee).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
        refundRequest.setTotalAmount(payAmount);
        refundRequest.setRefundAmount(payAmount);
        refundRequest.setTradeSn(tradeSn);
        refundRequest.setRefundSn(refundSn);
        try {
            SlodonRefundResponse refundResponse = slodonPay.refund(refundRequest, PayConst.METHOD_WX.toUpperCase());
            if (!refundResponse.getSuccess()) {
                log.error("微信重复支付退款失败，交易流水号：{}，失败原因：{}", tradeSn, refundResponse.getMsg());
            }
        } catch (Exception e) {
            log.error("微信重复支付退款失败，交易流水号：{}", tradeSn, e);
        }
    }

    /**
     * 支付宝退款
     *
     * @param refundSn     退款单号
     * @param tradeSn      交易流水号
     * @param refundAmount 退款金额
     */
    private void aliRefund(String refundSn, String tradeSn, BigDecimal refundAmount) {
        SlodonRefundRequest refundRequest = new SlodonRefundRequest();
        refundRequest.setAlipayProperties(payPropertiesUtil.getAliPayProperties());
        refundRequest.setTradeSn(tradeSn);
        refundRequest.setRefundSn(refundSn);
        refundRequest.setRefundAmount(refundAmount);
        try {
            SlodonRefundResponse refundResponse = slodonPay.refund(refundRequest, PayConst.METHOD_ALIPAY.toUpperCase());
            if (!refundResponse.getSuccess()) {
                log.error("支付宝重复支付退款失败，交易流水号：{}，失败原因：{}", tradeSn, refundResponse.getMsg());
            }
        } catch (Exception e) {
            log.error("支付宝重复支付退款失败，交易流水号：{}", tradeSn, e);
        }
    }

    /**
     * payPal退款
     *
     * @param refundSn     退款单号
     * @param tradeSn      交易流水号
     * @param refundAmount 退款金额
     */
    private void payPalRefund(String refundSn, String tradeSn, BigDecimal refundAmount) {
        SlodonRefundRequest refundRequest = new SlodonRefundRequest();
        refundRequest.setPayPalProperties(payPropertiesUtil.getPayPalProperties());
        refundRequest.setTradeSn(tradeSn);
        refundRequest.setRefundSn(refundSn);
        refundRequest.setRefundAmount(refundAmount);
        try {
            SlodonRefundResponse refundResponse = slodonPay.refund(refundRequest, PayConst.METHOD_ALIPAY.toUpperCase());
            if (!refundResponse.getSuccess()) {
                log.error("payPal重复支付退款失败，交易流水号：{}，失败原因：{}", tradeSn, refundResponse.getMsg());
            }
        } catch (Exception e) {
            log.error("payPal重复支付退款失败，交易流水号：{}", tradeSn, e);
        }
    }
}
