Penerapan kode promo dan diskon

Panduan ini memberikan referensi API teknis dan skema payload untuk menangani kode promosi dan diskon di versi 2026-04-08 Universal Commerce Protocol (UCP).

Sebelum membuat endpoint, pastikan Anda telah meninjau Ringkasan kode promo dan diskon untuk memahami konsep tingkat tinggi, invarian matematika, dan aturan penanganan error.

Discovery

Untuk menerima kode diskon dari Google, Anda harus mengiklankan dukungan diskon di profil Anda. Pada versi 2026-04-08, platform memeriksa apakah kemampuan checkout diperluas sebelum mengirimkan kode diskon.

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

Dampak pada item baris dan total

Diskon yang diterapkan tercermin dalam kolom checkout inti menggunakan dua jenis total yang berbeda. Jika diskon memiliki allocations yang mengarah ke item baris, diskon tersebut berkontribusi pada items_discount. Diskon tanpa alokasi, atau dengan alokasi untuk pengiriman atau biaya, berkontribusi pada discount.

Jenis diskon Jenis total Tempat tercermin
Diskon item baris items_discount line_items[].totals[type=items_discount]
Diskon tingkat pesanan discount totals[type=discount]

Persyaratan versi:

Untuk versi 2026-04-08, entri diskon di totals[] dan line_items[].totals[] harus menggunakan nilai negatif untuk mencerminkan efek pengurangan pada tanda terima. Jumlah di dalam array discounts.applied dan allocations selalu berupa bilangan bulat positif.

Contoh API untuk promosi yang diterapkan otomatis

Contoh berikut menunjukkan diskon yang diterapkan secara otomatis. Payload permintaan tidak berisi array discounts.codes, tetapi respons menyertakan "automatic": true dan menghilangkan kolom code.

Diskon tingkat item yang diterapkan otomatis

Penjualan di seluruh situs sebesar 10% yang otomatis diterapkan ke item baris tertentu.

Contoh permintaan:

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

Contoh respons:

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

Diskon tingkat pesanan yang diterapkan otomatis

Aturan promosi (misalnya, "Diskon Rp100.000 untuk pesanan di atas Rp500.000") diterapkan ke pesanan secara keseluruhan tanpa alokasi item baris tertentu.

Contoh permintaan:

{
  "line_items": [ ... ]
}

Contoh respons:

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

Contoh API untuk promosi yang diterapkan pengguna

Contoh berikut menunjukkan diskon yang dipicu oleh pengguna yang memasukkan kode promosi. Payload permintaan mencakup kode yang diminta, dan respons mengulanginya kembali sambil mengalokasikan jumlah yang diterapkan.

Diskon tingkat pesanan

Diskon tetap yang diterapkan ke total pesanan. Tidak ada alokasi yang diperlukan; diskon berlaku untuk seluruh pesanan dan menggunakan type: "discount".

Contoh permintaan:

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

Contoh respons:

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

Diskon campuran (tingkat item + pesanan)

Contoh ini menunjukkan kedua jenis diskon: diskon per item (potongan 20%) yang dialokasikan ke item baris, dan diskon pengiriman otomatis di tingkat pesanan.

Contoh permintaan:

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

Contoh respons:

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

Kode diskon ditolak

Jika kode tidak valid, kode tersebut akan diulang di codes, tetapi tidak ada di applied. Penolakan dikomunikasikan menggunakan warning dalam array messages[].

Contoh permintaan:

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

Contoh respons:

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

Diskon bertumpuk dengan alokasi

Beberapa diskon diterapkan dengan perincian alokasi penuh.

Contoh permintaan:

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

Contoh respons:

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