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

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

תהליך העסקה

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

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

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

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

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

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

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

דוגמאות מקיפות של שיחות ב-Node.js מפורטות בדוגמה של טרנזקציות ב-Node.js.

Setup (הגדרה)

כשיוצרים את Action, צריך לציין שרוצים לבצע טרנזקציות ב-Actions Console.

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

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

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

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

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

יצירת סצנה לבדיקת הדרישות לגבי העסקה
  1. מהכרטיסייה 'סצנות', מוסיפים סצנה חדשה בשם TransactionRequirementsCheck.
  2. בקטע מילוי משבצת, לוחצים על + כדי להוסיף יחידת קיבולת (Slot) חדשה.
  3. בקטע Select type בוחרים באפשרות actions.type.TransactionRequirementsCheckResult בתור הסוג של יחידת הקיבולת.
  4. בשדה השם של יחידת הקיבולת (Slot), מזינים את השם 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. בקטע transit (מעבר) בוחרים סצנה אחרת שמאפשרת למשתמש להמשיך את השיחה ולהמשיך בביצוע הטרנזקציה.

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

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

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

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

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

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

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

כשמגדירים את יחידת הקיבולת (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. בקטע מעבר, בוחרים באפשרות סיום השיחה כדי לסיים את השיחה, אם המשתמש לא מצליח לבצע עסקאות.

יצירת ההזמנה

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

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

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

יצירת הזמנה

במהלך השיחה תצטרכו לאסוף את הפריטים שהמשתמש רוצה לרכוש ואז ליצור אובייקט 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"
}
ברזיל
"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"
}
CLOUDPAYMENTS
"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"
}
GOPAY
"parameters": {
  "gateway": "gopay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
היט
"parameters": {
  "gateway": "hitrustpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
IMSOLUTIONS
"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"
}
AMOUNT_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"
}
PAYSafe
"parameters": {
  "gateway": "paysafe",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
PAYTURE
"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"
}
כסף RBK (RBK)
"parameters": {
  "gateway": "rbkmoney",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
SBERBANK
"parameters": {
  "gateway": "sberbank",
  "gatewayMerchantId": "YOUR_ORGANIZATION_NAME"
}
ריבוע
"parameters": {
  "gateway": "square",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
StripE
"parameters": {
  "gateway": "stripe",
  "stripe:version": "2018-10-31",
  "stripe:publishableKey": "YOUR_PUBLIC_STRIPE_KEY"
}
TAPPAY
"parameters": {
  "gateway": "tappay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
TINKOFF
"parameters": {
  "gateway": "tinkoff",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
UNITELLER
"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"
}
WORLDPAY
"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. בקטע מילוי משבצת, לוחצים על + כדי להוסיף יחידת קיבולת (Slot) חדשה.
  3. בקטע Select type בוחרים את הסוג actions.type.TransactionDecisionValue.
  4. בשדה השם של יחידת הקיבולת (Slot), מזינים את השם TransactionDecision.
  5. מפעילים את תיבת הסימון התאמה אישית של ערך המשבצת (מופעלת כברירת מחדל).
  6. בקטע הגדרת מיקום מודעה, בוחרים באפשרות שימוש בפרמטר סשן מהתפריט הנפתח.
  7. בקטע Configure o [הגדרת משבצת] מזינים בשדה הטקסט את השם של פרמטר הסשן שמשמש לשמירת ההזמנה (כלומר $session.params.order).
  8. לוחצים על Save (שמירה).

בניסיון למלא משבצת של TransactionDecisionValue, Assistant מתחילה חוויה מובנית שבה 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 בכל הזמנה. הקישור צריך לכלול קישור עומק לייצוג ההזמנה באפליקציה לנייד או באתר שלכם.
  • עליכם גם לשלוח קבלה רשמית באימייל שעומדת בכל הדרישות המשפטיות לביצוע עסקה, בנוסף לכרטיס הקבלה בשיחה של Action.

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

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

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. בתנאי הזה, מפעילים את התכונה Call your webhook ונותנים שם של handler של Intent, כמו 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 מורשות באמצעות אסימון גישה. כדי לבצע תיקון של עדכון הזמנה ל-Orders API, צריך להוריד מפתח של חשבון שירות JSON שמשויך לפרויקט Actions Console, ואז להחליף את המפתח של חשבון השירות באסימון למוכ"ז שאפשר להעביר אל הכותרת Authorization של בקשת ה-HTTP.

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

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

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

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

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

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

כתובת ה-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 שניתן להציג במכשיר של המשתמש כשהעדכון הזה נשלח. שימו לב שהוספה של האובייקט הזה לא מבטיחה שתופיע התראה במכשיר של המשתמש.

הקוד לדוגמה הבא מציג דוגמה 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 במסוף Actions כדי לבדוק את הפעולה בלי לחייב אמצעי תשלום. כדי להפעיל את מצב ארגז החול, בצעו את השלבים הבאים:

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

בעסקאות פיזיות, אפשר גם להגדיר את השדה isInSandbox כ-true בדוגמה. פעולה זו מקבילה להפעלת ההגדרה של מצב ארגז חול במסוף הפעולות. כדי לראות קטע קוד שמשתמש ב-isInSandbox, תוכלו לעיין בקטע Send order updates.

פתרון בעיות

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