KKSU
2025-02-07 62fc17e246f99c73f162f243490a811e540c0043
src/main/java/cc/mrbird/febs/pay/util/FiuuRefundUtil.java
@@ -1,7 +1,9 @@
package cc.mrbird.febs.pay.util;
import cc.mrbird.febs.pay.model.RefundStatus;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
@@ -9,17 +11,13 @@
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.*;
@Slf4j
@Service(value="FiuuRefundUtil")
public class FiuuRefundUtil {
    private static final String API_BASE_URL = "https://api.fiuu.com/RMS/API/refundAPI/";
    private static final String MERCHANT_ID = "e2umart01";
    private static final String VERIFY_KEY = "4e3a4ed58e62ddbfacf41f6d5ec56bf2";
    private static final int MAX_RETRIES = 3;
    private static final int POLL_INTERVAL = 1000; // 5秒
    private static final int TIMEOUT = 60000; // 60秒超时
    private final ObjectMapper objectMapper = new ObjectMapper();
@@ -47,41 +45,16 @@
        HttpGet request = new HttpGet(url);
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            String response = EntityUtils.toString(client.execute(request).getEntity());
            List<RefundStatus> refundStatusList = objectMapper.readValue(
                    response,
                    objectMapper.getTypeFactory().constructCollectionType(List.class, RefundStatus.class));
            log.info("Response: " + response);
            List<RefundStatus> refundStatusList = JSONUtil.toList(JSONUtil.parseArray(response), RefundStatus.class);
            return refundStatusList.get(0);
        }
    }
    // 异步轮询退款状态
    public RefundStatus pollRefundStatus(String txnId) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<RefundStatus> future = executor.submit(() -> {
            int retryCount = 0;
            while (retryCount < MAX_RETRIES) {
                try {
                    RefundStatus status = queryByTxnId(txnId);
                    if (!"pending".equals(status.getStatus())) {
                        return status;
                    }
                    Thread.sleep(POLL_INTERVAL);
                    retryCount++;
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Polling interrupted", e);
                }
            }
            throw new TimeoutException("Max retries reached");
        });
        try {
            return future.get(TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            throw new RuntimeException("Refund status check timeout");
        } finally {
            executor.shutdown();
        }
        RefundStatus status = queryByTxnId(txnId);
        return status;
    }
}