Wdrażanie kodów promocyjnych i zniżek

Ten przewodnik zawiera techniczną dokumentację interfejsu API i schematy ładunków do obsługi kodów promocyjnych i rabatów w wersji 2026-04-08 protokołu Universal Commerce Protocol (UCP).

Zanim zaczniesz tworzyć punkty końcowe, zapoznaj się z omówieniem kodów promocyjnych i rabatów, aby poznać ogólne koncepcje, niezmienniki matematyczne i reguły obsługi błędów.

Odkrywanie

Aby otrzymywać kody rabatowe od Google, musisz reklamować obsługę rabatów w swoim profilu. W wersji 2026-04-08 platformy sprawdzają, czy funkcja płatności jest rozszerzona, zanim prześlą kody rabatowe.

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

Wpływ na elementy zamówienia i sumy

Zastosowane rabaty są odzwierciedlane w podstawowych polach płatności za pomocą 2 różnych typów sum. Jeśli rabat ma allocations wskazujące na elementy zamówienia, jest uwzględniany w items_discount. Rabaty bez alokacji lub z alokacjami do wysyłki lub opłat są uwzględniane w discount.

Typ rabatu Typ sumy Gdzie jest odzwierciedlony
Rabat na element zamówienia items_discount line_items[].totals[type=items_discount]
Rabat na poziomie zamówienia discount totals[type=discount]

Wymaganie dotyczące wersji:

W wersji 2026-04-08 wpisy rabatów w totals[] i line_items[].totals[] muszą używać wartości ujemnych, aby odzwierciedlać ich efekt odejmowania na paragonie. Kwoty w tablicach discounts.applied i allocations zawsze pozostają dodatnimi liczbami całkowitymi.

Przykłady interfejsu API dotyczące automatycznie stosowanych promocji

Poniższe przykłady pokazują rabaty stosowane automatycznie. Ładunki żądań nie zawierają tablicy discounts.codes, ale odpowiedzi zawierają "automatic": true i pomijają pole code.

Automatycznie stosowany rabat na poziomie produktu

10% wyprzedaż w całym serwisie automatycznie stosowana do konkretnego elementu zamówienia.

Przykład żądania:

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

Przykład odpowiedzi:

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

Automatycznie stosowany rabat na poziomie zamówienia

Reguła promocyjna (np. „10 zł zniżki na zamówienia powyżej 50 zł”) stosowana do całego zamówienia bez konkretnych alokacji elementów zamówienia.

Przykład żądania:

{
  "line_items": [ ... ]
}

Przykład odpowiedzi:

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

Przykłady interfejsu API dotyczące promocji stosowanych przez użytkownika

Poniższe przykłady pokazują rabaty aktywowane przez użytkownika, który wpisuje kod promocyjny. Ładunki żądań zawierają żądane kody, a odpowiedzi je odzwierciedlają, jednocześnie przydzielając zastosowane kwoty.

Rabat na poziomie zamówienia

Stały rabat stosowany do sumy zamówienia. Nie są potrzebne żadne alokacje. Rabat dotyczy całego zamówienia i używa type: "discount".

Przykład żądania:

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

Przykład odpowiedzi:

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

Rabaty mieszane (na poziomie produktu i zamówienia)

Ten przykład pokazuje oba typy rabatów: rabat na produkt (20% zniżki) przypisany do elementów zamówienia oraz automatyczny rabat na wysyłkę na poziomie zamówienia.

Przykład żądania:

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

Przykład odpowiedzi:

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

Odrzucony kod rabatowy

Gdy kod jest nieprawidłowy, jest odzwierciedlany w codes, ale pomijany w applied. Odrzucenie jest sygnalizowane za pomocą warning w tablicy messages[].

Przykład żądania:

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

Przykład odpowiedzi:

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

Rabaty łączone z alokacjami

Wiele rabatów stosowanych z pełnymi podziałami alokacji.

Przykład żądania:

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

Przykład odpowiedzi:

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