יצירת עסקאות פיזיות באמצעות Google Pay

המדריך הזה מסביר את תהליך הפיתוח של פרויקט פעולות שמשולבים בו עסקאות של מוצרים פיזיים ועושים שימוש ב-Google Pay לתשלום.

תהליך העסקה

כשפרויקט Actions מטפל בעסקאות פיזיות באמצעות תשלומים בניהול המוכר, משתמשת בתהליך הבא:

  1. איסוף מידע (אופציונלי) – בהתאם לאופי של כדאי לאסוף מהמשתמש את הפרטים הבאים בהתחלה בשיחה:
    1. אימות הדרישות לעסקאות – בתחילת השיחה, לאמת שהמשתמש עומד בדרישות לביצוע עסקה, כמו כי פרטי התשלום מוגדרים כראוי וזמינים בתהליך היצירה של עגלת הקניות.
    2. לבקש כתובת למשלוח – אם העסקה מחייבת משלוח כתובת, לאסוף כתובת אחת מהמשתמש.
  2. הכנת ההזמנה – הדרכת המשתמש "הרכבת עגלת קניות" שבו הוא בוחר אילו פריטים הוא רוצה לרכוש.
  3. הצעת ההזמנה – לאחר השלמת עגלת הקניות, מציעים את ההזמנה את המשתמש, כדי שהוא יוכל לאשר שזה נכון. אם ההזמנה תאושר, עליך לקבל תשובה עם פרטי הזמנה ואסימון תשלום.
  4. השלמת ההזמנה ושליחת קבלה – לאחר שההזמנה אושרה, מעדכנים אותה את שירותי מעקב המלאי או שירותי מילוי הזמנות אחרים, ולאחר מכן לשלוח קבלה למשתמש.
  5. שליחת עדכוני הזמנות – במהלך משך החיים של מילוי ההזמנה, לעדכן את הזמנת המשתמש על ידי שליחת בקשות PATCH להזמנות API.

הנחיות בנושא הגבלות ובדיקה

חשוב לזכור שכללי מדיניות נוספים חלים על 'פעולות עם עסקאות'. הוא תהליך הבדיקה של פעולות עם עסקאות עשוי להימשך עד שישה שבועות, בזמן תכנון לוח הזמנים להשקה. כדי להקל את תהליך הבדיקה, עליך לעמוד בדרישות של מדיניות והנחיות בנושא עסקאות לפני שליחת הפעולה לבדיקה.

אפשר לפרוס פעולות למכירת מוצרים פיזיים רק במדינות הבאות:

אוסטרליה
ברזיל
קנדה
אינדונזיה
יפן
מקסיקו
רוסיה
סינגפור
תאילנד
טורקיה
בריטניה
ארצות הברית

בניית הפרויקט

לדוגמאות נרחבות של שיחות עם טרנזקציות, אפשר לעיין בעסקאות של Node.js דוגמה.

הגדרה

כשיוצרים את הפעולה, צריך לציין שרוצים לבצע עסקאות במסוף Actions.

כדי להגדיר את הפרויקט ואת מילוי ההזמנות:

  1. יוצרים פרויקט חדש או מייבאים פרויקט קיים.
  2. עוברים אל Deploy > (פריסה) >. פרטי הספרייה.
  3. בקטע מידע נוסף > עסקאות > מסמנים את התיבה שבה כתוב "ביצוע הפעולות שלך" להשתמש ב-Transactions API כדי לבצע עסקאות של מוצרים פיזיים?".

1. איסוף מידע (אופציונלי)

1א. אימות הדרישות לקבלת עסקאות (אופציונלי)

ברגע שהמשתמש ציין שהוא רוצה לבצע רכישה, עליך לוודא שהם יוכלו לבצע עסקה. לדוגמה, כשהיא מופעלת, הפעולה עשויה לשאול "האם תרצו להזמין נעליים, או לבדוק את היתרה בחשבון?" אם המשתמש אומר "להזמין נעליים", עליך לוודא שהוא יכול להמשיך ולאפשר לו לתקן הגדרות שמונעות ממנו להמשיך בביצוע העסקה. כדי לעשות את זה, צריך לעבור שמבצעת בדיקה של הדרישות לעסקה.

יצירת דרישות לעסקה – בדיקת סצנה
  1. בכרטיסיית הסצנות, מוסיפים סצנה חדשה בשם TransactionRequirementsCheck.
  2. בקטע מילוי משבצת, לוחצים על הסמל + כדי להוסיף משבצת חדשה.
  3. בקטע בחירת סוג, בוחרים actions.type.TransactionRequirementsCheckResult בתור סוג החריץ.
  4. בשדה 'שם מיקום', מזינים למשבצת את השם TransactionRequirementsCheck.
  5. מפעילים את תיבת הסימון התאמה אישית של כתיבת ערך מיקום בדף (מופעלת כברירת מחדל).
  6. לוחצים על שמירה.

בדיקת הדרישות לעסקה תוביל לאחת מהתוצאות הבאות:

  • אם הדרישות מתקיימות, פרמטר הסשן מוגדר בהצלחה ואפשר להמשיך בבניית ההזמנה של המשתמש.
  • אם לא ניתן לעמוד באחת או יותר מהדרישות, פרמטר הסשן מוגדר עם תנאי של כשל. במקרה כזה, צריך לסובב את השיחה בממשק עצמו, או לסיים את השיחה.
    • אם המשתמש יכול לתקן שגיאות שגרמו למצב הכשל, הם יתבקשו לפתור את הבעיות במכשיר שלהם. אם מתבצעת במשטח קולי בלבד, העברה מופעל לטלפון של המשתמש.

טיפול בדרישות לעסקה בתוצאה של בדיקת הדרישות

  1. בכרטיסייה סצנות, בוחרים את התמונה החדשה שיצרתם. סצנה אחת (TransactionRequirementsCheck).
  2. בקטע תנאי, לוחצים על הסמל + כדי להוסיף תנאי חדש.
  3. בשדה הטקסט, מזינים את תחביר התנאי הבא כדי לבדוק אם תנאי להצלחה:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. מעבירים את העכבר מעל התנאי שהוספתם ולוחצים על החץ למעלה. כדי להציב אותו לפני if scene.slots.status == "FINAL".

  5. מפעילים את האפשרות שליחת הנחיות ומספקים הנחיה פשוטה כדי ליידע את המשתמש הם מוכנים לבצע עסקה:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                You are ready to purchase physical goods.
    
  6. בקטע מעבר בוחרים סצנה אחרת, ומאפשרים למשתמש להמשיך ולהמשיך לביצוע עסקה.

  7. בוחרים את התנאי else if scene.slots.status == "FINAL".

  8. מפעילים את האפשרות שליחת הנחיות ומספקים הנחיה פשוטה כדי ליידע את המשתמש הם לא יכולים לבצע עסקה:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה אם משתמש לא יכול לבצע עסקאות.

בקשת כתובת למשלוח

אם בעסקה נדרשת כתובת למשלוח של המשתמש, צריך לבקש אותה מהמשתמש. זה יכול לעזור בקביעת המחיר הכולל. ליעד המשלוח או לאיסוף, או כדי לוודא שהמשתמש נמצא באזור השירות של העסק. כדי לעשות את זה, צריך לעבור לסצנה שבה המשתמש מתבקש כתובת למשלוח.

יצירת סצנת כתובת למשלוח

  1. מהכרטיסייה סצנות, מוסיפים סצנה חדשה בשם DeliveryAddress.
  2. בקטע מילוי משבצת, לוחצים על הסמל + כדי להוסיף משבצת חדשה.
  3. בקטע בחירת סוג, בוחרים את סוג המיקום actions.type.DeliveryAddressValue.
  4. בשדה 'שם מיקום', מזינים למשבצת את השם TransactionDeliveryAddress.
  5. מפעילים את תיבת הסימון התאמה אישית של כתיבת ערך מיקום בדף (מופעלת כברירת מחדל).
  6. מקישים על שמירה.

בהגדרת יחידת הקיבולת (Slot), אפשר לספק reason שמאפשר להקדים את הבקשה של Assistant לקבל כתובת במחרוזת.ברירת המחדל מחרוזת הסיבה היא "כדי לדעת לאן לשלוח את ההזמנה". לכן, Assistant עשוי לשאול את המשתמש: "כדי לדעת לאן לשלוח את ההזמנה, אצטרך לקבל את הכתובת שלך למשלוח".

  • בפלטפורמות עם מסך, המשתמשים יכולים לבחור באיזו כתובת להשתמש עבור העסקה. אם הוא לא נתן כתובת בעבר, הוא יקבל אפשר להזין כתובת חדשה.
  • בפלטפורמות של קול בלבד, Assistant תבקש מהמשתמש הרשאה לשתף את כתובת ברירת המחדל שלו עבור העסקה. אם הם לא עשו זאת בעבר בהינתן כתובת, השיחה תועבר לטלפון לצורך כניסה.

כדי לטפל בתוצאה של הכתובת למשלוח, יש לבצע את השלבים הבאים:

  1. בכרטיסייה סצנות, בוחרים את הסצנה החדשה שיצרתם ב-DeliveryAddress.
  2. בקטע תנאי, לוחצים על הסמל + כדי להוסיף תנאי חדש.
  3. בשדה הטקסט, מזינים את תחביר התנאי הבא כדי לבדוק אם תנאי להצלחה:

    scene.slots.status == "FINAL" && session.params.TransactionDeliveryAddress.userDecision == "ACCEPTED"
    
  4. מעבירים את העכבר מעל התנאי שהוספתם ולוחצים על החץ למעלה. כדי להציב אותו לפני if scene.slots.status == "FINAL".

  5. מפעילים את האפשרות שליחת הנחיות ושולחים הנחיה פשוטה, יודעים שקיבלתם את הכתובת שלהם:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Great! Your order will be delivered to
                $session.params.TransactionDeliveryAddress.location.postalAddress.locality
                $session.params.TransactionDeliveryAddress.location.postalAddress.administrativeArea
                $session.params.TransactionDeliveryAddress.location.postalAddress.regionCode
                $session.params.TransactionDeliveryAddress.location.postalAddress.postalCode
    
  6. בקטע מעבר, בוחרים סצנה אחרת ומאפשרים למשתמש להמשיך את השיחה.

  7. בוחרים את התנאי else if scene.slots.status == "FINAL".

  8. מפעילים את האפשרות שליחת הנחיות ומספקים הנחיה פשוטה כדי ליידע את המשתמש הם לא יכולים לבצע עסקה:

    candidates:
      - first_simple:
          variants:
            - speech: I failed to get your delivery address.
    
  9. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה אם המשתמש לא יכול לבצע עסקאות.

יצירת ההזמנה

לאחר שיהיה לך את פרטי המשתמש הדרושים לך, תיצרו 'עגלת קניות' assembly" שמנחה את המשתמש לבנות הזמנה. כל פעולה תהליך הרכבה של עגלת הקניות מעט שונה, בהתאם לגבי מוצר או שירות.

בחוויית ההרכבה הבסיסית ביותר של עגלת הקניות, המשתמשים יכולים לבחור פריטים מתוך רשימה להוספה לפי הסדר שלהם, למרות שאפשר לעצב את השיחה כדי לפשט את חוויית המשתמש. תוכלו לבנות חוויה של הרכבה של עגלת קניות שמאפשרת כדי להזמין מחדש את הרכישה האחרונה שבצעה באמצעות שאלה פשוטה של 'כן' או 'לא'. אפשר גם להציג למשתמש קרוסלה או כרטיס רשימה של הנכסים המובילים. או 'מומלץ' פריטים.

מומלץ להשתמש בטקסט עשיר תגובות להצגת האפשרויות למשתמש חזותית, אלא גם לעצב את השיחה כך שהמשתמש יוכל לבנות באמצעות הקול בלבד. לקבלת כמה שיטות מומלצות ודוגמאות הרכבת עגלות קניות באיכות גבוהה, הנחיות לעיצוב.

יצירת הזמנה

צריך לאסוף לאורך השיחה את הפריטים שהמשתמש רוצה כדי לרכוש ואז ליצור אובייקט Order.

לכל הפחות, Order חייב לכלול את הפרטים הבאים:

  • buyerInfo - מידע על המשתמש שמבצע את הרכישה.
  • transactionMerchant – מידע לגבי המוֹכר שאחראי כדי להשלים את ההזמנה.
  • contents – התוכן בפועל של ההזמנה שרשום כ-lineItems.
  • priceAttributes - פרטי מחיר של ההזמנה, כולל הסכום הכולל עלות ההזמנה כולל הנחות ומיסים.

אפשר להיעזר בOrder. תיעוד התגובות כדי לבנות את עגלת הקניות. לתשומת ליבכם: יכול להיות שתצטרכו לכלול בשדות שונים, בהתאם לסדר.

הקוד לדוגמה הבא מציג הזמנה מלאה, כולל שדות אופציונליים:

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',
  },
};

יצירת אפשרויות לסדר ולמצגת

לפני שהמשתמש יאשר את ההזמנה, תוצג לו הצעה כרטיס ההזמנה. אפשר להתאים אישית את האופן שבו הכרטיס הזה מוצג למשתמש על ידי להגדיר אפשרויות שונות של סדר והצגה.

בהמשך מפורטות אפשרויות ההזמנה וההצגה לביצוע הזמנה שדורשת כתובת למשלוח, כולל כתובת האימייל של המשתמש, שמופיעה בכרטיס אישור ההזמנה:

const orderOptions = {
      'requestDeliveryAddress': true,
      'userInfoOptions': {
        'userInfoProperties': ['EMAIL']
      }
    };

const presentationOptions = {
      'actionDisplayName': 'PLACE_ORDER'
    };

יצירת פרמטרים של תשלום

האובייקט paymentParameters יכלול פרמטרים של יצירת אסימונים משתנה בהתאם למעבד של Google Pay שבו אתם מתכוונים להשתמש (למשל Stripe , Braintree , ACI וכו').

const paymentParamenters = {
      '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',
          },
        }),
      },
    };

התוכן של האובייקט tokenizationSpecification יהיה שונה בכל אחד מהם שער לתשלומים. בטבלה הבאה מוצגים הפרמטרים שבהם נעשה שימוש בכל שער:

דוגמה
"parameters": {
  "gateway": "example",
  "gatewayMerchantId": "exampleGatewayMerchantId"
}
ACI
"parameters": {
  "gateway": "aciworldwide",
  "gatewayMerchantId": "YOUR_ENTITY_ID"
}
ADYEN
"parameters": {
  "gateway": "adyen",
  "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME"
}
ALFA-BANK
"parameters": {
  "gateway": "alfabank",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
BLUE_MEDIA
"parameters": {
  "gateway": "bluemedia",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
BLUESNAP
"parameters": {
  "gateway": "bluesnap",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
BRAINTREE
"parameters": {
  "gateway": "braintree",
  "braintree:apiVersion": "v1",
  "braintree:sdkVersion": braintree.client.VERSION,
  "braintree:merchantId": "YOUR_BRAINTREE_MERCHANT_ID",
  "braintree:clientKey": "YOUR_BRAINTREE_TOKENIZATION_KEY"
}
CHASE_PAYMENTECH
"parameters": {
  "gateway": "chase",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ACCOUNT_NUMBER"
}
תשלום
"parameters": {
  "gateway": "checkoutltd",
  "gatewayMerchantId": "YOUR_PUBLIC_KEY"
}
תשלומים בענן
"parameters": {
  "gateway": "cloudpayments",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
CYBERSOURCE
"parameters": {
  "gateway": "cybersource",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
DATATRANS
"parameters": {
  "gateway": "datatrans",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
EBANX
"parameters": {
  "gateway": "ebanx",
  "gatewayMerchantId": "YOUR_PUBLIC_INTEGRATION_KEY"
}
FIRST_DATA
"parameters": {
  "gateway": "firstdata",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
GLOBAL_PAYMENTS
"parameters": {
  "gateway": "globalpayments",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
Google Pay
"parameters": {
  "gateway": "gopay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
היטים
"parameters": {
  "gateway": "hitrustpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
פתרונות
"parameters": {
  "gateway": "imsolutions",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
LYRA
"parameters": {
  "gateway": "lyra",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
MPGS
"parameters": {
  "gateway": "mpgs",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
MONEY_MAIL_RU
"parameters": {
  "gateway": "moneymailru",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
NEWebPay
"parameters": {
  "gateway": "newebpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
NEXI
"parameters": {
  "gateway": "nexi",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
NMI
"parameters": {
  "gateway": "creditcall",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
תשלום בטוח
"parameters": {
  "gateway": "paysafe",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
תשלום
"parameters": {
  "gateway": "payture",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
PAYU
"parameters": {
  "gateway": "payu",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
PRZELEWY24
"parameters": {
  "gateway": "przelewy24",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
RBKMoney
"parameters": {
  "gateway": "rbkmoney",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
SBERBANK
"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"
}
TAPPAY
"parameters": {
  "gateway": "tappay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
טינקוף
"parameters": {
  "gateway": "tinkoff",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
יחידה
"parameters": {
  "gateway": "uniteller",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
VANTIV
"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"
}
YANDEX
"parameters": {
  "gateway": "yandexcheckout",
  "gatewayMerchantId": "YOUR_SHOP_ID"
}

שמירת נתוני ההזמנה בפרמטר של סשן

ברשימת ההזמנות, שומרים את נתוני ההזמנה בפרמטר של סשן. ההזמנה ייעשה שימוש באובייקט בכל סצנות באותו סשן.

conv.session.params.order = {
    '@type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec',
    order: order,
    orderOptions: orderOptions,
    presentationOptions: presentationOptions,
    paymentParameters: paymentParameters
};

הצעת ההזמנה

אחרי שיוצרים הזמנה, צריך להציג אותה למשתמש כדי לאשר או לדחות. כדי לעשות את זה, צריך לעבור לסצנה שבה מקבלים החלטה בנוגע לעסקה.

יצירת סצנה של החלטה על עסקה

  1. מהכרטיסייה סצנות, מוסיפים סצנה חדשה בשם TransactionDecision.
  2. בקטע מילוי משבצת, לוחצים על הסמל + כדי להוסיף משבצת חדשה.
  3. בקטע בחירת סוג, בוחרים את actions.type.TransactionDecisionValue בתור סוג משבצת הזמן.
  4. בשדה 'שם מיקום', מזינים למשבצת את השם TransactionDecision.
  5. מפעילים את תיבת הסימון התאמה אישית של כתיבת ערך מיקום בדף (מופעלת כברירת מחדל).
  6. בקטע הגדרת משבצת, בוחרים באפשרות שימוש בפרמטר סשן מהתפריט הנפתח.
  7. בקטע הגדרת משבצת,מזינים את השם של פרמטר הסשן שבו נעשה שימוש. לשמור את ההזמנה בשדה הטקסט (למשל $session.params.order).
  8. מקישים על שמירה.

Assistant מנסה למלא משבצת של TransactionDecisionValue חוויה מובנית שבה Order שהעברתם מעובדת ישירות 'כרטיס תצוגה מקדימה של עגלת הקניות'. המשתמש יכול לומר "place order" (הזמנה), לדחות את העסקה, לשנות אפשרות תשלום כמו כרטיס האשראי או הכתובת, או לבקש לשנות תוכן ההזמנה.

בשלב הזה, המשתמש גם יוכל לבקש שינויים בהזמנה. במקרה הזה, לוודא שמילוי ההזמנה יוכל לטפל בבקשות לשינוי הזמנה לאחר סיום החוויה של הרכבת עגלת הקניות.

טיפול בתוצאה של ההחלטה לגבי העסקה

כשמשבצת TransactionDecisionValue מתמלאת, התשובה של המשתמש ההחלטה בנוגע לעסקה תישמר בפרמטר של סשן. הערך הזה מכיל הבאים:

  • ORDER_ACCEPTED,
  • ORDER_REJECTED,
  • DELIVERY_ADDRESS_UPDATED,
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT.

כדי לטפל בתוצאה של החלטה לגבי עסקה:

  1. בכרטיסייה סצנות, בוחרים את הסצנה החדשה שיצרתם ב-TransactionDecision.
  2. בקטע תנאי, לוחצים על הסמל + כדי להוסיף תנאי חדש.
  3. בשדה הטקסט, מזינים את התחביר של התנאי הבא כדי לבדוק את התנאי להצלחה:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. מעבירים את העכבר מעל התנאי שהוספתם ולוחצים על החץ למעלה. כדי להציב אותו לפני if scene.slots.status == "FINAL".

  5. מפעילים את האפשרות שליחת הנחיות ומספקים הנחיה פשוטה כדי ליידע את המשתמש ההזמנה שלהם הושלמה:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your order
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה.

  7. בקטע תנאי, לוחצים על הסמל + כדי להוסיף תנאי חדש.

  8. בשדה הטקסט, מזינים את תחביר התנאי הבא כדי לבדוק אם תנאים של כשל:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. מעבירים את העכבר מעל התנאי שהוספתם ולוחצים על החץ למעלה. כדי להציב אותו לפני if scene.slots.status == "FINAL".

  10. מפעילים את האפשרות שליחת הנחיות ומספקים הנחיה פשוטה כדי ליידע את המשתמש ההזמנה נדחתה:

    candidates:
      - first_simple:
          variants:
            - speech: Look like you don't want to order anything. Goodbye.
    
  11. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה.

  12. בוחרים את התנאי else if scene.slots.status == "FINAL".

  13. מפעילים את האפשרות שליחת הנחיות ושולחים הנחיה פשוטה, יודעים שהם לא יכולים לבצע עסקה:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה אם המשתמש לא יכול לבצע עסקאות.

השלמת ההזמנה ושליחת קבלה

כשהמשבצת TransactionDecisionValue מחזירה תוצאה של ORDER_ACCEPTED, עליכם לבצע באופן מיידי כל עיבוד שנדרש כדי "לאשר" ה (למשל, לשמור אותו במסד הנתונים שלכם ולטעון את המשתמש).

אפשר לסיים את השיחה באמצעות התשובה הזו, אבל צריך לכלול שאלה פשוטה כדי למנוע את המשך השיחה. אחרי שתספקו את האות שמייצגת אותו orderUpdate, המשתמש יראה "כרטיס קבלה מכווץ" וגם כל השאר של התשובה שלך. הכרטיס הזה ישקף את הקבלה שהמשתמש מצא היסטוריית ההזמנות.

במהלך אישור ההזמנה, אובייקט ההזמנה יכול לכלול userVisibleOrderId, המזהה הזה שהמשתמש רואה בהזמנה. אפשר להשתמש שוב merchantOrderId בשדה הזה.

חלק מהאובייקט OrderUpdate צריך להכיל אובייקט פעולת המשך, שמנוסח כלחצנים של כתובות URL בחלק התחתון של פרטי ההזמנה שהמשתמש יכול להזין יכול למצוא בהיסטוריית ההזמנות שלהם ב-Assistant.

  • עליך לספק לכל הפחות VIEW_DETAILS פעולת המשך בכל הזמנה. הוא אמור להכיל קישור עומק אל ייצוג של ההזמנה באפליקציה לנייד או באתר שלכם.
  • כמו כן, עליכם לשלוח קבלה רשמית באימייל שעומדת בכל הדרישות המשפטיות דרישות לביצוע עסקה, בנוסף לכרטיס הקבלה בשיחה של הפעולה.

כדי לשלוח עדכון ראשוני של ההזמנה:

  1. בכרטיסייה סצנות, בוחרים את הסצנה TransactionDecision.
  2. בקטע תנאי, בוחרים את התנאי שבודק את התוצאה בהצלחה, ORDER_ACCEPTED:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. עבור התנאי הזה, צריך להפעיל את האפשרות קריאה לפעולה מאתר אחר (webhook) ולציין Intent שם ה-handler, למשל update_order.

  4. בקוד של תגובה לפעולה מאתר אחר (webhook), צריך להוסיף handler של Intent לשליחת הזמנה ראשונית עדכון:

    app.handle('update_order', conv => {
      const currentTime = new Date().toISOString();
      let order = conv.session.params.TransactionDecision.order;
      conv.add(new OrderUpdate({
        'updateMask': {
          'paths': [
            'purchase.status',
            'purchase.user_visible_status_label'
          ]
        },
        'order': {
          'merchantOrderId': order.merchantOrderId,
          'lastUpdateTime': currentTime,
          'purchase': {
            'status': 'CONFIRMED',
            'userVisibleStatusLabel': 'Order confirmed'
          },
        },
        'reason': 'Reason string
      }));
    });
    

שליחת עדכונים לגבי ההזמנה

צריך לעדכן את המשתמש לגבי סטטוס ההזמנה במהלך כל משך החיים שלו. שליחת עדכונים של הזמנת המשתמש על ידי שליחת HTTP בקשות PATCH ל-Orders API עם סטטוס ההזמנה ופרטי ההזמנה.

הגדרת בקשות אסינכרוניות ל-Orders API

בקשות לעדכון הזמנות ל-Orders API מורשות על ידי גישה ב-Assistant. כדי PATCH עדכון הזמנה ל-Orders API, צריך להוריד קובץ JSON מפתח של חשבון שירות שמשויך לפרויקט ב-Actions Console, ולאחר מכן החלפה את המפתח של חשבון השירות לאסימון למוכ"ז שניתן להעביר אל הכותרת Authorization של בקשת ה-HTTP.

כדי לאחזר את המפתח של חשבון השירות, מבצעים את השלבים הבאים:

  1. במסוף Google Cloud, צריך לעבור לתפריט TODO > ממשקי API שירותים > פרטי כניסה > יצירת פרטי כניסה > מפתח לחשבון השירות.
  2. בקטע Service Account (חשבון שירות), בוחרים באפשרות New Service Account (חשבון שירות חדש).
  3. מגדירים את חשבון השירות בתור service-account.
  4. מגדירים את Role לערך Project > בעלים.
  5. צריך להגדיר את סוג המפתח כ-JSON.
  6. בוחרים באפשרות יצירה.
  7. תתבצע הורדה של מפתח חשבון שירות פרטי בפורמט JSON למחשב המקומי שלך.

בקוד לעדכון ההזמנה, אפשר להחליף את מפתח השירות באסימון למוכ"ז באמצעות ספריית הלקוח של Google APIs ההיקף "https://www.googleapis.com/auth/actions.order.developer". טיפים נוספים לאופטימיזציה מפורטים שלבי ההתקנה ודוגמאות בספריית הלקוח של ה-API. דף GitHub.

אפשר לעיין גם בכתובת order-update.js דוגמה של Node.js לחילופי מפתחות לדוגמה.

שליחת עדכונים לגבי ההזמנה

אחרי שהחלפתם את המפתח של חשבון השירות באסימון למוכ"ז של OAuth, אפשרות לשלוח עדכוני הזמנות כבקשות PATCH מורשות ל-Orders API.

כתובת ה-URL של Orders API: PATCH https://actions.googleapis.com/v3/orders/${orderId}

צריך לכלול בבקשה את הכותרות הבאות:

  • "Authorization: Bearer token" עם האסימון למוכ"ז OAuth החלפתם את המפתח של חשבון השירות.
  • "Content-Type: application/json".

בקשת PATCH צריכה לקחת גוף 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:

// 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 client library.
const {OrderUpdate} = require('@assistant/conversation');

// 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: {
      paths: [
        'purchase.status',
        'purchase.user_visible_status_label'
      ]
    },
    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);
} catch (e) {
  console.log(`Error: ${e}`);
}
הגדרת סטטוס הרכישה

status של עדכון הזמנה חייב לתאר את המצב הנוכחי של הצו. בorder.purchase.status של העדכון צריך להשתמש באחד מהערכים הבאים:

  • CREATED – ההזמנה אושרה על ידי המשתמש ו'נוצרה' מנקודת מבט של הפעולה, אבל נדרש עיבוד ידני בקצה העורפי.
  • CONFIRMED – ההזמנה פעילה ומעובדת למילוי הזמנות.
  • IN_PREPARATION – ההזמנה נמצאת בהכנה למשלוח או למשלוח, למשל אוכל מבשלים או פריט שנארז.
  • READY_FOR_PICKUP – ההזמנה זמינה לאיסוף על ידי הנמען.
  • DELIVERED - ההזמנה נמסרה לנמען
  • OUT_OF_STOCK – פריט אחד או יותר בהזמנה חסרים במלאי.
  • CHANGE_REQUESTED – המשתמש ביקש לשנות את ההזמנה, והשינוי בתהליך עיבוד.
  • RETURNED – המשתמש החזיר את ההזמנה לאחר המסירה.
  • REJECTED – אם לא הצלחת לעבד את הבקשה, לבצע חיוב או בדרך אחרת 'הפעלה' כדי להשלים את ההזמנה.
  • CANCELLED - ההזמנה בוטלה על ידי המשתמש.

עליך לשלוח עדכונים של הזמנות עבור כל סטטוס שרלוונטי העסקה. לדוגמה, אם העסקה מחייבת עיבוד ידני כדי תיעוד ההזמנה לאחר ביצועה, שליחת עדכון הזמנה ב-CREATED עד שנדרש עיבוד נוסף. לא כל הזמנה מחייבת את כל ערכי הסטטוסים.

בדיקת הפרויקט

כשבודקים את הפרויקט, אפשר להפעיל את מצב ארגז החול במסוף הפעולות כדי לבדוק את הפעולה בלי לחייב אמצעי תשלום. כדי להפעיל את מצב Sandbox, מבצעים את השלבים הבאים:

  1. במסוף הפעולות, לוחצים על בדיקה בניווט.
  2. לוחצים על הגדרות.
  3. מפעילים את האפשרות פיתוח ארגז חול.

עבור עסקאות פיזיות, אפשר גם להגדיר את השדה isInSandbox לערך true ב לדוגמה. הפעולה הזו מקבילה להפעלת ההגדרה של מצב ארגז חול (sandbox) במסוף הפעולות. כדי לראות קטע קוד שמשתמש ב-isInSandbox, יש לעיין ב שליחת עדכוני הזמנות.

פתרון בעיות

אם תיתקלו בבעיות במהלך הבדיקה, כדאי לקרוא את השלבים לפתרון בעיות. לעסקאות.