You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:从Chrome网页返回Activity时如何获取处理结果

Android 从Chrome网页返回时的网银支付状态校验实现

核心原则先摆前面:所有前端/网页侧回传的支付状态仅可做UI层的即时提示,绝对不能作为最终支付结果的判定依据,最终状态必须以自家服务端和网银/支付机构的对账结果为准,避免参数篡改、伪造回调导致资损。


具体实现逻辑

1. 提前配置回调通道

优先用专属DeepLink作为网页跳转回应用的通道,不要依赖页面栈的自然返回:

  • 在AndroidManifest.xml中给接收支付结果的Activity配置专属intent-filter,注意设置独立的、辨识度高的scheme,避免和其他应用撞名:
<activity
    android:name=".PayResultActivity"
    android:exported="true"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="youruniquepayscheme"
            android:host="payresult" />
    </intent-filter>
</activity>
  • 和网银侧约定:用户支付完成、主动取消支付时,网页自动跳转到你配置的DeepLink地址,格式参考youruniquepayscheme://payresult?outOrderNo=本地订单号&tempStatus=success/cancel
  • Android 11及以上版本需要在Manifest中补充包查询权限,否则无法校验Chrome来源:
<queries>
    <package android:name="com.android.chrome" />
    <package android:name="com.chrome.beta" />
    <package android:name="com.chrome.dev" />
</queries>

2. 回调接收时的前置校验

在接收回调的Activity中,重写onCreate和onNewIntent方法处理回调Intent,先做三层前置校验,过滤非法请求:

// 本地记录的当前正在支付的订单号,发起支付时赋值
private var currentPayOrderNo: String? = null

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    handlePayCallback(intent)
}

private fun handlePayCallback(intent: Intent?) {
    // 第一层:校验调用来源,只认Chrome的回调,拦截其他恶意应用伪造的跳转
    val referer = intent?.getStringExtra(Intent.EXTRA_REFERRER)
    val validChromePackages = listOf(
        "com.android.chrome",
        "com.chrome.beta",
        "com.chrome.dev",
        "com.google.android.apps.chrome"
    )
    if (referer == null || validChromePackages.none { referer.contains(it) }) {
        handlePayError()
        return
    }

    val callbackUri = intent.data
    val callbackOrderNo = callbackUri?.getQueryParameter("outOrderNo")
    // 第二层:校验订单号一致性,防止串单
    if (callbackOrderNo.isNullOrEmpty() || callbackOrderNo != currentPayOrderNo) {
        handlePayError()
        return
    }

    // 第三层:不使用网页回传的tempStatus做最终判定,立刻请求服务端查询真实状态
    queryRealPayStatusFromServer(callbackOrderNo)
}

3. 兜底逻辑(处理用户未等网页回调直接返回的场景)

很多用户会在支付操作完成后,直接按返回键/切应用回到App,不会等网页触发DeepLink跳转,必须加生命周期兜底:

  • 发起支付跳Chrome时,将当前待支付的订单号持久化到ViewModel或本地数据库,不要存在容易被系统回收的临时变量里
  • 监听支付流程所在Activity的onResume生命周期:如果页面回到前台时存在待校验的支付订单,直接触发服务端订单状态查询,不要直接判定为支付取消
  • 查询服务端时建议加1-2次轮询(间隔2s左右),避免网银侧状态同步延迟导致查询结果不准

避坑要点

  • 不要直接读取Chrome回传参数里的success/cancel字段更新订单状态,这类参数可以被抓包篡改、被恶意应用伪造
  • 不要在用户从Chrome返回时直接弹窗提示“支付已取消”,必须等服务端查询结果返回后再做提示,避免用户实际支付成功却被误判取消
  • DeepLink的scheme不要用过于通用的命名(比如直接用pay、callback这类),避免和其他应用配置冲突导致被恶意拦截

内容的提问来源于stack exchange,提问作者rNkL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:36:23