PAYATHON 2026

React 如何查询 Callback URL 中的支付状态参数?

支付小周

结论

useParams() 用来读取路由中的路径参数,例如 /paymentstatus/:status/:id,无法读取 ?status=success&id=... 这样的查询参数。

当前 Callback URL 里的 status 和 id 都是 query params,应通过 React Router 的 useSearchParams() 读取,也可以使用浏览器原生的 URLSearchParams。

使用 useSearchParams()

如果当前项目使用的 React Router 支持 useSearchParams,可以这样写:

import { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import Axios from "axios";

function ConfirmationPage({ baseurl, token }) {
  const [searchParams] = useSearchParams();

  const status = searchParams.get("status");
  const id = searchParams.get("id");

  const [paymentRef, setPaymentRef] = useState("");
  const [paymentStatus, setPaymentStatus] = useState("loading");

  useEffect(() => {
    if (status !== "success" || !id) {
      setPaymentStatus("failure");
      return;
    }

    let ignore = false;

    setPaymentStatus("loading");

    Axios.get(`${baseurl}/query/transactionid/${encodeURIComponent(id)}`, {
      headers: {
        "content-type": "application/json",
        "x-access-token": token,
      },
    })
      .then((response) => {
        if (ignore) return;

        setPaymentRef(response.data);
        setPaymentStatus("success");
      })
      .catch(() => {
        if (ignore) return;

        setPaymentStatus("failure");
      });

    return () => {
      ignore = true;
    };
  }, [baseurl, id, status, token]);

  if (paymentStatus === "loading") {
    return <p>正在确认支付结果,请稍候……</p>;
  }

  if (paymentStatus === "success") {
    return (
      <div>
        <h1>支付成功</h1>
        <p>您的付款已成功并完成确认。</p>
        <p>Payment reference: {String(paymentRef)}</p>
      </div>
    );
  }

  return (
    <div>
      <h1>支付失败</h1>
      <p>暂时无法确认本次付款,请检查交易状态或稍后重试。</p>
    </div>
  );
}

export default ConfirmationPage;

对于以下地址:

http://reactappName/paymentstatus/?status=success&id=267062191825950

读取到的结果是:

status === "success";
id === "267062191825950";

URLSearchParams.get() 的返回类型是 string | null,因此还要检查 id 是否存在,以免请求地址中出现 undefined 或 null。

使用浏览器原生的 URLSearchParams

如果当前 React Router 版本不支持 useSearchParams(),可以直接读取 window.location.search:

const searchParams = new URLSearchParams(window.location.search);

const status = searchParams.get("status");
const id = searchParams.get("id");

完整逻辑可以写成:

import { useEffect, useState } from "react";
import Axios from "axios";

function ConfirmationPage({ baseurl, token }) {
  const [paymentRef, setPaymentRef] = useState("");
  const [paymentStatus, setPaymentStatus] = useState("loading");

  useEffect(() => {
    const searchParams = new URLSearchParams(window.location.search);
    const status = searchParams.get("status");
    const id = searchParams.get("id");

    if (status !== "success" || !id) {
      setPaymentStatus("failure");
      return;
    }

    Axios.get(`${baseurl}/query/transactionid/${encodeURIComponent(id)}`, {
      headers: {
        "content-type": "application/json",
        "x-access-token": token,
      },
    })
      .then((response) => {
        setPaymentRef(response.data);
        setPaymentStatus("success");
      })
      .catch(() => {
        setPaymentStatus("failure");
      });
  }, [baseurl, token]);

  // 根据 paymentStatus 渲染页面
}

如果应用已经在使用 React Router,建议选择 useSearchParams()。路由中的查询字符串发生变化时,它会随之更新组件。

useParams() 什么时候才适用

路由声明了路径参数时,useParams() 才能读取相应的值。例如:

<Route
  path="/paymentstatus/:status/:id"
  element={<ConfirmationPage />}
/>

对应的访问地址必须是:

/paymentstatus/success/267062191825950

此时可以这样读取:

const { status, id } = useParams();

当前支付网关返回的是查询字符串,无需为此修改路由结构,直接读取 query params 即可。

注意事项

Callback URL 中的 status=success 只能用于判断是否发起查询,不能作为支付成功的最终依据。用户可以手动修改浏览器地址,所以最终状态必须以服务端调用交易查询接口后返回的结果为准。

示例中的这行代码:

setPaymentRef(response.data);

是否正确,要看查询接口实际返回的数据结构。如果接口返回的是对象,例如:

{
  "paymentReference": "ABC123",
  "status": "successful"
}

就应读取具体字段,并检查服务端确认的交易状态:

const transaction = response.data;

if (transaction.status === "successful") {
  setPaymentRef(transaction.paymentReference);
  setPaymentStatus("success");
} else {
  setPaymentStatus("failure");
}

具体字段名和代表成功的状态值应以接口的实际响应为准。HTTP 请求成功并不等于支付成功,不能仅凭请求成功就把交易标记为支付成功。

备注:内容仅供参考。