إعداد Checkout

يتم استدعاء عملية الدفع عندما ينشئ المستخدم سلة تسوّق. يتم إرسال محتوى سلة تسوّق المستخدم وتفاصيل الطلب إلى خدمة الويب الشاملة للطلب. تم التحقّق من صحة هذه المعلومات من خلال خدمة الويب، وبعد ذلك يمكنك إما المتابعة أو إجراء تعديلات على سلة التسوق حسب الحاجة.

يجب أن يستجيب معالج الدفع في خدمة الويب إلى طلبات POST. عندما يختار العميل إتمام الدفع، ترسل Google إلى خدمة الويب الشاملة للطلب نص طلب JSON في شكل CheckoutRequestMessage يحتوي على تفاصيل Cart الخاصة بالعميل. تستجيب خدمة الويب بعد ذلك لتقديم CheckoutResponseMessage. ويوضح الرسم البياني التالي هذه العملية.

تعرض CheckoutResponseMessage سلة التسوق غير المعدلة للعميل أو حدوث خطأ.

عند استلام طلب دفع، يجب أن تنفّذ خدمة الويب الشاملة للطلب ما يلي:

  • تحقق من صلاحية سلة التسوق بناءً على أسعار العناصر الحالية ومدى توفرها وخدمة المزود.
  • احسب السعر الإجمالي (بما في ذلك أي خصومات وضرائب ورسوم التسليم).
  • في حال نجاح هذا الإجراء، يمكنك الردّ باستخدام سلة تسوّق غير معدّلة.
  • إذا لم تنجح في حل المشكلة، يمكنك الردّ برسالة خطأ وطلب جديد مقترَح.

قبل البدء بتنفيذ عملية الدفع، ننصحك بمراجعة مستندات نظرة عامة على توصيل الطلبات.

رسالة طلب الدفع

للتحقّق من صحّة سلّة التسوّق، عندما يختار العميل إتمام الدفع، ترسل Google طلبًا إلى خدمة الويب الخاصة بك يتضمّن نص JSON على شكل CheckoutRequestMessage. لا يتم تقديم طلب العميل حتى وقت لاحق في تدفق الطلب من البداية إلى النهاية.

تشمل البيانات الواردة في CheckoutRequestMessage ما يلي:

  • الغرض: يحتوي الحقل inputs[0].intent لكل نص طلب دفع على قيمة سلسلة actions.foodordering.intent.CHECKOUT.
  • سلة التسوّق: يحتوي الحقل inputs[0].arguments[0].extension لطلب الدفع على عنصر Cart يمثّل سلّة التسوّق الخاصة بالعميل.
  • خدمة التوصيل أو طلب الوجبات الجاهزة لتناولها خارج المطعم: يحتوي حقل الإضافة الخاص بالعنصر Cart على عنصر FoodCartExtension يحدّد خصائص خدمة التوصيل أو الطعام السفري:
    • بالنسبة إلى طلبات التسليم، يتضمّن العنصر FoodCartExtension عنوان التسليم
    • في ما يتعلق بطلبات الاستلام أو الطعام السفري، لا يحتوي عنصر FoodCartExtension على أي معلومات عن الموقع الجغرافي.
  • وضع الحماية: يحتوي الحقل isInSandbox لطلب الدفع على قيمة منطقية تشير إلى ما إذا كانت المعاملة تستخدم عمليات الدفع في وضع الحماية.

مثال على طلب الدفع

في ما يلي مثال على CheckoutRequestMessage:

{
    "user": {},
    "conversation": {
        "conversationId": "CTZbZfUlHCybEdcz_5PB3Ttf"
    },
    "inputs": [
        {
            "intent": "actions.foodordering.intent.CHECKOUT",
            "arguments": [
                {
                    "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.Cart",
                        "merchant": {
                            "id": "restaurant/Restaurant/QWERTY",
                            "name": "Tep Tep Chicken Club"
                        },
                        "lineItems": [
                            {
                                "name": "Spicy Fried Chicken",
                                "type": "REGULAR",
                                "id": "299977679",
                                "quantity": 2,
                                "price": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "39",
                                        "nanos": 600000000
                                    }
                                },
                                "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                }
                            }
                        ],
                        "extension": {
                            "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                            "fulfillmentPreference": {
                                "fulfillmentInfo": {
                                    "delivery": {
                                        "deliveryTimeIso8601": "P0M"
                                    }
                                }
                            },
                            "location": {
                                "coordinates": {
                                    "latitude": -33.8376441,
                                    "longitude": 151.0868736
                                },
                                "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                "zipCode": "2138",
                                "city": "Concord West",
                                "postalAddress": {
                                    "regionCode": "AU",
                                    "postalCode": "2138",
                                    "administrativeArea": "NSW",
                                    "locality": "Concord West",
                                    "addressLines": [
                                        "Killoola St",
                                        "1"
                                    ]
                                }
                            }
                        }
                    }
                }
            ]
        }
    ],
    "directActionOnly": true,
    "isInSandbox": true
}

رسالة الرد على Checkout

بعد تلقّي طلب من خدمة "الطلب التام بين الأطراف"، يجب أن تعالجه خدمة الويب الخاصة بالدفع على الويب وأن تردّ عليه باستخدام CheckoutResponseMessage. يجب أن تغطي السمة CheckoutResponseMessage إما طلب ناجح أو غير ناجح.

تم الطلب بنجاح

إذا تم قبول طلب الدفع، يجب أن يتضمّن CheckoutResponseMessage كلاً من ProposedOrder وPaymentOptions:

  • ProposedOrder

    • cart: عنصر cart مطابق لسلة التسوّق المقدّمة في CheckoutRequestMessage في حال الحاجة إلى تغيير أي من محتوى سلة التسوّق، يجب أن تتضمّن CheckoutResponseMessage بدلاً من ذلك عنصر FoodErrorExtension مع ProposedOrder تم تصحيحه.
    • otherItems: السلع التي يضيفها مقدّم الخدمة، مثل رسوم التسليم والضرائب وغيرها من الرسوم وقد يتضمن أيضًا إكراءً أضافه المستخدم.
    • totalPrice: السعر الإجمالي للطلب
    • extension: تحدّد السمة FoodOrderExtension معلومات تنفيذ الطلب، مثل مدة التسليم.
  • PaymentOptions

    • في مقالة إعداد Google Pay، ستظهر لاحقًا عملية إعداد معالجة الدفعات. يمكنك استخدام العنصر النائب JSON في CheckoutResponseMessage إلى أن تصبح جاهزًا لتنفيذ عملية معالجة الدفعات.
    • لإضافة خيارات الدفع النائبة في CheckoutResponseMessage، يُرجى الاطّلاع على المثال أدناه، والذي يستخدم نموذجًا لبوابة الدفع في PaymentOptions.

مثال على الاستجابة الناجحة

{
    "finalResponse": {
        "richResponse": {
            "items": [
                {
                    "structuredResponse": {
                        "checkoutResponse": {
                            "proposedOrder": {
                                "cart": {
                                    "merchant": {
                                        "id": "restaurant/Restaurant/QWERTY",
                                        "name": "Tep Tep Chicken Club"
                                    },
                                    "lineItems": [
                                        {
                                            "name": "Spicy Fried Chicken",
                                            "type": "REGULAR",
                                            "id": "299977679",
                                            "quantity": 2,
                                            "price": {
                                                "type": "ESTIMATE",
                                                "amount": {
                                                    "currencyCode": "AUD",
                                                    "units": "39",
                                                    "nanos": 600000000
                                                }
                                            },
                                            "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                            "extension": {
                                                "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                            }
                                        }
                                    ],
                                    "extension": {
                                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                                        "fulfillmentPreference": {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        },
                                        "location": {
                                            "coordinates": {
                                                "latitude": -33.8376441,
                                                "longitude": 151.0868736
                                            },
                                            "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                            "zipCode": "2138",
                                            "city": "Concord West",
                                            "postalAddress": {
                                                "regionCode": "AU",
                                                "postalCode": "2138",
                                                "administrativeArea": "NSW",
                                                "locality": "Concord West",
                                                "addressLines": [
                                                    "Killoola St",
                                                    "1"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "totalPrice": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "43",
                                        "nanos": 100000000
                                    }
                                },
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                                    "availableFulfillmentOptions": [
                                        {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        }
                                    ]
                                },
                                "otherItems": [
                                    {
                                        "name": "Delivery fee",
                                        "price": {
                                            "type": "ESTIMATE",
                                            "amount": {
                                                "currencyCode": "AUD",
                                                "units": "3",
                                                "nanos": 500000000
                                            }
                                        },
                                        "type": "DELIVERY"
                                    }
                                ]
                            },
                            "paymentOptions": {
                                "googleProvidedOptions": {
                                    "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"AUD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"43.1\"}} "
                                }
                            },
                            "additionalPaymentOptions": [
                                {
                                    "actionProvidedOptions": {
                                        "paymentType": "ON_FULFILLMENT",
                                        "displayName": "Pay when you get your food.",
                                        "onFulfillmentPaymentData": {
                                            "supportedPaymentOptions": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

تعذّرت معالجة الطلب.

في حال لم ينجح طلب الدفع، يجب أن يتضمّن CheckoutResponseMessage FoodErrorExtension، الذي يحتوي على قائمة بعناصر FoodOrderError التي تصف أي أخطاء حدثت. في حال ظهور أي أخطاء في الطلب يمكن استردادها، مثل تغيير في سعر سلعة في سلة التسوق، يجب أن تتضمّن السمة FoodErrorExtension correctedProposedOrder.

مثال على ردّ غير ناجح

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

تنفيذ عملية الدفع

يجب اتّخاذ الخطوات التالية عند تنفيذ عملية الدفع.

التحقُّق من الخدمة

عرض FoodOrderError لحالة خطأ الخدمة الأولى التي تم العثور عليها. هذه الأخطاء غير قابلة للاسترداد، لذا يجب عرض أول خطأ يظهر. يُرجى الاطّلاع على أخطاء المعالجة للحصول على وصف للأخطاء التي يمكن استردادها.

  1. اقرأ السمة FulfillmentOptionInfo في الطلب لتحديد ما إذا كان نوع التنفيذ هو delivery أو pickup.
  2. عرض أنواع الأخطاء التالية إذا لزم الأمر:

    نوع الخطأ حالة الاستخدام
    INVALID نوع طريقة التنفيذ غير صالح.
    NOT_FOUND لم يتم العثور على نوع طريقة التنفيذ.
    مغلقة
    • لا توجد نوافذ OperationHours للطلب.
    • الطلب متاح في أقرب وقت ممكن ولا تتوفّر ServiceHours في الوقت الحالي في أقرب وقت ممكن.
    • تم إغلاق الخدمة في حالات الطوارئ أو تم تفعيل الخدمة في isDisabled.
    ملاحظة: يكون للنوافذ الخاصة الأولوية على النوافذ العادية. اطّلِع على أمثلة في مقالة طلب التحقّق من المهلة الزمنية وإزالة كيانات الخدمة مؤقتًا.
    UNAVAILABLE_SLOT لا يمكن تنفيذ الطلب المسبَق.
    NO_CAPACITY المطعم مزدحم ولا يتلقّى الطلبات في الوقت الحالي.
    OUT_OF_SERVICE_AREA لا يمكن تسليم الطلب إلى عنوان المستخدم. راجع التحقق من عنوان التسليم للحصول على مثال.
    NO_COURIER_AVAILABLE لا يمكن تسليم الطلب بسبب محدودية موظفي التسليم.

التحقّق من صحة سلة التسوق وتسعيرها

  1. ابحث عن كل سلة تسوّق.lineItems وتحقّق من صحتها باستخدام البيانات الحالية في نظامك أو في نظام التاجر. ويتم تضمين القيمة MenuItemOffer.sku من كيان الخلاصة على أنّها LineItem.offerId. أنشئ FoodOrderError لكل عنصر إذا لزم الأمر. أنشئ خطأ واحدًا بحد أقصى لكل عنصر. اعرض أنواع الأخطاء التالية إذا لزم الأمر:

    نوع الخطأ حالة الاستخدام قابلة للاسترداد
    INVALID بيانات السلع أو أيّ من بيانات الخيارات غير صالحة. لا
    NOT_FOUND لم يتم العثور على العنصر أو أي من الخيارات. لا
    PRICE_CHANGED تم تغيير سعر عنصر أو إضافة. يمكن التعامل مع هذا الخطأ على أنه قابل للإصلاح. نعم
    AVAILABILITY_CHANGED لا يتوفّر المبلغ المطلوب لتفاصيل الإعلان أو أيٍّ من الخيارات. نعم
    REQUIREMENTS_NOT_MET لم يتم استيفاء الحد الأدنى للطلب أو الحد الأقصى للطلب. يمكن تحديد ذلك من خلال التحقّق مما إذا كان سعر سلة التسوّق أقلّ من الرسوم.eligibleTransactionVolumeMin أو أعلى من الرسوم.eligibleTransactionVolumeMax. اطّلِع على المثال في مقالة التحقّق من صحة قيمة طلب الشراء. لا
  2. عرض قائمة lineItems التي تم التحقق من صحتها باستخدام LineItemType REGULAR. يكون مجموع كل أسعار عناصر سلة التسوق هو سعر سلة التسوق أو SUBTOTAL.

اطّلِع على أمثلة في عملية التحقق من صحة سلع سلة التسوّق.

حساب رسوم الخدمة

  1. ابحث عن كيان Fee الصحيح للخدمة استنادًا إلى eligibleRegion وvalidFrom وvalidThrough وpriority.
  2. احسب مبلغ الرسوم استنادًا إلى ما إذا تم تحديد الكيان باستخدام السمة price أو percentageOfCart أو pricePerMeter.
  3. يمكنك إرجاع رسوم خدمة التوصيل أو طلب الوجبات الجاهزة لتناولها خارج المطعم على أنّها LineItem مع إدخال LineItemType DELIVERY أو FEE على التوالي. أضف الرسوم إلى قائمة سلة التسوق.otherItems.

تطبيق الإعلانات الترويجية

  1. ابحث عن الكيان Deal (الصفقة) استنادًا إلى القيمة المُطابِقة للقيمة العرض الترويجي.coupon مع الصفقة.dealCode.
  2. تأكَّد من صحة الصفقة وأدخِل FoodOrderError إذا لزم الأمر. يمكن التعامل مع هذه الأخطاء على أنها قابلة للإصلاح. اعرض أنواع الأخطاء التالية إذا لزم الأمر:

    نوع الخطأ حالة الاستخدام
    PROMO_NOT_RECOGNIZED لم يتم التعرف على رمز القسيمة.
    PROMO_EXPIRED انتهت صلاحية الصفقة.
    PROMO_ORDER_INELIGIBLE الطلب غير مؤهل للحصول على القسيمة.
    PROMO_NOT_APPLICABLE أي سبب آخر.
  3. يمكنك احتساب سعر الصفقة استنادًا إلى الصفقة.discount أو الصفقة.discountPercentage.

  4. طبِّق سعر الصفقة باستخدام إجمالي سلة التسوق أو إجمالي الرسوم وفقًا للصفقة.dealType.

  5. يمكنك إرجاع سلة التسوق.promotions مع العرض الترويجي المطبَّق.

  6. أعِد العرض الترويجي على شكل LineItem باستخدام LineItemType DISCOUNT. أضِف الخصم إلى قائمة سلة التسوق.otherItems بسعر سلبي.

عرض الرد

  1. أنشِئ ProposedOrder.cart، وستتطابق سلة تسوّق الردّ مع سلة تسوّق الطلب في حال عدم حدوث أيّ أخطاء أثناء التحقّق.
  2. أعِد قائمة ProposedOrder.otherItems والتي تشمل الضريبة والرسوم والإكرامية والخصم في حال تطبيقها. راجِع الدرجة غير المجانية للحصول على مزيد من التفاصيل حول كيفية ضبط عنصر الإكرامية.
  3. أدرِج ProposedOrder.totalPrice عبر إضافة سعر سلة التسوق والرسوم والخصم والضرائب والإكرامية.
  4. أرسِل السمة FoodOrderExtension.availableFulfillmentOptions مع قيمة FulfillmentOption ذات الصلة. عدِّل الوقت المقدّر للاستلام أو التسليم إلى الوقت المتوقّع
  5. إذا كان هناك FoodOrderErrors تم إنشاؤه من عمليات التحقق السابقة من صحة البيانات:
    • أدرِج StructuredResponse.error وقائمة الأخطاء في FoodErrorExtension.foodOrderErrors.
    • اعرض ProposedOrder في الحقل correctedProposedOrder إذا كان من الممكن استرداد جميع الأخطاء.
    • ارجع إلى PaymentOptions في الحقل paymentOptions إذا كان من الممكن استرداد جميع الأخطاء.
    • اختياريًا، يمكنك تضمين additionalPaymentOptions إذا كانت هناك خيارات دفع أخرى متاحة ويمكن استرداد جميع الأخطاء.
  6. إذا لم تكن هناك أخطاء في عملية التحقّق، اعرض proposedOrder، paymentOptions في العنصر CheckoutResponse. اختياريًا، يمكنك تضمين additionalPaymentOptions إذا كانت هناك خيارات دفع أخرى متاحة.