PAYATHON 2026

智能手表如何绑定设备并集成离线支付功能

支付阿杰

结论

智能手表绑定手机或其他智能设备时,一般先通过 Bluetooth Low Energy(BLE)发现设备,再用二维码、数字验证码或 NFC 碰一碰确认设备身份,最后由服务端签发设备凭证。

实现离线支付,不能只在手表中增加一个付款页面。开发商还需要具备安全硬件、支付凭证令牌化、交易限额与计数器、密钥管理、挂失和撤销机制,并接入银行、卡组织或持牌支付机构。银行卡 NFC 离线支付通常还要完成 EMVCo、卡组织及相关安全合规认证。开发商不能自行保存银行卡号或复制支付密钥。

开发前,需要先明确“离线支付”指哪种情况:

  • 手表离线、收款终端在线:这是最常见、相对容易落地的方式。手表通过 NFC 或动态二维码出示支付凭证,由联网终端完成授权。
  • 手表和终端都离线:这是真正的双离线支付。终端需要暂存交易,恢复联网后再清算,因此风险和合规要求更高。
  • 封闭场景离线支付:例如园区、校园、交通或门店储值账户,通常比开放式银行卡支付更容易实现。

设备绑定流程

比较稳妥的绑定方式是“BLE 建链 + 用户确认 + 服务端登记”。BLE 配对成功只代表设备之间建立了连接,不能直接视为账号绑定完成。

典型流程如下:

  1. 手表首次启动时生成设备密钥对,私钥保存在 Secure Element(SE)、eSE、TEE 或其他不可导出的安全存储区。
  2. 手机应用通过 BLE 扫描手表广播。
  3. 手机与手表交换临时公钥,并通过 ECDH 协商会话密钥。
  4. 手表显示一次性验证码,或由手机扫描手表上的二维码。
  5. 用户确认后,手机将设备标识、公钥、账号令牌和证明材料发送给服务端。
  6. 服务端验证请求,建立用户、手机和手表之间的绑定关系,并签发短期设备证书或访问令牌。
  7. 后续通信使用会话密钥加密,并加入随机数、时间戳和递增计数器,防止重放攻击。

二维码或验证码只能用于确认当前绑定的是用户眼前的手表,不能充当长期密钥。

下面是简化后的 Android BLE 发现示例,只展示扫描入口,不包括完整的权限、重连和加密处理:

private val scanCallback = object : ScanCallback() {
    override fun onScanResult(callbackType: Int, result: ScanResult) {
        val device = result.device
        if (result.scanRecord?.serviceUuids?.contains(WATCH_SERVICE_UUID) == true) {
            bluetoothLeScanner.stopScan(this)
            connectAndStartSecureBinding(device)
        }
    }

    override fun onScanFailed(errorCode: Int) {
        handleScanError(errorCode)
    }
}

fun startWatchScan() {
    val filter = ScanFilter.Builder()
        .setServiceUuid(WATCH_SERVICE_UUID)
        .build()

    val settings = ScanSettings.Builder()
        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
        .build()

    bluetoothLeScanner.startScan(
        listOf(filter),
        settings,
        scanCallback
    )
}

实际产品还要处理绑定超时、重复绑定、手机更换、恢复出厂设置、设备丢失和远程解绑等情况。

离线支付的实现路线

NFC 银行卡支付

银行卡 NFC 支付一般采用令牌化方案。支付机构不会把真实卡号和发卡行主密钥直接写入手表,而是为具体设备签发受限的支付令牌,再将相关密钥或凭证安全写入 SE。

基本链路如下:

用户绑卡
  → 发卡行或支付机构校验身份
  → Token Service Provider 签发设备支付令牌
  → 凭证安全写入手表
  → 手表通过 NFC 与 POS 交互
  → POS 联机授权或按规则接受离线交易
  → 后续清算

采用这条路线,通常需要与银行、收单机构、卡组织或其认可的服务商合作。手表厂商完成 NFC 通信或 APDU 处理,并不代表已经具备银行卡受理能力。

下面的概念性 APDU 分发代码用于说明手表端支付应用的接口形态。响应值和状态机必须按照实际采用的支付规范确定,不能直接用于生产:

int process_apdu(
    const uint8_t *command,
    size_t command_len,
    uint8_t *response,
    size_t *response_len
) {
    if (!secure_element_is_ready()) {
        return SW_CONDITIONS_NOT_SATISFIED;
    }

    if (!verify_apdu_sequence(command, command_len)) {
        return SW_COMMAND_NOT_ALLOWED;
    }

    return secure_element_transceive(
        command,
        command_len,
        response,
        response_len
    );
}

支付密钥应始终在 SE 内使用,不应读取到应用处理器的普通内存。HCE 可以用于部分卡模拟场景,但它能否接入目标支付网络、是否具备所需的离线能力,仍取决于操作系统、安全架构和合作机构的规则,不能默认可行。

动态二维码支付

动态二维码适合手表离线、收款端在线的场景。手表可以预先获取一组受限令牌,付款时根据令牌、计数器和时间窗口生成短时有效的付款码。

概念性载荷可以设计为:

{
  "version": 1,
  "deviceToken": "opaque-device-token",
  "counter": 1842,
  "issuedAt": 1789286400,
  "nonce": "random-value",
  "signature": "base64url-signature"
}

签名示意:

signature = Sign(
    devicePrivateKey,
    SHA-256(version || deviceToken || counter || issuedAt || nonce)
)

收款端或支付后台必须检查签名、令牌状态、计数器和使用次数。付款码不能长期保持不变,否则被截图复制后可能遭到重复使用。

如果手表需要长时间离线,可以预置数量有限的一次性支付令牌。每个令牌只能使用一次,同时要设置有效期、单笔限额和累计限额。令牌耗尽后,手表必须联网补充。

封闭账户或储值支付

园区、交通、校园等封闭场景可以使用自有账户和清算系统。进行双离线交易时,手表和终端可以共同维护计数器,终端恢复联网后再上传交易。

服务端可以按照类似逻辑检查交易:

public PaymentResult verifyOfflinePayment(OfflinePayment payment) {
    Device device = deviceRepository.findActive(payment.deviceId());

    if (device == null) {
        return PaymentResult.reject("DEVICE_NOT_ACTIVE");
    }

    if (!signatureService.verify(
            device.publicKey(),
            payment.signedPayload(),
            payment.signature())) {
        return PaymentResult.reject("INVALID_SIGNATURE");
    }

    if (payment.counter() <= device.lastAcceptedCounter()) {
        return PaymentResult.reject("REPLAY_DETECTED");
    }

    if (payment.amount().compareTo(device.remainingOfflineLimit()) > 0) {
        return PaymentResult.reject("OFFLINE_LIMIT_EXCEEDED");
    }

    return PaymentResult.acceptPendingSettlement();
}

生产系统还必须处理并发终端、计数器跳号、重复清算、退款、冲正和终端时钟不可信等问题,不能只依靠上述检查。

开发商的落地步骤

第一步是确定支付边界,包括使用 NFC 还是二维码、面向银行卡还是封闭账户,以及只允许手表离线,还是要求手表与终端双离线。不同选择对应的资质要求、技术方案和风险成本差别很大。

接下来要确认硬件是否具备 NFC 控制器、SE/eSE、设备唯一密钥、安全启动、固件签名、调试口关闭和防回滚机制。如果设备没有可信的密钥存储,就不适合承载可直接付款的长期凭证。

服务端至少需要具备以下能力:

  • 设备注册、绑定、解绑和状态查询。
  • 支付令牌申请、写入、续期和撤销。
  • 风险限额、离线次数和累计金额控制。
  • 设备丢失挂失、黑名单和远程停用。
  • 交易上传、去重、冲正、退款和清算。
  • 密钥轮换、审计日志和异常告警。

基础系统完成后,还要与银行、支付机构或卡组织联调并接受认证。具体认证项目取决于支付网络、销售地区、硬件方案和业务角色,正式清单应由合作机构提供。

安全与合规注意事项

不要在手表、手机应用、日志或普通数据库中保存 CVV、支付主密钥,或其他可被直接滥用的完整银行卡数据。需要保存卡号相关信息时,应尽量使用支付令牌,并确认系统是否进入 PCI DSS 等合规范围。

离线交易无法实时查询余额、挂失状态和风险名单,因此必须设置:

  • 单笔金额上限。
  • 离线累计金额上限。
  • 连续离线交易次数上限。
  • 凭证有效期和强制定期联网要求。
  • 设备解锁、PIN 或生物识别条件。
  • 重放检测和终端交易去重机制。

系统也不能完全依赖手表时间,因为本地时钟可能被修改。更稳妥的方式是结合签名计数器、最近一次可信的服务端时间、令牌批次和有效窗口进行判断。

设备恢复出厂设置时,应删除本地支付凭证,并使旧令牌失效。如果只清除界面数据,却没有撤销服务端令牌,实际支付风险仍然存在。

推荐方案

首次开发时,可以先采用“BLE 安全绑定 + 动态二维码 + 收款端联机验证”,也可以先在园区等封闭场景中试点,用来验证设备绑定、令牌生命周期和风控系统。

如果目标是银行卡 NFC 支付,应尽早确定支付合作机构和通过认证的 SE 方案,再根据合作方提供的令牌化、个人化及认证规范进行开发。不要等到硬件定型后才开始接洽,因为 SE、NFC 路由和设备安全架构都可能影响最终的认证结果。

备注:内容仅供参考。