คู่มือนี้มีข้อมูลอ้างอิงทางเทคนิคของ API และสคีมาเพย์โหลดสำหรับการพุชข้อมูลอัปเดตสถานะคำสั่งซื้อทั้งหมด เหตุการณ์การดำเนินการตามคำสั่งซื้อ และการปรับไปยัง Google โดยใช้เว็บฮุคสำหรับ Universal Commerce Protocol (UCP) เวอร์ชัน 2026-04-08
ก่อนสร้างปลายทาง โปรดตรวจสอบว่าคุณได้อ่านภาพรวม ของวงจรชีวิตของคำสั่งซื้อเพื่อทำความเข้าใจแนวคิดระดับสูง เหตุการณ์ที่ต้องมี และรายละเอียดปลายทางของเว็บฮุคแล้ว
การตรวจสอบสิทธิ์และการลงนามคำขอ
การเปลี่ยนแปลงที่สำคัญในเวอร์ชัน 2026-04-08 ได้แก่ การเปิดตัวส่วนหัวของเว็บฮุคใหม่ที่ต้องมีและขั้นตอนการลงนามคำขอที่เฉพาะเจาะจง
ส่วนหัวของเว็บฮุคที่ต้องมี
ส่วนหัว HTTP ต่อไปนี้เป็นส่วนหัวที่ต้องมีสำหรับคำขอเว็บฮุคทั้งหมด
Webhook-Id: ตัวระบุที่ไม่ซ้ำกันสำหรับเหตุการณ์เว็บฮุคนี้ รหัสนี้ควรตรงกับidของเหตุการณ์หลักที่ส่ง (เช่น รหัสเหตุการณ์การดำเนินการตามคำสั่งซื้อหรือรหัสเหตุการณ์การปรับ)Webhook-Timestamp: การประทับเวลาที่ระบุเวลาที่เกิดเหตุการณ์
ส่วนหัวเหล่านี้จะแทนที่ช่อง id และ created_time ที่คาดไว้ก่อนหน้านี้ในเพย์โหลดคำสั่งซื้อ
การลงนามคำขอ
- คำนวณไดเจสต์ SHA-256 ของเนื้อหาคำขอแบบดิบและตั้งค่าส่วนหัว
Content-Digest - เลือกคีย์การลงนามจาก
signing_keysในโปรไฟล์ UCP - สร้างฐานลายเซ็นตาม RFC
9421
- ดูข้อมูลจำเพาะสำหรับคอมโพเนนต์ที่มีการลงนาม
- ตั้งค่าส่วนหัว
UCP-Agent,Signature-InputและSignatureUCP-Agentคือลิงก์ไปยังโปรไฟล์ UCP ในรูปแบบprofile="https://merchant.example.com/.well-known/ucp"Signature-Inputคือฟิลด์ที่มีโครงสร้างแบบพจนานุกรมที่อธิบายคอมโพเนนต์ที่อยู่ในลายเซ็น รวมถึงkeyidที่ใช้ในการลงนาม ซึ่งต้องตรงกับkidของคีย์การลงนามที่เลือกจากsigning_keysในโปรไฟล์ UCP- ส่วนหัว
Signatureมีฐานลายเซ็นที่ลงนามโดยใช้คีย์ส่วนตัวแล้วเข้ารหัส Base64
ดูข้อมูลเพิ่มเติมได้ที่วิธีการลงนามใน ucp.dev
เหตุการณ์คำสั่งซื้อที่สร้างขึ้น
- ทริกเกอร์: ทันทีหลังจากยืนยันคำสั่งซื้อ (
status: processing)
การเปลี่ยนแปลงที่สำคัญในเวอร์ชันนี้:
- ตอนนี้ต้องระบุช่อง
currencyที่ระดับบนสุดของออบเจ็กต์คำสั่งซื้อ - ตอนนี้ช่อง
typeภายในแต่ละออบเจ็กต์ในอาร์เรย์totalsเป็นสตริงแบบเปิด (เช่น "subtotal", "tax", "fee", "total") - ส่วนหัว
Webhook-Idที่ต้องมีมีตัวระบุที่ไม่ซ้ำกันสำหรับเหตุการณ์เว็บฮุค โปรดทราบว่ายังคงต้องระบุช่องidในเพย์โหลดที่มีรหัสการยืนยันคำสั่งซื้อ - ส่วนหัว
Webhook-Timestampที่ต้องมีจะระบุเวลาที่สร้างขึ้น ซึ่งจะแทนที่ช่องcreated_timeเดิมในเพย์โหลด
ตัวอย่าง: ตัวอย่างนี้แสดงคำสั่งซื้อที่สร้างขึ้นหลังจากผู้ซื้อชำระเงินเสร็จสมบูรณ์
ส่วนหัวที่ต้องมี:
Webhook-Id: order_01Webhook-Timestamp: 2026-03-23T19:00:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_01",
"checkout_id": "checkout_01",
"currency": "USD",
// Always include all line items, even for single-item checkouts. This ensures any add-ons, gifts, or separate charges are accounted for.
"line_items": [
{
"id": "line_1",
"item":
{
"id": "product_123",
"title": "Running Shoes",
"price": 10000
},
"quantity": { "total": 1, "fulfilled": 0 },
"totals": [
{"type": "subtotal", "display_text": null, "amount": 10000},
{"type": "total", "display_text": null, "amount": 10000}
],
// The status of a line item must match total and fulfilled quantities (e.g., total 1, fulfilled 0 -> status: processing).
"status": "processing"
}
],
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 10000}, // Tax-inclusive markets: Set display_text to "Subtotal (including taxes)". Amount must include tax.
{"type": "fee", "display_text": "Service Fee", "amount": 100},
{"type": "tax", "display_text": "Tax", "amount": 800}, // Tax-inclusive markets: Omit this entry.
{"type": "total", "display_text": "Total", "amount": 10900}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Arrives in 2-3 business days", // Maximum length: 200 characters.
"fulfillable_on": "now"
}
]
},
"permalink_url": "https://merchant.example.com/orders/789"
}
เหตุการณ์การดำเนินการตามคำสั่งซื้อ
ระบบจะส่งเหตุการณ์เหล่านี้เป็นส่วนหนึ่งของอาร์เรย์ fulfillment.events
จัดส่งคำสั่งซื้อแล้ว
เมื่อมีการจัดส่งสินค้าในคำสั่งซื้อแล้ว ช่อง tracking_number และ tracking_url เป็นช่องที่ต้องระบุสำหรับเหตุการณ์ที่จัดส่งแล้ว เนื่องจากจำเป็นต้องใช้เพื่อจัดกลุ่มสินค้าในหน้า "คำสั่งซื้อของฉัน" อย่างถูกต้อง
นำส่งคำสั่งซื้อแล้ว
เมื่อมีการนำส่งสินค้าในคำสั่งซื้อแล้ว
ตัวอย่าง (shipped และ delivered): ตัวอย่างนี้แสดงการอัปเดตคำสั่งซื้อหลังจากมีการจัดส่งและนำส่งสินค้าแล้ว
ส่วนหัวที่ต้องมี:
Webhook-Id: fulfill_evt_2Webhook-Timestamp: 2026-02-10T14:00:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_01",
"checkout_id": "checkout_01",
"currency": "USD",
"line_items": [
{
"id": "line_1",
"item":
{
"id": "product_123",
"title": "Running Shoes",
"price": 10000
},
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "amount": 10000},
{"type": "total", "amount": 10000}
],
// Updated fulfillment details
"fulfillment": {
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Shipping departed from warehouse"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-10T14:00:00Z",
"type": "delivered",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Package delivered"
}
],
"expectations": [{ "...": "..." }]
},
"permalink_url": "https://merchant.example.com/orders/123"
}
ตัวอย่างคำสั่งซื้อที่มีสินค้าหลายรายการ
ตัวอย่างต่อไปนี้แสดงวิธีจัดโครงสร้างการอัปเดตสำหรับคำสั่งซื้อที่มีสินค้าหลายรายการและการจัดส่งแยก ดูข้อมูลเกี่ยวกับกฎในการกำหนดสถานะแพ็กเกจได้ที่ วิธีพิจารณาสถานะแพ็กเกจ
คำสั่งซื้อที่มีสินค้าหลายรายการและการนำส่งแพ็กเกจเดียวกัน
ตัวอย่างนี้แสดงการอัปเดตคำสั่งซื้อสำหรับแพ็กเกจเดียวที่มีสินค้าหลายรายการ ระบบจะจัดกลุ่มรายการโฆษณาทั้งหมดไว้ในเหตุการณ์ shipped เดียวกันซึ่งใช้หมายเลขติดตามพัสดุเดียวกัน
ส่วนหัวที่ต้องมี:
Webhook-Id: fulfill_evt_1Webhook-Timestamp: 2026-02-08T10:30:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_multi_01",
"checkout_id": "checkout_multi_01",
"currency": "USD",
"line_items": [
{
"id": "line_1",
"item": { "id": "product_1", "title": "Item 1", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "display_text": null, "amount": 5000},
{"type": "total", "display_text": null, "amount": 5000}
],
"status": "fulfilled"
},
{
"id": "line_2",
"item": { "id": "product_2", "title": "Item 2", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "display_text": null, "amount": 5000},
{"type": "total", "display_text": null, "amount": 5000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
{"type": "fee", "display_text": "Shipping", "amount": 500},
{"type": "total", "display_text": "Total", "amount": 10500}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [
{ "id": "line_1", "quantity": 1 },
{ "id": "line_2", "quantity": 1 }
],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Standard Shipping",
"fulfillable_on": "now"
}
],
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [
{ "id": "line_1", "quantity": 1 },
{ "id": "line_2", "quantity": 1 }
],
"tracking_number": "123456789",
"tracking_url": "https://fedex.com/track/123456789",
"carrier": "FedEx",
"description": "Both items shipped together"
}
]
},
"permalink_url": "https://merchant.example.com/orders/456"
}
คำสั่งซื้อที่มีสินค้าหลายรายการและการจัดส่งแยก
ตัวอย่างนี้แสดงการอัปเดตคำสั่งซื้อสำหรับการจัดส่งแยก มีเหตุการณ์ shipped หลายรายการ ซึ่งแต่ละรายการอ้างอิง line_items ที่เฉพาะเจาะจงภายในแพ็กเกจนั้นๆ โดยใช้หมายเลขติดตามที่ไม่ซ้ำกัน เนื่องจากแต่ละแพ็กเกจแสดงถึงข้อผูกมัดในการดำเนินการตามคำสั่งซื้อที่แตกต่างกัน (เช่น ความเร็วและค่าใช้จ่ายที่แตกต่างกันจากการชำระเงินแบบหลายกลุ่ม) ระบบจึงแยก expectations ด้วย
ส่วนหัวที่ต้องมี:
Webhook-Id: fulfill_evt_2Webhook-Timestamp: 2026-02-09T14:00:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_multi_02",
"checkout_id": "checkout_multi_02",
"currency": "USD",
"line_items": [
{
"id": "line_1",
"item": { "id": "product_1", "title": "Item 1", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "display_text": null, "amount": 5000},
{"type": "total", "display_text": null, "amount": 5000}
],
"status": "fulfilled"
},
{
"id": "line_2",
"item": { "id": "product_2", "title": "Item 2", "price": 5000 },
"quantity": { "total": 1, "fulfilled": 1 },
"totals": [
{"type": "subtotal", "display_text": null, "amount": 5000},
{"type": "total", "display_text": null, "amount": 5000}
],
"status": "fulfilled"
}
],
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": 10000},
{"type": "fee", "display_text": "Shipping", "amount": 1500},
{"type": "total", "display_text": "Total", "amount": 11500}
],
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Standard Shipping",
"fulfillable_on": "now"
},
{
"id": "exp_2",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Alice",
"last_name": "Example",
"street_address": "123 Main St",
"address_locality": "Austin",
"address_region": "TX",
"address_country": "US",
"postal_code": "78701"
},
"description": "Express Shipping",
"fulfillable_on": "now"
}
],
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-08T10:30:00Z",
"type": "shipped",
"line_items": [{ "id": "line_1", "quantity": 1 }],
"tracking_number": "PKG1_TRACKING",
"tracking_url": "https://fedex.com/track/PKG1_TRACKING",
"carrier": "FedEx",
"description": "First item shipped in package 1"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-09T14:00:00Z",
"type": "shipped",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"tracking_number": "PKG2_TRACKING",
"tracking_url": "https://fedex.com/track/PKG2_TRACKING",
"carrier": "FedEx",
"description": "Second item shipped in package 2"
}
]
},
"permalink_url": "https://merchant.example.com/orders/457"
}
ตัวอย่างเหตุการณ์การปรับ
ตัวอย่างต่อไปนี้แสดงวิธีจัดโครงสร้างการอัปเดตสำหรับการคืนเงิน การคืนสินค้า และการยกเลิก ดูรายการเหตุการณ์ที่รองรับและ คำจำกัดความของเหตุการณ์เหล่านั้นได้ที่เหตุการณ์การปรับใน ภาพรวมของวงจรชีวิตของคำสั่งซื้อ
การยกเลิกและการคืนเงินตามคำสั่งซื้อ
ตัวอย่างนี้แสดงคำสั่งซื้อที่ยกเลิกและคืนเงินสินค้าหลังจากสั่งซื้อได้ไม่นาน
การเปลี่ยนแปลงที่สำคัญในเวอร์ชันนี้ในตัวอย่างนี้:
- ตอนนี้รายการโฆษณาที่ได้รับผลกระทบจาก
cancellationจะใช้"status": "removed"ใน อาร์เรย์line_itemsหลัก - เมื่อ
line_items.statusเป็นremovedระบบจะดำเนินการดังนี้- ตั้งค่า
line_items.quantity.totalเป็น0 - จัดเก็บจำนวนเดิมไว้ในช่อง
line_items.quantity.originalใหม่
- ตั้งค่า
ส่วนหัวที่ต้องมี:
Webhook-Id: adj_refund_1Webhook-Timestamp: 2026-02-09T11:05:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_02",
"checkout_id": "checkout_02",
"currency": "USD",
"line_items": [
{
"id": "line_2",
"item": {
"id": "product_456",
"title": "Smart Watch",
"price": 29900
},
"quantity": {
"total": 0, // Item removed from order total.
"original": 1, // Original quantity before removal.
"fulfilled": 0 // Item was not fulfilled before cancellation.
},
"totals": [
{"type": "subtotal", "amount": 29900},
{"type": "tax", "amount": 2400},
{"type": "total", "amount": 32300}
],
"status": "removed" // Item is cancelled, returned, or refunded.
}
],
"totals": [
{"type": "subtotal", "amount": 29900},
{"type": "tax", "amount": 2400},
{"type": "total", "amount": 32300}
],
// Fulfillment expectations should still be present even if cancelled early.
"fulfillment": {
"expectations": [
{
"id": "exp_1",
"line_items": [{ "id": "line_2", "quantity": 1 }],
"method_type": "shipping",
"destination": {
"first_name": "Bob",
"last_name": "Consumer",
"street_address": "456 Oak Ave",
"address_locality": "Anytown",
"address_region": "CA",
"address_country": "US",
"postal_code": "90210"
},
"description": "Standard Shipping",
"fulfillable_on": "now"
}
]
// "events": [] // No fulfillment events occurred before cancellation.
},
"adjustments": [
{
"id": "adj_cancel_1",
"type": "cancellation",
"description": "Customer changed mind",
"line_items": [{ "id": "line_2", "quantity": -1 }],
"occurred_at": "2026-02-09T11:00:00Z",
"status": "completed"
},
{
"id": "adj_refund_1",
"type": "refund",
"description": "Refund for cancelled item",
"line_items": [{ "id": "line_2", "quantity": -1 }],
"totals": [
{"type": "subtotal", "display_text": "Subtotal", "amount": -29900}, // Negative amounts indicate money returned to the buyer. Tax-inclusive markets: Set display_text to "Subtotal (including taxes)". Amount must include tax.
{"type": "tax", "amount": -2400}, // Tax-inclusive markets: Omit this entry.
{"type": "total", "display_text": "Total", "amount": -32300}
],
"occurred_at": "2026-02-09T11:05:00Z",
"status": "completed"
}
],
"permalink_url": "https://merchant.example.com/orders/12345"
}
การคืนสินค้าและการคืนเงินตามคำสั่งซื้อ
ตัวอย่างนี้แสดงคำสั่งซื้อที่จัดส่ง นำส่ง คืนสินค้า และคืนเงินแล้ว
การเปลี่ยนแปลงที่สำคัญในเวอร์ชันนี้ในตัวอย่างนี้:
- ตอนนี้รายการโฆษณาที่ได้รับผลกระทบจาก
returnจะใช้"status": "removed"ในอาร์เรย์line_itemsหลัก - เมื่อ
line_items.statusเป็นremovedระบบจะดำเนินการดังนี้- ตั้งค่า
line_items.quantity.totalเป็น0 - จัดเก็บจำนวนเดิมไว้ในช่อง
line_items.quantity.originalใหม่
- ตั้งค่า
- ใน
adjustmentsประเภทreturnช่องline_items.quantityภายในรายการปรับจะใช้ค่าติดลบ (เช่น-1) เพื่อระบุสินค้าที่นำกลับ
ส่วนหัวที่ต้องมี:
Webhook-Id: adj_refund_2Webhook-Timestamp: 2026-02-10T10:00:00Z
{
"ucp": {
"version": "2026-04-08",
"capabilities": {
"dev.ucp.shopping.order": [{"version": "2026-04-08"}]
}
},
"id": "order_03",
"checkout_id": "checkout_03",
"currency": "USD",
"line_items": [
{
"id": "line_3",
"item": {
"id": "product_789",
"title": "Wireless Earbuds",
"price": 14900
},
"quantity": {
"total": 0, // Item removed from order total.
"original": 1, // Original quantity before removal.
"fulfilled": 1 // Was fulfilled before return.
},
"totals": [
{"type": "subtotal", "amount": 14900},
{"type": "tax", "amount": 1200},
{"type": "total", "amount": 16100}
],
"status": "removed" // Item is cancelled, returned, or refunded.
}
],
"totals": [
{"type": "subtotal", "amount": 14900},
{"type": "tax", "amount": 1200},
{"type": "total", "amount": 16100}
],
"fulfillment": {
"events": [
{
"id": "fulfill_evt_1",
"occurred_at": "2026-02-05T09:00:00Z",
"type": "shipped",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item shipped"
},
{
"id": "fulfill_evt_2",
"occurred_at": "2026-02-07T16:00:00Z",
"type": "delivered",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item delivered"
},
{
"id": "fulfill_evt_3",
"occurred_at": "2026-02-09T09:00:00Z",
"type": "returned",
"line_items": [{ "id": "line_3", "quantity": 1 }],
"tracking_number": "987654321",
"tracking_url": "https://fedex.com/track/987654321",
"carrier": "FedEx",
"description": "Item returned"
}
],
"expectations": [{ "...": "..." }]
},
"adjustments": [
{
"id": "adj_return_1",
"type": "return", // a matching fulfillment event is also added to represent return shipping.
"description": "Item not compatible",
"line_items": [{ "id": "line_3", "quantity": -1 }], // Uses a negative value (such as -1) to indicate a return.
"occurred_at": "2026-02-09T09:00:00Z",
"status": "completed"
},
{
"id": "adj_refund_2",
"type": "refund",
"description": "Refund for returned item",
"line_items": [{ "id": "line_3", "quantity": -1 }],
"totals": [
{"type": "subtotal", "amount": -14900}, // Negative amounts indicate money returned to the buyer.
{"type": "tax", "amount": -1200},
{"type": "total", "amount": -16100}
],
"occurred_at": "2026-02-10T10:00:00Z",
"status": "completed"
}
],
"permalink_url": "https://merchant.example.com/orders/67890"
}