促销代码和折扣的实现

本指南提供了通用商务协议 (UCP) 版本 2026-04-08 中处理促销代码和折扣的技术 API 参考文档和载荷架构。

在构建端点之前,请务必查看促销代码和 折扣概览,了解 高级概念、数学不变式和错误处理规则。

发现

如需从 Google 接收折扣代码,您必须在个人资料中宣传折扣支持。在版本 2026-04-08 中,平台会在提交折扣代码之前检查结账功能是否已扩展。

{
  "ucp": {
    "version": "2026-04-08",
    "capabilities": {
      "dev.ucp.shopping.discount": [
        {
          "version": "2026-04-08",
          "extends": ["dev.ucp.shopping.checkout"],
          "spec": "https://ucp.dev/2026-04-08/specification/discount",
          "schema": "https://ucp.dev/2026-04-08/schemas/shopping/discount.json"
        }
      ]
    }
  }
}

对订单项和总金额的影响

应用折扣会使用两种不同的总金额类型反映在核心结账字段中。如果折扣的 allocations 指向订单项,则该折扣会影响 items_discount。没有分配项或分配给运费或手续费的折扣会影响 discount

折扣类型 总金额类型 反映位置
订单项折扣 items_discount line_items[].totals[type=items_discount]
订单级折扣 discount totals[type=discount]

版本要求

对于版本 2026-04-08totals[]line_items[].totals[] 中的折扣条目必须使用 负值 ,以反映其 对收据的减法效应。discounts.appliedallocations 数组中的金额始终为正整数。

自动应用促销活动的 API 示例

以下示例展示了自动应用的折扣。请求 载荷不包含 discounts.codes 数组,但响应包含 "automatic": true 并省略了 code 字段。

自动应用的商品级折扣

自动应用于特定订单项的 10% 全场促销活动。

请求示例:

{
  "line_items": [
    {
      "id": "li_1",
      "item": { "title": "Sneakers", "price": 10000 },
      "quantity": 1
    }
  ]
}

响应示例:

{
  "line_items": [
    {
      "id": "li_1",
      "item": { "title": "Sneakers", "price": 10000 },
      "quantity": 1,
      "totals": [
        {"type": "subtotal", "amount": 10000},
        {"type": "items_discount", "amount": -1000},
        {"type": "total", "amount": 9000}
      ]
    }
  ],
  "discounts": {
    "applied": [
      {
        "title": "10% Off Sitewide Sale",
        "amount": 1000,
        "automatic": true,
        "method": "each",
        "allocations": [
          {"path": "$.line_items[0]", "amount": 1000}
        ]
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
    {"type": "items_discount", "display_text": "Item Discounts", "amount": -1000},
    {"type": "total", "display_text": "Total", "amount": 9000}
  ]
}

自动应用的订单级折扣

促销规则(例如“订单金额满 50 美元立减 10 美元”)应用于整个订单,没有特定的订单项分配。

请求示例:

{
  "line_items": [ ... ]
}

响应示例:

{
  "line_items": [ ... ],
  "discounts": {
    "applied": [
      {
        "title": "$10 Off Orders Over $50",
        "amount": 1000,
        "automatic": true
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 6000},
    {"type": "discount", "display_text": "Order Promo", "amount": -1000},
    {"type": "total", "display_text": "Total", "amount": 5000}
  ]
}

用户应用的促销活动的 API 示例

以下示例展示了因用户输入促销代码而触发的折扣。请求载荷包含请求的代码,响应会回显这些代码,同时分配应用金额。

订单级折扣

应用于订单总金额的固定折扣。无需分配; 折扣适用于整个订单,并使用 type: "discount"

请求示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SAVE10"]
  }
}

响应示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SAVE10"],
    "applied": [
      {
        "code": "SAVE10",
        "title": "$10 Off Your Order",
        "amount": 1000
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 5000},
    {"type": "discount", "display_text": "Order Discount", "amount": -1000},
    {"type": "total", "display_text": "Total", "amount": 4000}
  ]
}

混合折扣(商品级 + 订单级)

此示例展示了两种折扣类型:分配给订单项的每件商品折扣(20% 折扣)和订单级的自动运费折扣。

请求示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SUMMER20"]
  }
}

响应示例:

{
  "line_items": [
    {
      "id": "li_1",
      "item": { "title": "T-Shirt", "price": 2000 },
      "quantity": 2,
      "totals": [
        {"type": "subtotal", "amount": 4000},
        {"type": "items_discount", "amount": -800},
        {"type": "total", "amount": 3200}
      ]
    }
  ],
  "discounts": {
    "codes": ["SUMMER20"],
    "applied": [
      {
        "code": "SUMMER20",
        "title": "Summer Sale 20% Off",
        "amount": 800,
        "allocations": [
          {"path": "$.line_items[0]", "amount": 800}
        ]
      },
      {
        "title": "Free shipping on orders over $30",
        "amount": 599,
        "automatic": true
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 4000},
    {"type": "items_discount", "display_text": "Item Discounts", "amount": -800},
    {"type": "discount", "display_text": "Order Discounts", "amount": -599},
    {"type": "fulfillment", "display_text": "Shipping", "amount": 0},
    {"type": "total", "display_text": "Total", "amount": 2601}
  ]
}

被拒绝的折扣代码

如果代码无效,则会在 codes 中回显,但会从 applied 中省略。拒绝信息会使用 messages[] 数组中的 warning 进行传达。

请求示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SAVE10", "EXPIRED50"]
  }
}

响应示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SAVE10", "EXPIRED50"],
    "applied": [
      {
        "code": "SAVE10",
        "title": "$10 Off Your Order",
        "amount": 1000
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 5000},
    {"type": "discount", "display_text": "Order Discount", "amount": -1000},
    {"type": "total", "display_text": "Total", "amount": 4000}
  ],
  "messages": [
    {
      "type": "warning",
      "code": "discount_code_expired",
      "path": "$.discounts.codes[1]",
      "content": "Code 'EXPIRED50' expired on December 1st"
    }
  ]
}

叠加折扣(含分配)

应用了多个折扣,并提供完整的分配明细。

请求示例:

{
  "line_items": [ ... ],
  "discounts": {
    "codes": ["SUMMER20", "EXTRA5"]
  }
}

响应示例:

{
  "line_items": [
    {
      "id": "li_1",
      "item": { "title": "T-Shirt", "price": 6000 },
      "quantity": 1,
      "totals": [
        {"type": "subtotal", "amount": 6000},
        {"type": "items_discount", "amount": -1500},
        {"type": "total", "amount": 4500}
      ]
    },
    {
      "id": "li_2",
      "item": { "title": "Socks", "price": 4000 },
      "quantity": 1,
      "totals": [
        {"type": "subtotal", "amount": 4000},
        {"type": "items_discount", "amount": -1000},
        {"type": "total", "amount": 3000}
      ]
    }
  ],
  "discounts": {
    "codes": ["SUMMER20", "EXTRA5"],
    "applied": [
      {
        "code": "SUMMER20",
        "title": "Summer Sale 20% Off",
        "amount": 2000,
        "method": "each",
        "priority": 1,
        "allocations": [
          {"path": "$.line_items[0]", "amount": 1200},
          {"path": "$.line_items[1]", "amount": 800}
        ]
      },
      {
        "code": "EXTRA5",
        "title": "Extra $5 Off",
        "amount": 500,
        "method": "across",
        "priority": 2,
        "allocations": [
          {"path": "$.line_items[0]", "amount": 300},
          {"path": "$.line_items[1]", "amount": 200}
        ]
      }
    ]
  },
  "totals": [
    {"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
    {"type": "items_discount", "display_text": "Item Discounts", "amount": -2500},
    {"type": "total", "display_text": "Total", "amount": 7500}
  ]
}