6.5 支付结果查询

6.5.1 交互流程

根据技术方案的分析,交互流程如下:

1、支付渠道代理服务调用支付宝下单接口完成后向MQ发送“支付结果查询”消息(延迟消息),消费方为支付渠道代理服务。

2、支付渠道代理服务监听消息队列,接收“支付结果查询”消息。

3、支付渠道代理服务调用第三方支付系统的支付结果查询接口。

6.5.2 发送消息

6.5.2.1 配置RocketMQ

1)在支付渠道代理工程中添加RocketMQ依赖:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq‐spring‐boot‐starter</artifactId>
    <version>2.1.1</version>
</dependency>

2)在Nacos中添加spring-boot-starter-rocketmq.yaml配置,Data ID: spring-boot-starter-rocketmq.yaml, Group: COMMON_GROUP

rocketmq:
 nameServer: 127.0.0.1:9876
 producer:
  group: PID_PAY_PRODUCER

3)在huiminpay-payment-agent-service工程bootstrap.yml中引入此配置:

‐
  refresh: true
  data‐id: spring‐boot‐starter‐rocketmq.yaml # rocketmq配置
  group: COMMON_GROUP # 通用配置组
6.5.2.2 生产消息类

1、修改支付宝下单调用方法createPayOrderByAliWAP,调用PayProducer发送消息。

发送支付结果查询延迟消息代码如下:

try { 
    //发送支付结果查询延迟消息 
    PaymentResponseDTO<AliConfigParam> notice = new PaymentResponseDTO<AliConfigParam>(); 
    notice.setOutTradeNo(alipayBean.getOutTradeNo()); 
    notice.setContent(aliConfigParam); 
    notice.setMsg("ALIPAY_WAP"); 
    payProducer.payOrderNotice(notice); 

    // 调用SDK提交表单 
    AlipayTradeWapPayResponse response = client.pageExecute(alipayRequest); 
    log.info("支付宝手机网站支付预支付订单信息" + response); 
    PaymentResponseDTO res = new PaymentResponseDTO(); 
    res.setContent(response.getBody()); 
    return res; 
} catch (Exception e) {
    e.printStackTrace(); 
    throw new BusinessException(CommonErrorCode.E_400002);//支付宝确认支付失败 
}

2、在支付渠道代理服务中编写生产消息类PayProducer

package com.huiminpay.paymentagent.message;

import com.huiminpay.common.api.dto.PaymentResponseDTO; 
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate; 
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
@Slf4j
@Component
public class PayProducer {

    //消息Topic
    private static final String TOPIC_ORDER = "TP_PAYMENT_ORDER";

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    public void payOrderNotice(PaymentResponseDTO result) {
        log.info("支付通知发送延迟消息:{}", result);
        try {
            //处理消息存储格式
            Message<PaymentResponseDTO> message = MessageBuilder.withPayload(result).build();
            SendResult sendResult = rocketMQTemplate.syncSend(TOPIC_ORDER, message, 1000, 3);
        } catch (Exception e) {
            log.warn(e.getMessage(), e);
        }
    }
}

6.5.3 接收消息

定义PayConsumer类,监听“支付结果查询”消息队列。

package com.huiminpay.paymentagent.message; 

@Slf4j 
@Service 
@RocketMQMessageListener(topic = "TP_PAYMENT_ORDER", consumerGroup = "CID_PAYMENT_CONSUMER") 
public class PayConsumer implements RocketMQListener<MessageExt> { 

    @Resource 
    private PayChannelAgentService payAgentService; 

    @Override 
    public void onMessage(MessageExt messageExt) { 

        log.info("开始消费支付结果查询消息:{}", messageExt); 
        //取出消息内容 
        String body = new String(messageExt.getBody(), StandardCharsets.UTF_8); 
        PaymentResponseDTO response = JSON.parseObject(body, PaymentResponseDTO.class); 
        String outTradeNo = response.getOutTradeNo(); 
        String msg = response.getMsg(); 
        String param = String.valueOf(response.getContent()); 
        AliConfigParam aliConfigParam = JSON.parseObject(param, AliConfigParam.class); 
        //判断是支付宝还是微信 
        PaymentResponseDTO result = new PaymentResponseDTO(); 
        if ("ALIPAY_WAP".equals(msg)) { 
            //查询支付宝支付结果 
            result = payAgentService.queryPayOrderByAli(aliConfigParam, outTradeNo); 
        } else if ("WX_JSAPI".equals(msg)) { 
            //查询微信支付结果 
        } 
        //返回查询获得的支付状态 
        if (TradeStatus.UNKNOWN.equals(result.getTradeState()) 
            || TradeStatus.USERPAYING.equals(result.getTradeState())) { 
            //在支付状态未知或支付中,抛出异常会重新消息此消息 
            log.info("支付代理‐‐‐支付状态未知,等待重试"); 
            throw new RuntimeException("支付状态未知,等待重试"); 
        } 
    } 
}