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

# UCP端点测试与合规验证指南

> UCP端点测试与合规验证方法完整实践指南，涵盖/.well-known/ucp Profile合规性Bash自动化验证脚本、结账会话六状态全流程集成测试、基于RFC 9421的HTTP消息签名验证、OAuth身份关联授权测试方法及生产环境安全检查清单，确保商家UCP接入质量符合上线标准

# 测试与验证

## 9.1 UCP Profile验证

Profile是所有AI代理对接的入口，必须通过严格验证。

### 基础检查

```bash theme={null}
# 1. 检查HTTPS和无重定向
curl -sI "https://mystore.com/.well-known/ucp" | head -5
# 期望: HTTP/2 200 (不能是3xx)

# 2. 检查Cache-Control
curl -sI "https://mystore.com/.well-known/ucp" | grep -i cache-control
# 期望: cache-control: public, max-age=N (N >= 60)

# 3. 检查Content-Type
curl -sI "https://mystore.com/.well-known/ucp" | grep -i content-type
# 期望: content-type: application/json

# 4. 获取并验证JSON
curl -s "https://mystore.com/.well-known/ucp" | jq .
```

### Profile字段验证清单

| 字段                       | 验证规则                                                     | 必须 |
| ------------------------ | -------------------------------------------------------- | -- |
| `supported_versions`     | 非空数组，包含有效日期格式版本号                                         | 是  |
| `services`               | 至少一个服务，`base_url` 必须是HTTPS                               | 是  |
| `capabilities`           | 至少一个能力，命名空间格式正确                                          | 是  |
| `capabilities.*.version` | 有效日期格式，在 `supported_versions` 范围内                        | 是  |
| `payment_handlers`       | 数组，反向DNS命名格式                                             | 否  |
| `signing_keys`           | JWK数组，每个key有 `kid`, `kty`, `crv`, `x`, `y`, `use`, `alg` | 否  |

### Profile自动化验证脚本

```bash theme={null}
#!/bin/bash
URL="https://mystore.com/.well-known/ucp"

echo "=== UCP Profile Validation ==="

# 检查HTTP状态码（不跟随重定向）
STATUS=$(curl -so /dev/null -w "%{http_code}" --max-redirs 0 "$URL")
if [ "$STATUS" = "200" ]; then
  echo "PASS: HTTP 200 (no redirect)"
else
  echo "FAIL: HTTP $STATUS (expected 200, no redirects allowed)"
fi

# 检查HTTPS
if [[ "$URL" == https://* ]]; then
  echo "PASS: HTTPS"
else
  echo "FAIL: Must be HTTPS"
fi

# 检查Cache-Control
CACHE=$(curl -sI "$URL" | grep -i "cache-control" | tr -d '\r')
if echo "$CACHE" | grep -qi "public"; then
  echo "PASS: Cache-Control includes public"
else
  echo "FAIL: Cache-Control must include 'public'"
fi

# 检查JSON有效性
BODY=$(curl -s "$URL")
if echo "$BODY" | jq . > /dev/null 2>&1; then
  echo "PASS: Valid JSON"
else
  echo "FAIL: Invalid JSON"
fi

# 检查必须字段
if echo "$BODY" | jq -e '.supported_versions | length > 0' > /dev/null 2>&1; then
  echo "PASS: supported_versions present"
else
  echo "FAIL: supported_versions missing or empty"
fi

if echo "$BODY" | jq -e '.services | keys | length > 0' > /dev/null 2>&1; then
  echo "PASS: services present"
else
  echo "FAIL: services missing or empty"
fi

if echo "$BODY" | jq -e '.capabilities | keys | length > 0' > /dev/null 2>&1; then
  echo "PASS: capabilities present"
else
  echo "FAIL: capabilities missing or empty"
fi

# 检查签名密钥格式
KEYS=$(echo "$BODY" | jq -r '.signing_keys | length')
if [ "$KEYS" -gt 0 ]; then
  echo "INFO: $KEYS signing key(s) found"
  echo "$BODY" | jq -r '.signing_keys[] | "  kid=\(.kid) alg=\(.alg) crv=\(.crv)"'
else
  echo "INFO: No signing keys (Webhook signing not configured)"
fi

echo "=== Validation Complete ==="
```

## 9.2 结账流程测试

### 完整结账流程

```bash theme={null}
BASE="https://mystore.com/ucp"
TOKEN="Bearer ucp_pk_test_xxxx"

# 步骤1: 创建结账会话
SESSION=$(curl -s -X POST "$BASE/checkout/sessions" \
  -H "Content-Type: application/json" \
  -H "Authorization: $TOKEN" \
  -d '{
    "line_items": [{"product_id": "prod_001", "quantity": 1}],
    "buyer": {"email": "test@example.com"}
  }')
echo "Create: $(echo $SESSION | jq -r '.checkout_session.status')"
# 期望: incomplete

SESSION_ID=$(echo $SESSION | jq -r '.checkout_session.id')

# 步骤2: 更新买家信息和配送
curl -s -X PATCH "$BASE/checkout/sessions/$SESSION_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: $TOKEN" \
  -d '{
    "buyer": {
      "name": "Test User",
      "shipping_address": {
        "line1": "123 Test St",
        "city": "Beijing",
        "state": "Beijing",
        "postal_code": "100000",
        "country_code": "CN"
      }
    },
    "fulfillment": {"method": "standard_shipping"}
  }' | jq '.checkout_session.status'

# 步骤3: 查询会话状态
STATUS=$(curl -s "$BASE/checkout/sessions/$SESSION_ID" \
  -H "Authorization: $TOKEN" | jq -r '.checkout_session.status')
echo "After update: $STATUS"
# 期望: incomplete 或 ready_for_complete

# 步骤4: 取消会话（测试环境建议取消而非完成）
curl -s -X POST "$BASE/checkout/sessions/$SESSION_ID/cancel" \
  -H "Content-Type: application/json" \
  -H "Authorization: $TOKEN" \
  -d '{"reason": "test_cancellation"}' | jq '.checkout_session.status'
# 期望: canceled
```

### 状态机验证

测试所有6个状态的转换路径是否正确：

| 测试场景           | 起始状态                 | 操作       | 期望结果                   |
| -------------- | -------------------- | -------- | ---------------------- |
| 创建空会话          | -                    | Create   | `incomplete`           |
| 补充完整信息         | `incomplete`         | Update   | `ready_for_complete`   |
| 提交完成           | `ready_for_complete` | Complete | `complete_in_progress` |
| 取消进行中的会话       | `incomplete`         | Cancel   | `canceled`             |
| 对已完成会话调用Cancel | `completed`          | Cancel   | 400错误                  |
| 对已取消会话调用Update | `canceled`           | Update   | 400错误                  |
| 触发人工介入         | `incomplete`         | 特定条件     | `requires_escalation`  |

## 9.3 商品数据验证

每个商品记录必须通过以下验证：

```text theme={null}
必填字段检查:
  [x] id: 非空且唯一
  [x] name: 非空字符串
  [x] price.amount: 正整数（最小货币单位）
  [x] price.currency_code: 有效的ISO 4217代码（如CNY, USD, JPY）
  [x] availability: in_stock / out_of_stock / preorder 之一
  [x] images: 至少一项，URL可通过HTTPS访问

可选字段格式检查:
  [x] variants[].sku: 如存在则唯一
  [x] variants[].price.amount: 正整数
  [x] gtin: 如存在则符合GTIN-13或GTIN-14格式
  [x] compare_at_price.amount: 如存在则大于price.amount（划线价高于实际价）

金额一致性:
  [x] 所有price对象使用相同的currency_code
  [x] 金额值与货币的最小单位一致（CNY用分，JPY用円）
```

## 9.4 签名验证测试

如果配置了Webhook签名，测试签名的创建和验证：

```bash theme={null}
# 模拟商家发送带签名的Webhook
# 1. 创建测试请求体
BODY='{"event_type":"order.created","order_id":"ord_test_001"}'

# 2. 计算Content-Digest
DIGEST=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64)
echo "Content-Digest: sha-256=:$DIGEST:"

# 3. 验证商家Profile中的签名密钥
curl -s "https://mystore.com/.well-known/ucp" | jq '.signing_keys'
# 确认kid、alg(ES256)、crv(P-256)等字段正确
```

## 9.5 OAuth流程测试

```bash theme={null}
# 1. 验证授权服务器发现
curl -s "https://mystore.com/.well-known/oauth-authorization-server" | jq .
# 检查: authorization_endpoint, token_endpoint, revocation_endpoint

# 2. 验证授权端点支持PKCE
# 检查 code_challenge_methods_supported 包含 "S256"

# 3. 验证scope支持
# 检查 scopes_supported 包含 "ucp:scopes:checkout_session"

# 4. 测试令牌撤销端点 (RFC 7009)
curl -s -X POST "https://mystore.com/oauth/revoke" \
  -d "token=expired_test_token&token_type_hint=access_token&client_id=test" \
  -w "\nHTTP Status: %{http_code}\n"
# 期望: 200 (即使token无效也应返回200)
```

## 9.6 性能基准

UCP端点需要在合理的时间内响应：

| 端点类型                       | 响应时间目标  | 并发要求     |
| -------------------------- | ------- | -------- |
| `/.well-known/ucp` Profile | 100ms以内 | 100+ QPS |
| 商品搜索                       | 500ms以内 | 50+ QPS  |
| 商品详情                       | 200ms以内 | 100+ QPS |
| 结账操作                       | 1s以内    | 20+ QPS  |
| OAuth令牌端点                  | 300ms以内 | 50+ QPS  |

```bash theme={null}
# 简单性能测试
# Profile端点延迟
for i in $(seq 1 10); do
  curl -so /dev/null -w "%{time_total}\n" "https://mystore.com/.well-known/ucp"
done

# 商品搜索并发测试 (需要安装ab或wrk)
ab -n 100 -c 10 "https://mystore.com/ucp/catalog/products?query=test&limit=10"
```

## 9.7 常见问题排查

| 问题                | 原因            | 解决方案                            |
| ----------------- | ------------- | ------------------------------- |
| AI代理无法发现Profile   | 3xx重定向或非HTTPS | 确保直接返回200，不经过重定向                |
| Cache-Control验证失败 | max-age不足60秒  | 设置 `public, max-age=3600`       |
| 价格显示异常            | 未使用最小货币单位     | 确认amount是整数（分/美分），不是小数          |
| 签名验证失败            | kid不匹配或密钥过期   | 检查Profile中signing\_keys的kid是否一致 |
| OAuth流程中断         | 缺少PKCE支持      | 实现S256 code\_challenge验证        |
| 能力协商结果为空          | 版本号不匹配        | 确保双方supported\_versions有交集      |
| Webhook未收到        | 签名验证失败被拒      | 检查Content-Digest和Signature是否正确  |

***

**下一章**: [实战案例与扩展](/zh/book-3/ch10-case-studies) — Buyer Consent扩展、AP2 Mandate和集成实战路径
