Google Pay

📘

Legend Base SDK 通过 Google Pay API 为合作伙伴提供网页内支付能力。用户在当前网页内完成支付,无需重定向;支付结果通过 LegendBase 构造时传入的 onPay / onError 回调返回。

支付过程中的中间态(点击按钮、sheet 弹起、下单中)也通过 onPay 返回,用于驱动 loading UI,详见下方 支付过程中的 loading 处理

集成路线图

如果你是第一次接入 Google Pay,按以下顺序走:

步骤说明
1️⃣ 完成 SDK 初始化new LegendBase() 实例化与登录授权,参考 开始使用
2️⃣ 检测设备能力canSetupGooglePay() 确认当前浏览器是否支持 Google Pay
3️⃣ 拉起支付setupGooglePay() 在指定容器内挂载 Google Pay 官方品牌按钮
4️⃣ 处理结果用户点击按钮 → SDK 自动唤起支付 sheet → 通过 onPay / onError 回调拿到订单结果
%%{init: {"flowchart": {"htmlLabels": true, "curve": "basis"}, "themeVariables": {"fontSize": "20px"}}}%%
flowchart LR
    A["1. SDK 初始化<br/>new LegendBase()<br/>+ 登录授权"] --> B["2. canSetupGooglePay()<br/>检测设备能力"]
    B --> C["3. setupGooglePay()<br/>挂载 Google Pay 按钮<br/>到指定容器"]
    C --> D["4. 处理结果<br/>onPay / onError<br/>回调返回订单数据"]

UI 触发时机

集成路线图讲的是「SDK 方法是什么」;这一节讲的是「在交易所自己的 UI 上,用户的哪个动作触发哪个 SDK 调用」。

%%{init: {"sequence": {"actorMargin": 60, "messageMargin": 35}, "themeVariables": {"fontSize": "16px"}}}%%
sequenceDiagram
    autonumber
    participant U as 用户
    participant E as 交易所页面
    participant SDK as Legend Base SDK
    participant G as Google Pay 浮层

    U->>E: 进入购买页
    E->>SDK: canSetupGooglePay()
    SDK-->>E: true / false
    E->>SDK: setupGooglePay({...})
    SDK-->>E: 在指定容器内挂载 Google Pay 按钮

    U->>E: 填金额、选 Google Pay
    U->>E: 点击 Google Pay 按钮
    SDK-->>E: onPay('clicked') → 开 loading
    SDK->>G: 自动唤起 Google Pay 支付浮层
    SDK-->>E: onPay('authorizing') → 可关 loading
    U->>G: 选卡 + 授权
    G-->>SDK: walletToken
    SDK-->>E: onPay('processing') → 重新开 loading
    SDK->>SDK: 自动下单(Sandbox 可达 20-40s)
    SDK-->>E: 触发 onPay / onError 回调
    E-->>U: 显示 success / failed UI

用户若在浮层中主动关闭,SDK 触发 onPay('cancelled')不是 onError)。

UI 时机速查表

用户的 UI 动作调用方法 / 回调用途
购买页加载(如 onMount / mountedcanSetupGooglePay() + setupGooglePay({...})检测能力 + 在指定容器挂载 Google Pay 官方按钮
用户点击 Google Pay 按钮onPay('clicked', { provider })SDK 自动捕获点击,无需额外调用;收到回调后开 loading + disable 按钮
支付浮层弹起onPay('authorizing', { provider })浮层会遮住页面,可选关闭页面 loading
用户在浮层内授权完成onPay('processing', { provider })浮层关闭、SDK 正在下单,Sandbox 实测 20–40 秒,务必显示 loading
用户在浮层内主动取消onPay('cancelled', { provider, reason })终态;不是错误,不要弹错误提示
支付完成或失败onPay('success' / 'pending' / 'failed') / onError返回订单结果,关闭 loading
💡

onPay / onError 回调需要在 new LegendBase({ onPay, onError }) 实例化 SDK 时传入,不是在 UI 时机里动态绑定。详见 前端集成 中的事件回调说明。

在开始集成前我们建议阅读下面的文档说明:

当前网页的支付流程

🟢

优点

集成简单,无需额外配置 Google Pay 商户证书或域名验证;交互流程短,所有数据传输都在当前网页内完成。

🟠

缺点

仅支持在当前网页内完成支付,不支持重定向到外部页面(跨设备场景需自行实现)。

  • 调用canSetupGooglePay()方法,获取当前运行环境是否支持 Google Pay。
const resp = await legend.canSetupGooglePay()
console.log("canSetupGooglePay: \n", resp);

调用前请确保页面中已有匹配 wrapperSelector 的 DOM 元素(例如 <div class="google-pay-wrapper"></div>),Google Pay 按钮会插入到该元素内部。

  • 调用setupGooglePay()方法,初始化 Google Pay 的支付按钮。
await legend.setupGooglePay({
  wrapperSelector: '.google-pay-wrapper',
  button: {
    buttonColor: 'default', // 'default' | 'black' | 'white'
    buttonType: 'buy',      // 'buy' | 'pay' | 'plain' | 'donate' | 'short' | 'subscribe'
  },
  order: {
    app_state, // 合作伙伴自定义的订单关联字符串,会原样回传给回调
    network: "ETH",
    pair: "USDCUSD",
    side: "buy",
    size: "50",
    external_order_id: `otcsb-googlepay-${Date.now().toString()}`
  }
});

按钮注入后用户点击会自动唤起 Google Pay 支付,授权完成后 SDK 自动下单。支付结果通过 LegendBase 构造时传入的 onPay / onError 回调返回,详见 前端集成 中的事件回调说明。




支付过程中的 loading 处理

Google Pay 原生按钮流程中有两段用户看不到进度的空档:

  1. 点击按钮 → 浮层弹出:Google Pay 内部要做商户能力校验、加载资源,可能耗时数百毫秒到 1 秒。
  2. 授权完成 → 拿到订单结果:浮层已关闭、页面回到你自己的 UI,SDK 正在调用 Legend 下单接口。该阶段在 Sandbox 环境实测耗时 20–40 秒,如果不给提示,用户会以为页面卡死。

SDK 通过 onPay 的三个中间态覆盖这两段空档:

status含义建议动作
clicked用户点下按钮setLoading(true) + disable 按钮
authorizing支付浮层即将弹起可选 setLoading(false)(浮层会遮住页面)
processing已授权,正在下单setLoading(true) —— 最关键的一段
💡

三个中间态都不是终态,收到之后保证会跟随一个终态(success / pending / failed / cancelled),可以据此安全地配对开关 loading。完整状态机见 前端集成 § 8.onPay 支付回调

const legend = new LegendBase({
  mode: "sandbox",
  onPay: (status, paymentData) => {
    switch (status) {
      case 'clicked':
        // 用户刚点下 Google Pay 按钮
        setLoading(true);
        disablePayButton();
        break;

      case 'authorizing':
        // 支付浮层即将弹起,会遮住页面,可选关闭 loading
        setLoading(false);
        break;

      case 'processing':
        // 已授权、正在下单 —— Sandbox 可能 20-40 秒
        setLoading(true, '正在处理支付,请稍候…');
        break;

      case 'success':
        setLoading(false);
        showSuccessPage(paymentData.data);
        break;

      case 'pending':
        setLoading(false);
        showPendingPage();
        break;

      case 'failed':
        setLoading(false);
        showErrorModal(paymentData.subject, paymentData.message);
        break;

      case 'cancelled':
        // 用户主动关闭了浮层 —— 不是错误,不要弹错误提示
        setLoading(false);
        showToast('支付已取消');
        enablePayButton();
        break;
    }
  },
  onError: (error) => {
    // 这里只包含真正的技术异常,用户主动取消已经走 onPay('cancelled')
    setLoading(false);
    showErrorModal(error.message);
  },
});

用户取消的识别

🚨

行为变更:旧版本中用户关闭 Google Pay 浮层会作为异常派发到 onError(错误对象形如 { statusCode: "CANCELED" })。从本版本起,SDK 单独识别该场景并派发到 onPay('cancelled', { provider: 'googlepay', reason: 'user_abort' })onError 只保留真正的技术异常。

如果你此前在 onError 里通过 err.statusCode === "CANCELED" 判断取消,请迁移到 onPaycase 'cancelled': 分支。