跳到主要内容

04 — 3D Secure 认证(两条路径)

银行有时要求买家「再证明一次你是你」(3D Secure 强认证)。在 agent 流程里,这一步谁来弹、怎么弹、结果怎么回填?ACP 给了两条路。源头:rfcs/rfc.agentic_checkout.md(内联)与 rfcs/rfc.delegate_authentication.md(独立 API)。

4.1 背景:3DS 是什么,为什么是 agent 的痛点

3D Secure 2(3DS2)是发卡行对一笔交易做的额外验证:有时无感(frictionless)——风控通过就放行;有时要挑战(challenge)——弹个窗让用户输 OTP/做生物识别。问题是:agent 跑在一个不一定有完整浏览器/UI 的环境里,这个「弹窗」怎么处理?这正是 03 章 interventions 协商里 3ds 那一项的现实落地。

4.2 路径一:checkout 内联认证

最轻的方式——认证嵌在 checkout 主线里(rfcs/rfc.agentic_checkout.md:158-164):

agent → POST /complete(不带 authentication_result)
◀── status: authentication_required
+ authentication_metadata(做认证要的信息)
agent 用 metadata 做 3DS 认证(无论成败)
agent → POST /complete(这次带上 authentication_result)
◀── status: completed + order

硬规则:

  • 商家在需要认证时必须session.status 置为 authentication_required,且响应必须authentication_metadata(rfcs/rfc.agentic_checkout.md:159、校验 :339)。
  • 处于该状态时,agent 必须做认证并把 authentication_result 带回 complete——无论认证成败都要带(:160)。
  • 若 agent 在该状态下不带 authentication_result 就调 complete → 商家必须回 4XX,且 type: invalid_requestcode: requires_3dsparam: $.authentication_result(:162-164,错误实例 :717-724)。

两个关键数据结构(rfcs/rfc.agentic_checkout.md:221-226):

  • AuthenticationMetadata:acquirer_detailsdirectory_server(amex/mastercard/visa)、可选 flow_preference(challenge/frictionless)。
  • AuthenticationResult:outcome + outcome_details,后者含 three_ds_cryptogramelectronic_commerce_indicator(ECI)、transaction_idversion——这些就是认证产出的、要随授权一起送给发卡行的「凭据」。complete 请求实例见 :573-612

注意区分两个相似的错误码(rfcs/rfc.agentic_checkout.md:200-201):requires_3ds 是「该带 authentication_result 没带」;intervention_required 是「这单需要某种 agent 根本不支持的介入」(由 03 章的能力协商决定)。别混。

4.3 路径二:独立的 delegate_authentication API

当认证逻辑复杂、需要 agent 直接和认证提供方对话(而不绕经商家)时,用这套独立 API(rfcs/rfc.delegate_authentication.md)。它的范围很窄但很明确:只做 3DS2、只做浏览器渠道、只做原生集成(非重定向)(:18-21)。

三步生命周期,会话化(返回 authentication_session_id,后续放进 URL path,rfcs/rfc.delegate_authentication.md:36):

① POST /delegate_authentication (建会话:商家+卡+金额)
◀── status: action_required(给 fingerprint 动作)
| pending(不需指纹)
| not_supported(卡未登记 → 可不走 3DS)

② POST /delegate_authentication/{id}/authenticate (提交指纹结果,触发认证)
◀── status: authenticated(无感成功)
| action_required(需 challenge)
| attempted / not_authenticated / rejected / ...

③ GET /delegate_authentication/{id} (取最终结果)
◀── authentication_result{ cryptogram, ECI, trans_status, ... }

端点与状态枚举见 rfcs/rfc.delegate_authentication.md:97-162

4.4 浏览器侧的两个动作:fingerprint 与 challenge

这套 API 的「动作」对应 3DS2 协议里两个真实的浏览器交互(rfcs/rfc.delegate_authentication.md:180-199):

  • Device Fingerprinting:create 回 action.type: fingerprint 时,agent 在隐藏 iframe 里把 threeDSMethodData POST 到发卡行的 three_ds_method_url,让 ACS(发卡行的认证服务器)采集设备指纹;收到通知或 10 秒超时后,带 fingerprint_completion(Y/N/U)调 authenticate。
  • Challenge Flow:authenticate 回 action.type: challenge 时,agent 把 CReq base64(无 padding)POST 到 acs_url,在 iframe/modal 里让用户完成挑战;ACS 把 CRes 回调到 agent 的 challenge_notification_url,agent 再 GET 取结果。

agent 因此要实现回调端点接收异步通知(fingerprint/challenge/可选 RReq,:44-49)。

4.5 一个值得注意的安全约束

认证提供方必须做来源限制——请求只能来自 agent 已验证的基础设施(rfcs/rfc.delegate_authentication.md:227-228)。再加上这套 API 要求 Signature 必须验证(注意:这里 SignatureREQUIRED,比 checkout 主线的 RECOMMENDED 更严,:67)。原因显而易见:认证是欺诈攻防的最前线,放任意来源调用等于开后门。

4.6 本章要带走的三句话

  • 两条路:内联(会话进 authentication_required,带 authentication_result 回 complete)与独立 API(create→authenticate→retrieve 三步)。
  • 3DS2 的两个真实浏览器动作 = fingerprint(采指纹)challenge(弹挑战);独立 API 把它们映射成 action
  • 认证是攻防最前线:独立 API 把 Signature 升级为必须,且强制 agent 基础设施来源限制。