package shop.alien.store.strategy.merchantPayment.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import shop.alien.entity.result.R;
import shop.alien.entity.store.MerchantPaymentOrder;
import shop.alien.entity.store.RefundRecord;
import shop.alien.entity.store.StorePaymentConfig;
import shop.alien.entity.store.UserReservation;
import shop.alien.entity.store.UserReservationOrder;
import shop.alien.store.service.*;
import shop.alien.store.strategy.merchantPayment.MerchantPaymentStrategy;
import shop.alien.util.common.UniqueRandomNumGenerator;
import shop.alien.util.common.constant.PaymentEnum;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 商户支付宝支付策略（预订订单，使用 StorePaymentConfig 按门店配置）
 *
 * @author system
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MerchantAlipayPaymentStrategyImpl implements MerchantPaymentStrategy {

    /**
     * 支付宝网关地址
     */
    @Value("${payment.aliPay.host}")
    private String aliPayHost;

    /** 预支付结果 Redis 缓存 key 前缀 */
    private static final String REDIS_PREPAY_KEY_PREFIX = "merchant:alipay:prepay:order:";
    /** 预支付缓存过期时间（秒），与支付宝预支付单 15 分钟一致 */
    private static final long REDIS_PREPAY_EXPIRE_SECONDS = 15 * 60;
    /** 防抖 key 前缀：同一订单在有效期内仅允许一次创建预支付 */
    private static final String REDIS_PREPAY_DEBOUNCE_KEY_PREFIX = "merchant:alipay:prepay:debounce:order:";
    /** 防抖有效期（秒），期内重复调用返回请勿重复提交 */
    private static final long REDIS_PREPAY_DEBOUNCE_SECONDS = 5;
    /** 支付状态：退款中 */
    private static final int PAY_STATUS_REFUNDING = 4;
    /** 退款记录状态：退款失败 */
    private static final String REFUND_STATUS_FAIL = "FAIL";

    private final StorePaymentConfigService storePaymentConfigService;
    private final UserReservationOrderService userReservationOrderService;
    private final MerchantPaymentOrderService merchantPaymentOrderService;
    private final RefundRecordAsyncService refundRecordAsyncService;
    private final RefundRecordService refundRecordService;
    private final ReservationOrderPaymentTimeoutService reservationOrderPaymentTimeoutService;
    private final UserReservationService userReservationService;
    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public R<Map<String, Object>> createPrePay(Integer storeId, Integer orderId, String amountYuan, String subject, Integer userId, String smid) {
        if (storeId == null || orderId == null) {
            return R.fail("门店ID和订单ID不能为空");
        }
        if (StringUtils.isBlank(amountYuan)) {
            return R.fail("支付金额不能为空");
        }
        BigDecimal amountYuanBD;
        try {
            amountYuanBD = new BigDecimal(amountYuan).setScale(2, RoundingMode.HALF_UP);
        } catch (NumberFormatException e) {
            return R.fail("支付金额格式不正确");
        }
        if (amountYuanBD.compareTo(BigDecimal.ZERO) <= 0) {
            return R.fail("支付金额必须大于0");
        }
        if (StringUtils.isBlank(subject)) {
            return R.fail("订单描述不能为空");
        }
//        StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
//        if (config == null) {
//            return R.fail("该门店未配置支付参数");
//        }
//        if (StringUtils.isBlank(config.getAppSecretCert())
//                || config.getAppPublicCert() == null || config.getAppPublicCert().length == 0
//                || config.getAlipayPublicCert() == null || config.getAlipayPublicCert().length == 0
//                || config.getAlipayRootCert() == null || config.getAlipayRootCert().length == 0) {
//            return R.fail("门店支付配置不完整（缺少应用私钥或证书）");
//        }
        UserReservationOrder order = userReservationOrderService.getById(orderId);
        if (order == null) {
            return R.fail("预订订单不存在");
        }
        if (!order.getStoreId().equals(storeId)) {
            return R.fail("订单与门店不匹配");
        }
        if (order.getPaymentStatus() != null && order.getPaymentStatus() == 1) {
            return R.fail("订单已支付");
        }
        // 校验支付金额与订单订金金额一致（考虑精度，保留2位小数）
        BigDecimal depositAmount = order.getDepositAmount() != null ? order.getDepositAmount() : BigDecimal.ZERO;
        if (amountYuanBD.compareTo(depositAmount.setScale(2, RoundingMode.HALF_UP)) != 0) {
            return R.fail("支付金额与订单订金金额不一致");
        }

        // 再次调用时优先从 Redis 获取已生成的预支付信息（未过期则直接返回）
        String redisKey = REDIS_PREPAY_KEY_PREFIX + orderId;
        String cached = stringRedisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isNotBlank(cached)) {
            try {
                @SuppressWarnings("unchecked")
                Map<String, Object> data = JSON.parseObject(cached, Map.class);
                if (data != null && !data.isEmpty()) {
                    log.info("商户预订订单预支付命中缓存，orderId={}", orderId);
                    return R.data(data);
                }
            } catch (Exception e) {
                log.warn("解析预支付缓存失败，将重新发起预支付，orderId={}", orderId, e);
            }
        }

        // 防抖：同一订单在有效期内只允许一次创建预支付，防止重复调用
        String debounceKey = REDIS_PREPAY_DEBOUNCE_KEY_PREFIX + orderId;
        Boolean debounceSet = stringRedisTemplate.opsForValue().setIfAbsent(debounceKey, "1", REDIS_PREPAY_DEBOUNCE_SECONDS, TimeUnit.SECONDS);
        if (Boolean.FALSE.equals(debounceSet)) {
            log.warn("商户支付宝预支付防抖拦截，orderId={}", orderId);
            return R.fail("请勿重复提交，请稍后再试");
        }

        // 未命中缓存：先按订单ID+支付类型将原支付单逻辑删除，再生成新预支付（仅删除同 pay_type）
        int deleted = merchantPaymentOrderService.logicDeleteByOrderIdAndPayType(orderId, PaymentEnum.ALIPAY.getType());
        if (deleted > 0) {
            log.info("未命中缓存，已逻辑删除该订单下支付宝支付单 {} 条，orderId={}", deleted, orderId);
        }

        String outTradeNo = UniqueRandomNumGenerator.generateUniqueCode(19);

        MerchantPaymentOrder paymentOrder = new MerchantPaymentOrder();
        paymentOrder.setPaymentNo(merchantPaymentOrderService.generatePaymentNo());
        paymentOrder.setOrderType("reservation_order");
        paymentOrder.setOrderId(order.getId());
        paymentOrder.setOrderSn(order.getOrderSn());
        paymentOrder.setStoreId(storeId);
        paymentOrder.setPayType(PaymentEnum.ALIPAY.getType());
        paymentOrder.setOutTradeNo(outTradeNo);
        paymentOrder.setPayAmount(amountYuanBD);
        paymentOrder.setPayStatus(0);
        paymentOrder.setPayerUserId(userId);
        paymentOrder.setSubject(subject);
        paymentOrder.setCreatedTime(new Date());
        paymentOrder.setUpdatedTime(new Date());
        merchantPaymentOrderService.save(paymentOrder);

        try {
//            com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
//            AlipayClient client = new DefaultAlipayClient(alipayConfig);
//            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//            model.setOutTradeNo(outTradeNo);
//            model.setTotalAmount(amountYuanBD.toPlainString());
//            model.setSubject(subject);
//            // 预支付单有效时间 15 分钟（相对超时，格式 1m～15d）
//            model.setTimeoutExpress("15m");
//            request.setBizModel(model);
//            // 必须用 certificateExecute 请求支付宝网关预创建交易，否则仅 sdkExecute 本地签名不会在支付宝侧落单，查单会报「交易不存在」
//            //AlipayTradeAppPayResponse response = client.certificateExecute(request);
//            AlipayTradeAppPayResponse response = client.sdkExecute(request);
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

            // 构造请求参数以调用接口
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

            model.setOutTradeNo(outTradeNo);
            BigDecimal total = new BigDecimal(String.valueOf(amountYuanBD));
            model.setTotalAmount(String.valueOf(total));

            model.setSubject(subject);

            model.setTimeoutExpress("15m");

            // 1. 构建二级商户信息
            SubMerchant subMerchant = new SubMerchant();
            subMerchant.setMerchantId(smid); // 替换为实际的二级商户编号
            // 【关键】设置二级商户信息（直付通必传）
            model.setSubMerchant(subMerchant);

            SettleInfo settleInfo = new SettleInfo();
            SettleDetailInfo settleDetailInfo = new SettleDetailInfo();
            settleDetailInfo.setTransInType("defaultSettle");
            settleDetailInfo.setAmount(total.toString());
            List<SettleDetailInfo> settleDetailInfos = new ArrayList<>();
            settleDetailInfos.add(settleDetailInfo);
            settleInfo.setSettleDetailInfos(settleDetailInfos);
            model.setSettleInfo(settleInfo);

            request.setNotifyUrl("https://frp-off.com:40279/alienStore/alipayPartnerNotify");
            request.setBizModel(model);

            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            String orderStr = response.getBody();

//            String orderStr = response.isSuccess() ? response.getBody() : "";

            if (!response.isSuccess()) {
                return R.fail("预支付失败：" + response.getSubMsg());
            }

            Map<String, Object> data = new HashMap<>();
            data.put("orderStr", orderStr);
            data.put("outTradeNo", outTradeNo);
            data.put("orderSn", order.getOrderSn());
            data.put("orderId", order.getId());
            data.put("paymentNo", paymentOrder.getPaymentNo());
            stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(data), REDIS_PREPAY_EXPIRE_SECONDS, TimeUnit.SECONDS);
//            log.info("商户预订订单预支付成功并写入缓存，storeId={}, orderSn={}, outTradeNo={}, appId={}, aliPayHost={}", storeId, order.getOrderSn(), outTradeNo, config.getAppId(), aliPayHost);
            return R.data(data);
        } catch (AlipayApiException e) {
            log.error("商户预订订单预支付异常，storeId={}, orderId={}", storeId, orderId, e);
            return R.fail("预支付失败：" + e.getErrMsg());
        } catch (Exception e) {
            log.error("构建支付宝配置异常，storeId={}", storeId, e);
            return R.fail("预支付失败：" + e.getMessage());
        }
    }

    @Override
    public R<Object> queryPayStatus(Integer storeId, String outTradeNo) {
        if (storeId == null || StringUtils.isBlank(outTradeNo)) {
            return R.fail("门店ID和商户订单号不能为空");
        }
        StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
//        if (config == null) {
//            return R.fail("该门店未配置支付参数");
//        }
        MerchantPaymentOrder paymentOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
        if (paymentOrder == null) {
            return R.fail("支付单不存在");
        }
        UserReservationOrder order = userReservationOrderService.getById(paymentOrder.getOrderId());
        if (order == null) {
            return R.fail("预订订单不存在");
        }
        // 本地已标记已支付，直接返回成功，不再调用支付宝
        if (order.getPaymentStatus() != null && order.getPaymentStatus() == 1) {
            return R.success("支付成功");
        }
        try {
//            com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
//            AlipayClient client = new DefaultAlipayClient(alipayConfig);
//            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
//            JSONObject bizContent = new JSONObject();
//            bizContent.put("out_trade_no", outTradeNo);
//            request.setBizContent(bizContent.toJSONString());
//            AlipayTradeQueryResponse response = client.certificateExecute(request);

            AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            model.setOutTradeNo(outTradeNo);
            List<String> queryOptions = new ArrayList<>();
            queryOptions.add("trade_settle_info");
            model.setQueryOptions(queryOptions);
            request.setBizModel(model);

            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (!response.isSuccess()) {
                String subMsg = response.getSubMsg();
                String subCode = response.getSubCode();
                // 支付宝返回「交易不存在」多为：预支付与查询 app_id/环境不一致、或沙箱未落单
                if (StringUtils.isNotBlank(subCode) && subCode.contains("TRADE_NOT_EXIST")
                        || StringUtils.isNotBlank(subMsg) && subMsg.contains("交易不存在")) {
                    log.warn("支付宝查询返回交易不存在，请核对预支付与查询是否同一门店、同一环境。storeId={}, outTradeNo={}, appId={}, aliPayHost={}, subCode={}, subMsg={}",
                            storeId, outTradeNo, config.getAppId(), aliPayHost, subCode, subMsg);
                    return R.fail("交易不存在或已过期，请重新发起支付");
                }
                return R.fail("查询失败：" + subMsg);
            }
            String tradeStatus = response.getTradeStatus();
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                Date now = new Date();
                paymentOrder.setPayStatus(1);
                paymentOrder.setTradeNo(response.getTradeNo());
                paymentOrder.setPayTime(now);
                paymentOrder.setUpdatedTime(now);
                merchantPaymentOrderService.updateById(paymentOrder);

                order.setPaymentStatus(1);
                order.setPayTime(now);
                order.setOutTradeNo(outTradeNo);
                order.setPaymentMethod("alipay");
                order.setOrderStatus(1);
                if (StringUtils.isBlank(order.getVerificationCode())) {
                    order.setVerificationCode("YS" + UniqueRandomNumGenerator.generateUniqueCode(10));
                }
                order.setUpdatedTime(now);
                userReservationOrderService.updateById(order);
                if (order.getReservationId() != null) {
                    UserReservation reservation = userReservationService.getById(order.getReservationId());
                    if (reservation != null) {
                        reservation.setStatus(1);
                        userReservationService.updateById(reservation);
                    }
                }
                reservationOrderPaymentTimeoutService.cancelReservationOrderPaymentTimeout(order.getOrderSn());
                return R.success("支付成功");
            }
            if ("TRADE_CLOSED".equals(tradeStatus)) {
                return R.fail("交易已关闭");
            }
            if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
                return R.fail("等待买家付款");
            }
            return R.success("订单状态：" + tradeStatus);
        } catch (AlipayApiException e) {
            log.error("查询商户订单支付状态异常，outTradeNo={}", outTradeNo, e);
            return R.fail("查询异常：" + e.getErrMsg());
        } catch (Exception e) {
            log.error("构建支付宝配置异常，storeId={}", storeId, e);
            return R.fail("查询失败：" + e.getMessage());
        }
    }

    @Override
    public R<String> refund(Integer storeId, String outTradeNo, String refundAmount, String refundReason, Integer refundType) {
        if (storeId == null || StringUtils.isBlank(outTradeNo)) {
            return R.fail("门店ID和商户订单号不能为空");
        }
        if (StringUtils.isBlank(refundAmount) || new BigDecimal(refundAmount).compareTo(BigDecimal.ZERO) <= 0) {
            return R.fail("退款金额必须大于0");
        }
//        StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
//        if (config == null) {
//            return R.fail("该门店未配置支付参数");
//        }
        MerchantPaymentOrder paymentOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
        if (paymentOrder == null) {
            return R.fail("支付单不存在");
        }
        UserReservationOrder order = userReservationOrderService.getById(paymentOrder.getOrderId());
        if (order == null) {
            return R.fail("预订订单不存在");
        }
        if (order.getPaymentStatus() == null || order.getPaymentStatus() != 1) {
            return R.fail("订单未支付或已退款，无法退款");
        }
        try {
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            model.setOutTradeNo(outTradeNo);
            model.setRefundAmount(refundAmount);
            model.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "用户申请退款");
            request.setBizModel(model);
            AlipayTradeRefundResponse response = refundRun(request);


//            com.alipay.api.AlipayConfig alipayConfig = buildAlipayConfigFromStore(config);
//            AlipayClient client = new DefaultAlipayClient(alipayConfig);
//            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
//            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
//            model.setOutTradeNo(outTradeNo);
//            model.setRefundAmount(refundAmount);
//            model.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "用户申请退款");
//            request.setBizModel(model);
//            AlipayTradeRefundResponse response = client.certificateExecute(request);
            if (!response.isSuccess()) {
                String failMsg = "退款失败：" + response.getSubMsg();
                markRefundFailed(order, paymentOrder, failMsg, refundReason, storeId, outTradeNo);
                return R.fail(failMsg);
            }
            JSONObject responseBody = JSONObject.parseObject(response.getBody());
            JSONObject refundResponse = responseBody != null ? responseBody.getJSONObject("alipay_trade_refund_response") : null;
            String tradeNo = refundResponse != null ? refundResponse.getString("trade_no") : null;

            Date now = new Date();
            BigDecimal refundAmountDecimal = new BigDecimal(refundAmount);
            paymentOrder.setPayStatus(3);
            paymentOrder.setUpdatedTime(now);

            order.setOrderStatus(7);
            order.setPaymentStatus(2);
            order.setRefundAmount(refundAmountDecimal);
            order.setRefundTime(now);
            order.setRefundReason(refundReason);
            order.setUpdatedTime(now);
            order.setRefundType(refundType);
            userReservationOrderService.updateById(order);

            //修改用户预约信息表状态
            UserReservation reservation = userReservationService.getById(order.getReservationId());
            if (reservation != null) {
                reservation.setStatus(3);
                userReservationService.updateById(reservation);
            }

            RefundRecord record = new RefundRecord();
            record.setPayType(PaymentEnum.ALIPAY.getType());
            record.setOutTradeNo(outTradeNo);
            record.setTransactionId(tradeNo);
            record.setOutRefundNo(UniqueRandomNumGenerator.generateUniqueCode(19));
            record.setRefundStatus("SUCCESS");
            record.setRefundAmount(refundAmountDecimal.multiply(new BigDecimal(100)).longValue());
            record.setRefundReason(refundReason);
            record.setOrderId(String.valueOf(order.getId()));
            record.setStoreId(storeId);
            record.setUserId(order.getUserId());
            record.setCreatedTime(now);
            record.setCreatedUserId(order.getUserId());
            record.setUpdatedUserId(order.getUserId());
            record.setDeleteFlag(0);
            refundRecordAsyncService.completeRefundAsync(paymentOrder, record);

            log.info("商户预订订单退款成功，outTradeNo={}", outTradeNo);
            return R.data("退款成功");
        } catch (AlipayApiException e) {
            log.error("商户预订订单退款异常，outTradeNo={}", outTradeNo, e);
            String errMsg = "退款失败：" + e.getErrMsg();
            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
            if (resOrder != null && payOrder != null) {
                markRefundFailed(resOrder, payOrder, errMsg, refundReason, storeId, outTradeNo);
            }
            return R.fail(errMsg);
        } catch (Exception e) {
            log.error("构建支付宝配置异常，storeId={}", storeId, e);
            String errMsg = "退款失败：" + e.getMessage();
            MerchantPaymentOrder payOrder = merchantPaymentOrderService.getByOutTradeNo(outTradeNo);
            UserReservationOrder resOrder = payOrder != null ? userReservationOrderService.getById(payOrder.getOrderId()) : null;
            if (resOrder != null && payOrder != null) {
                markRefundFailed(resOrder, payOrder, errMsg, refundReason, storeId, outTradeNo);
            }
            return R.fail(errMsg);
        }
    }

    /**
     * 执行退款请求
     */
    private AlipayTradeRefundResponse refundRun(AlipayTradeRefundRequest request) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
        AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
        return response;
    }



    /**
     * 构建退款请求
     */
    private AlipayTradeRefundRequest buildRefundRequest(Map<String, String> params) {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(params.get("outTradeNo"));
        model.setRefundAmount(params.get("refundAmount"));
        model.setRefundReason(params.get("refundReason"));
        if (StringUtils.isNotBlank(params.get("partialRefundCode"))) {
            model.setOutRequestNo(params.get("partialRefundCode"));
        }
        request.setBizModel(model);
        return request;
    }

    /** 退款失败时：订单与支付单置为退款中，并写入退款失败记录 */
    private void markRefundFailed(UserReservationOrder order, MerchantPaymentOrder paymentOrder,
                                  String errorMsg, String refundReason, Integer storeId, String outTradeNo) {
        try {
            Date now = new Date();
            order.setPaymentStatus(PAY_STATUS_REFUNDING);
            order.setUpdatedTime(now);
            userReservationOrderService.updateById(order);
            paymentOrder.setPayStatus(PAY_STATUS_REFUNDING);
            paymentOrder.setUpdatedTime(now);
            merchantPaymentOrderService.updateById(paymentOrder);
            RefundRecord record = new RefundRecord();
            record.setOutTradeNo(outTradeNo);
            record.setPayType(PaymentEnum.ALIPAY.getType());
            record.setRefundStatus(REFUND_STATUS_FAIL);
            record.setOrderId(String.valueOf(order.getId()));
            record.setStoreId(storeId);
            record.setUserId(order.getUserId());
            record.setRefundReason(StringUtils.isNotBlank(refundReason) ? refundReason : "退款失败");
            record.setErrorMsg(errorMsg != null ? errorMsg : "退款失败");
            record.setDeleteFlag(0);
            refundRecordService.save(record);
        } catch (Exception ex) {
            log.error("标记退款失败状态异常，outTradeNo={}", outTradeNo, ex);
        }
    }

    @Override
    public String getType() {
        return PaymentEnum.ALIPAY.getType();
    }

    private com.alipay.api.AlipayConfig buildAlipayConfigFromStore(StorePaymentConfig config) {
        com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig();
        alipayConfig.setServerUrl(aliPayHost);
        alipayConfig.setAppId(config.getAppId());
        alipayConfig.setPrivateKey(config.getAppSecretCert());
        alipayConfig.setFormat("json");
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");

        // 使用证书内容（字符串）设置，避免每次请求写临时文件
        if (config.getAppPublicCert() != null && config.getAppPublicCert().length > 0) {
            alipayConfig.setAppCertContent(new String(config.getAppPublicCert(), StandardCharsets.UTF_8));
        }
        if (config.getAlipayPublicCert() != null && config.getAlipayPublicCert().length > 0) {
            alipayConfig.setAlipayPublicCertContent(new String(config.getAlipayPublicCert(), StandardCharsets.UTF_8));
        }
        if (config.getAlipayRootCert() != null && config.getAlipayRootCert().length > 0) {
            alipayConfig.setRootCertContent(new String(config.getAlipayRootCert(), StandardCharsets.UTF_8));
        }
        // 若使用的支付宝 SDK 支持，可设置查单超时以减轻「查询太慢」：alipayConfig.setConnectTimeout(10000); alipayConfig.setReadTimeout(15000);

        return alipayConfig;
    }

    private static AlipayConfig getAlipayConfig() {
        String privateKey  = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCBTOvScNrk0mw+WbR6Qtx2+HrPxB5IU/V2HSPGZUTDNiCiSU9UZcuXlo0UNwMksFYR43btk4BHW9OsZETdr3uJzbEEko4jQPrY49V6V8d3yFUiexcbLKf9W2X+h7EwdPDahHk6wmM73Lm500xzv8JxdGeo/d2uGTh+qD66HcPW+QYj1YbjRV1JyCOiJ2OiwLcb28arNNLOgj6PktQ69FPSWS4hWrM7nl6DLRr6SdOlyfBT47gwPtW0BQ96/2b9O+qxKBPfrcqdRDH323HvrGFDwa8GoWTdchnKwFjmfIFHMvf+eq3tzilFi8H7vQRtzVRrndwrNa0z+1ss07fcWFDRAgMBAAECggEAItgU0OAizPk7vE22SiBMgy8RAX5rXrhpdIwDwQo3Tpf+kV1KKIdKJy6mFCWDDlcKysVOnlVag2BmmZVnzYnls8wfgQjxjuSK9Pno5JBVK51r+9/J6UPOfYMs6Duu700EPw7mEISj81TXJBGiD6tEfgiNisfm/mzDgbZbORKeXQbaTyrtB+GZn6FNSyyHA1vraARMrgfMEGNzQ4AbtfcUxGO+mejdTFs0PxAq6lovHBY3fYYHI1Nx6kf9iPoom/G4UrcMO67W6QU+1tOCZCXjy4bD2y421z/8XD73+WDyYp+Tjy0hTLqVZc7TpYAOximo1vMIUe23EdJJngdlkdpDFQKBgQDFyETL0knwBSakLfAe2BmFb2x++B4YXUnt4dGbCFBnVooxf5i06GVt/CrfkJhYK6hBSowOScIRf8P6BOSQptRZb2/I1ngQm4vcpAZw6EjUTlgOj/J3XJ+ApUNQnRqE28jDrE4m2RHg4BkQo6yA3DizJAluPCtFoCYDm1a7dV7u7wKBgQCnXEH5sD8VSxURv02/gn80g/uZIP/EOU3ycjBEqZdRGkNINwXT+zqrlZIGYb+bxLvU/R2OqKC5vhcyAL3T1A8ORYqPu5KLnAxg7C+rHuVilUWwCEH7POpCk+ETPXCZwcNvLNa5PIqBH/gdV9Y9PBTef6J4rN6V6TDFgosf5by8PwKBgDpVG71Fk1sAGep4RgbC05wgRc6Y3T9wXDqVzJ098YDY7D83E9HfbPLoWbjAS75Nef1vwCkCpgNFPIbD5KmpGp4aGM0SPC0hwzlbAy9PwxMi3CPHXsrHfZ+SnmzrOQQQUoErk40vnm9FiP74VwtWaD6llUZ25ohNeIi9yvHU5x/vAoGAdU2d1JOq85LHtsO+i9+8pyNnAsJ1YqTDtI5CtK2lqKvewswGIrlxOvi//AchVN3ExZmP0QDyfp31BhAs/T8iOl+Vqf7PzVjX+Eszch5aqwlzadmv3ZepnnamCGVE+hAsmkz0R6tebPjqYC7Ds/HbssQFLc4EyVBD5fwE5ZuR+OMCgYAvGHUYpi0dY9uMHXzL721tIopiwUfKCgLAn3yhSH3p7644NxHBqLLaBLVT2q7JAZQUaZUvXlwiyxU1zvo0xmvcbnB/Vd2qp8KbEUkvHyIYVJkM6Fn+9xBosorcrHv+7B2V1XR9WQcXvppxbN/8farWGuAA0anBD+UGrxd8B0/hHg==";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnxevClLpYc6c8A9lwmnftPO2BeU+X6aZ/+b/n1Cvq096VJKiHmqcsRgRbrnSlmPDHRrQpDti4en2Ys0L2lx7CObIr/2xP/jJVwjIO1iWHUj/w/NAbjv7dLW/FFY4SeNp8rU+hlgGgviyUxzonfNfr3v+o8grFqQq27/hiZJAofsQRMQu1dEQqoKdJj7eQLkTstiK5miJMyQ+Y3tLztrEUMBz/zRgaCEfGqmFmRZ2diy2X+1dGaX6H4+0QJ2u50eY2QTBkNuvREGbAn6/lttAgvg/+CywPYKGeC4xOfnl5wP8iA1QXYbXrVJRkZjU097nyOmSNhLy9KvJH2BNpojS1QIDAQAB";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId("2021005196608960");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        return alipayConfig;
    }
}
