Skip to content

当用户支付成功后,支付宝会根据我们设置的服务器通知地址,通知我们用户的支付结果,我们需要对结果进行验签,防止用户伪造,然后再提取需要的参数,来完善我们的业务逻辑,例如更改订单状态、填充订单支付成功时间和支付宝生成的交易号等等。

提取返回参数实体类对象

支付宝支付成功回调参数说明,我这里截取了项目常用到的参数,如果你有特殊需要可以去异步通知参数说明查询。

java
import cn.hutool.core.date.DateUtil;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AliPayCallbackDto {

    /**
     * 商户订单号
     */
    private String orderId;
    /**
     * 支付宝交易号
     */
    private String waterId;
    /**
     * 交易状态
     */
    private String tradeStatus;

    /**
     * 付款时间
     */
    private Date payTime;

    public AliPayCallbackDto(HttpServletRequest request) {
        this.orderId = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        this.waterId = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        this.tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        String payTime = new String(request.getParameter("gmt_payment").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        // 调用Hutool工具包将字符串转换成日期类型
        this.payTime = DateUtil.parse(payTime);
    }
}

支付宝验签方法

java
@Slf4j
@Component
public class AliPayUtils {
    @Autowired
    private AliPayConfig aliPayConfig;

    @Autowired
    private AlipayClient alipayClient;


    /**
     * 支付宝支付成功回调通知验签
     * @return true验签通过
     */
    public boolean rsaCheck(HttpServletRequest request) {
        // 获取支付宝POST过来反馈信息,对数据进行验签
        Map<String, String> params = new HashMap<>();
        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);
        }

        try {
            return AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(), "UTF-8", aliPayConfig.getSignType());
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
}

回调接口开发

java
@Slf4j
@RestController
@RequestMapping("/api/v1/ali")
public class AlipayController {

    @Autowired
    private AliPayUtils aliPayUtils;

    @PostMapping("/ali/pay/callback")
    public String courseAliCallback(HttpServletRequest request, HttpServletResponse response) {
        // 获取支付宝POST过来反馈信息,对数据进行验签
        boolean flag = aliPayUtils.rsaCheck(request);

        if (flag) {
            AliPayCallbackDto dto = new AliPayCallbackDto(request);
            if ("TRADE_SUCCESS".equals(dto.getTradeStatus()) || "TRADE_FINISHED".equals(dto.getTradeStatus())) {
                // TODO 执行你的业务逻辑
            }
            return "success";
        } else {
            //验证失败
            return "fail";
        }
    }
}