H Honor
ZH
DiDi finanzas

文档中心

提供接入指南、接口文档、测试指引等全流程接入所需信息

4. Merchant APP 容器要求

背景说明:对于所有接入DiDI BNPL H5的客户,都需要对齐容器的配置,以免在唤起DiDi H5页面的时候出现不可预计的问题,影响Merchant的交易成功率。

适配环境:仅仅适配iOS原生和Android 原生,不适用于网页版、Linux系统、或者其他Windows系统。本文档的使用对象,Merchant App 只提供的网页承载配置和检查方法。

"容器"的说明:本文所说的"容器",就是Merchant App 内打开网页的方式:

  • Android WebView/Custom Tabs,或
  • iOS WKWebView/SFSafariViewController。

1. Android APP 自检:代码和配置检查

只检查实际承载我方 H5 的 Activity/Fragment,不要只看公共 WebView 基类或模板代码。先确认容器类型,再按对应小节检查。

1.1 先确认容器类型

检查项 如何检查 结果
容器 确认入口使用 Android WebView,还是 Custom Tabs 记录容器类型、入口 Activity/Fragment、App 版本
如果是 WebView 继续检查 1.2~1.5 需要检查 App 的 WebView 代码和配置
如果是 Custom Tabs 跳到 1.6 不检查Merchant App 的 WebSettings/WebChromeClient

注:根据不同供应商反应的历史,Custom Tabs存在外跳的情况,导致流程异常,不建议适用Custom Tabs。

1.2 系统和网页权限

检查项 如何检查 通过标准
App 相机权限 查看最终合并 Manifest;在 Android 6/API 23+ 查看运行时权限 有 CAMERA,真实测试时状态为 granted
网页摄像头权限 查看最终 WebChromeClient.onPermissionRequest;联调时记录 request.getOrigin() 和 request.getResources() 实际人脸页面 origin 在允许范围内,只授予 RESOURCE_VIDEO_CAPTURE;不能无条件放行全部资源
麦克风(仅当出现音频请求) 阿里 SDK 是否使用麦克风不能预设;只有 onPermissionRequest() 的资源列表出现 AUDIO_CAPTURE 时,才检查 RECORD_AUDIO 和网页授权 未出现 AUDIO_CAPTURE 时不申请麦克风;出现后才按实际人脸页面 origin 放行

1.3 WebView 基础配置

检查项 如何检查 通过标准
JavaScript 查看最终 WebSettings,不要只看初始化默认值 javaScriptEnabled == true
DOM Storage 查看最终 WebSettings domStorageEnabled == true

1.4 页面地址、跳转和功能

检查项 如何检查 通过标准
HTTPS 地址 在 onPageStarted、shouldOverrideUrlLoading、onReceivedError 或 WebView 远程调试 Network 中查看初始、最终和重定向 URL 页面请求使用 https://;无 HTTP 降级、证书错误或 SSL 错误
页面跳转/资源 检查 WebViewClient 的 URL 拦截、资源拦截和域名白名单;联调时查看 Network 请求 不拦截人脸页面、跨域 iframe、HTTPS 重定向和必要资源
输入法:屏幕上推 检查参数是否设置正确。 windowSoftInputMode="adjustUnspecified|stateHidden"

1.5 页面生命周期和版本

检查项 如何检查 通过标准
页面生命周期 检查进入后台、返回、旋转、切 Tab、退出时的处理 人脸过程中不主动刷新、销毁或替换 WebView
WebView 版本 运行时读取 WebView.getCurrentWebViewPackage() 提供 provider 包名、版本和 Android 系统版本

1.6 Android Custom Tabs(不推荐)

Custom Tabs 由浏览器 provider 承载,Merchant App 通常不能读取或修改其内部 WebView 的 WebChromeClient、WebSettings 或媒体回调。

需要确认:

  1. 使用的浏览器/provider、版本和 Android 系统版本;
  2. 系统相机权限和浏览器权限可用;
  3. HTTPS 页面和真实人脸流程可完成。

不要要求 Custom Tabs 提供自建 WebView 的 onPermissionRequest 日志。

2. iOS APP 自检:代码和配置检查

只检查实际承载我方 H5 的 ViewController/WKWebView。

先确认容器类型,再按对应小节检查。

2.1 先确认容器类型

检查项 如何检查 结果
容器 确认入口使用自建 WKWebView,还是 SFSafariViewController 记录容器类型、ViewController、App 版本
如果是 WKWebView 继续检查 2.2~2.5 需要检查 App 的 WKWebView 代码和配置
如果是 SFSafariViewController 跳到 2.6 不检查Merchant App 的 WKWebView 内部配置

2.2 系统和网页权限

检查项 如何检查 通过标准
相机声明 查看最终 App 的 Info.plist 存在 NSCameraUsageDescription,文案有效
相机授权 在真实设备检查系统设置和首次授权结果 相机权限为允许
媒体权限回调 检查是否实现 requestMediaCapturePermissionForOrigin(iOS 15+) 若实现,实际人脸页面 origin 的 camera 请求不能被拒绝;不得用其他拦截逻辑拒绝
麦克风(仅当出现音频请求) 阿里 SDK 是否使用麦克风不能预设;只有媒体权限回调的请求类型包含 microphone 时,才检查 NSMicrophoneUsageDescription 和系统授权 未出现 microphone 请求时不申请麦克风;出现后才放行实际人脸页面的 microphone

2.3 视频显示配置

检查项 如何检查 通过标准
内联播放 查看创建 WKWebViewConfiguration 的代码 创建 WKWebView 前设置 allowsInlineMediaPlayback = YES

2.4 页面地址、跳转和资源

检查项 如何检查 通过标准
HTTPS 地址 在 WKNavigationDelegate 的导航回调或 Safari Web Inspector 中查看初始、最终和重定向 URL 页面请求使用 https://;无 HTTP 降级、证书错误或加载失败
导航与资源 检查 navigationDelegate、URL 白名单、重定向和 iframe 策略 不拦截人脸页面、HTTPS 重定向和必要资源

2.5 页面生命周期和版本

检查项 如何检查 通过标准
页面生命周期 检查返回、切后台、旋转和退出处理 人脸过程中不主动刷新、销毁或替换 WKWebView
版本 记录 iOS 系统版本和 App 版本 实时摄像头按 iOS 14.3+ 真机验证;低版本不能承诺支持

2.6 iOS SFSafariViewController

SFSafariViewController 的内部页面由系统浏览器承载,Merchant App 不能配置 allowsInlineMediaPlayback、WKUIDelegate 或内部媒体回调。Merchant只需提供系统版本、App 版本并完成真实人脸验收;若画面异常,按系统浏览器/版本和真实现象排查。

3. Merchant App JSBridge 环境信息(Suggested)

JSBridge 不是 H5 正常打开和完成认证的硬性条件。

但DiDi侧强烈建议Merchant App 完成JSBridge,提供一个稳定的方法,让 DiDi H5 在出现问题,可快速读取原生容器参数,进行问题的快速诊断。

Android 和 iOS 使用同一套返回结构,H5 不需要分别解析两种格式。

3.1 适用环节说明

人脸验证之前:DiDi H5获取Merchant APP信息。

Merchant APP原生层设定JSBridge,用于DiDi H5获得容器的相关信息,以便在出现问题时进行快速问题定位,协助Merchant APP解决问题,并提升PSR。

H5 (DiDi)  --调用 JSBridge-->  Merchant App 原生层
           <--返回 JSON--      (容器类型/系统版本/权限状态/WebView版本...)

3.2 统一返回格式

Android 示例:

{
  "code": "OK",
  "data": {
    "system": "Android",
    "systemVersion": "15",
    "appVersion": "1.1",
    "containerType": "WEBVIEW",
    "permissions": {
      "camera": {
        "native": "GRANTED",
        "web": "GRANTED"
      },
      "microphone": {
        "native": "NOT_REQUESTED",
        "web": "NOT_REQUESTED"
      }
    },
    "webView": {
      "provider": "com.google.android.webview",
      "version": "131.0.6778.81"
    },
    "webViewConfig": {
      "javaScriptEnabled": true,
      "domStorageEnabled": true,
      "allowsInlineMediaPlayback": null,
      "mediaPlaybackRequiresUserGesture": true
    }
  }
}

同一结构用于 iOS:

{
  "code": "OK",
  "data": {
    "system": "iOS",
    "systemVersion": "26.0",
    "appVersion": "1.1",
    "containerType": "WKWEBVIEW",
    "permissions": {
      "camera": {
        "native": "GRANTED",
        "web": "GRANTED"
      },
      "microphone": {
        "native": "NOT_REQUESTED",
        "web": "NOT_REQUESTED"
      }
    },
    "webView": {
      "provider": "WKWebView",
      "version": "26.0"
    },
    "webViewConfig": {
      "javaScriptEnabled": true,
      "domStorageEnabled": true,
      "allowsInlineMediaPlayback": true,
      "mediaPlaybackRequiresUserGesture": null
    }
  }
}

3.3 字段和状态

字段 含义
code Bridge 调用结果;成功返回 OK,失败返回明确错误码;不表示摄像头权限结果
system / systemVersion 系统名称和系统版本
appVersion Merchant App 版本
containerType WEBVIEW、WKWEBVIEW、CUSTOM_TABS 或 SFSafariViewController
permissions.camera.native App 原生相机权限
permissions.camera.web 网页摄像头媒体权限最近一次结果
permissions.microphone.native App 原生麦克风权限
permissions.microphone.web 网页麦克风媒体权限最近一次结果
webView.provider / webView.version WebView 或系统网页容器的提供方和版本
webViewConfig 实际生效的网页配置;不适用的平台字段返回 null

权限状态统一使用:GRANTED、DENIED、NOT_REQUESTED、UNKNOWN、NOT_APPLICABLE。

3.4 平台边界

  • allowsInlineMediaPlayback 是 iOS WKWebView 配置;Android 没有同名配置,返回 null,不要伪造值。
  • mediaPlaybackRequiresUserGesture 主要用于 Android;iOS 不适用时返回 null。
  • CUSTOM_TABS 和 SFSafariViewController 无法读取的 WebView 配置和网页权限返回 UNKNOWN 或 NOT_APPLICABLE。
  • Bridge 查询不得主动申请权限、弹窗或调用摄像头。
  • 3.2 的环境查询只返回容器、版本和权限状态;
  • JSBridge 方法名、调用方式和异步回调方式由双方接入时约定。

4. 最终效果

4.1 最终要达到的效果

这一节不需要看代码。把我方 H5 放进商户的 App 后,需要达到如下的效果。

现场确认 怎么看 通过标准
H5 能打开 在三方 App 内打开我方 H5 入口 页面能显示,按钮能点击,没有白屏或一直转圈
页面地址安全(HTTPS) 如果页面有地址栏,地址以 https:// 开头;如果是内嵌页面没有地址栏,由 RD 按第 2/3 节检查初始地址、最终地址和跳转地址 所有页面地址都是 https://,没有跳到 http:// 的页面
能使用相机 点击开始人脸,允许系统相机权限 能看到实时摄像头画面
画面和提示都能看到 观察摄像头画面出现后,动作提示是否仍在同一页面可见 画面没有全屏遮挡"请眨眼"等提示
结果能返回 分别完成一次成功、拒绝权限或主动退出 H5 能显示成功或失败结果,不白屏、不死循环

4.2 商户APP容器环境现状梳理

本节不做通过/不通过判定,只记录我方 H5 的人脸流程在该商户 App 中与相机权限交互的真实表现,作为后续排错与适配的依据。请逐项实测并如实填写,未知项标记"待确认";iOS 与 Android、不同容器分别记录。

梳理项 需要记录的现状
相机权限状态 进入人脸流程时的权限态:已授权、尚未申请、已拒绝或受系统限制;如涉及网页权限,另行记录网页授权状态
无权限时的端内处理 能否调起系统权限弹窗,由 App、网页还是浏览器容器触发;用户允许或拒绝后的提示及后续动作
需要跳出时的处理 是否需跳转系统设置页;由按钮跳转还是用户手动进入;需用户完成哪些操作;能否返回原人脸页面
返回后的流程衔接 返回 App 后是否重新检查权限,是继续原流程、重新拍摄还是重新发起;已拒绝且无法再次弹窗或系统限制时,如何提示或退出

请分别实测"首次未授权""拒绝后再次进入""设置页授权后返回"三种场景,记录操作步骤及是否跳出当前 App/容器,避免仅凭"支持相机权限"判断实际体验。

复制成功