PaymentResultManager.java 5.04 KB
package com.diligrp.cashier.trade.manager;

import com.diligrp.cashier.shared.service.ServiceEndpointSupport;
import com.diligrp.cashier.shared.service.ThreadPoolService;
import com.diligrp.cashier.shared.spi.IPaymentEventListener;
import com.diligrp.cashier.shared.spi.domain.PaymentResultBO;
import com.diligrp.cashier.shared.spi.domain.RefundResultBO;
import com.diligrp.cashier.shared.util.JsonUtils;
import com.diligrp.cashier.shared.util.ObjectUtils;
import com.diligrp.cashier.trade.domain.OnlinePaymentResult;
import com.diligrp.cashier.trade.domain.OnlineRefundResult;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Service("paymentResultManager")
public class PaymentResultManager {

    private static final Logger LOG = LoggerFactory.getLogger(PaymentResultManager.class);

    @Resource
    private ObjectProvider<IPaymentEventListener> eventListeners;

    /**
     * 通知业务系统在线支付通道处理结果,并阻塞一段时间保证通知完成
     */
    public void notifyPaymentResult(String uri, OnlinePaymentResult paymentResult, long waitMillis) {
        Future<?> future = notifyPaymentResult(uri, paymentResult);
        try {
            future.get(waitMillis, TimeUnit.MILLISECONDS);
        } catch (Exception ex) {
            // Ignore exception
        }
    }
    /**
     * 通知业务系统在线支付通道处理结果
     */
    public Future<?> notifyPaymentResult(String uri, OnlinePaymentResult paymentResult) {
        return ThreadPoolService.getIoThreadPoll().submit(() -> {
            List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList();
            LOG.info("Notifying online payment result: {}, {}", paymentResult.getTradeId(), paymentResult.getPaymentId());
            if (!lifeCycles.isEmpty()) {
                PaymentResultBO paymentEvent = new PaymentResultBO(paymentResult.getTradeId(), paymentResult.getPaymentId(),
                    paymentResult.getState(), paymentResult.getOutTradeNo(), paymentResult.getOutPayType(),
                    paymentResult.getPayerId(), paymentResult.getWhen(), paymentResult.getMessage());
                for (IPaymentEventListener listener : lifeCycles) {
                    try {
                        listener.onEvent(paymentEvent);
                    } catch (Exception ex) {
                        LOG.error("Failed to notify online payment result", ex);
                    }
                }
            }

            if (ObjectUtils.isNotEmpty(uri)) {
                try {
                    String payload = JsonUtils.toJsonString(paymentResult);
                    ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload);
                    if (httpResult.statusCode != 200) {
                        LOG.error("Failed to notify online payment result");
                    }
                } catch (Exception ex) {
                    LOG.error("Failed to notify online payment result", ex);
                };
            }
        });
    }

    /**
     * 通知业务系统退款处理结果
     */
    public void notifyRefundResult(String uri, OnlineRefundResult refundResult) {
        ThreadPoolService.getIoThreadPoll().submit(() -> {
            List<IPaymentEventListener> lifeCycles = eventListeners.stream().toList();
            if (!lifeCycles.isEmpty()) {
                RefundResultBO refundEvent = new RefundResultBO(refundResult.getRefundId(), refundResult.getTradeId(),
                    refundResult.getState(), refundResult.getWhen(), refundResult.getMessage());
                for (IPaymentEventListener listener : lifeCycles) {
                    try {
                        listener.onEvent(refundEvent);
                    } catch (Exception ex) {
                        LOG.error("Failed to notify trade refund result", ex);
                    }
                }
            }
        });

        if (ObjectUtils.isEmpty(uri)) {
            return;
        }

        ThreadPoolService.getIoThreadPoll().submit(() -> {
            try {
                String payload = JsonUtils.toJsonString(refundResult);
                LOG.info("Notifying online trade refund result: {}", payload);
                ServiceEndpointSupport.HttpResult httpResult = new NotifyHttpClient(uri).send(payload);
                if (httpResult.statusCode != 200) {
                    LOG.error("Failed to notify trade refund result");
                }
            } catch (Exception ex) {
                LOG.error("Failed to notify trade refund result", ex);
            }
        });
    }

    private static class NotifyHttpClient extends ServiceEndpointSupport {
        private final String baseUrl;

        public NotifyHttpClient(String baseUrl) {
            this.baseUrl =  baseUrl;
        }

        public HttpResult send(String body) {
            return send(baseUrl, body);
        }
    }
}