Triển khai mã khuyến mãi và chiết khấu

Hướng dẫn này cung cấp thông tin tham khảo kỹ thuật về API và giản đồ tải trọng để xử lý mã khuyến mãi và chiết khấu trong phiên bản 2026-04-08 của Giao thức thương mại toàn cầu (UCP).

Trước khi tạo các điểm cuối, hãy đảm bảo bạn đã xem Tổng quan về mã khuyến mãi và chiết khấu để biết các khái niệm cấp cao, bất biến toán học và quy tắc xử lý lỗi.

Chiến dịch Khám phá

Để nhận mã giảm giá của Google, bạn phải quảng cáo việc hỗ trợ chiết khấu trong hồ sơ của mình. Trong phiên bản 2026-04-08, các nền tảng sẽ kiểm tra xem khả năng thanh toán có được mở rộng hay không trước khi gửi mã chiết khấu.

{
  "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"
        }
      ]
    }
  }
}

Ảnh hưởng đến mục hàng và tổng số

Các khoản chiết khấu được áp dụng sẽ xuất hiện trong các trường thanh toán chính bằng cách sử dụng 2 loại tổng riêng biệt. Nếu một chiết khấu có allocations trỏ đến các mục hàng, thì chiết khấu đó sẽ đóng góp vào items_discount. Chiết khấu không được phân bổ hoặc được phân bổ cho phí vận chuyển hoặc các khoản phí sẽ đóng góp vào discount.

Loại giảm giá Loại tổng Nơi được phản ánh
Chiết khấu mục hàng items_discount line_items[].totals[type=items_discount]
Chiết khấu ở cấp đơn đặt hàng discount totals[type=discount]

Yêu cầu về phiên bản:

Đối với phiên bản 2026-04-08, các mục chiết khấu trong totals[]line_items[].totals[] phải sử dụng giá trị âm để phản ánh hiệu ứng trừ của các mục đó trên biên nhận. Số tiền trong mảng discounts.appliedallocations luôn là số nguyên dương.

Ví dụ về API cho chương trình khuyến mãi được áp dụng tự động

Các ví dụ sau đây minh hoạ chiết khấu được áp dụng tự động. Tải trọng yêu cầu không chứa mảng discounts.codes, nhưng các phản hồi bao gồm "automatic": true và bỏ qua trường code.

Chiết khấu tự động áp dụng ở cấp mặt hàng

Một chương trình giảm giá 10% trên toàn trang web được tự động áp dụng cho một mục hàng cụ thể.

Ví dụ về yêu cầu:

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

Ví dụ về phản hồi:

{
  "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}
  ]
}

Chiết khấu tự động áp dụng ở cấp đơn đặt hàng

Một quy tắc khuyến mãi (ví dụ: "Giảm 100.000 VND cho đơn đặt hàng trên 500.000 VND") được áp dụng cho đơn đặt hàng nói chung mà không có mức phân bổ cụ thể cho từng mặt hàng.

Ví dụ về yêu cầu:

{
  "line_items": [ ... ]
}

Ví dụ về phản hồi:

{
  "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}
  ]
}

Ví dụ về API cho chương trình khuyến mãi do người dùng áp dụng

Các ví dụ sau đây minh hoạ chiết khấu được kích hoạt khi người dùng nhập mã khuyến mãi. Tải trọng yêu cầu bao gồm các mã được yêu cầu và các phản hồi sẽ phản ánh lại các mã đó trong khi phân bổ số tiền đã áp dụng.

Chiết khấu ở cấp đơn đặt hàng

Chiết khấu cố định được áp dụng cho tổng giá trị đơn đặt hàng. Bạn không cần phân bổ; chiết khấu áp dụng cho toàn bộ đơn đặt hàng và sử dụng type: "discount".

Ví dụ về yêu cầu:

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

Ví dụ về phản hồi:

{
  "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}
  ]
}

Chiết khấu hỗn hợp (cấp mặt hàng + cấp đơn đặt hàng)

Ví dụ này cho thấy cả hai loại chiết khấu: chiết khấu theo mặt hàng (giảm 20%) được phân bổ cho các mục hàng và chiết khấu vận chuyển tự động ở cấp đơn đặt hàng.

Ví dụ về yêu cầu:

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

Ví dụ về phản hồi:

{
  "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}
  ]
}

Mã giảm giá bị từ chối

Khi mã không hợp lệ, mã đó sẽ được lặp lại trong codes nhưng bị bỏ qua trong applied. Yêu cầu bị từ chối sẽ được thông báo bằng warning trong mảng messages[].

Ví dụ về yêu cầu:

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

Ví dụ về phản hồi:

{
  "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"
    }
  ]
}

Chiết khấu theo bậc có phân bổ

Nhiều khoản chiết khấu được áp dụng với thông tin chi tiết đầy đủ về việc phân bổ.

Ví dụ về yêu cầu:

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

Ví dụ về phản hồi:

{
  "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}
  ]
}