sumsub-integrate-dint-websdk
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSumsub — Device Intelligence via the WebSDK
Sumsub — 通过WebSDK实现设备智能
Add Device Intelligence (DI) to a project that already embeds the Sumsub
WebSDK. DI is the fraud-detection layer that captures low-level device/browser
signals (device fingerprint, bot/automation, VPN/proxy, emulator, incognito,
reused-device) and attaches them to the applicant as device risk labels
that feed risk scoring.
The JS module that does the capture is called Fisherman (npm
) — same thing, different name. Inside the WebSDK you almost
never touch it directly; the SDK ships and drives it for you.
@sumsub/fisherman为已嵌入Sumsub WebSDK的项目添加设备智能(DI)功能。DI是欺诈检测层,可捕获底层设备/浏览器信号(设备指纹、机器人/自动化工具、VPN/代理、模拟器、隐身模式、重复使用设备),并将这些信号作为设备风险标签关联到申请人,为风险评分提供数据支持。
负责捕获数据的JS模块名为Fisherman(npm包)——两者指代同一功能,只是名称不同。在WebSDK中,你几乎无需直接操作该模块,SDK会自动加载并驱动它运行。
@sumsub/fisherman⚠️ Sandbox tokens only
⚠️ 仅使用沙箱令牌
Do not accept or use a production App Token / secret during integration
work. Insist on a sandbox pair from
https://cockpit.sumsub.com/checkus/devSpace/appTokens — toggle the workspace
to Sandbox first, then Create. Token + secret are revealed once at
creation; copy both before closing the dialog. Helper scripts in sibling skills
enforce this with an prefix check; the curl recipes here assume the same.
Deeper auth mechanics: .
sbx:sumsub-api-auth集成过程中请勿使用生产环境的应用令牌/密钥。请从https://cockpit.sumsub.com/checkus/devSpace/appTokens获取沙箱令牌对——先将工作区切换为Sandbox,再点击Create。令牌和密钥仅在创建时显示一次,请在关闭对话框前复制两者。同目录下其他技能中的辅助脚本会通过前缀检查强制验证这一点;本文中的curl命令也遵循此规则。更详细的认证机制请参考:。
sbx:sumsub-api-authThe lifecycle in one picture
生命周期示意图
┌───────────────────────────────┐ ← one-time, in the dashboard
│ 1. "Capture device data" on │ (verification level settings)
│ on the verification level │
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐ ← your existing sumsub-integrate-websdk
│ 2. WebSDK launches as usual │ code. NOTHING new on the frontend.
│ (same access token) │
└───────────────┬───────────────┘
│ the SDK auto-inits Fisherman with that token,
│ fingerprints the device, attaches it to the applicant
┌───────────────▼───────────────┐ ┌─────────────────────────────────┐
│ 3. Sumsub computes device │─▶│ Device risk labels on the │
│ signals + risk labels │ │ applicant; feed risk scoring │
└───────────────┬───────────────┘ └─────────────────────────────────┘
│
┌───────────────▼───────────────┐ ← server reads the applicant /
│ 4. You read the verdict + │ receives the webhook (same as
│ device signals server-side │ the base WebSDK flow)
└────────────────────────────────┘The headline: for a standard WebSDK integration, DI is a dashboard toggle, not
new code. Stages 3–4 below are the advanced (self-rendered) path and the
result-reading details.
┌───────────────────────────────┐ ← 仅需在控制台操作一次
│ 1. 在验证级别开启"捕获设备数据" │ (验证级别设置)
│ 选项 │
└───────────────┬───────────────┘
│
┌───────────────▼───────────────┐ ← 你已有的sumsub-integrate-websdk
│ 2. WebSDK正常启动 │ 代码。前端无需修改任何内容。
│ (使用相同的访问令牌) │
└───────────────┬───────────────┘
│ SDK会自动使用该令牌初始化Fisherman,
│ 为设备生成指纹并关联到申请人
┌───────────────▼───────────────┐ ┌─────────────────────────────────┐
│ 3. Sumsub计算设备信号和风险标签 │─▶│ 申请人的设备风险标签,为风险评分提供数据 │
└───────────────┬───────────────┘ └─────────────────────────────────┘
│
┌───────────────▼───────────────┐ ← 服务器端读取审核结果和
│ 4. 你在服务器端读取审核结果和 │ 设备信号(与基础WebSDK流程一致,
│ 设备信号 │ 可通过Webhook接收)
└────────────────────────────────┘核心要点:对于标准WebSDK集成,DI仅需在控制台切换开关,无需编写新代码。以下第3-4阶段为高级(自定义渲染)实现路径和结果读取细节。
Stage 1 — Enable device capture on the level
阶段1 — 在验证级别启用设备捕获
DI rides along automatically in WebSDK 2.0 and the Mobile SDKs only when
"Capture device data" is enabled in the verification level settings. In the
dashboard: open the level → Device intelligence section → tick Capture
device data. If you don't see the setting, DI isn't provisioned for the workspace —
contact Sumsub to enable the product before continuing.
Optional BYOK: you can supply your own Fingerprint Pro credentials (public +
secret API key) under DevSpace → Integrations → Fingerprint so devices are
captured under your Fingerprint account. Without BYOK, Sumsub's own credentials
are used — both work; BYOK only matters if you already run Fingerprint Pro.
That's the entire required setup. Re-launch your existing WebSDK flow and devices
start getting captured.
仅当验证级别设置中开启「捕获设备数据」选项时,DI才会自动在WebSDK 2.0和移动SDK中运行。操作步骤:在控制台中打开对应验证级别 → 进入设备智能板块 → 勾选捕获设备数据。若未找到该设置,说明当前工作区未启用DI功能,请联系Sumsub启用产品后再继续。
可选BYOK(自带密钥):你可以在DevSpace → Integrations → Fingerprint中提供自己的Fingerprint Pro凭证(公钥+密钥API密钥),这样设备数据会捕获到你的Fingerprint账户下。若不使用BYOK,将默认使用Sumsub自身的凭证——两种方式均可生效;仅当你已在使用Fingerprint Pro时,BYOK才有实际意义。
以上就是全部必要设置。重新启动你已有的WebSDK流程,设备数据将开始被捕获。
Stage 2 — The automatic in-SDK lifecycle (no code)
阶段2 — SDK内自动执行的生命周期(无需编码)
With "Capture device data" on, the WebSDK, using the same access token your
token endpoint
already mints:
sumsub-integrate-websdk- Initializes Fisherman against the SDK's API host once the SDK config loads.
- Fingerprints the device on each step transition, binding it to the current
.
(applicantId, attemptId) - Re-initializes on a level transition (the changes), so a multi-level flow gets a fresh device binding per level.
attemptId - Forwards the resulting device id to the backend on subsequent calls so the capture is tied to the applicant.
You do not write, configure, or call any of this. It is listed so you can
recognise it in logs / network traffic (, an events POST,
an request header).
/di/info/bhv/...X-External-Device-Fingerprint开启「捕获设备数据」后,WebSDK会使用你已有的令牌端点生成的相同访问令牌执行以下操作:
sumsub-integrate-websdk- 加载SDK配置后,针对SDK的API主机初始化Fisherman。
- 在每个步骤切换时为设备生成指纹,并将其绑定到当前的。
(applicantId, attemptId) - 在验证级别切换时(变化)重新初始化,确保多级别流程中每个级别都能获取新的设备绑定。
attemptId - 在后续调用中将生成的设备ID转发到后端,使捕获的数据与申请人关联。
你无需编写、配置或调用任何上述代码。列出这些步骤是为了让你能在日志/网络请求中识别相关操作(如、事件POST请求、请求头)。
/di/info/bhv/...X-External-Device-FingerprintStage 3 — Advanced: self-rendered / headless wiring
阶段3 — 高级:自定义渲染/无UI配置
Only relevant if you do not use the prebuilt widget and drive
the verification API yourself. Then you own the Fisherman lifecycle. Mirror the
SDK's own behaviour — see :
snsWebSdkexamples/fisherman-self-render.tsts
// Shape only — the full impl (single-active-session class, attemptId re-init,
// try/catch fail-open, header forwarding) is in examples/fisherman-self-render.ts.
import { init, destroy, type Fisherman } from '@sumsub/fisherman'
let fisherman: Fisherman | undefined // module-level singleton
// init once with the SDK access token + region API host
fisherman = await init({ token, baseUrl, onError: () => { destroy() /* re-init after token refresh */ } })
// on each step transition — gate, then fingerprint bound to (applicantId, attemptId)
if (fisherman?.isDeviceIntelligenceEnabled) {
const { visitorId } = await fisherman.fingerprint({
linkedId: applicantId,
deviceBindingId: `${applicantId}-${attemptId}`, // MUST change per level
})
// forward visitorId as the X-External-Device-Fingerprint header on the API calls that follow
}Key rules the SDK follows and you must too:
- Two-layer gate. The SDK gates itself on the config-level flag
init()— when DI is off for the level it never callsconfig.deviceIntelligenceSettings.enabled. Then it gates eachinit()on the runtime flagfingerprint()(fromfisherman.isDeviceIntelligenceEnabled). Mirror both: skip init when the config flag is false, never fingerprint unless the runtime flag is true (it errors / wastes a call)./di/info - On a level transition (changes)
attemptIdthendestroy()again before the nextinit(), so devices bind to the right level.fingerprint() - Forward the returned as the
visitorIdheader on the verification API calls that follow the capture. (This header is device/stats enrichment — the actual applicant binding is the per-attemptX-External-Device-Fingerprint(deviceBindingId) above, not the header.)applicantId-attemptId
仅当你不使用预构建的组件,而是自行调用验证API时,此部分才适用。此时你需要自行管理Fisherman的生命周期。请参考SDK自身的实现逻辑——详见:
snsWebSdkexamples/fisherman-self-render.tsts
// 仅展示代码结构——完整实现(单活动会话类、attemptId重新初始化、
// try/catch容错、请求头转发)请查看examples/fisherman-self-render.ts。
import { init, destroy, type Fisherman } from '@sumsub/fisherman'
let fisherman: Fisherman | undefined // 模块级单例
// 使用SDK访问令牌和区域API主机初始化一次
fisherman = await init({ token, baseUrl, onError: () => { destroy() /* 令牌刷新后重新初始化 */ } })
// 在每个步骤切换时——先判断,再为设备生成指纹并绑定到(applicantId, attemptId)
if (fisherman?.isDeviceIntelligenceEnabled) {
const { visitorId } = await fisherman.fingerprint({
linkedId: applicantId,
deviceBindingId: `${applicantId}-${attemptId}`, // 每个验证级别必须更换
})
// 在后续的API调用中,将visitorId作为X-External-Device-Fingerprint请求头转发
}SDK遵循的关键规则,你也必须遵守:
- 双层校验。SDK会先根据配置级别的标志判断是否调用
config.deviceIntelligenceSettings.enabled——当验证级别未启用DI时,SDK绝不会调用init()。然后,每次调用init()前都会根据运行时标志fingerprint()(来自fisherman.isDeviceIntelligenceEnabled)进行校验。请完全遵循这两层校验:当配置标志为false时跳过初始化,仅当运行时标志为true时才执行指纹捕获(否则会报错或浪费请求)。/di/info - 当验证级别切换时(变化),先调用
attemptId再重新destroy(),然后再执行下一次init(),确保设备绑定到正确的级别。fingerprint() - 将返回的作为
visitorId请求头,在捕获后的验证API调用中转发。(该请求头用于设备/统计信息补充——实际与申请人绑定的是上述每个尝试的X-External-Device-Fingerprint(deviceBindingId),而非请求头。)applicantId-attemptId
Stage 4 — Read the device signals
阶段4 — 读取设备信号
DI does not change how you read the verdict — it enriches it. Keep the
server-as-source-of-truth rule from the base WebSDK skill (webhook +
authenticated applicant GET), and read the device data alongside it.
In the dashboard:
- Applicant profile → Devices tab — every device seen, with risk labels.
- Completed verification → Device Check block.
- Transactions → a device row → View device details.
Via API / webhooks: the device risk labels land on the applicant, not in
the webhook payload. The webhook carries the verdict only
() — treat it as the trigger to read the applicant server-side
(same App-Token + HMAC auth as the base skill), here keyed by your :
applicantReviewedreviewResultexternalUserIdbash
USER_ID="<your-externalUserId>" # for a Sumsub applicant id instead: /resources/applicants/<applicantId>/one
PATH_Q="/resources/applicants/-;externalUserId=${USER_ID}/one"
TS=$(date -u +%s)
SIG=$(printf '%s%s%s' "$TS" "GET" "$PATH_Q" \
| openssl dgst -sha256 -hmac "$SUMSUB_SECRET_KEY" -hex | awk '{print $NF}')
curl -sS --fail-with-body -H "X-App-Token: $SUMSUB_APP_TOKEN" -H "X-App-Access-Ts: $TS" \
-H "X-App-Access-Sig: $SIG" -H "X-Agent-Source: sumsub-skills" \
-H "X-Agent-Source-Ver: 1.2.0" \
"https://api.sumsub.com${PATH_Q}"Runnable version of that GET: .
examples/read-device-results.shThe full device-signal / risk-label catalog and where each surfaces:
.
references/device-signals.mdDI不会改变你读取审核结果的方式——只会丰富结果内容。请遵循基础WebSDK技能中的「服务器作为唯一可信源」规则(Webhook + 认证后的申请人信息GET请求),并同时读取设备数据。
在控制台中:
- 申请人档案 → 设备标签页——显示所有检测到的设备及其风险标签。
- 已完成的验证 → 设备检查区块。
- 交易记录 → 设备行 → 查看设备详情。
通过API/Webhook:设备风险标签会关联到申请人,而非Webhook payload中。 Webhook仅携带审核结果()——请将其作为触发信号,在服务器端读取申请人信息(使用与基础技能相同的App-Token + HMAC认证),以下示例使用你的作为查询键:
applicantReviewedreviewResultexternalUserIdbash
USER_ID="<your-externalUserId>" # 若使用Sumsub申请人ID,请替换为:/resources/applicants/<applicantId>/one
PATH_Q="/resources/applicants/-;externalUserId=${USER_ID}/one"
TS=$(date -u +%s)
SIG=$(printf '%s%s%s' "$TS" "GET" "$PATH_Q" \
| openssl dgst -sha256 -hmac "$SUMSUB_SECRET_KEY" -hex | awk '{print $NF}')
curl -sS --fail-with-body -H "X-App-Token: $SUMSUB_APP_TOKEN" -H "X-App-Access-Ts: $TS" \
-H "X-App-Access-Sig: $SIG" -H "X-Agent-Source: sumsub-skills" \
-H "X-Agent-Source-Ver: 1.2.0" \
"https://api.sumsub.com${PATH_Q}"可直接运行的GET请求示例:。
examples/read-device-results.sh完整的设备信号/风险标签目录及其展示位置:。
references/device-signals.mdSandbox testing
沙箱测试
- Sandbox has no real device signals — Fingerprint is simulated. Devices are still captured and risk labels still appear, but values are synthetic.
- For deterministic test outcomes the module accepts a (
simulationConfig) onFpSimulationConfto force specific signals; only relevant on the self-rendered path. The prebuilt WebSDK handles sandbox simulation itself.init - Run a full sandbox WebSDK verification (see the base skill's test docs) and confirm a device appears under the applicant's Devices tab.
- 沙箱环境中无真实设备信号——Fingerprint功能是模拟的。设备仍会被捕获,风险标签也会显示,但数值为合成数据。
- 为了获得可预测的测试结果,模块在时接受
init(simulationConfig)参数,可强制设置特定信号;仅在自定义渲染路径中需要配置。预构建的WebSDK会自行处理沙箱模拟。FpSimulationConf - 运行完整的沙箱WebSDK验证流程(请参考基础技能的测试文档),并确认设备显示在申请人的设备标签页下。
Going live checklist
上线检查清单
- "Capture device data" is enabled on the production level (it's per-level, per-workspace — enabling it in sandbox does not carry over).
- Your server reads device risk labels from the applicant / webhook, not from the browser.
- If you gate access on device risk, you decided which labels are blocking
vs informational ().
references/device-signals.md - BYOK Fingerprint keys (if used) are the production keys in the prod workspace, sandbox keys only in sandbox.
- Self-rendered path only: gate, per-
isDeviceIntelligenceEnabledre-init, andattemptIdforwarding all verified against a real sandbox run.X-External-Device-Fingerprint
- 在生产验证级别中开启「捕获设备数据」选项(该设置按级别和工作区独立配置——沙箱中启用不会自动同步到生产环境)。
- 你的服务器从申请人信息/Webhook中读取设备风险标签,而非从浏览器读取。
- 若你根据设备风险限制访问权限,请明确哪些标签是拦截型、哪些是提示型(参考)。
references/device-signals.md - 若使用BYOK Fingerprint密钥,请确保生产工作区使用生产密钥,沙箱工作区仅使用沙箱密钥。
- 仅针对自定义渲染路径:已在真实沙箱运行中验证校验、按
isDeviceIntelligenceEnabled重新初始化、attemptId转发功能均正常。X-External-Device-Fingerprint
See also
相关链接
- — the base WebSDK embed this skill sits on top of (token endpoint, lifecycle, webhooks).
sumsub-integrate-websdk - — Device Intelligence on pages with no WebSDK widget (login / signup / checkout).
sumsub-integrate-dint-standalone - — HMAC signing shared by every Sumsub skill.
sumsub-api-auth - — device risk labels + where they surface.
references/device-signals.md - — the advanced headless wiring.
examples/fisherman-self-render.ts - — read the applicant (incl. device risk labels) server-side.
examples/read-device-results.sh - Device Intelligence docs and Get started — authoritative source if this skill drifts.
- ——本技能基于的基础WebSDK嵌入技能(令牌端点、生命周期、Webhook)。
sumsub-integrate-websdk - ——无WebSDK组件页面(登录/注册/结账)的设备智能集成方案。
sumsub-integrate-dint-standalone - ——所有Sumsub技能共享的HMAC签名机制。
sumsub-api-auth - ——设备风险标签及其展示位置。
references/device-signals.md - ——高级无UI配置示例。
examples/fisherman-self-render.ts - ——服务器端读取申请人信息(含设备风险标签)的示例。
examples/read-device-results.sh - 设备智能文档和快速开始——若本技能内容与官方文档有出入,请以官方文档为准。