इस गाइड में, Universal Commerce Protocol (UCP) के वर्शन 2026-04-08 के लिए, वेबहुक का इस्तेमाल करके, Google को ऑर्डर के स्टेटस से जुड़े पूरे अपडेट, फ़ुलफ़िलमेंट इवेंट, और अडजस्टमेंट भेजने के लिए, एपीआई का तकनीकी रेफ़रंस और पेलोड स्कीमा दिए गए हैं.
एंडपॉइंट बनाने से पहले, पक्का करें कि आपने ऑर्डर के लाइफ़साइकल की खास जानकारी देखी हो. इसमें, ज़रूरी इवेंट, वेबहुक एंडपॉइंट की जानकारी, और बड़े लेवल के कॉन्सेप्ट शामिल हैं.
अनुमति और अनुरोध पर साइन करना
वर्शन 2026-04-08 में किए गए अहम बदलावों में, नए ज़रूरी वेबहुक हेडर और अनुरोध पर साइन करने की खास प्रोसेस शामिल हैं.
ज़रूरी वेबहुक हेडर
सभी वेबहुक अनुरोधों के लिए, ये एचटीटीपी हेडर ज़रूरी हैं:
Webhook-Id: यह खास वेबहुक इवेंट के लिए यूनीक आइडेंटिफ़ायर है. यह आईडी, भेजे जा रहे मुख्य इवेंट केidसे मैच होना चाहिए. उदाहरण के लिए, फ़ुलफ़िलमेंट इवेंट आईडी या अडजस्टमेंट इवेंट आईडी.Webhook-Timestamp: यह टाइमस्टैंप, इवेंट होने का समय दिखाता है.
ये हेडर, ऑर्डर के पेलोड में पहले से मौजूद id और created_time फ़ील्ड की जगह इस्तेमाल किए जाते हैं.
अनुरोध पर साइन करना
- अनुरोध के रॉ बॉडी का SHA-256 डाइजेस्ट कैलकुलेट करें और
Content-Digestहेडर सेट करें. - अपनी यूसीपी प्रोफ़ाइल में मौजूद
signing_keysसे, साइनिंग की चुनें. - RFC 9421 के मुताबिक, सिग्नेचर बेस बनाएं.
- साइन किए गए कॉम्पोनेंट के लिए खास जानकारी देखें
UCP-Agent,Signature-Input, औरSignatureहेडर सेट करें.UCP-Agentआपकी यूसीपी प्रोफ़ाइल का लिंक है. यहprofile="https://merchant.example.com/.well-known/ucp"फ़ॉर्मैट में होता है.Signature-Inputएक डिक्शनरी स्ट्रक्चर्ड फ़ील्ड है. इसमें, सिग्नेचर में शामिल कॉम्पोनेंट के साथ-साथ, साइन करने के लिए इस्तेमाल किया गयाkeyidभी शामिल होता है. यह, आपकी यूसीपी प्रोफ़ाइल में मौजूदsigning_keysसे चुनी गई साइनिंग की केkidसे मैच होना चाहिए.Signatureहेडर में आपका सिग्नेचर बेस शामिल होता है. इस पर आपकी निजी की का इस्तेमाल करके साइन किया जाता है. इसके बाद, इसे base64 में एनकोड किया जाता है.
ज़्यादा जानकारी के लिए, साइन करने के निर्देश ucp.dev पर देखें.
ऑर्डर क्रिएट किया गया इवेंट
- ट्रिगर: ऑर्डर की पुष्टि होने के तुरंत बाद (
status: processing).
इस वर्शन में किए गए अहम बदलाव:
- ऑर्डर ऑब्जेक्ट के टॉप लेवल पर,
currencyफ़ील्ड अब ज़रूरी है. totalsकैटगरी में मौजूद हर ऑब्जेक्ट में,typeफ़ील्ड अब एक ओपन स्ट्रिंग है. उदाहरण के लिए, "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से प्रभावित लाइन आइटम अब मुख्यline_itemsकैटगरी में"status": "removed"का इस्तेमाल करते हैं.- जब
line_items.statusकी वैल्यूremovedहोती है, तब:line_items.quantity.totalकी वैल्यू0पर सेट हो जाती है.- ऑरिजनल संख्या, नए
line_items.quantity.originalफ़ील्ड में सेव की जाती है.
returnटाइप केadjustmentsमें, अडजस्टमेंट में मौजूद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"
}