سيرشدك هذا الدليل خلال عملية تطوير مشروع المهام. تُدرج معاملات للسلع المادية وتستخدم Google Pay للدفع
تدفق المعاملة
عندما يعالج مشروع "المهام" المعاملات المادية باستخدام Google Pay، التدفق التالي:
- جمع المعلومات (اختياري) - اعتمادًا على طبيعة
فيمكنك جمع المعلومات التالية من المستخدم في البداية
من المحادثة.
- التحقّق من صحة متطلبات المعاملات: استخدِم "مساعد متطلبات المعاملات". في بداية المحادثة للتأكّد من تقديم معلومات الدفع الخاصة بالمستخدم بشكل صحيح وتوفرها قبل أن يقوم المستخدم بإنشاء سلة التسوق الخاصة به.
- طلب عنوان التسليم: إذا كانت المعاملة تتطلّب تسليمًا العنوان، طلب تنفيذ عنوان مساعد عنوان التسليم جمع واحدة من المستخدم.
- إنشاء الطلب - وجِّه المستخدم نحو "تجميع عربة التسوق" حيث يختارون العناصر التي يريدون شراءها.
- اقتراح الطلب - بعد اكتمال سلة التسوّق، يمكنك اقتراح الطلب من أجل المستخدم حتى يتمكنوا من تأكيد صحته. إذا تم تأكيد الطلب، فيجب تتلقّى ردًا يتضمّن تفاصيل الطلب ورمزًا للدفع.
- إنهاء الطلب وإرسال إيصال: بعد تأكيد الطلب، يمكنك تعديل تتبُّع المستودع أو خدمات توصيل الطلبات الأخرى، ثم إرسال إيصال للمستخدم.
- إرسال تعديلات الطلب: طوال فترة توصيل الطلب لتزويد المستخدم بتحديثات الطلب من خلال إرسال طلبات التصحيح إلى واجهة برمجة التطبيقات.
إرشادات المراجعة والقيود
يُرجى العلم أنّ سياسات إضافية تنطبق على "المهام مع مساعد Google". قد تستغرق مراجعة الإجراءات التي تتضمن معاملات ما يصل إلى ستة أسابيع، لذا يجب أخذ هذا الوقت في الاعتبار عند التخطيط للجدول الزمني للإصدار. لتسهيل عملية المراجعة، تأكَّد من الالتزام بالسياسات والإرشادات الخاصة بالمعاملات قبل إرسال الإجراء للمراجعة.
يمكنك تفعيل "المهام" التي تبيع سلعًا مادية في البلدان التالية فقط:
أستراليا البرازيل كندا إندونيسيا |
اليابان المكسيك قطر روسيا |
سنغافورة سويسرا تايلاند تركيا المملكة المتحدة الولايات المتحدة |
إنشاء مشروعك
للحصول على أمثلة شاملة على المحادثات المتعلقة بالمعاملات، يمكنك الاطّلاع على نماذج المعاملات في Node.js وJava.
إعداد المشروع
عند إنشاء الإجراء الخاص بك، يجب تحديد أنّك تريد إجراء المعاملات. في وحدة تحكّم الإجراءات. أيضًا، إذا كنت باستخدام مكتبة برامج Node.JS، يمكنك إعداد التنفيذ لاستخدام أحدث إصدار من Orders API.
لإعداد مشروعك وتنفيذك، قم بما يلي:
- أنشِئ مشروعًا جديدًا أو استورِد مشروعًا حاليًا.
- انتقل إلى نشر > معلومات الدليل:
ضمن معلومات إضافية > المعاملات > حدد المربع الذي يقول "تنفيذ إجراءاتك استخدام واجهة برمجة التطبيقات للمعاملات لإجراء معاملات السلع المادية؟"
إذا كنت تستخدم مكتبة برامج Node.JS لإنشاء عملية تنفيذ الإجراء، افتح رمز توصيل الطلب وعدِّل عملية تغيير التطبيق من أجل ضبط إبلاغ "
ordersv3
" عن "true
" يعرض مقتطف الرمز التالي مثالاً على تطبيق لإصدار الطلبات 3.
Node.js
const {dialogflow} = require('actions-on-google'); let app = dialogflow({ clientId, // If using account linking debug: true, ordersv3: true, });
Node.js
const {actionssdk} = require('actions-on-google'); let app = actionssdk({ clientId, // If using account linking debug: true, ordersv3: true, });
1. جمع المعلومات (اختياري)
1(أ)- التحقّق من صحة متطلبات المعاملة (اختياري)
تجربة المستخدم
عندما يبدي المستخدم رغبته في إجراء عملية شراء، نوصي بتشغيل
actions.intent.TRANSACTION_REQUIREMENTS_CHECK
يهدف إلى التأكد بسرعة من أنه سيتم
قادرًا على إجراء معاملة. على سبيل المثال، عند استدعاء الإجراء، قد يسأل الإجراء التالي:
"هل ترغب في طلب أحذية، أم التحقق من رصيد حسابك؟" إذا قال المستخدم
"طلب أحذية"، يجب طلب هذا الغرض على الفور. سيضمن ذلك
يمكنه المتابعة ومنحه فرصة لتعديل أي إعدادات
تمنعه من مواصلة المعاملة.
طلب المعاملات الرغبة في التحقق من استيفاء المتطلبات إلى أحد النتائج التالية:
- في حال استيفاء المتطلبات، سيتم إرسال الغرض من ذلك إلى طريقة التنفيذ مع تضمين نجاحك ويمكنك متابعة إنشاء طلب المستخدم.
- إذا تعذّر استيفاء شرط واحد أو أكثر من المتطلبات، سيتم إرسال الغرض مرة أخرى.
إلى التنفيذ مع شرط الفشل. في هذه الحالة، يجب عليك محور
الخروج من التجربة المتعلقة بالمعاملات أو إنهاء المحادثة.
- إذا كان بإمكان المستخدم إصلاح أي أخطاء تنتج عن حالة الفشل، سيُطلب منهم حلّ هذه المشاكل على أجهزتهم. إذا كانت المحادثة على سطح الصوت فقط، سيتم بدء التسليم إلى هاتف المستخدم.
توصيل الطلبات
لضمان تلبية المستخدم
متطلبات المعاملات، تطلب تنفيذ
actions.intent.TRANSACTION_REQUIREMENTS_CHECK
هدفًا بضمان
العنصر TransactionRequirementsCheckSpec.
الاطّلاع على المتطلبات
يمكنك التحقّق لمعرفة ما إذا كان المستخدم يستوفي متطلبات المعاملات باستخدام مكتبة العملاء:
Node.js
conv.ask(new TransactionRequirements());
Node.js
conv.ask(new TransactionRequirements());
Java
return getResponseBuilder(request) .add(new TransactionRequirements()) .build();
Java
return getResponseBuilder(request) .add(new TransactionRequirements()) .build();
JSON
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Looks like you're good to go! Next I'll need your delivery address.Try saying \"get delivery address\"." } } ], "suggestions": [ { "title": "get delivery address" } ] } } } }
JSON
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TEXT" } ], "inputPrompt": { "richInitialPrompt": { "items": [ { "simpleResponse": { "textToSpeech": "Looks like you're good to go! Next I'll need your delivery address.Try saying \"get delivery address\"." } } ], "suggestions": [ { "title": "get delivery address" } ] } } } ], "conversationToken": "{\"data\":{\"paymentType\":\"google_payment\"}}" }
استلام نتيجة فحص المتطلبات
بعد أن ينفِّذ "مساعد Google" الغرض، يرسل طلبًا لتنفيذ المهمة.
بهدف actions.intent.TRANSACTION_REQUIREMENTS_CHECK
مع النتيجة
الشيك.
لمعالجة هذا الطلب بشكل صحيح، يجب تعريف الغرض من Dialogflow الذي يتم تشغيله عن طريق
الحدث actions_intent_TRANSACTION_REQUIREMENTS_CHECK
. عند التشغيل،
التعامل معها أثناء التنفيذ باستخدام مكتبة العملاء:
Node.js
app.intent('Transaction Check Complete', (conv) => { const arg = conv.arguments.get('TRANSACTION_REQUIREMENTS_CHECK_RESULT'); if (arg && arg.resultType === 'CAN_TRANSACT') { // Normally take the user through cart building flow conv.ask(`Looks like you're good to go! ` + `Next I'll need your delivery address.` + `Try saying "get delivery address".`); conv.ask(new Suggestions('get delivery address')); } else { // Exit conversation conv.close('Transaction failed.'); } });
Node.js
app.intent('actions.intent.TRANSACTION_REQUIREMENTS_CHECK', (conv) => { const arg = conv.arguments.get('TRANSACTION_REQUIREMENTS_CHECK_RESULT'); if (arg && arg.resultType === 'CAN_TRANSACT') { // Normally take the user through cart building flow conv.ask(`Looks like you're good to go! ` + `Next I'll need your delivery address.` + `Try saying "get delivery address".`); conv.ask(new Suggestions('get delivery address')); } else { // Exit conversation conv.close('Transaction failed.'); } });
Java
@ForIntent("Transaction Check Complete") public ActionResponse transactionCheckComplete(ActionRequest request) { LOGGER.info("Checking Transaction Requirements Result."); // Check result of transaction requirements check Argument transactionCheckResult = request .getArgument("TRANSACTION_REQUIREMENTS_CHECK_RESULT"); boolean result = false; if (transactionCheckResult != null) { Map<String, Object> map = transactionCheckResult.getExtension(); if (map != null) { String resultType = (String) map.get("resultType"); result = resultType != null && resultType.equals("CAN_TRANSACT"); } } ResponseBuilder responseBuilder = getResponseBuilder(request); if (result) { // Normally take the user through cart building flow responseBuilder .add("Looks like you're good to go! Next " + "I'll need your delivery address. Try saying " + "\"get delivery address\".") .addSuggestions(new String[]{"get delivery address"}); } else { // Exit conversation responseBuilder.add("Transaction failed."); } return responseBuilder.build(); }
Java
@ForIntent("actions.intent.TRANSACTION_REQUIREMENTS_CHECK") public ActionResponse transactionCheckComplete(ActionRequest request) { LOGGER.info("Checking Transaction Requirements Result."); // Check result of transaction requirements check Argument transactionCheckResult = request .getArgument("TRANSACTION_REQUIREMENTS_CHECK_RESULT"); boolean result = false; if (transactionCheckResult != null) { Map<String, Object> map = transactionCheckResult.getExtension(); if (map != null) { String resultType = (String) map.get("resultType"); result = resultType != null && resultType.equals("CAN_TRANSACT"); } } ResponseBuilder responseBuilder = getResponseBuilder(request); if (result) { // Normally take the user through cart building flow responseBuilder .add("Looks like you're good to go! Next " + "I'll need your delivery address. Try saying " + "\"get delivery address\".") .addSuggestions(new String[]{"get delivery address"}); } else { // Exit conversation responseBuilder.add("Transaction failed."); } return responseBuilder.build(); }
JSON
{ "responseId": "db1a333c-2781-41e3-84b1-cc0cc37643d7-594de0a7", "queryResult": { "queryText": "actions_intent_TRANSACTION_REQUIREMENTS_CHECK", "action": "transaction.check.complete", "parameters": {}, "allRequiredParamsPresent": true, "fulfillmentText": "Failed to get transaction check results", "fulfillmentMessages": [ { "text": { "text": [ "Failed to get transaction check results" ] } } ], "outputContexts": [ { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/google_assistant_input_type_keyboard" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/merchant_payment", "lifespanCount": 1 }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_transaction_requirements_check", "parameters": { "TRANSACTION_REQUIREMENTS_CHECK_RESULT": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult", "resultType": "CAN_TRANSACT" }, "text": "" } } ], "intent": { "name": "projects/df-transactions/agent/intents/fd16d86b-60db-4d19-a683-5b52a22f4795", "displayName": "Transaction Check Complete" }, "intentDetectionConfidence": 1, "languageCode": "en" }, "originalDetectIntentRequest": { "source": "google", "version": "2", "payload": { "user": { "locale": "en-US", "lastSeen": "2019-09-23T19:49:32Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy", "type": "ACTIVE", "conversationToken": "[\"merchant_payment\"]" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK", "rawInputs": [ { "inputType": "KEYBOARD" } ], "arguments": [ { "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT", "extension": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult", "resultType": "CAN_TRANSACT" } }, { "name": "text" } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.ACCOUNT_LINKING" }, { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.SCREEN_OUTPUT" } ] } ] } }, "session": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" }
JSON
{ "user": { "locale": "en-US", "lastSeen": "2019-11-11T23:56:03Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw", "type": "ACTIVE", "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\"}}" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK", "rawInputs": [ {} ], "arguments": [ { "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT", "extension": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckResult", "resultType": "CAN_TRANSACT" } }, { "name": "text" } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.ACCOUNT_LINKING" }, { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.WEB_BROWSER" } ] } ] }
1(ب)- طلب عنوان التسليم (اختياري)
إذا كانت معاملتك تتطلب عنوان تسليم خاص بالمستخدم، يمكنك طلب
تنفيذ هدف actions.intent.DELIVERY_ADDRESS
. قد يكون هذا
مفيدة لتحديد السعر الإجمالي، أو موقع التسليم/الاستلام، أو
التأكد من أنّ المستخدم ضمن منطقة نطاق خدمتك
عند طلب تحقيق هذا الهدف، تسمح بخيار reason
تتيح لك تقديم طلب المساعد للحصول على عنوان بسلسلة.
على سبيل المثال، إذا حددت "معرفة مكان إرسال الطلب"، فسيبدأ "مساعد Google"
المستخدم:
"لمعرفة مكان إرسال الطلب، سأحتاج إلى الحصول على عنوان التسليم"
تجربة المستخدم
على مساحات العرض التي تحتوي على شاشة، سيختار المستخدم العنوان الذي يريد استخدامه. مقابل المعاملة. وإذا لم يسبق له تقديم عنوان، فسيتم تتمكن من إدخال عنوان جديد.
على مساحات العرض الصوتية فقط، سيطلب "مساعد Google" من المستخدم الإذن لمشاركة المحتوى. عنوانه الافتراضي للمعاملة. إذا لم يسبق له تقديم ، سيتم تسليم المحادثة إلى الهاتف للدخول.
طلب العنوان
Node.js
app.intent('Delivery Address', (conv) => { conv.ask(new DeliveryAddress({ addressOptions: { reason: 'To know where to send the order', }, })); });
Node.js
conv.ask(new DeliveryAddress({ addressOptions: { reason: 'To know where to send the order', }, }));
Java
@ForIntent("Delivery Address") public ActionResponse deliveryAddress(ActionRequest request) { DeliveryAddressValueSpecAddressOptions addressOptions = new DeliveryAddressValueSpecAddressOptions() .setReason("To know where to send the order"); return getResponseBuilder(request) .add(new DeliveryAddress() .setAddressOptions(addressOptions)) .build(); }
Java
DeliveryAddressValueSpecAddressOptions addressOptions = new DeliveryAddressValueSpecAddressOptions() .setReason("To know where to send the order"); return getResponseBuilder(request) .add(new DeliveryAddress() .setAddressOptions(addressOptions)) .build();
JSON
{ "payload": { "google": { "expectUserResponse": true, "systemIntent": { "intent": "actions.intent.DELIVERY_ADDRESS", "data": { "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValueSpec", "addressOptions": { "reason": "To know where to send the order" } } } } } }
JSON
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.DELIVERY_ADDRESS", "inputValueData": { "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValueSpec", "addressOptions": { "reason": "To know where to send the order" } } } ] } ], "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\"}}" }
استلام العنوان
بعد أن ينفِّذ "مساعد Google" الغرض، يرسل طلبًا لتنفيذ المهمة.
بهدف actions.intent.DELIVERY_ADDRESS
.
لمعالجة هذا الطلب بشكل صحيح، يجب تعريف الغرض من Dialogflow الذي يتم تشغيله عن طريق
الحدث actions_intent_DELIVERY_ADDRESS
. عند التشغيل، تعامل مع
التنفيذ باستخدام مكتبة العملاء:
Node.js
app.intent('Delivery Address Complete', (conv) => { const arg = conv.arguments.get('DELIVERY_ADDRESS_VALUE'); if (arg && arg.userDecision ==='ACCEPTED') { conv.data.location = arg.location; conv.ask('Great, got your address! Now say "confirm transaction".'); conv.ask(new Suggestions('confirm transaction')); } else { conv.close('Transaction failed.'); } });
Node.js
app.intent('actions.intent.DELIVERY_ADDRESS', (conv) => { const arg = conv.arguments.get('DELIVERY_ADDRESS_VALUE'); if (arg && arg.userDecision ==='ACCEPTED') { conv.data.location = arg.location; conv.ask('Great, got your address! Now say "confirm transaction".'); conv.ask(new Suggestions('confirm transaction')); } else { conv.close('Transaction failed.'); } });
Java
@ForIntent("Delivery Address Complete") public ActionResponse deliveryAddressComplete(ActionRequest request) { Argument deliveryAddressValue = request.getArgument("DELIVERY_ADDRESS_VALUE"); Location deliveryAddress = null; if (deliveryAddressValue != null) { Map<String, Object> map = deliveryAddressValue.getExtension(); if (map != null) { String userDecision = (String) map.get("userDecision"); Location location = (Location) map.get("location"); deliveryAddress = userDecision != null && userDecision.equals("ACCEPTED") ? location : null; } } ResponseBuilder responseBuilder = getResponseBuilder(request); if (deliveryAddress != null) { // Cache delivery address in conversation data for later use Map<String, Object> conversationData = request.getConversationData(); conversationData.put("location", GSON_BUILDER.create().toJson(deliveryAddress, Location.class)); responseBuilder .add("Great, got your address! Now say \"confirm transaction\".") .addSuggestions(new String[] { "confirm transaction" }); } else { responseBuilder.add("Transaction failed.").endConversation(); } return responseBuilder.build(); }
Java
@ForIntent("actions.intent.DELIVERY_ADDRESS") public ActionResponse deliveryAddressComplete(ActionRequest request) { Argument deliveryAddressValue = request.getArgument("DELIVERY_ADDRESS_VALUE"); Location deliveryAddress = null; if (deliveryAddressValue != null) { Map<String, Object> map = deliveryAddressValue.getExtension(); if (map != null) { String userDecision = (String) map.get("userDecision"); Location location = (Location) map.get("location"); deliveryAddress = userDecision != null && userDecision.equals("ACCEPTED") ? location : null; } } ResponseBuilder responseBuilder = getResponseBuilder(request); if (deliveryAddress != null) { // Cache delivery address in conversation data for later use Map<String, Object> conversationData = request.getConversationData(); conversationData.put("location", GSON_BUILDER.create().toJson(deliveryAddress, Location.class)); responseBuilder .add("Great, got your address! Now say \"confirm transaction\".") .addSuggestions(new String[] { "confirm transaction" }); } else { responseBuilder.add("Transaction failed.").endConversation(); } return responseBuilder.build(); }
JSON
{ "responseId": "58b0c305-b437-47ac-8593-4fb0122a19e6-594de0a7", "queryResult": { "queryText": "actions_intent_DELIVERY_ADDRESS", "parameters": {}, "allRequiredParamsPresent": true, "fulfillmentMessages": [ { "text": { "text": [ "" ] } } ], "outputContexts": [ { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_delivery_address", "parameters": { "DELIVERY_ADDRESS_VALUE": { "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValue", "userDecision": "ACCEPTED", "location": { "coordinates": { "latitude": 37.432524, "longitude": -122.098545 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" } }, "text": "1600 AMPHITHEATRE PKWY" } } ], "intent": { "name": "projects/df-transactions/agent/intents/0be5d130-1760-4355-85e9-4dc01da8bf3c", "displayName": "Delivery Address Complete" }, "intentDetectionConfidence": 1, "languageCode": "en" }, "originalDetectIntentRequest": { "source": "google", "version": "2", "payload": { "user": { "locale": "en-US", "lastSeen": "2019-09-23T19:49:55Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy", "type": "ACTIVE", "conversationToken": "[]" }, "inputs": [ { "intent": "actions.intent.DELIVERY_ADDRESS", "rawInputs": [ { "query": "1600 AMPHITHEATRE PKWY" } ], "arguments": [ { "name": "DELIVERY_ADDRESS_VALUE", "extension": { "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValue", "userDecision": "ACCEPTED", "location": { "coordinates": { "latitude": 37.432524, "longitude": -122.098545 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" } } } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.ACCOUNT_LINKING" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.AUDIO_OUTPUT" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.SCREEN_OUTPUT" } ] } ] } }, "session": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" }
JSON
{ "user": { "locale": "en-US", "lastSeen": "2019-11-11T23:57:20Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw", "type": "ACTIVE", "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\"}}" }, "inputs": [ { "intent": "actions.intent.DELIVERY_ADDRESS", "rawInputs": [ { "inputType": "VOICE", "query": "1600 AMPHITHEATRE PKWY" } ], "arguments": [ { "name": "DELIVERY_ADDRESS_VALUE", "extension": { "@type": "type.googleapis.com/google.actions.v2.DeliveryAddressValue", "userDecision": "ACCEPTED", "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" } } }, { "name": "text", "rawText": "1600 AMPHITHEATRE PKWY", "textValue": "1600 AMPHITHEATRE PKWY" } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.ACCOUNT_LINKING" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.SCREEN_OUTPUT" } ] } ] }
2. إنشاء الطلب
تجربة المستخدم
بمجرد حصولك على معلومات المستخدم التي تحتاجها، يمكنك إنشاء "عربة التسوق" لتجميع" الخبرة التي توجه المستخدم لإنشاء طلب. سيؤدي كل إجراء إلى يكون لها تدفق تجميع عربة مختلف قليلاً حسبما يتناسب منتجك أو خدمتك.
تتضمن التجربة الأساسية لتجميع سلة التسوق إمكانية اختيار المستخدم لعناصر من قائمة لإضافتها بترتيبها، إلا أنه يمكنك تصميم المحادثة لتبسيط تجربة المستخدم. يمكنك إنشاء تجربة تجميع عربة التسوق التي تمكن إعادة طلب آخر عملية شراء عن طريق سؤال بسيط يكون الإجابة بنعم أو لا. يمكنك أيضًا تقديم لوحة عرض دوّارة أو بطاقة قائمة بأهم العناصر "المميزة" للمستخدم. أو "مقترَح" عناصر.
نقترح استخدام عبارات تتضمن الردود لعرض خيارات المستخدم بصريًا، ولكن أيضًا تصميم المحادثة بحيث يمكن للمستخدم بناء عربة التسوق باستخدام صوته فقط. للحصول على بعض أفضل الممارسات والأمثلة على عالية الجودة لتجميع عربة التسوق، راجع إرشادات تصميم المعاملات:
توصيل الطلبات
خلال محادثتك، ستحتاج إلى جمع العناصر التي يريدها المستخدم
لشرائه، ثم إنشاء عنصر Order
.
على الأقل، يجب أن يحتوي Order
على ما يلي:
buyerInfo
: معلومات حول المستخدم الذي يُجري عملية الشراءtransactionMerchant
- معلومات حول التاجر الذي سهّل طلبك.contents
: المحتوى الفعلي للطلب المدرَج على أنّهlineItems
priceAttributes
- تفاصيل سعر الطلب، بما في ذلك إجمالي المبلغ تكلفة الطلب مع الخصومات والضرائب.
راجِع مستندات الرد Order
.
لإنشاء عربة التسوق الخاصة بك. يُرجى العِلم أنّك قد تحتاج إلى تضمين حقول مختلفة.
اعتمادًا على الطلب.
يوضح الرمز النموذجي أدناه طلبًا كاملاً، بما في ذلك الحقول الاختيارية:
Node.js
const order = { createTime: '2019-09-24T18:00:00.877Z', lastUpdateTime: '2019-09-24T18:00:00.877Z', merchantOrderId: orderId, // A unique ID String for the order userVisibleOrderId: orderId, transactionMerchant: { id: 'http://www.example.com', name: 'Example Merchant', }, contents: { lineItems: [ { id: 'LINE_ITEM_ID', name: 'Pizza', description: 'A four cheese pizza.', priceAttributes: [ { type: 'REGULAR', name: 'Item Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 8990000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 9990000, }, taxIncluded: true, }, ], notes: [ 'Extra cheese.', ], purchase: { quantity: 1, unitMeasure: { measure: 1, unit: 'POUND', }, itemOptions: [ { id: 'ITEM_OPTION_ID', name: 'Pepperoni', prices: [ { type: 'REGULAR', state: 'ACTUAL', name: 'Item Price', amount: { currencyCode: 'USD', amountInMicros: 1000000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 1000000, }, taxIncluded: true, }, ], note: 'Extra pepperoni', quantity: 1, subOptions: [], }, ], }, }, ], }, buyerInfo: { email: 'janedoe@gmail.com', firstName: 'Jane', lastName: 'Doe', displayName: 'Jane Doe', }, priceAttributes: [ { type: 'SUBTOTAL', name: 'Subtotal', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 9990000, }, taxIncluded: true, }, { type: 'DELIVERY', name: 'Delivery', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 2000000, }, taxIncluded: true, }, { type: 'TAX', name: 'Tax', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 3780000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 15770000, }, taxIncluded: true, }, ], followUpActions: [ { type: 'VIEW_DETAILS', title: 'View details', openUrlAction: { url: 'http://example.com', }, }, { type: 'CALL', title: 'Call us', openUrlAction: { url: 'tel:+16501112222', }, }, { type: 'EMAIL', title: 'Email us', openUrlAction: { url: 'mailto:person@example.com', }, }, ], termsOfServiceUrl: 'http://www.example.com', note: 'Sale event', promotions: [ { coupon: 'COUPON_CODE', }, ], purchase: { status: 'CREATED', userVisibleStatusLabel: 'CREATED', type: 'FOOD', returnsInfo: { isReturnable: false, daysToReturn: 1, policyUrl: 'http://www.example.com', }, fulfillmentInfo: { id: 'FULFILLMENT_SERVICE_ID', fulfillmentType: 'DELIVERY', expectedFulfillmentTime: { timeIso8601: '2019-09-25T18:00:00.877Z', }, location: location, price: { type: 'REGULAR', name: 'Delivery Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 2000000, }, taxIncluded: true, }, fulfillmentContact: { email: 'johnjohnson@gmail.com', firstName: 'John', lastName: 'Johnson', displayName: 'John Johnson', }, }, purchaseLocationType: 'ONLINE_PURCHASE', }, };
Node.js
const order = { createTime: '2019-09-24T18:00:00.877Z', lastUpdateTime: '2019-09-24T18:00:00.877Z', merchantOrderId: orderId, // A unique ID String for the order userVisibleOrderId: orderId, transactionMerchant: { id: 'http://www.example.com', name: 'Example Merchant', }, contents: { lineItems: [ { id: 'LINE_ITEM_ID', name: 'Pizza', description: 'A four cheese pizza.', priceAttributes: [ { type: 'REGULAR', name: 'Item Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 8990000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 9990000, }, taxIncluded: true, }, ], notes: [ 'Extra cheese.', ], purchase: { quantity: 1, unitMeasure: { measure: 1, unit: 'POUND', }, itemOptions: [ { id: 'ITEM_OPTION_ID', name: 'Pepperoni', prices: [ { type: 'REGULAR', state: 'ACTUAL', name: 'Item Price', amount: { currencyCode: 'USD', amountInMicros: 1000000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 1000000, }, taxIncluded: true, }, ], note: 'Extra pepperoni', quantity: 1, subOptions: [], }, ], }, }, ], }, buyerInfo: { email: 'janedoe@gmail.com', firstName: 'Jane', lastName: 'Doe', displayName: 'Jane Doe', }, priceAttributes: [ { type: 'SUBTOTAL', name: 'Subtotal', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 9990000, }, taxIncluded: true, }, { type: 'DELIVERY', name: 'Delivery', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 2000000, }, taxIncluded: true, }, { type: 'TAX', name: 'Tax', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 3780000, }, taxIncluded: true, }, { type: 'TOTAL', name: 'Total Price', state: 'ESTIMATE', amount: { currencyCode: 'USD', amountInMicros: 15770000, }, taxIncluded: true, }, ], followUpActions: [ { type: 'VIEW_DETAILS', title: 'View details', openUrlAction: { url: 'http://example.com', }, }, { type: 'CALL', title: 'Call us', openUrlAction: { url: 'tel:+16501112222', }, }, { type: 'EMAIL', title: 'Email us', openUrlAction: { url: 'mailto:person@example.com', }, }, ], termsOfServiceUrl: 'http://www.example.com', note: 'Sale event', promotions: [ { coupon: 'COUPON_CODE', }, ], purchase: { status: 'CREATED', userVisibleStatusLabel: 'CREATED', type: 'FOOD', returnsInfo: { isReturnable: false, daysToReturn: 1, policyUrl: 'http://www.example.com', }, fulfillmentInfo: { id: 'FULFILLMENT_SERVICE_ID', fulfillmentType: 'DELIVERY', expectedFulfillmentTime: { timeIso8601: '2019-09-25T18:00:00.877Z', }, location: location, price: { type: 'REGULAR', name: 'Delivery Price', state: 'ACTUAL', amount: { currencyCode: 'USD', amountInMicros: 2000000, }, taxIncluded: true, }, fulfillmentContact: { email: 'johnjohnson@gmail.com', firstName: 'John', lastName: 'Johnson', displayName: 'John Johnson', }, }, purchaseLocationType: 'ONLINE_PURCHASE', }, };
Java
// Transaction Merchant MerchantV3 transactionMerchant = new MerchantV3() .setId("http://www.example.com") .setName("Example Merchant"); // Line Item PriceAttribute itemPrice = new PriceAttribute() .setType("REGULAR") .setName("Item Price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(8990000L) ) .setTaxIncluded(true); PriceAttribute totalItemPrice = new PriceAttribute() .setType("TOTAL") .setName("Total Price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(9990000L) ) .setTaxIncluded(true); // Purchase Item Extension PurchaseItemExtension purchaseItemExtension = new PurchaseItemExtension() .setQuantity(1) .setUnitMeasure(new MerchantUnitMeasure() .setMeasure(1.0) .setUnit("POUND")) .setItemOptions(Arrays.asList(new PurchaseItemExtensionItemOption() .setId("ITEM_OPTION_ID") .setName("Pepperoni") .setPrices(Arrays.asList( new PriceAttribute() .setType("REGULAR") .setState("ACTUAL") .setName("Item Price") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(1000000L)) .setTaxIncluded(true), new PriceAttribute() .setType("TOTAL") .setState("ACTUAL") .setName("Total Price") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(1000000L)) .setTaxIncluded(true) )) .setNote("Extra pepperoni") .setQuantity(1))); LineItemV3 lineItem = new LineItemV3() .setId("LINE_ITEM_ID") .setName("Pizza") .setDescription("A four cheese pizza.") .setPriceAttributes(Arrays.asList(itemPrice, totalItemPrice)) .setNotes(Collections.singletonList("Extra cheese.")) .setPurchase(purchaseItemExtension); // Order Contents OrderContents contents = new OrderContents() .setLineItems(Collections.singletonList(lineItem)); // User Info UserInfo buyerInfo = new UserInfo() .setEmail("janedoe@gmail.com") .setFirstName("Jane") .setLastName("Doe") .setDisplayName("Jane Doe"); // Price Attributes PriceAttribute subTotal = new PriceAttribute() .setType("SUBTOTAL") .setName("Subtotal") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(9990000L) ) .setTaxIncluded(true); PriceAttribute deliveryFee = new PriceAttribute() .setType("DELIVERY") .setName("Delivery") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(2000000L) ) .setTaxIncluded(true); PriceAttribute tax = new PriceAttribute() .setType("TAX") .setName("Tax") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(3780000L) ) .setTaxIncluded(true); PriceAttribute totalPrice = new PriceAttribute() .setType("TOTAL") .setName("Total Price") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(15770000L) ) .setTaxIncluded(true); // Follow up actions Action viewDetails = new Action() .setType("VIEW_DETAILS") .setTitle("View details") .setOpenUrlAction(new OpenUrlAction() .setUrl("https://example.com")); Action call = new Action() .setType("CALL") .setTitle("Call us") .setOpenUrlAction(new OpenUrlAction() .setUrl("tel:+16501112222")); Action email = new Action() .setType("EMAIL") .setTitle("Email us") .setOpenUrlAction(new OpenUrlAction() .setUrl("mailto:person@example.com")); // Terms of service and order note String termsOfServiceUrl = "http://example.com"; String orderNote = "Sale event"; // Promotions PromotionV3 promotion = new PromotionV3() .setCoupon("COUPON_CODE"); // Purchase Order Extension Location location = GSON_BUILDER.create().fromJson( (String) conversationData.get("location"), Location.class); PurchaseOrderExtension purchaseOrderExtension = new PurchaseOrderExtension() .setStatus("CREATED") .setUserVisibleStatusLabel("CREATED") .setType("FOOD") .setReturnsInfo(new PurchaseReturnsInfo() .setIsReturnable(false) .setDaysToReturn(1) .setPolicyUrl("https://example.com")) .setFulfillmentInfo(new PurchaseFulfillmentInfo() .setId("FULFILLMENT_SERVICE_ID") .setFulfillmentType("DELIVERY") .setExpectedFulfillmentTime(new TimeV3() .setTimeIso8601("2019-09-25T18:00:00.877Z")) .setLocation(location) .setPrice(new PriceAttribute() .setType("REGULAR") .setName("Delivery price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(2000000L)) .setTaxIncluded(true)) .setFulfillmentContact(new UserInfo() .setEmail("johnjohnson@gmail.com") .setFirstName("John") .setLastName("Johnson") .setDisplayName("John Johnson"))) .setPurchaseLocationType("ONLINE_PURCHASE"); OrderV3 order = new OrderV3() .setCreateTime("2019-09-24T18:00:00.877Z") .setLastUpdateTime("2019-09-24T18:00:00.877Z") .setMerchantOrderId(orderId) .setUserVisibleOrderId(orderId) .setTransactionMerchant(transactionMerchant) .setContents(contents) .setBuyerInfo(buyerInfo) .setPriceAttributes(Arrays.asList( subTotal, deliveryFee, tax, totalPrice )) .setFollowUpActions(Arrays.asList( viewDetails, call, email )) .setTermsOfServiceUrl(termsOfServiceUrl) .setNote(orderNote) .setPromotions(Collections.singletonList(promotion)) .setPurchase(purchaseOrderExtension);
Java
// Transaction Merchant MerchantV3 transactionMerchant = new MerchantV3() .setId("http://www.example.com") .setName("Example Merchant"); // Line Item PriceAttribute itemPrice = new PriceAttribute() .setType("REGULAR") .setName("Item Price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(8990000L) ) .setTaxIncluded(true); PriceAttribute totalItemPrice = new PriceAttribute() .setType("TOTAL") .setName("Total Price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(9990000L) ) .setTaxIncluded(true); // Purchase Item Extension PurchaseItemExtension purchaseItemExtension = new PurchaseItemExtension() .setUnitMeasure(new MerchantUnitMeasure() .setMeasure(1.0) .setUnit("POUND")) .setItemOptions(Arrays.asList(new PurchaseItemExtensionItemOption() .setId("ITEM_OPTION_ID") .setName("Pepperoni") .setPrices(Arrays.asList( new PriceAttribute() .setType("REGULAR") .setState("ACTUAL") .setName("Item Price") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(1000000L)) .setTaxIncluded(true), new PriceAttribute() .setType("TOTAL") .setState("ACTUAL") .setName("Total Price") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(1000000L)) .setTaxIncluded(true) )) .setNote("Extra pepperoni"))); LineItemV3 lineItem = new LineItemV3() .setId("LINE_ITEM_ID") .setName("Pizza") .setDescription("A four cheese pizza.") .setPriceAttributes(Arrays.asList(itemPrice, totalItemPrice)) .setNotes(Collections.singletonList("Extra cheese.")) .setPurchase(purchaseItemExtension); // Order Contents OrderContents contents = new OrderContents() .setLineItems(Collections.singletonList(lineItem)); // User Info UserInfo buyerInfo = new UserInfo() .setEmail("janedoe@gmail.com") .setFirstName("Jane") .setLastName("Doe") .setDisplayName("Jane Doe"); // Price Attributes PriceAttribute subTotal = new PriceAttribute() .setType("SUBTOTAL") .setName("Subtotal") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(9990000L) ) .setTaxIncluded(true); PriceAttribute deliveryFee = new PriceAttribute() .setType("DELIVERY") .setName("Delivery") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(2000000L) ) .setTaxIncluded(true); PriceAttribute tax = new PriceAttribute() .setType("TAX") .setName("Tax") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(3780000L) ) .setTaxIncluded(true); PriceAttribute totalPrice = new PriceAttribute() .setType("TOTAL") .setName("Total Price") .setState("ESTIMATE") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(15770000L) ) .setTaxIncluded(true); // Follow up actions Action viewDetails = new Action() .setType("VIEW_DETAILS") .setTitle("View details") .setOpenUrlAction(new OpenUrlAction() .setUrl("https://example.com")); Action call = new Action() .setType("CALL") .setTitle("Call us") .setOpenUrlAction(new OpenUrlAction() .setUrl("tel:+16501112222")); Action email = new Action() .setType("EMAIL") .setTitle("Email us") .setOpenUrlAction(new OpenUrlAction() .setUrl("mailto:person@example.com")); // Terms of service and order note String termsOfServiceUrl = "http://example.com"; String orderNote = "Sale event"; // Promotions PromotionV3 promotion = new PromotionV3() .setCoupon("COUPON_CODE"); // Purchase Order Extension Location location = GSON_BUILDER.create().fromJson( (String) conversationData.get("location"), Location.class); PurchaseOrderExtension purchaseOrderExtension = new PurchaseOrderExtension() .setStatus("CREATED") .setUserVisibleStatusLabel("CREATED") .setType("FOOD") .setReturnsInfo(new PurchaseReturnsInfo() .setIsReturnable(false) .setDaysToReturn(1) .setPolicyUrl("https://example.com")) .setFulfillmentInfo(new PurchaseFulfillmentInfo() .setId("FULFILLMENT_SERVICE_ID") .setFulfillmentType("DELIVERY") .setExpectedFulfillmentTime(new TimeV3() .setTimeIso8601("2019-09-25T18:00:00.877Z")) .setLocation(location) .setPrice(new PriceAttribute() .setType("REGULAR") .setName("Delivery price") .setState("ACTUAL") .setAmount(new MoneyV3() .setCurrencyCode("USD") .setAmountInMicros(2000000L)) .setTaxIncluded(true)) .setFulfillmentContact(new UserInfo() .setEmail("johnjohnson@gmail.com") .setFirstName("John") .setLastName("Johnson") .setDisplayName("John Johnson"))) .setPurchaseLocationType("ONLINE_PURCHASE"); OrderV3 order = new OrderV3() .setCreateTime("2019-09-24T18:00:00.877Z") .setLastUpdateTime("2019-09-24T18:00:00.877Z") .setMerchantOrderId(orderId) .setUserVisibleOrderId(orderId) .setTransactionMerchant(transactionMerchant) .setContents(contents) .setBuyerInfo(buyerInfo) .setPriceAttributes(Arrays.asList( subTotal, deliveryFee, tax, totalPrice )) .setFollowUpActions(Arrays.asList( viewDetails, call, email )) .setTermsOfServiceUrl(termsOfServiceUrl) .setNote(orderNote) .setPromotions(Collections.singletonList(promotion)) .setPurchase(purchaseOrderExtension);
3- اقتراح الطلب
بمجرد إنشاء طلب، يجب عليك تقديمه إلى المستخدم لتأكيد أو
الرفض. طلب actions.intent.TRANSACTION_DECISION
وقدم الطلب الذي أنشأته.
انطباع المستخدم
عند طلب intent لـ actions.intent.TRANSACTION_DECISION
، يستخدم "مساعد Google"
تبدأ تجربة مدمجة يكون فيها Order
الذي نجحت في تجاوزه
مباشرةً في "بطاقة معاينة سلة التسوق". يمكن للمستخدم قول "تقديم الطلب"،
رفض المعاملة أو تغيير خيار الدفع مثل بطاقة الائتمان أو
أو طلب تغيير محتوى الطلب.
يمكن للمستخدم أيضًا طلب إجراء تغييرات على الطلب في هذه المرحلة. وفي هذه الحالة، يجب أن تتأكّد من أنّ خدمة توصيل الطلبات قادرة على التعامل مع طلبات تغيير الطلب بعد الانتهاء من تجربة تجميع عربة التسوق.
توصيل الطلبات
عند طلب
actions.intent.TRANSACTION_DECISION
هدفًا: عليك إنشاء
TransactionDecision
الذي يحتوي على Order
فضلاً عن orderOptions
وpaymentParameters
.
سيحتوي عنصر paymentParameters
على مَعلمات للترميز تتغيّر.
بناءً على معالج Google Pay الذي تنوي استخدامه (مثل Stripe
Braintree وACI وغيرها).
يعرض الرمز التالي مثالاً على TransactionsDecision
لأحد الطلبات:
Node.js
conv.ask(new TransactionDecision({ orderOptions: { userInfoOptions: { userInfoProperties: [ 'EMAIL', ], }, }, paymentParameters: { googlePaymentOption: { // facilitationSpec is expected to be a serialized JSON string facilitationSpec: JSON.stringify({ apiVersion: 2, apiVersionMinor: 0, merchantInfo: { merchantName: 'Example Merchant', }, allowedPaymentMethods: [ { type: 'CARD', parameters: { allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], allowedCardNetworks: [ 'AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'], }, tokenizationSpecification: { type: 'PAYMENT_GATEWAY', parameters: { gateway: 'example', gatewayMerchantId: 'exampleGatewayMerchantId', }, }, }, ], transactionInfo: { totalPriceStatus: 'FINAL', totalPrice: '15.77', currencyCode: 'USD', }, }), }, }, presentationOptions: { actionDisplayName: 'PLACE_ORDER', }, order: order, }));
Node.js
conv.ask(new TransactionDecision({ orderOptions: { userInfoOptions: { userInfoProperties: [ 'EMAIL', ], }, }, paymentParameters: { googlePaymentOption: { // facilitationSpec is expected to be a serialized JSON string facilitationSpec: JSON.stringify({ apiVersion: 2, apiVersionMinor: 0, merchantInfo: { merchantName: 'Example Merchant', }, allowedPaymentMethods: [ { type: 'CARD', parameters: { allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], allowedCardNetworks: [ 'AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'], }, tokenizationSpecification: { type: 'PAYMENT_GATEWAY', parameters: { gateway: 'example', gatewayMerchantId: 'exampleGatewayMerchantId', }, }, }, ], transactionInfo: { totalPriceStatus: 'FINAL', totalPrice: '15.77', currencyCode: 'USD', }, }), }, }, presentationOptions: { actionDisplayName: 'PLACE_ORDER', }, order: order, }));
Java
// Create order options OrderOptionsV3 orderOptions = new OrderOptionsV3() .setUserInfoOptions(new UserInfoOptions() .setUserInfoProperties(Collections.singletonList("EMAIL"))); // Create presentation options PresentationOptionsV3 presentationOptions = new PresentationOptionsV3() .setActionDisplayName("PLACE_ORDER"); // Create payment parameters JSONObject merchantInfo = new JSONObject(); merchantInfo.put("merchantName", "Example Merchant"); JSONObject facilitationSpec = new JSONObject(); facilitationSpec.put("apiVersion", 2); facilitationSpec.put("apiVersionMinor", 0); facilitationSpec.put("merchantInfo", merchantInfo); JSONObject allowedPaymentMethod = new JSONObject(); allowedPaymentMethod.put("type", "CARD"); JSONArray allowedAuthMethods = new JSONArray(); allowedAuthMethods.addAll(Arrays.asList("PAN_ONLY", "CRYPTOGRAM_3DS")); JSONArray allowedCardNetworks = new JSONArray(); allowedCardNetworks.addAll(Arrays.asList("AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA")); JSONObject allowedPaymentMethodParameters = new JSONObject(); allowedPaymentMethodParameters.put("allowedAuthMethods", allowedAuthMethods); allowedPaymentMethodParameters.put("allowedCardNetworks", allowedCardNetworks); allowedPaymentMethod.put("parameters", allowedPaymentMethodParameters); JSONObject tokenizationSpecificationParameters = new JSONObject(); tokenizationSpecificationParameters.put("gateway", "example"); tokenizationSpecificationParameters.put("gatewayMerchantId", "exampleGatewayMerchantId"); JSONObject tokenizationSpecification = new JSONObject(); tokenizationSpecification.put("type", "PAYMENT_GATEWAY"); tokenizationSpecification.put("parameters", tokenizationSpecificationParameters); allowedPaymentMethod.put("tokenizationSpecification", tokenizationSpecification); JSONArray allowedPaymentMethods = new JSONArray(); allowedPaymentMethods.add(allowedPaymentMethod); facilitationSpec.put("allowedPaymentMethods", allowedPaymentMethods); JSONObject transactionInfo = new JSONObject(); transactionInfo.put("totalPriceStatus", "FINAL"); transactionInfo.put("totalPrice", "15.77"); transactionInfo.put("currencyCode", "USD"); facilitationSpec.put("transactionInfo", transactionInfo); GooglePaymentOption googlePaymentOption = new GooglePaymentOption() .setFacilitationSpec(facilitationSpec.toJSONString()); paymentParameters.setGooglePaymentOption(googlePaymentOption); return getResponseBuilder(request) .add(new TransactionDecision() .setOrder(order) .setOrderOptions(orderOptions) .setPresentationOptions(presentationOptions) .setPaymentParameters(paymentParameters) ) .build();
Java
// Create order options OrderOptionsV3 orderOptions = new OrderOptionsV3() .setUserInfoOptions(new UserInfoOptions() .setUserInfoProperties(Collections.singletonList("EMAIL"))); // Create presentation options PresentationOptionsV3 presentationOptions = new PresentationOptionsV3() .setActionDisplayName("PLACE_ORDER"); // Create payment parameters JSONObject merchantInfo = new JSONObject(); merchantInfo.put("merchantName", "Example Merchant"); JSONObject facilitationSpec = new JSONObject(); facilitationSpec.put("apiVersion", 2); facilitationSpec.put("apiVersionMinor", 0); facilitationSpec.put("merchantInfo", merchantInfo); JSONObject allowedPaymentMethod = new JSONObject(); allowedPaymentMethod.put("type", "CARD"); JSONArray allowedAuthMethods = new JSONArray(); allowedAuthMethods.addAll(Arrays.asList("PAN_ONLY", "CRYPTOGRAM_3DS")); JSONArray allowedCardNetworks = new JSONArray(); allowedCardNetworks.addAll(Arrays.asList("AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA")); JSONObject allowedPaymentMethodParameters = new JSONObject(); allowedPaymentMethodParameters.put("allowedAuthMethods", allowedAuthMethods); allowedPaymentMethodParameters.put("allowedCardNetworks", allowedCardNetworks); allowedPaymentMethod.put("parameters", allowedPaymentMethodParameters); JSONObject tokenizationSpecificationParameters = new JSONObject(); tokenizationSpecificationParameters.put("gateway", "example"); tokenizationSpecificationParameters.put("gatewayMerchantId", "exampleGatewayMerchantId"); JSONObject tokenizationSpecification = new JSONObject(); tokenizationSpecification.put("type", "PAYMENT_GATEWAY"); tokenizationSpecification.put("parameters", tokenizationSpecificationParameters); allowedPaymentMethod.put("tokenizationSpecification", tokenizationSpecification); JSONArray allowedPaymentMethods = new JSONArray(); allowedPaymentMethods.add(allowedPaymentMethod); facilitationSpec.put("allowedPaymentMethods", allowedPaymentMethods); JSONObject transactionInfo = new JSONObject(); transactionInfo.put("totalPriceStatus", "FINAL"); transactionInfo.put("totalPrice", "15.77"); transactionInfo.put("currencyCode", "USD"); facilitationSpec.put("transactionInfo", transactionInfo); GooglePaymentOption googlePaymentOption = new GooglePaymentOption() .setFacilitationSpec(facilitationSpec.toJSONString()); paymentParameters.setGooglePaymentOption(googlePaymentOption); return getResponseBuilder(request) .add(new TransactionDecision() .setOrder(order) .setOrderOptions(orderOptions) .setPresentationOptions(presentationOptions) .setPaymentParameters(paymentParameters) ) .build();
JSON
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction Decision Placeholder." } } ] }, "systemIntent": { "intent": "actions.intent.TRANSACTION_DECISION", "data": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec", "orderOptions": { "userInfoOptions": { "userInfoProperties": [ "EMAIL" ] } }, "paymentParameters": { "merchantPaymentOption": { "defaultMerchantPaymentMethodId": "12345678", "managePaymentMethodUrl": "https://example.com/managePayment", "merchantPaymentMethod": [ { "paymentMethodDisplayInfo": { "paymentMethodDisplayName": "VISA **** 1234", "paymentType": "PAYMENT_CARD" }, "paymentMethodGroup": "Payment method group", "paymentMethodId": "12345678", "paymentMethodStatus": { "status": "STATUS_OK", "statusMessage": "Status message" } } ] } }, "presentationOptions": { "actionDisplayName": "PLACE_ORDER" }, "order": { "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T18:00:00.877Z", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "description": "A four cheese pizza.", "priceAttributes": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 8990000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true } ], "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "unitMeasure": { "measure": 1, "unit": "POUND" }, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "state": "ACTUAL", "name": "Item Price", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1, "subOptions": [] } ] } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 3780000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 15770000 }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "http://www.example.com", "note": "Sale event", "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CREATED", "userVisibleStatusLabel": "CREATED", "type": "FOOD", "returnsInfo": { "isReturnable": false, "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "city": "MOUNTAIN VIEW", "coordinates": { "latitude": 37.432524, "longitude": -122.098545 }, "phoneNumber": "+1 123-456-7890", "postalAddress": { "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "postalCode": "94043-1351", "recipients": [ "John Doe" ], "regionCode": "US" }, "zipCode": "94043-1351" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE" } } } } } }, "outputContexts": [ { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/_actions_on_google", "lifespanCount": 99, "parameters": { "data": "{\"location\":{\"coordinates\":{\"latitude\":37.432524,\"longitude\":-122.098545},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}" } } ] }
JSON
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TRANSACTION_DECISION", "inputValueData": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec", "orderOptions": { "userInfoOptions": { "userInfoProperties": [ "EMAIL" ] } }, "paymentParameters": { "merchantPaymentOption": { "defaultMerchantPaymentMethodId": "12345678", "managePaymentMethodUrl": "https://example.com/managePayment", "merchantPaymentMethod": [ { "paymentMethodDisplayInfo": { "paymentMethodDisplayName": "VISA **** 1234", "paymentType": "PAYMENT_CARD" }, "paymentMethodGroup": "Payment method group", "paymentMethodId": "12345678", "paymentMethodStatus": { "status": "STATUS_OK", "statusMessage": "Status message" } } ] } }, "presentationOptions": { "actionDisplayName": "PLACE_ORDER" }, "order": { "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T18:00:00.877Z", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "description": "A four cheese pizza.", "priceAttributes": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 8990000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true } ], "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "unitMeasure": { "measure": 1, "unit": "POUND" }, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "state": "ACTUAL", "name": "Item Price", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1, "subOptions": [] } ] } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 3780000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 15770000 }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "http://www.example.com", "note": "Sale event", "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CREATED", "userVisibleStatusLabel": "CREATED", "type": "FOOD", "returnsInfo": { "isReturnable": false, "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE" } } } } ], "inputPrompt": { "richInitialPrompt": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction Decision Placeholder." } } ] } } } ], "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" }
سيختلف محتوى عنصر tokenizationSpecification
حسب كل عنصر.
بوابة الدفع يعرض الجدول التالي المَعلمات التي يستخدمها كل مدخل:
"parameters": { "gateway": "example", "gatewayMerchantId": "exampleGatewayMerchantId" }
"parameters": { "gateway": "aciworldwide", "gatewayMerchantId": "YOUR_ENTITY_ID" }
"parameters": { "gateway": "adyen", "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME" }
"parameters": { "gateway": "alfabank", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "bluemedia", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "bluesnap", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "braintree", "braintree:apiVersion": "v1", "braintree:sdkVersion": braintree.client.VERSION, "braintree:merchantId": "YOUR_BRAINTREE_MERCHANT_ID", "braintree:clientKey": "YOUR_BRAINTREE_TOKENIZATION_KEY" }
"parameters": { "gateway": "chase", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ACCOUNT_NUMBER" }
"parameters": { "gateway": "checkoutltd", "gatewayMerchantId": "YOUR_PUBLIC_KEY" }
"parameters": { "gateway": "cloudpayments", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "cybersource", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "datatrans", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "ebanx", "gatewayMerchantId": "YOUR_PUBLIC_INTEGRATION_KEY" }
"parameters": { "gateway": "firstdata", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "globalpayments", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "gopay", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "hitrustpay", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "imsolutions", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "lyra", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "mpgs", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "moneymailru", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "newebpay", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "nexi", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "creditcall", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "paysafe", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "payture", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "payu", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "przelewy24", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "rbkmoney", "gatewayMerchantId": "YOUR_MERCHANT_ID" }
"parameters": { "gateway": "sberbank", "gatewayMerchantId": "YOUR_ORGANIZATION_NAME" }
"parameters": { "gateway": "square", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "stripe", "stripe:version": "2018-10-31", "stripe:publishableKey": "YOUR_PUBLIC_STRIPE_KEY" }
"parameters": { "gateway": "tappay", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "tinkoff", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "uniteller", "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" }
"parameters": { "gateway": "vantiv", "vantiv:merchantPayPageId": "YOUR_PAY_PAGE_ID", "vantiv:merchantOrderId": "YOUR_ORDER_ID", "vantiv:merchantTransactionId": "YOUR_TRANSACTION_ID", "vantiv:merchantReportGroup": "*web" }
"parameters": { "gateway": "worldpay", "gatewayMerchantId": "YOUR_WORLDPAY_MERCHANT_ID" }
"parameters": { "gateway": "yandexcheckout", "gatewayMerchantId": "YOUR_SHOP_ID" }
التعامل مع قرار المستخدم
بعد أن ينفِّذ "مساعد Google" الغرض، يرسل طلبًا لتنفيذ المهمة.
بهدف actions_intent_TRANSACTION_DECISION
الحصول على إجابة من المستخدم عن
لقرار المعاملة. سيصلك
Argument
يحتوي على TransactionDecisionValue. ستحتوي هذه القيمة على ما يلي:
transactionDecision
- قرار المستخدم بشأن المحتوى المقترَح طلبك. القيم المحتملة هيORDER_ACCEPTED
وORDER_REJECTED
وDELIVERY_ADDRESS_UPDATED
وCART_CHANGE_REQUESTED
وUSER_CANNOT_TRANSACT
deliveryAddress
- عنوان تسليم تم تعديله في حال غيَّر المستخدم عنوان التسليم. في هذه الحالة، تشير قيمة سيكونtransactionDecision
DELIVERY_ADDRESS_UPDATED
.
لمعالجة هذا الطلب بشكل صحيح، يجب تعريف الغرض من Dialogflow الذي يتم تشغيله عن طريق
الحدث actions_intent_TRANSACTION_DECISION
. عند التشغيل، تعامل مع
توصيل الطلبات:
Node.js
const arg = conv.arguments.get('TRANSACTION_DECISION_VALUE'); if (arg && arg.transactionDecision === 'ORDER_ACCEPTED') { console.log('Order accepted.'); const order = arg.order; }
Node.js
const arg = conv.arguments.get('TRANSACTION_DECISION_VALUE'); if (arg && arg.transactionDecision === 'ORDER_ACCEPTED') { console.log('Order accepted.'); const order = arg.order; }
Java
// Check transaction decision value Argument transactionDecisionValue = request .getArgument("TRANSACTION_DECISION_VALUE"); Map<String, Object> extension = null; if (transactionDecisionValue != null) { extension = transactionDecisionValue.getExtension(); } String transactionDecision = null; if (extension != null) { transactionDecision = (String) extension.get("transactionDecision"); } ResponseBuilder responseBuilder = getResponseBuilder(request); if ((transactionDecision != null && transactionDecision.equals("ORDER_ACCEPTED"))) { OrderV3 order = ((OrderV3) extension.get("order")); }
Java
// Check transaction decision value Argument transactionDecisionValue = request .getArgument("TRANSACTION_DECISION_VALUE"); Map<String, Object> extension = null; if (transactionDecisionValue != null) { extension = transactionDecisionValue.getExtension(); } String transactionDecision = null; if (extension != null) { transactionDecision = (String) extension.get("transactionDecision"); } ResponseBuilder responseBuilder = getResponseBuilder(request); if ((transactionDecision != null && transactionDecision.equals("ORDER_ACCEPTED"))) { OrderV3 order = ((OrderV3) extension.get("order")); }
JSON
{ "responseId": "aba44717-4236-4602-af55-e5ae1fc2d97a-594de0a7", "queryResult": { "queryText": "actions_intent_TRANSACTION_DECISION", "action": "transaction.decision.complete", "parameters": {}, "allRequiredParamsPresent": true, "fulfillmentText": "Failed to get transaction decision", "fulfillmentMessages": [ { "text": { "text": [ "Failed to get transaction decision" ] } } ], "outputContexts": [ { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_media_response_audio" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_audio_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_account_linking" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_screen_output" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_capability_web_browser" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/google_assistant_input_type_voice" }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/_actions_on_google", "lifespanCount": 97, "parameters": { "data": "{\"location\":{\"coordinates\":{\"latitude\":37.432524,\"longitude\":-122.098545},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"}}" } }, { "name": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy/contexts/actions_intent_transaction_decision", "parameters": { "TRANSACTION_DECISION_VALUE": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue", "transactionDecision": "ORDER_ACCEPTED", "order": { "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T18:00:00.877Z", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "description": "A four cheese pizza.", "priceAttributes": [ { "type": "REGULAR", "name": "Line Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 8990000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true } ], "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "unitMeasure": { "measure": 1, "unit": "POUND" }, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "state": "ACTUAL", "name": "Item Price", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1, "subOptions": [] } ] } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 3780000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 15770000 }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "www.example.com", "note": "Sale event", "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CREATED", "userVisibleStatusLabel": "CREATED", "type": "FOOD", "returnsInfo": { "isReturnable": false, "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": {}, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE" } } }, "text": "" } } ], "intent": { "name": "projects/df-transactions/agent/intents/fd16d86b-60db-4d19-a683-5b52a22f4795", "displayName": "Transaction Decision Complete" }, "intentDetectionConfidence": 1, "languageCode": "en" }, "originalDetectIntentRequest": { "source": "google", "version": "2", "payload": { "user": { "locale": "en-US", "lastSeen": "2019-09-23T19:49:32Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy", "type": "ACTIVE", "conversationToken": "[\"merchant_payment\"]" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "rawInputs": [ { "inputType": "KEYBOARD" } ], "arguments": [ { "name": "TRANSACTION_DECISION_VALUE", "extension": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue", "transactionDecision": "ORDER_ACCEPTED", "order": { "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T19:00:00.877Z", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "description": "A four cheese pizza.", "priceAttributes": [ { "type": "REGULAR", "name": "Line Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 8990000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true } ], "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "unitMeasure": { "measure": 1, "unit": "POUND" }, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "state": "ACTUAL", "name": "Item Price", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 1000000 }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1, "subOptions": [] } ] } } ] }, "buyerInfo": { "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 9990000 }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 3780000 }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": 15770000 }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "www.example.com", "note": "Sale event", "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CREATED", "userVisibleStatusLabel": "CREATED", "type": "FOOD", "returnsInfo": { "isReturnable": false, "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": {}, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": 2000000 }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE" } } } }, { "name": "text" } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.ACCOUNT_LINKING" }, { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.WEB_BROWSER" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.SCREEN_OUTPUT" } ] } ] } }, "session": "projects/df-transactions/agent/sessions/ABwppHGYEP2Fj7tJBxoaKMevL6lZ2rs063lOEWhSW5etZWVOoJe7Dzm_bLejRTYIYXL3D78ER7YvA5aN9Wpy" }
JSON
{ "user": { "locale": "en-US", "lastSeen": "2019-11-11T23:57:31Z", "userVerificationStatus": "VERIFIED" }, "conversation": { "conversationId": "ABwppHGFwStZlYaQ9YT8rg9t_idVsxZrku1pUDrEbGSJmSUMatVdPwPEEQSCe1IwIBoN4sS4Weyn9pmgetEgbsWgw3JSvQmw", "type": "ACTIVE", "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "rawInputs": [ {} ], "arguments": [ { "name": "TRANSACTION_DECISION_VALUE", "extension": { "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue", "transactionDecision": "ORDER_ACCEPTED", "order": { "googleOrderId": "05528125187071048269", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "buyerInfo": { "email": "janedoe@example.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T18:00:00.877Z", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "priceAttributes": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "8990000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "9990000" }, "taxIncluded": true } ], "description": "A four cheese pizza.", "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1 } ], "unitMeasure": { "measure": 1, "unit": "POUND" } }, "vertical": { "@type": "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseItemExtension", "quantity": 1, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1 } ], "unitMeasure": { "measure": 1, "unit": "POUND" } } } ] }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "9990000" }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "3780000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "15770000" }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "http://www.example.com", "note": "Sale event", "paymentData": { "paymentResult": { "merchantPaymentMethodId": "12345678" }, "paymentInfo": { "paymentMethodDisplayInfo": { "paymentType": "PAYMENT_CARD", "paymentMethodDisplayName": "VISA **** 1234" }, "paymentMethodProvenance": "PAYMENT_METHOD_PROVENANCE_MERCHANT" } }, "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CREATED", "type": "FOOD", "returnsInfo": { "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE", "userVisibleStatusLabel": "CREATED" }, "vertical": { "@type": "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseOrderExtension", "status": "CREATED", "type": "FOOD", "returnsInfo": { "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE", "userVisibleStatusLabel": "CREATED" } } } }, { "name": "text" } ] } ], "surface": { "capabilities": [ { "name": "actions.capability.AUDIO_OUTPUT" }, { "name": "actions.capability.MEDIA_RESPONSE_AUDIO" }, { "name": "actions.capability.ACCOUNT_LINKING" }, { "name": "actions.capability.SCREEN_OUTPUT" } ] }, "availableSurfaces": [ { "capabilities": [ { "name": "actions.capability.SCREEN_OUTPUT" }, { "name": "actions.capability.WEB_BROWSER" }, { "name": "actions.capability.AUDIO_OUTPUT" } ] } ] }
4. إكمال الطلب وإرسال إيصال
عندما يعود الغرض من actions.intent.TRANSACTION_DECISION
مع إدخال
transactionDecision
من ORDER_ACCEPTED
، يجب تنفيذ أي خطوة
يجب المعالجة من أجل "التأكيد" بالترتيب (مثل الاحتفاظ به في
قاعدة البيانات الخاصة بك وتحصيل رسوم من المستخدم).
يمكنك إنهاء المحادثة بهذا الردّ، ولكن عليك تضمين ردّ بسيط.
للحفاظ على سير المحادثة. عند تقديم قيمة orderUpdate
الأولية هذه،
سيرى المستخدم "بطاقة إيصال مصغّرة". إلى جانب بقية ردودك.
ستُحاكي هذه البطاقة الإيصال الذي يعثر عليه المستخدم في "سجلّ الطلبات".
أثناء تأكيد الطلب، يمكن أن يشتمل عنصر الطلب على userVisibleOrderId
المعرّف الذي يراه المستخدم للطلب. يمكنك إعادة استخدام merchantOrderId
.
لهذا الحقل.
جزء من OrderUpdate أن يحتوي الكائن على إجراء للمتابعة والذي يظهر كأزرار عنوان URL أسفل تفاصيل الطلب التي التي يمكن للمستخدم العثور عليها في سجلّ طلبات "مساعد Google"
توصيل الطلبات
Node.js
// Set lastUpdateTime and update status of order const order = arg.order; order.lastUpdateTime = '2019-09-24T19:00:00.877Z'; order.purchase.status = 'CONFIRMED'; order.purchase.userVisibleStatusLabel = 'Order confirmed'; // Send synchronous order update conv.ask(`Transaction completed! Your order` + ` ${conv.data.latestOrderId} is all set!`); conv.ask(new Suggestions('send order update')); conv.ask(new OrderUpdate({ type: 'SNAPSHOT', reason: 'Reason string', order: order, }));
Node.js
// Set lastUpdateTime and update status of order const order = arg.order; order.lastUpdateTime = '2019-09-24T19:00:00.877Z'; order.purchase.status = 'CONFIRMED'; order.purchase.userVisibleStatusLabel = 'Order confirmed'; // Send synchronous order update conv.ask(`Transaction completed! Your order ` + `${conv.data.latestOrderId} is all set!`); conv.ask(new Suggestions('send order update')); conv.ask(new OrderUpdate({ type: 'SNAPSHOT', reason: 'Reason string', order: order, }));
Java
OrderV3 order = ((OrderV3) extension.get("order")); order.setLastUpdateTime("2019-09-24T19:00:00.877Z"); // Update order status PurchaseOrderExtension purchaseOrderExtension = order.getPurchase(); purchaseOrderExtension.setStatus("CONFIRMED"); purchaseOrderExtension.setUserVisibleStatusLabel("Order confirmed"); order.setPurchase(purchaseOrderExtension); // Order update OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setType("SNAPSHOT") .setReason("Reason string") .setOrder(order); Map<String, Object> conversationData = request.getConversationData(); String orderId = (String) conversationData.get("latestOrderId"); responseBuilder .add("Transaction completed! Your order " + orderId + " is all set!") .addSuggestions(new String[] {"send order update"}) .add(new StructuredResponse().setOrderUpdateV3(orderUpdate));
Java
OrderV3 order = ((OrderV3) extension.get("order")); order.setLastUpdateTime("2019-09-24T19:00:00.877Z"); // Update order status PurchaseOrderExtension purchaseOrderExtension = order.getPurchase(); purchaseOrderExtension.setStatus("CONFIRMED"); purchaseOrderExtension.setUserVisibleStatusLabel("Order confirmed"); order.setPurchase(purchaseOrderExtension); // Order update OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setType("SNAPSHOT") .setReason("Reason string") .setOrder(order); Map<String, Object> conversationData = request.getConversationData(); String orderId = (String) conversationData.get("latestOrderId"); responseBuilder .add("Transaction completed! Your order " + orderId + " is all set!") .addSuggestions(new String[] {"send order update"}) .add(new StructuredResponse().setOrderUpdateV3(orderUpdate));
JSON
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction completed! Your order undefined is all set!" } }, { "structuredResponse": { "orderUpdateV3": { "order": { "buyerInfo": { "displayName": "Jane Doe", "email": "janedoe@gmail.com", "firstName": "Jane", "lastName": "Doe" }, "contents": { "lineItems": [ { "description": "A four cheese pizza.", "id": "LINE_ITEM_ID", "name": "Pizza", "notes": [ "Extra cheese." ], "priceAttributes": [ { "amount": { "amountInMicros": 8990000, "currencyCode": "USD" }, "name": "Line Item Price", "state": "ACTUAL", "taxIncluded": true, "type": "REGULAR" }, { "amount": { "amountInMicros": 9990000, "currencyCode": "USD" }, "name": "Total Price", "state": "ACTUAL", "taxIncluded": true, "type": "TOTAL" } ], "purchase": { "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "note": "Extra pepperoni", "prices": [ { "amount": { "amountInMicros": 1000000, "currencyCode": "USD" }, "name": "Item Price", "state": "ACTUAL", "taxIncluded": true, "type": "REGULAR" }, { "amount": { "amountInMicros": 1000000, "currencyCode": "USD" }, "name": "Total Price", "state": "ACTUAL", "taxIncluded": true, "type": "TOTAL" } ], "quantity": 1, "subOptions": [] } ], "quantity": 1, "unitMeasure": { "measure": 1, "unit": "POUND" } } } ] }, "createTime": "2019-09-24T18:00:00.877Z", "followUpActions": [ { "openUrlAction": { "url": "http://example.com" }, "title": "View details", "type": "VIEW_DETAILS" }, { "openUrlAction": { "url": "tel:+16501112222" }, "title": "Call us", "type": "CALL" }, { "openUrlAction": { "url": "mailto:person@example.com" }, "title": "Email us", "type": "EMAIL" } ], "lastUpdateTime": "2019-09-24T19:00:00.877Z", "merchantOrderId": "ORDER_ID", "note": "Sale event", "priceAttributes": [ { "amount": { "amountInMicros": 9990000, "currencyCode": "USD" }, "name": "Subtotal", "state": "ESTIMATE", "taxIncluded": true, "type": "SUBTOTAL" }, { "amount": { "amountInMicros": 2000000, "currencyCode": "USD" }, "name": "Delivery", "state": "ACTUAL", "taxIncluded": true, "type": "DELIVERY" }, { "amount": { "amountInMicros": 3780000, "currencyCode": "USD" }, "name": "Tax", "state": "ESTIMATE", "taxIncluded": true, "type": "TAX" }, { "amount": { "amountInMicros": 15770000, "currencyCode": "USD" }, "name": "Total Price", "state": "ESTIMATE", "taxIncluded": true, "type": "TOTAL" } ], "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "fulfillmentInfo": { "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "fulfillmentContact": { "displayName": "John Johnson", "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson" }, "fulfillmentType": "DELIVERY", "id": "FULFILLMENT_SERVICE_ID", "location": {}, "price": { "amount": { "amountInMicros": 2000000, "currencyCode": "USD" }, "name": "Delivery Price", "state": "ACTUAL", "taxIncluded": true, "type": "REGULAR" } }, "purchaseLocationType": "ONLINE_PURCHASE", "returnsInfo": { "daysToReturn": 1, "isReturnable": false, "policyUrl": "http://www.example.com" }, "status": "CONFIRMED", "type": "FOOD", "userVisibleStatusLabel": "Order confirmed" }, "termsOfServiceUrl": "www.example.com", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "userVisibleOrderId": "ORDER_ID" }, "reason": "Reason string", "type": "SNAPSHOT" } } } ], "suggestions": [ { "title": "send order update" } ] } } } }
JSON
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.TEXT" } ], "inputPrompt": { "richInitialPrompt": { "items": [ { "simpleResponse": { "textToSpeech": "Transaction completed! Your order ORDER_ID is all set!" } }, { "structuredResponse": { "orderUpdateV3": { "type": "SNAPSHOT", "reason": "Reason string", "order": { "googleOrderId": "05528125187071048269", "merchantOrderId": "ORDER_ID", "userVisibleOrderId": "ORDER_ID", "buyerInfo": { "email": "janedoe@example.com", "firstName": "Jane", "lastName": "Doe", "displayName": "Jane Doe" }, "createTime": "2019-09-24T18:00:00.877Z", "lastUpdateTime": "2019-09-24T19:00:00.877Z", "transactionMerchant": { "id": "http://www.example.com", "name": "Example Merchant" }, "contents": { "lineItems": [ { "id": "LINE_ITEM_ID", "name": "Pizza", "priceAttributes": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "8990000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "9990000" }, "taxIncluded": true } ], "description": "A four cheese pizza.", "notes": [ "Extra cheese." ], "purchase": { "quantity": 1, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1 } ], "unitMeasure": { "measure": 1, "unit": "POUND" } }, "vertical": { "@type": "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseItemExtension", "quantity": 1, "itemOptions": [ { "id": "ITEM_OPTION_ID", "name": "Pepperoni", "prices": [ { "type": "REGULAR", "name": "Item Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "1000000" }, "taxIncluded": true } ], "note": "Extra pepperoni", "quantity": 1 } ], "unitMeasure": { "measure": 1, "unit": "POUND" } } } ] }, "priceAttributes": [ { "type": "SUBTOTAL", "name": "Subtotal", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "9990000" }, "taxIncluded": true }, { "type": "DELIVERY", "name": "Delivery", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, { "type": "TAX", "name": "Tax", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "3780000" }, "taxIncluded": true }, { "type": "TOTAL", "name": "Total Price", "state": "ESTIMATE", "amount": { "currencyCode": "USD", "amountInMicros": "15770000" }, "taxIncluded": true } ], "followUpActions": [ { "type": "VIEW_DETAILS", "title": "View details", "openUrlAction": { "url": "http://example.com" } }, { "type": "CALL", "title": "Call us", "openUrlAction": { "url": "tel:+16501112222" } }, { "type": "EMAIL", "title": "Email us", "openUrlAction": { "url": "mailto:person@example.com" } } ], "termsOfServiceUrl": "http://www.example.com", "note": "Sale event", "paymentData": { "paymentResult": { "merchantPaymentMethodId": "12345678" }, "paymentInfo": { "paymentMethodDisplayInfo": { "paymentType": "PAYMENT_CARD", "paymentMethodDisplayName": "VISA **** 1234" }, "paymentMethodProvenance": "PAYMENT_METHOD_PROVENANCE_MERCHANT" } }, "promotions": [ { "coupon": "COUPON_CODE" } ], "purchase": { "status": "CONFIRMED", "type": "FOOD", "returnsInfo": { "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE", "userVisibleStatusLabel": "Order confirmed" }, "vertical": { "@type": "type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseOrderExtension", "status": "CREATED", "type": "FOOD", "returnsInfo": { "daysToReturn": 1, "policyUrl": "http://www.example.com" }, "fulfillmentInfo": { "id": "FULFILLMENT_SERVICE_ID", "fulfillmentType": "DELIVERY", "expectedFulfillmentTime": { "timeIso8601": "2019-09-25T18:00:00.877Z" }, "location": { "coordinates": { "latitude": 37.421578499999995, "longitude": -122.0837816 }, "zipCode": "94043-1351", "city": "MOUNTAIN VIEW", "postalAddress": { "regionCode": "US", "postalCode": "94043-1351", "administrativeArea": "CA", "locality": "MOUNTAIN VIEW", "addressLines": [ "1600 AMPHITHEATRE PKWY" ], "recipients": [ "John Doe" ] }, "phoneNumber": "+1 123-456-7890" }, "price": { "type": "REGULAR", "name": "Delivery Price", "state": "ACTUAL", "amount": { "currencyCode": "USD", "amountInMicros": "2000000" }, "taxIncluded": true }, "fulfillmentContact": { "email": "johnjohnson@gmail.com", "firstName": "John", "lastName": "Johnson", "displayName": "John Johnson" } }, "purchaseLocationType": "ONLINE_PURCHASE", "userVisibleStatusLabel": "CREATED" } } } } } ], "suggestions": [ { "title": "send order update" } ] } } } ], "conversationToken": "{\"data\":{\"paymentType\":\"merchant_payment\",\"location\":{\"coordinates\":{\"latitude\":37.421578499999995,\"longitude\":-122.0837816},\"zipCode\":\"94043-1351\",\"city\":\"MOUNTAIN VIEW\",\"postalAddress\":{\"regionCode\":\"US\",\"postalCode\":\"94043-1351\",\"administrativeArea\":\"CA\",\"locality\":\"MOUNTAIN VIEW\",\"addressLines\":[\"1600 AMPHITHEATRE PKWY\"],\"recipients\":[\"John Doe\"]},\"phoneNumber\":\"+1 123-456-7890\"},\"latestOrderId\":\"ORDER_ID\"}}" }
5- إرسال آخر أخبار الطلبات
ويجب إبقاء المستخدم على اطّلاع بحالة الطلب على مدار حياته. يمكنك إرسال تعديلات طلب المستخدم من خلال إرسال HTTP. تصحيح الطلبات إلى واجهة برمجة التطبيقات Orders API مع توضيح حالة الطلب وتفاصيله.
إعداد الطلبات غير المتزامنة في Orders API
يتم السماح بطلبات تعديل الطلبات المرسَلة إلى Orders API من خلال إذن وصول
الرمز المميز. لتصحيح تعديل الطلب في واجهة برمجة التطبيقات Orders API، يجب تنزيل ملف JSON.
مفتاح حساب الخدمة المرتبط بمشروع "وحدة تحكّم المهام"، ثم استبدال
مفتاح حساب الخدمة لرمز الحامل المميز الذي يمكن تمريره إلى
عنوان Authorization
لطلب HTTP.
لاسترداد مفتاح حساب الخدمة، عليك اتّباع الخطوات التالية:
- في وحدة تحكُّم Google Cloud، الانتقال إلى رمز القائمة ⋮ > واجهات برمجة التطبيقات الخدمات > بيانات الاعتماد > إنشاء بيانات الاعتماد > مفتاح حساب الخدمة.
- ضمن حساب الخدمة، اختَر حساب خدمة جديد.
- اضبط حساب الخدمة على
service-account
. - ضبط الدور على مشروع > المالك:
- اضبط نوع المفتاح على JSON.
- اختَر إنشاء.
- سيتم تنزيل مفتاح حساب خدمة JSON خاص إلى جهازك المحلي.
في رمز تعديلات الطلب، يمكنك استبدال مفتاح الخدمة برمز حامل مميّز. باستخدام مكتبة برامج Google APIs والنطاق "https://www.googleapis.com/auth/actions.order.developer". يمكنك العثور على خطوات التثبيت الأمثلة على صفحة GitHub في مكتبة برامج واجهة برمجة التطبيقات.
يمكنك أيضًا الرجوع إلى order-update.js
في نموذجي Node.js وJava
كمثال لتبادل المفاتيح.
إرسال آخر أخبار الطلبات
بعد استبدال مفتاح حساب الخدمة برمز حامل OAuth المميز، يمكنك إرسال تحديثات الطلبات كطلبات تصحيح معتمدة إلى واجهة برمجة تطبيقات الطلبات.
عنوان URL لواجهة برمجة التطبيقات Orders API:
PATCH https://actions.googleapis.com/v3/orders/${orderId}
قدِّم العناوين التالية في طلبك:
"Authorization: Bearer token"
يتضمن الرمز المميز لحامل OAuth الذي استبدلت مفتاح حساب الخدمة من أجله."Content-Type: application/json"
.
يجب أن يأخذ طلب التصحيح نص JSON بالتنسيق التالي:
{ "orderUpdate": OrderUpdate }
OrderUpdate
من الحقول ذات المستوى الأعلى التالية:
updateMask
: حقول الطلب الذي تُعدِّله لتحديث وحالة الطلب اضبط القيمة علىpurchase.status, purchase.userVisibleStatusLabel
.order
: محتوى التعديل إذا كنت تقوم بتحديث محتوى الطلب، اضبط القيمة على عنصرOrder
المعدَّل. في حالة تحديث حالة الطلب (على سبيل المثال، من من"CONFIRMED"
إلى"SHIPPED"
)، يحتوي الكائن على الحقول التالية:merchantOrderId
: رقم التعريف نفسه الذي ضبطته في عنصرOrder
lastUpdateTime
- الطابع الزمني لهذا التعديلpurchase
- كائن يحتوي على ما يلي:status
- حالة الطلب باعتبارهPurchaseStatus
على سبيل المثال "SHIPPED
" أو "DELIVERED
".userVisibleStatusLabel
- تصنيف موجه للمستخدمين يوفر تفاصيل عن حالة الطلب، مثل "تم شحن طلبك وهو على ".
userNotification
(اختياري) - أuserNotification
يمكن عرضه على جهاز المستخدم عند إرسال هذا التحديث. ملاحظة أن تضمين هذا الكائن لا يضمن ظهور الإشعار على جهاز المستخدم.
يعرض الرمز النموذجي التالي مثالاً على OrderUpdate
يعدِّل
حالة الطلب إلى DELIVERED
:
Node.js
// Import the 'googleapis' module for authorizing the request. const {google} = require('googleapis'); // Import the 'request-promise' module for sending an HTTP POST request. const request = require('request-promise'); // Import the OrderUpdate class from the Actions on Google client library. const {OrderUpdate} = require('actions-on-google'); // Import the service account key used to authorize the request. // Replacing the string path with a path to your service account key. // i.e. const serviceAccountKey = require('./service-account.json') // Create a new JWT client for the Actions API using credentials // from the service account key. let jwtClient = new google.auth.JWT( serviceAccountKey.client_email, null, serviceAccountKey.private_key, ['https://www.googleapis.com/auth/actions.order.developer'], null, ); // Authorize the client let tokens = await jwtClient.authorize(); // Declare order update const orderUpdate = new OrderUpdate({ updateMask: [ 'lastUpdateTime', 'purchase.status', 'purchase.userVisibleStatusLabel', ].join(','), order: { merchantOrderId: orderId, // Specify the ID of the order to update lastUpdateTime: new Date().toISOString(), purchase: { status: 'DELIVERED', userVisibleStatusLabel: 'Order delivered', }, }, reason: 'Order status updated to delivered.', }); // Set up the PATCH request header and body, // including the authorized token and order update. let options = { method: 'PATCH', uri: `https://actions.googleapis.com/v3/orders/${orderId}`, auth: { bearer: tokens.access_token, }, body: { header: { isInSandbox: true, }, orderUpdate, }, json: true, }; // Send the PATCH request to the Orders API. try { await request(options); conv.close(`The order has been updated.`); } catch (e) { console.log(`Error: ${e}`); conv.close(`There was an error sending an order update.`); }
Node.js
// Import the 'googleapis' module for authorizing the request. const {google} = require('googleapis'); // Import the 'request-promise' module for sending an HTTP POST request. const request = require('request-promise'); // Import the OrderUpdate class from the Actions on Google client library. const {OrderUpdate} = require('actions-on-google'); // Import the service account key used to authorize the request. // Replacing the string path with a path to your service account key. // i.e. const serviceAccountKey = require('./service-account.json') // Create a new JWT client for the Actions API using credentials // from the service account key. let jwtClient = new google.auth.JWT( serviceAccountKey.client_email, null, serviceAccountKey.private_key, ['https://www.googleapis.com/auth/actions.order.developer'], null, ); // Authorize the client let tokens = await jwtClient.authorize(); // Declare order update const orderUpdate = new OrderUpdate({ updateMask: [ 'lastUpdateTime', 'purchase.status', 'purchase.userVisibleStatusLabel', ].join(','), order: { merchantOrderId: orderId, // Specify the ID of the order to update lastUpdateTime: new Date().toISOString(), purchase: { status: 'DELIVERED', userVisibleStatusLabel: 'Order delivered', }, }, reason: 'Order status updated to delivered.', }); // Set up the PATCH request header and body, // including the authorized token and order update. let options = { method: 'PATCH', uri: `https://actions.googleapis.com/v3/orders/${orderId}`, auth: { bearer: tokens.access_token, }, body: { header: { isInSandbox: true, }, orderUpdate, }, json: true, }; // Send the PATCH request to the Orders API. try { await request(options); conv.close(`The order has been updated.`); } catch (e) { console.log(`Error: ${e}`); conv.close(`There was an error sending an order update.`); }
Java
// Setup service account credentials String serviceAccountFile = MyActionsApp.class.getClassLoader() .getResource(SERVICE_ACCOUNT_KEY_FILE_NAME) .getFile(); InputStream actionsApiServiceAccount = new FileInputStream( serviceAccountFile); ServiceAccountCredentials serviceAccountCredentials = (ServiceAccountCredentials) ServiceAccountCredentials.fromStream(actionsApiServiceAccount) .createScoped(Collections.singleton( "https://www.googleapis.com/auth/actions.order.developer")); AccessToken token = serviceAccountCredentials.refreshAccessToken(); // Setup request with headers HttpPatch patchRequest = new HttpPatch( "https://actions.googleapis.com/v3/orders/" + orderId); patchRequest.setHeader("Content-type", "application/json"); patchRequest.setHeader("Authorization", "Bearer " + token.getTokenValue()); // Create order update FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList( "lastUpdateTime", "purchase.status", "purchase.userVisibleStatusLabel")) .build(); OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setOrder(new OrderV3() .setMerchantOrderId(orderId) .setLastUpdateTime(Instant.now().toString()) .setPurchase(new PurchaseOrderExtension() .setStatus("DELIVERED") .setUserVisibleStatusLabel("Order delivered."))) .setUpdateMask(FieldMaskUtil.toString(fieldMask)) .setReason("Order status was updated to delivered."); // Setup JSON body containing order update JsonParser parser = new JsonParser(); JsonObject orderUpdateJson = parser.parse(new Gson().toJson(orderUpdate)).getAsJsonObject(); JsonObject body = new JsonObject(); body.add("orderUpdate", orderUpdateJson); JsonObject header = new JsonObject(); header.addProperty("isInSandbox", true); body.add("header", header); StringEntity entity = new StringEntity(body.toString()); entity.setContentType(ContentType.APPLICATION_JSON.getMimeType()); patchRequest.setEntity(entity); // Make request HttpClient httpClient = HttpClientBuilder.create().build(); HttpResponse response = httpClient.execute(patchRequest); LOGGER.info(response.getStatusLine().getStatusCode() + " " + response .getStatusLine().getReasonPhrase()); return getResponseBuilder(request) .add("The order has been updated.") .build();
Java
// Setup service account credentials String serviceAccountFile = MyActionsApp.class.getClassLoader() .getResource(SERVICE_ACCOUNT_KEY_FILE_NAME) .getFile(); InputStream actionsApiServiceAccount = new FileInputStream( serviceAccountFile); ServiceAccountCredentials serviceAccountCredentials = (ServiceAccountCredentials) ServiceAccountCredentials.fromStream(actionsApiServiceAccount) .createScoped(Collections.singleton( "https://www.googleapis.com/auth/actions.order.developer")); AccessToken token = serviceAccountCredentials.refreshAccessToken(); // Setup request with headers HttpPatch patchRequest = new HttpPatch( "https://actions.googleapis.com/v3/orders/" + orderId); patchRequest.setHeader("Content-type", "application/json"); patchRequest.setHeader("Authorization", "Bearer " + token.getTokenValue()); // Create order update FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList( "lastUpdateTime", "purchase.status", "purchase.userVisibleStatusLabel")) .build(); OrderUpdateV3 orderUpdate = new OrderUpdateV3() .setOrder(new OrderV3() .setMerchantOrderId(orderId) .setLastUpdateTime(Instant.now().toString()) .setPurchase(new PurchaseOrderExtension() .setStatus("DELIVERED") .setUserVisibleStatusLabel("Order delivered."))) .setUpdateMask(FieldMaskUtil.toString(fieldMask)) .setReason("Order status was updated to delivered."); // Setup JSON body containing order update JsonParser parser = new JsonParser(); JsonObject orderUpdateJson = parser.parse(new Gson().toJson(orderUpdate)).getAsJsonObject(); JsonObject body = new JsonObject(); body.add("orderUpdate", orderUpdateJson); JsonObject header = new JsonObject(); header.addProperty("isInSandbox", true); body.add("header", header); StringEntity entity = new StringEntity(body.toString()); entity.setContentType(ContentType.APPLICATION_JSON.getMimeType()); patchRequest.setEntity(entity); // Make request HttpClient httpClient = HttpClientBuilder.create().build(); HttpResponse response = httpClient.execute(patchRequest); LOGGER.info(response.getStatusLine().getStatusCode() + " " + response .getStatusLine().getReasonPhrase()); return getResponseBuilder(request) .add("The order has been updated.") .build();
ضبط حالة الشراء
status
لتعديل الطلب
يجب أن يقدّم وصفًا عن الحالة الحالية للطلب. في تحديثك order.purchase.status
استخدم إحدى القيم التالية:
CREATED
- يقبل المستخدم الطلب ويكون "تم إنشاؤه" من المنظور الإجراء الخاص بك ولكنه يتطلب معالجة يدوية على الخادم الخلفي.CONFIRMED
: الطلب نشط وتتم معالجته ليتم تنفيذه.IN_PREPARATION
- يتم إعداد الطلب للشحن/التوصيل، مثل الطعام المطبوخة أو عنصر يتم تغليفه.READY_FOR_PICKUP
- الطلب متاح للمستلمين استلامه.DELIVERED
: تم تسليم الطلب إلى المستلم.OUT_OF_STOCK
- هناك سلعة واحدة أو أكثر في الطلب غير متوفّرة.CHANGE_REQUESTED
- طلب المستخدم إجراء تغيير على الطلب، وأصبح التغيير قيد المعالجة.RETURNED
: تم إرجاع الطلب من قِبل المستخدم بعد التسليم.REJECTED
- إذا تعذّر عليك معالجة البيانات أو تحصيل الرسوم أو غير ذلك "تفعيل" بالترتيب.CANCELLED
- ألغى المستخدم الطلب.
يجب إرسال تحديثات الطلب لكل حالة ذات صلة بـ
معاملة. على سبيل المثال، إذا كانت معاملتك تتطلب المعالجة اليدوية
تسجيل الطلب بعد تقديمه، وإرسال تعديل بشأن الطلب بقيمة CREATED
حتى
إتمام المعالجة الإضافية. لا يتطلب كل طلب كل قيمة حالة.
تحديد المشاكل وحلّها
في حال مواجهة أي مشاكل أثناء الاختبار، يُرجى الاطّلاع على خطوات تحديد المشاكل وحلّها. للمعاملات