PAYATHON 2026

Revolut Checkout 集成时 sandbox embed.js 返回 404

支付阿杰

结论

无需从 https://sandbox-merchant.revolut.com/embed.js 加载脚本。如果该地址返回 404,请改用通用的 Checkout 脚本:

https://merchant.revolut.com/embed.js

初始化 RevolutCheckout 时,需要明确指定 sandbox 环境:

RevolutCheckout(publicId, "sandbox")

脚本托管地址与交易环境是两个独立的配置。通过生产域名加载 embed.js,不代表支付请求会进入生产环境。交易实际使用的环境取决于初始化参数,以及后端创建订单时连接的 Merchant API 环境。

推荐的接入方式

<script src="https://merchant.revolut.com/embed.js"></script>

<button id="checkout-button" type="button">
  Pay
</button>

<script>
  document
    .getElementById("checkout-button")
    .addEventListener("click", async function () {
      try {
        // publicId 必须由 sandbox Merchant API 创建订单后返回。
        const publicId = "YOUR_SANDBOX_PUBLIC_ID";

        const checkout = await RevolutCheckout(publicId, "sandbox");

        checkout.payWithPopup({
          onSuccess() {
            console.log("Checkout completed");
          },
          onError(error) {
            console.error("Checkout failed", error);
          },
          onCancel() {
            console.log("Checkout cancelled");
          }
        });
      } catch (error) {
        console.error("Unable to initialise Revolut Checkout", error);
      }
    });
</script>

如果后端动态返回 public_id,可以等订单创建成功后再初始化 Checkout:

async function startCheckout() {
  const response = await fetch("/api/create-order", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    }
  });

  if (!response.ok) {
    throw new Error(`Order creation failed: HTTP ${response.status}`);
  }

  const order = await response.json();

  if (!order.public_id) {
    throw new Error("The response does not contain public_id");
  }

  const checkout = await RevolutCheckout(order.public_id, "sandbox");

  checkout.payWithPopup({
    onSuccess() {
      console.log("Payment successful");
    },
    onError(error) {
      console.error("Payment error", error);
    },
    onCancel() {
      console.log("Payment cancelled");
    }
  });
}

需要保持一致的环境配置

前后端必须连接同一个环境:

  • 后端通过 sandbox Merchant API 创建订单。
  • 前端使用该订单对应的 sandbox public_id。
  • 前端调用 RevolutCheckout(publicId, "sandbox")。
  • 不要在 prod 模式下使用 sandbox 创建的 public_id。

省略第二个参数时,SDK 可能使用默认环境。集成期间应明确传入 "sandbox",以免 sandbox 订单被误送到生产 Checkout。

仍然无法弹出 Checkout 时

请先在浏览器开发者工具中检查:

  1. https://merchant.revolut.com/embed.js 是否成功返回 JavaScript。
  2. 控制台是否出现 RevolutCheckout is not defined。
  3. public_id 是否来自 sandbox 订单,而非内部订单 ID。
  4. Checkout 是否由用户点击触发。浏览器可能会拦截未经用户操作直接打开的弹窗。
  5. 页面的 CSP 是否阻止了脚本或弹窗,例如 script-src、frame-src 或 connect-src。
  6. 广告拦截器、隐私扩展或公司代理是否拦截了 Revolut 域名。

如果页面启用了严格的 CSP,请根据实际网络请求补充 Revolut 使用的域名,不要为了绕过限制而直接使用范围过宽的 * 或 'unsafe-inline'。

注意事项

https://sandbox-merchant.revolut.com/embed.js 返回 404,可能是旧接入方式已经失效,也可能与部署异常或文档和实际 CDN 状态不一致有关。不要自行复制、缓存或托管从其他环境获取的 embed.js,Checkout SDK 可能随时更新。

支付成功回调只能用来更新前端界面,不能作为最终入账依据。订单的最终状态应由后端通过 Merchant API 查询,或通过 Revolut webhook 确认。

备注:内容仅供参考。