Skip to content
目录

支付架构详解

概述

UCP 采用解耦的支付架构来解决平台、商家和支付凭证提供商之间的 "N-to-N" 复杂度问题。这种设计将支付工具(接受什么)与支付处理器(如何处理工具)分离,确保安全性和可扩展性。

核心问题

N-to-N 复杂度问题

传统支付集成中:

  • N 个平台需要与 M 个商家集成
  • 每个商家可能支持多个支付提供商
  • 复杂度呈指数级增长:O(N × M × P)

UCP 的解决方案

通过**支付处理器(Payment Handler)**抽象:

  • 平台和商家都实现 UCP 标准
  • 支付提供商定义处理器规范
  • 复杂度降低到:O(N + M + P)

安全与信任模型

Trust-by-Design 哲学

支付架构建立在"信任设计"哲学之上:

  1. 商家 ↔ 支付凭证提供商:预先存在的法律和技术关系

    • 商家持有 API 密钥
    • 有合同关系
  2. 平台 ↔ 支付凭证提供商:平台与支付凭证提供商的接口交互

    • 平台调用提供商的 API/SDK
    • 平台不是资金的"所有者"
  3. 平台 ↔ 商家:平台将结果(令牌或授权)传递给商家完成订单

    • 平台不接触原始金融凭证
    • 只传递不透明的令牌

信任三角

┌─────────────┐
│   Business  │
│   (商家)    │
└──────┬──────┘
       │ 信任关系
       │ (API Keys, Contract)

┌──────▼──────────┐         ┌─────────────┐
│ Payment Handler │────────▶│  Platform   │
│   (PSP/CP)     │         │  (平台)     │
└─────────────────┘         └─────────────┘

       │ 令牌化

┌──────▼──────────┐
│  Credential     │
│  Provider       │
└─────────────────┘

PCI-DSS 范围管理

平台范围

大多数平台实现可以通过以下方式避免 PCI-DSS 范围

  • 使用提供不透明凭证的处理器(加密数据、令牌引用等)
  • 永远不访问或存储原始支付数据(卡号、CVV 等)
  • 转发凭证但无法直接使用
  • 使用 PSP 令牌化支付处理器,原始凭证从不通过平台

商家范围

商家可以通过以下方式最小化 PCI 范围:

  • 使用支付凭证提供商托管的令牌化(提供商存储凭证,商家接收令牌引用)
  • 使用提供加密凭证的钱包提供商(Google Pay、Shop Pay)
  • 永远不记录原始凭证
  • 将凭证处理委托给 PCI 认证的支付凭证提供商

支付凭证提供商范围

支付凭证提供商(PSP、钱包)通常是 PCI-DSS Level 1 认证,处理:

  • 原始凭证收集
  • 凭证保护(令牌化、加密、安全存储)
  • 凭证验证和处理
  • PCI 合规基础设施

支付处理器(Payment Handler)

定义

支付处理器是规范(Specification),不是实体。它定义了如何处理支付工具的合约,将三个参与者绑定在一起。

重要区别

  • 支付凭证提供商 = 参与者(实体,如 Google Pay、Shop Pay)
  • 支付处理器 = 提供商编写的规范(如 com.google.paydev.shopify.shop_pay

处理器生命周期

支付在 UCP 中遵循标准的 3 步生命周期:

┌──────────────┐      ┌──────────────┐      ┌──────────────┐
│ Negotiation  │─────▶│ Acquisition  │─────▶│  Completion  │
│  (协商)      │      │  (获取)      │      │  (完成)      │
└──────────────┘      └──────────────┘      └──────────────┘
商家广告处理器         平台执行处理器逻辑     平台提交凭证给商家

1. Negotiation(协商)

商家 → 平台:商家在 UCP Profile 中广告可用的支付处理器。

示例

json
{
  "ucp": {
    "payment_handlers": {
      "com.google.pay": [
        {
          "id": "gpay_1234",
          "version": "2026-01-23",
          "config": {
            "api_version": 2,
            "merchant_info": {
              "merchant_id": "01234567890123456789"
            }
          }
        }
      ]
    }
  }
}

2. Acquisition(获取)

平台 ↔ 支付凭证提供商:平台执行处理器的逻辑。

  • 发生在客户端或代理端
  • 直接与支付凭证提供商交互
  • 商家不参与,确保原始数据不接触商家的前端 API

示例

javascript
// 平台端代码
const paymentData = await googlePaySDK.loadPaymentData({
  merchantId: handler.config.merchant_info.merchant_id,
  // ... 其他配置
});

3. Completion(完成)

平台 → 商家:平台提交不透明的凭证(令牌)给商家。

json
{
  "payment": {
    "instruments": [
      {
        "handler_id": "gpay_1234",
        "type": "card",
        "credential": {
          "type": "PAYMENT_GATEWAY",
          "token": "{\"signature\":\"...\",\"protocolVersion\":\"ECv2\"...}"
        }
      }
    ]
  }
}

商家使用它通过后端集成与支付凭证提供商捕获资金。

处理器声明结构

Business Schema(商家声明)

商家在 Profile 中声明处理器配置:

json
{
  "id": "processor_tokenizer_1234",
  "version": "2026-01-23",
  "spec": "https://example.com/specs/payments/processor_tokenizer",
  "schema": "https://example.com/schemas/payments/merchant_tokenizer.json",
  "available_instruments": [
    {
      "type": "card",
      "constraints": {
        "brands": ["visa", "mastercard", "amex"]
      }
    }
  ],
  "config": {
    "type": "CARD",
    "tokenization_specification": {
      "type": "PUSH",
      "parameters": {
        "token_retrieval_url": "https://api.psp.example.com/v1/tokens"
      }
    }
  }
}

Platform Schema(平台声明)

平台在 Profile 中声明支持的处理器:

json
{
  "id": "platform_tokenizer_2345",
  "version": "2026-01-23",
  "spec": "https://example.com/specs/payments/processor_tokenizer",
  "schema": "https://example.com/schemas/payments/merchant_tokenizer.json",
  "available_instruments": [
    {
      "type": "card",
      "constraints": {
        "brands": ["visa", "mastercard", "amex", "discover"]
      }
    }
  ]
}

Response Schema(响应 Schema)

运行时配置,包含解析后的上下文:

json
{
  "id": "processor_tokenizer_1234",
  "version": "2026-01-23",
  "available_instruments": [
    {
      "type": "card",
      "constraints": {
        "brands": ["visa", "mastercard", "amex"]
      }
    }
  ],
  "config": {
    "api_version": 2,
    "environment": "production",
    "business_id": "business_xyz_789"
  }
}

available_instruments 解析

解析流程

  1. 平台声明能力:平台的 Profile 在每个处理器声明中包含 available_instruments

    • 告诉商家平台可以处理什么(例如,只支持 ["visa", "mastercard", "amex", "discover"]
  2. 商家解析:收到请求后,商家通过交集计算解析的 available_instruments

    • 平台的广告 available_instruments(其能力)
    • 自己的 business_schema 声明(商家实际设置接受的内容)
    • 购物车/结账上下文(例如,某些商品类型可能限制符合条件的支付方式)
  3. 响应是权威的:响应中的 available_instruments 反映商家为此特定结账解析的选择

    • 平台必须将其视为权威
    • 平台不得尝试使用响应中未包含的工具类型或应用与其矛盾的约束

解析示例

available_instruments
平台 Profile[{type: "card", constraints: {brands: ["visa", "mastercard", "amex", "discover"]}}]
商家 Profile[{type: "card", constraints: {brands: ["visa", "mastercard", "amex"]}}]
响应(解析后)[{type: "card", constraints: {brands: ["visa", "mastercard", "amex"]}}]

在此示例中,商家的 PSP 未配置 Discover,因此即使平台支持,Discover 也会从响应中排除。

动态过滤

商家必须根据购物车上下文过滤 handlers 列表:

  • 移除订阅商品的"先买后付"选项
  • 根据配送地址过滤区域支付方式
  • 根据商品类型限制支付方式

支付场景示例

场景 A:数字钱包

平台识别支付凭证提供商(如 com.google.paydev.shopify.shop_pay)并使用其 API 获取加密支付令牌。

1. 商家广告

json
{
  "ucp": {
    "payment_handlers": {
      "com.google.pay": [
        {
          "id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
          "version": "2026-01-23",
          "config": {
            "api_version": 2,
            "merchant_info": {
              "merchant_name": "Example Merchant",
              "merchant_id": "01234567890123456789"
            },
            "allowed_payment_methods": [
              {
                "type": "CARD",
                "parameters": {
                  "allowed_auth_methods": ["PAN_ONLY"],
                  "allowed_card_networks": ["VISA", "MASTERCARD"]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

2. 令牌执行(平台端)

平台识别 com.google.pay,将 config 传递给相应的处理器 API,处理器返回加密令牌数据。

3. 完成结账

json
POST /checkout-sessions/{id}/complete

{
  "payment": {
    "instruments": [
      {
        "id": "pm_1234567890abc",
        "handler_id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
        "type": "card",
        "selected": true,
        "display": {
          "brand": "visa",
          "last_digits": "4242"
        },
        "credential": {
          "type": "PAYMENT_GATEWAY",
          "token": "{\"signature\":\"...\",\"protocolVersion\":\"ECv2\"...}"
        }
      }
    ]
  }
}

场景 B:直接令牌化与挑战(SCA)

平台使用通用令牌化器请求会话令牌或网络令牌。银行要求强客户认证(SCA/3DS),强制商家暂停完成并请求挑战。

1. 商家广告

json
{
  "ucp": {
    "payment_handlers": {
      "com.example.tokenizer": [
        {
          "id": "merchant_tokenizer",
          "version": "2026-01-23",
          "available_instruments": [
            {
              "type": "card",
              "constraints": {
                "brands": ["visa", "mastercard"]
              }
            }
          ],
          "config": {
            "token_url": "https://api.psp.com/tokens",
            "public_key": "pk_123"
          }
        }
      ]
    }
  }
}

2. 令牌执行(平台端)

平台调用 https://api.psp.com/tokens,接收 tok_visa_123(可能是存储的卡或网络令牌)。

3. 完成结账

json
POST /checkout-sessions/{id}/complete

{
  "payment": {
    "instruments": [
      {
        "handler_id": "merchant_tokenizer",
        "credential": { "token": "tok_visa_123" }
      }
    ]
  }
}

4. 需要挑战(商家响应)

商家尝试扣款,但 PSP 返回"软拒绝",需要 3DS。

json
HTTP/1.1 200 OK
{
  "status": "requires_escalation",
  "messages": [{
    "type": "error",
    "code": "requires_3ds",
    "content": "bank requires verification.",
    "severity": "requires_buyer_input"
  }],
  "continue_url": "https://psp.com/challenge/123"
}

平台现在必须在 WebView/Window 中打开 continue_url 供用户完成银行检查,然后重试完成。

场景 C:自主代理(AP2)

此场景演示代理推荐流程。代理生成加密授权而不是会话令牌。

1. 商家广告

json
{
  "ucp": {
    "payment_handlers": {
      "dev.ucp.ap2_mandate_compatible_handlers": [
        {
          "id": "ap2_234352",
          "version": "2026-01-23",
          "available_instruments": [
            {"type": "ap2_mandate"}
          ]
        }
      ]
    }
  }
}

2. 代理执行

代理使用用户的私钥在非代理表面上加密签名对象。

3. 完成结账

json
POST /checkout-sessions/{id}/complete

{
  "payment": {
    "instruments": [
      {
        "handler_id": "ap2_234352",
        "credential": {
          "type": "card",
          "token": "eyJhbGciOiJ..."  // 包含 payment_mandate,签名的资金授权证明
        }
      }
    ]
  },
  "ap2": {
    "checkout_mandate": "eyJhbGciOiJ..."  // 签名的结账条款证明
  }
}

这为商家提供了不可否认的证据,证明用户授权了此特定交易,支持安全的自主处理。

凭证流与 PCI 范围

单向流

为了最小化合规开销(PCI-DSS):

  1. 单向流:凭证只从平台 → 商家流动

    • 商家不得在响应中回显凭证
  2. 不透明凭证:平台处理令牌(如网络令牌)、加密 payload 或授权,而不是原始 PAN

  3. 处理器 ID 路由:payload 中的 handler_id 确保商家知道确切使用哪个支付凭证提供商密钥进行解密/扣款,防止密钥混淆攻击

安全最佳实践

对于商家

  1. 在处理前验证 handler_id(确保处理器在广告集合中)
  2. 为 TEST 与 PRODUCTION 环境使用单独的 PSP 凭证
  3. 实现支付处理的幂等性(防止重复扣款)
  4. 记录支付事件但不记录凭证
  5. 设置适当的凭证超时
  6. 对于需要加密证明的自主商务场景,考虑支持 dev.ucp.shopping.ap2_mandate 扩展

对于平台

  1. 始终对结账 API 调用使用 HTTPS
  2. 在执行协议前验证处理器配置
  3. 实现凭证获取的超时处理
  4. 提交后从内存中清除凭证
  5. 优雅处理凭证过期(如需要则重新获取)
  6. 对于自主代理,考虑使用 dev.ucp.shopping.ap2_mandate 扩展进行加密授权证明

对于支付凭证提供商

  1. 为特定商家保护凭证(加密、令牌化或其他处理器特定方法)
  2. 在凭证获取上实现速率限制
  3. 在提供凭证前验证平台授权
  4. 设置合理的凭证过期(例如,令牌 15 分钟,时间限制的加密 payload)
  5. 确保凭证不能由平台直接使用(只能由预期商家使用)

风险信号

为了帮助进行欺诈评估,平台可以complete 调用中包含额外的风险信号,为商家提供有关交易合法性的更多上下文。

示例(灵活结构)

json
{
  "risk_signals": {
    "session_id": "abc_123_xyz",
    "score": 0.95
  }
}

风险信号的结构和内容没有严格定义,允许根据平台和商家之间的协议或特定支付处理器要求灵活处理。

支付架构扩展

核心支付架构可以扩展以支持专业用例:

AP2 Mandates 扩展

dev.ucp.shopping.ap2_mandate:为需要不可否认证据的自主商务场景添加加密用户授权证明。

自定义处理器类型

支付凭证提供商可以定义自定义处理器以支持新的支付工具。参见 Payment Handler Guide 了解详情。

扩展模型确保核心架构保持简单,同时在需要时支持高级安全和合规要求。

总结

UCP 的支付架构通过以下方式解决了传统支付集成的复杂性:

  1. 解耦设计:将支付工具与处理逻辑分离
  2. 处理器抽象:通过规范而非实体定义处理流程
  3. 安全优先:最小化 PCI 范围,支持加密授权
  4. 灵活扩展:支持多种支付方式和场景
  5. 标准化:使用开放标准而非专有协议

这种设计使得平台、商家和支付提供商能够以标准化、安全的方式集成,同时保持灵活性和可扩展性。

MIT License.