> ## Documentation Index
> Fetch the complete documentation index at: https://developers.uqpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 3DS 集成指南 - 方式 2

> 使用方式 2 集成 3D Secure 身份验证，为线上卡交易增加一层安全保护。

<h2 id="overview">概览</h2>

3D Secure（3DS）是一种身份验证协议，用于为线上信用卡和借记卡交易提供额外的安全保护。它要求持卡人在完成交易前先向发卡机构进行身份验证，从而防止未授权用卡。

<h3 id="3ds-authentication-modes">3DS 身份验证模式</h3>

3DS 身份验证流程根据发卡机构的风险评估结果而有所不同，可能出现以下三种情况：

1. **无摩擦 3DS（Frictionless 3DS）**：低风险交易自动完成身份验证，无需客户操作。系统通过 iframe 完成风险评估后直接完成支付，不要求 OTP。

2. **挑战 3DS（Challenge 3DS）**：高风险交易要求立即进行客户验证。客户直接被跳转至 ACS 身份验证页面输入 OTP 或完成生物特征验证。

3. **混合 3DS（Mixed 3DS）**：系统先通过 iframe 进行风险评估。如需进一步验证，客户随后被跳转至 ACS 页面输入 OTP。

> **集成要点**：你无法预先判断会走哪种模式，这由发卡机构根据实时风险评估决定。你的集成必须通过检查 API 响应结构（`next_action` 字段）和 webhook 类型，动态处理所有场景。

<h2 id="integration-steps">集成步骤</h2>

<h3 id="integration-flow">集成流程</h3>

下图展示了基于 API 响应处理的 3DS 身份验证流程：

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Client as Merchant Client
    participant Server as Merchant Server
    participant UQPay as UQPay API
    participant ACS as Card Issuer ACS

    User->>Client: Click Checkout
    Client->>Server: Initiate Payment
    Server->>UQPay: Create Payment Intent (three_ds_action=enforce_3ds)
    UQPay-->>Server: Response (PI = REQUIRES_CUSTOMER_ACTION)
    
    Note over Server: Check next_action field
    
    alt next_action = redirect_to_url
        Note over Server,Client: Direct challenge required
        Server-->>Client: Send redirect URL
        Client->>ACS: Redirect to ACS Page
        User->>ACS: Enter OTP
        alt OTP Success
            ACS-->>Client: Redirect to return_url
            UQPay->>Server: Webhook (acquiring.payment_intent.succeeded)
        else OTP Failed
            ACS-->>Client: Redirect to Failure Page
            UQPay->>Server: Webhook (acquiring.payment_intent.failed)
        end
        
    else next_action = redirect_iframe
        Note over Server,Client: Risk assessment required
        Server-->>Client: Send iframe code
        Client->>Client: Embed and auto-submit iframe
        Client->>ACS: Submit risk assessment data
        
        Note over Server: Wait for webhook response
        
        alt Webhook: acquiring.payment_intent.succeeded
            Note over Server,Client: Frictionless - No OTP required
            UQPay->>Server: Webhook (succeeded)
            Server-->>Client: Payment Success
            Client-->>User: Show Success Page
            
        else Webhook: acquiring.payment_intent.requires_action
            Note over Server,Client: Challenge required after assessment
            UQPay->>Server: Webhook (requires_action with redirect_to_url)
            Server-->>Client: Extract and send redirect URL
            Client->>ACS: Redirect to ACS Page
            User->>ACS: Enter OTP
            alt OTP Success
                ACS-->>Client: Redirect to return_url
                UQPay->>Server: Webhook (acquiring.payment_intent.succeeded)
            else OTP Failed
                ACS-->>Client: Redirect to Failure Page
                UQPay->>Server: Webhook (acquiring.payment_intent.failed)
            end
        end
    end
```

<h3 id="step-1-enable-3ds-in-payment-request">步骤 1：在支付请求中启用 3DS</h3>

要启用 3DS 身份验证，在 Payment Intent 创建或确认请求中加入以下参数：

| 字段                | 类型     | 必填 | 说明                                                           |
| ----------------- | ------ | -- | ------------------------------------------------------------ |
| `three_ds_action` | string | 是  | 设置为 `enforce_3ds` 以强制 3DS 身份验证                               |
| `browser_info`    | object | 是  | 从客户设备采集的浏览器和设备信息。这些数据对风险评估至关重要；信息不准确或缺失可能导致 3DS 服务提供方拒绝该笔交易。 |
| `ip_address`      | string | 是  | 客户的 IP 地址                                                    |

<h3 id="step-2-handle-3ds-authentication">步骤 2：处理 3DS 身份验证</h3>

创建启用 3DS 的 Payment Intent 后，根据响应按以下步骤处理：

<h4 id="step-2-1-check-next_action-in-response">步骤 2.1：检查响应中的 `next_action`</h4>

响应状态会是 `REQUIRES_CUSTOMER_ACTION`。查看 `next_action` 字段以确定下一步：

**情况 A：响应中存在 `next_action.redirect_to_url`**

响应直接包含跳转 URL（不含 iframe），表示需要立即进入挑战流程。

1. 从响应中提取 `next_action.redirect_to_url.url`
2. 将客户跳转至该 URL 完成 OTP 验证
3. 等待最终 webhook：
   * `acquiring.payment_intent.succeeded` —— OTP 验证成功
   * `acquiring.payment_intent.failed` —— OTP 验证失败或被取消

**情况 B：响应中存在 `next_action.redirect_iframe`**

响应包含用于风险评估的 iframe，按以下步骤处理：

1. 从响应中提取 `next_action.redirect_iframe.iframe`
2. 将 iframe 嵌入你的页面并执行（自动提交）
3. 继续执行步骤 2.2 处理 webhook 响应

<h4 id="step-2-2-handle-webhook-after-iframe-execution-case-b-only">步骤 2.2：iframe 执行后处理 webhook（仅情况 B）</h4>

iframe 执行后，你会收到以下两种 webhook 之一：

**Webhook 情况 1：`acquiring.payment_intent.succeeded`**

表示无摩擦身份验证成功，无需后续处理。

* 交易未经 OTP 即已完成
* 客户保持在你的页面
* 展示成功信息

**Webhook 情况 2：`acquiring.payment_intent.requires_action`**

表示风险评估后仍需挑战验证。

1. 从 webhook payload 中提取 `next_action.redirect_to_url.url`
2. 将客户跳转至该 URL 完成 OTP 验证
3. 等待最终 webhook：
   * `acquiring.payment_intent.succeeded` —— OTP 验证成功
   * `acquiring.payment_intent.failed` —— OTP 验证失败或被取消

> **实现提示**：你的集成必须动态处理两种响应类型（`redirect_to_url` 与 `redirect_iframe`），并处理 iframe 执行后的两种 webhook 场景。

> **注意**：沙盒环境使用 OTP `0101`。生产环境使用实际发送给持卡人的 OTP。

<h3 id="step-3-handle-post-authentication">步骤 3：处理身份验证后流程</h3>

支付流程完成后：

1. **成功**：客户会被跳转至初始请求中指定的 `return_url`。
2. **失败**：客户会被跳转至 UQ 支付失败页面。

<h2 id="sandbox-testing">沙盒测试</h2>

沙盒环境中的 3DS 测试，使用以下测试卡模拟不同身份验证模式：

<h3 id="test-card-frictionless-3ds">测试卡 —— 无摩擦 3DS</h3>

| 字段           | 值                  |
| :----------- | :----------------- |
| **卡组织**      | visa               |
| **持卡人姓名**    | John Smith         |
| **卡号**       | `4176660000000068` |
| **有效期月**     | 12                 |
| **有效期年**     | 2027               |
| **CVC**      | 774                |
| **是否需要 OTP** | 否                  |

该卡模拟低风险交易，无需客户操作即可完成。

<h3 id="test-card-challenge-3ds">测试卡 —— 挑战 3DS</h3>

| 字段          | 值                  |
| :---------- | :----------------- |
| **卡组织**     | visa               |
| **持卡人姓名**   | John Smith         |
| **卡号**      | `4176660000000092` |
| **有效期月**    | 12                 |
| **有效期年**    | 2027               |
| **CVC**     | 774                |
| **测试用 OTP** | 0101               |

该卡模拟高风险交易，要求立即进行 OTP 验证。

<h3 id="test-card-mixed-3ds">测试卡 —— 混合 3DS</h3>

| 字段          | 值                  |
| :---------- | :----------------- |
| **卡组织**     | visa               |
| **持卡人姓名**   | John Smith         |
| **卡号**      | `4176660000000118` |
| **有效期月**    | 12                 |
| **有效期年**    | 2027               |
| **CVC**     | 774                |
| **测试用 OTP** | 0101               |

该卡模拟需先进行风险评估、再进入挑战验证的交易。
