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