สร้างการจอง (Dialogflow)

คู่มือนี้จะแนะนำขั้นตอนการพัฒนาโปรเจ็กต์ Actions ที่ใช้ Orders API ในการจอง

ขั้นตอนการทำธุรกรรม

เมื่อโปรเจ็กต์ Actions จัดการการจอง จะใช้ขั้นตอนต่อไปนี้

  1. ตรวจสอบข้อกำหนดด้านธุรกรรม (ไม่บังคับ) - ใช้ผู้ช่วยข้อกำหนดของธุรกรรมเมื่อเริ่มการสนทนาเพื่อให้แน่ใจว่าผู้ใช้จะทำธุรกรรมได้
  2. สร้างคำสั่งซื้อ - พาผู้ใช้ไปดู "ชุดประกอบรถเข็น" ที่พวกเขาสร้างรายละเอียดการจอง
  3. เสนอคำสั่งซื้อ - เมื่อ "รถเข็น" เสร็จสมบูรณ์ ให้เสนอ "คำสั่งซื้อ" การจองแก่ผู้ใช้เพื่อให้ผู้ใช้ยืนยันว่าถูกต้อง หากการจองได้รับการยืนยันแล้ว คุณจะได้รับการตอบกลับพร้อมรายละเอียดการจอง
  4. สรุปคำสั่งซื้อและส่งใบเสร็จ - เมื่อยืนยันคำสั่งซื้อแล้ว ให้อัปเดตระบบการจองและส่งใบเสร็จให้ผู้ใช้
  5. ส่งการอัปเดตคำสั่งซื้อ - ให้การอัปเดตสถานะการจองของผู้ใช้ตลอดระยะเวลาอายุการใช้งานของการจองโดยส่งคำขอ Patch ไปยัง Orders API

ข้อจำกัดและหลักเกณฑ์การตรวจสอบ

โปรดทราบว่านโยบายเพิ่มเติมมีผลบังคับใช้กับการดำเนินการที่ใช้ Transaction และ Orders API เราอาจใช้เวลาถึง 6 สัปดาห์ในการตรวจสอบการดำเนินการที่มีธุรกรรม ดังนั้นโปรดคำนึงถึงเวลาดังกล่าวเมื่อวางแผนกำหนดการเผยแพร่ เพื่อช่วยให้กระบวนการตรวจสอบง่ายขึ้น โปรดตรวจสอบว่าคุณปฏิบัติตามนโยบายและหลักเกณฑ์สำหรับธุรกรรมก่อนส่งการดำเนินการเข้ารับการตรวจสอบ

คุณใช้งานการดำเนินการที่ใช้ Orders API ได้ในประเทศต่อไปนี้เท่านั้น

ออสเตรเลีย
บราซิล
แคนาดา
อินโดนีเซีย
ญี่ปุ่น
เม็กซิโก
กาตาร์
รัสเซีย
สิงคโปร์
สวิตเซอร์แลนด์
ไทย
ตุรกี
สหราชอาณาจักร
สหรัฐอเมริกา

สร้างโปรเจ็กต์

ดูตัวอย่างธุรกรรมของเราใน Node.js และ Java เพื่อดูตัวอย่างการสนทนาเกี่ยวกับธุรกรรมทั้งหมด

ตั้งค่าโครงการ

เมื่อสร้างการดำเนินการ คุณต้องระบุว่าคุณต้องการดำเนินธุรกรรมในคอนโซล Actions นอกจากนี้ หากใช้ไลบรารีของไคลเอ็นต์ Node.JS ให้ตั้งค่า Fulfillment ให้ใช้ Orders API เวอร์ชันล่าสุดด้วย

หากต้องการตั้งค่าโปรเจ็กต์และการดำเนินการตามคำสั่งซื้อ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างโปรเจ็กต์ใหม่หรือนำเข้าโปรเจ็กต์ที่มีอยู่
  2. ไปที่ทำให้ใช้งานได้ > ข้อมูลไดเรกทอรี
  3. ในส่วนข้อมูลเพิ่มเติม > ธุรกรรม > เลือกช่องที่ระบุว่า "การดำเนินการของคุณใช้ Transaction API ในการทำธุรกรรมสินค้าที่จับต้องได้ไหม"

  4. หากคุณใช้ไลบรารีของไคลเอ็นต์ Node.JS เพื่อสร้าง Fulfillment ของการดำเนินการ ให้เปิดโค้ด Fulfillment และอัปเดตการจัดการแอปเพื่อตั้งค่าแฟล็ก 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. ตรวจสอบข้อกำหนดของธุรกรรม (ไม่บังคับ)

ประสบการณ์ของผู้ใช้

ทันทีที่ผู้ใช้ระบุว่าต้องการตั้งค่าการจอง เราขอแนะนำให้ทริกเกอร์ Intent actions.intent.TRANSACTION_REQUIREMENTS_CHECK เพื่อให้แน่ใจว่าจะขอจองได้ ตัวอย่างเช่น เมื่อเรียกใช้ การดำเนินการของคุณอาจถามว่า "คุณต้องการสำรองที่นั่งไหม" หากผู้ใช้ตอบว่า "ใช่" คุณควรขอ Intent นี้ทันที ซึ่งจะช่วยให้มั่นใจว่าผู้ใช้จะดำเนินการต่อได้และเปิดโอกาสให้ผู้ใช้แก้ไขการตั้งค่าที่ขัดขวางการทำธุรกรรมต่อได้

การขอให้ตรวจสอบ Intent ของธุรกรรมจะส่งผลให้เกิดผลลัพธ์อย่างใดอย่างหนึ่งต่อไปนี้

  • หากเป็นไปตามข้อกำหนด การดำเนินการตามคำสั่งซื้อจะได้รับ Intent ที่มีเงื่อนไข "สำเร็จ" และคุณจะสร้างคำสั่งซื้อของผู้ใช้ต่อไปได้
  • หากไม่เป็นไปตามข้อกำหนดอย่างน้อย 1 ข้อ การดำเนินการของคุณจะได้รับ Intent ที่มีเงื่อนไขล้มเหลว ในกรณีนี้ ให้จบการสนทนาหรือ สลับออกจากขั้นตอนการจอง

    หากผู้ใช้แก้ไขข้อผิดพลาดได้ ระบบจะแจ้งให้แก้ไขปัญหาในอุปกรณ์โดยอัตโนมัติ ถ้าการสนทนาเกิดขึ้นบนพื้นผิวที่ใช้เสียงอย่างเดียว เช่น ลำโพงอัจฉริยะ เสียงนั้นจะส่งไปที่โทรศัพท์ของผู้ใช้

การดำเนินการตามคำสั่งซื้อ

โปรดส่งคำขอ Fulfillment ของ actions.intent.TRANSACTION_REQUIREMENTS_CHECK ด้วยออบเจ็กต์ TransactionRequirementsCheckSpec เพื่อให้แน่ใจว่าผู้ใช้เป็นไปตามข้อกำหนดด้านธุรกรรม

ตรวจสอบข้อกำหนด

ตรวจสอบว่าผู้ใช้มีคุณสมบัติตรงตามข้อกำหนดการจองที่มีไลบรารีของไคลเอ็นต์หรือไม่ ดังนี้

Node.js
conv.ask(new TransactionRequirements());
Java
return getResponseBuilder(request)
    .add("Placeholder for transaction requirements text")
    .add(new TransactionRequirements())
    .build();
Dialogflow JSON

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec"
        }
      }
    }
  }
}
API ของ Actions SDK

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec"
          }
        }
      ]
    }
  ]
}
รับผลการตรวจสอบข้อกำหนด

หลังจากที่ Assistant ดำเนินการตามความตั้งใจแล้ว ก็จะส่งคำขอสำหรับการดำเนินการตามเจตนารมณ์ actions.intent.TRANSACTION_REQUIREMENTS_CHECK ของคุณมาพร้อมกับผลการตรวจสอบ

โปรดประกาศ Intent ของ Dialogflow ที่ทริกเกอร์โดยเหตุการณ์ actions_intent_TRANSACTION_REQUIREMENTS_CHECK เพื่อจัดการคำขอนี้อย่างเหมาะสม เมื่อทริกเกอร์ ให้จัดการ Intent นี้ใน Fulfillment

Node.js
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!`);
} else {
  conv.close('Transaction failed.');
}
Java
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) {
  responseBuilder.add("Looks like you're good to go! Now say 'confirm transaction'");
} else {
  responseBuilder.add("Transaction failed");
}
return responseBuilder.build();
Dialogflow JSON

โปรดทราบว่า JSON ด้านล่างอธิบายคำขอเว็บฮุค

{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "reservation_transaction_check_complete_df",
      "displayName": "reservation_transaction_check_complete_df"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": [
            {
              "extension": {
                "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult",
                "resultType": "CAN_TRANSACT"
              },
              "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT"
            }
          ]
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}
API ของ Actions SDK

โปรดทราบว่า JSON ด้านล่างอธิบายคำขอเว็บฮุค

{
  "user": {},
  "device": {},
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "conversation": {},
  "inputs": [
    {
      "rawInputs": [],
      "intent": "reservation_transaction_check_complete_asdk",
      "arguments": [
        {
          "extension": {
            "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult",
            "resultType": "CAN_TRANSACT"
          },
          "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT"
        }
      ]
    }
  ],
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

2. สร้างคำสั่งซื้อ

ประสบการณ์ของผู้ใช้

เมื่อคุณมีข้อมูลผู้ใช้ที่ต้องการแล้ว ให้สร้างการใช้งาน "การประกอบรถเข็น" ที่จะช่วยแนะนำการสร้างการจอง การทำงานทุกครั้งจะมีขั้นตอนการประกอบรถเข็นที่แตกต่างกันเล็กน้อยตามที่เหมาะสมสำหรับการบริการ

ในการประกอบรถเข็นแบบพื้นฐาน ผู้ใช้จะเลือกตัวเลือกจากรายการเพื่อเพิ่มลงในการจอง แม้ว่าคุณจะออกแบบการสนทนาเพื่อลดความซับซ้อนของประสบการณ์ผู้ใช้ได้ก็ตาม เช่น สร้างประสบการณ์การประกอบรถเข็นที่ช่วยให้ผู้ใช้กำหนดเวลาการจองรายเดือนได้ด้วยคำถามใช่หรือไม่ง่ายๆ คุณยังแสดงภาพสไลด์หรือการ์ดลิสต์ของการจอง "แนะนำ" แก่ผู้ใช้ได้ด้วย

เราขอแนะนำให้ใช้การตอบกลับที่สมบูรณ์เพื่อนำเสนอตัวเลือกของผู้ใช้ให้เห็นเป็นภาพ แต่ก็ออกแบบการสนทนาเพื่อให้ผู้ใช้สร้างรถเข็นได้โดยใช้เพียงเสียงเท่านั้น ดูแนวทางปฏิบัติแนะนำและตัวอย่างประสบการณ์ประกอบรถเข็นได้ที่หลักเกณฑ์การออกแบบธุรกรรม

การดำเนินการตามคำสั่งซื้อ

ระหว่างการสนทนา ให้รวบรวมรายละเอียดการจองที่ผู้ใช้ต้องการซื้อ แล้วสร้างออบเจ็กต์ Order

Order ของคุณต้องมีข้อมูลต่อไปนี้เป็นอย่างน้อย

  • buyerInfo - ข้อมูลเกี่ยวกับผู้ใช้ที่กำหนดเวลาจอง
  • transactionMerchant - ข้อมูลเกี่ยวกับผู้ขายที่อำนวยความสะดวกในการจอง
  • contents - รายละเอียดจริงของการจองที่แสดงเป็น lineItems

โปรดดูเอกสารประกอบการตอบกลับของ Order เพื่อสร้างรถเข็นของคุณ โปรดทราบว่าคุณอาจต้องใส่ช่องที่ต่างกัน ทั้งนี้ขึ้นอยู่กับการจอง

โค้ดตัวอย่างด้านล่างแสดงคำสั่งซื้อการจองที่สมบูรณ์ รวมถึงช่องที่ไม่บังคับ

Node.js
app.intent('build_reservation_df', (conv) => {
  const now = new Date().toISOString();
  const order = {
    createTime: now,
    lastUpdateTime: now,
    merchantOrderId: 'UNIQUE_ORDER_ID',
    userVisibleOrderId: 'USER_VISIBLE_ORDER_ID',
    transactionMerchant: {
      id: 'https://www.example.com',
      name: 'Example Merchant',
    },
    contents: {
      lineItems: [
        {
          id: 'LINE_ITEM_ID',
          name: 'Dinner reservation',
          description: 'A world of flavors all in one destination.',
          reservation: {
            status: 'PENDING',
            userVisibleStatusLabel: 'Reservation is pending.',
            type: 'RESTAURANT',
            reservationTime: {
              timeIso8601: '2020-01-16T01:30:15.01Z',
            },
            userAcceptableTimeRange: {
              timeIso8601: '2020-01-15/2020-01-17',
            },
            partySize: 6,
            staffFacilitators: [
              {
                name: 'John Smith',
              },
            ],
            location: {
              zipCode: '94086',
              city: 'Sunnyvale',
              postalAddress: {
                regionCode: 'US',
                postalCode: '94086',
                administrativeArea: 'CA',
                locality: 'Sunnyvale',
                addressLines: [
                  '222, Some other Street',
                ],
              },
            },
          },
        },
      ],
    },
    buyerInfo: {
      email: 'janedoe@gmail.com',
      firstName: 'Jane',
      lastName: 'Doe',
      displayName: 'Jane Doe',
    },
    followUpActions: [
      {
        type: 'VIEW_DETAILS',
        title: 'View details',
        openUrlAction: {
          url: 'https://example.com',
        },
      },
      {
        type: 'CALL',
        title: 'Call us',
        openUrlAction: {
          url: 'tel:+16501112222',
        },
      },
      {
        type: 'EMAIL',
        title: 'Email us',
        openUrlAction: {
          url: 'mailto:person@example.com',
        },
      },
    ],
    termsOfServiceUrl: 'https://www.example.com',
  };

Java
private static OrderV3 createOrder() {
  // Transaction Merchant
  MerchantV3 transactionMerchant = new MerchantV3()
      .setId("http://www.example.com")
      .setName("Example Merchant");

  // Line Item

  // Reservation Item Extension
  ReservationItemExtension reservationItemExtension = new ReservationItemExtension()
      .setStatus("PENDING")
      .setUserVisibleStatusLabel("Reservation pending.")
      .setType("RESTAURANT")
      .setReservationTime(new TimeV3()
          .setTimeIso8601("2020-01-16T01:30:15.01Z"))
      .setUserAcceptableTimeRange(new TimeV3()
          .setTimeIso8601("2020-01-15/2020-01-17"))
      .setPartySize(6)
      .setStaffFacilitators(Collections.singletonList(new StaffFacilitator()
          .setName("John Smith")))
      .setLocation(new Location()
          .setZipCode("94086")
          .setCity("Sunnyvale")
          .setPostalAddress(new PostalAddress()
              .setRegionCode("US")
              .setPostalCode("94086")
              .setAdministrativeArea("CA")
              .setLocality("Sunnyvale")
              .setAddressLines(
                  Collections.singletonList("222, Some other Street"))));

  LineItemV3 lineItem = new LineItemV3()
      .setId("LINE_ITEM_ID")
      .setName("Dinner reservation")
      .setDescription("A world of flavors all in one destination.")
      .setReservation(reservationItemExtension);

  // 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");

  // 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 = "https://example.com";

  String now = Instant.now().toString();

  OrderV3 order = new OrderV3()
      .setCreateTime(now)
      .setLastUpdateTime(now)
      .setMerchantOrderId("UNIQUE_ORDER_ID")
      .setUserVisibleOrderId("UNIQUE_USER_VISIBLE_ORDER_ID")
      .setTransactionMerchant(transactionMerchant)
      .setContents(contents)
      .setBuyerInfo(buyerInfo)
      .setFollowUpActions(Arrays.asList(
          viewDetails,
          call,
          email
      ))
      .setTermsOfServiceUrl(termsOfServiceUrl);

  return order;
}
JSON

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "order": {
            "createTime": "2019-07-17T18:25:30.182Z",
            "lastUpdateTime": "2019-07-17T18:25:30.182Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
            "transactionMerchant": {
              "id": "https://www.example.com",
              "name": "Example Merchant"
            },
            "contents": {
              "lineItems": [
                {
                  "id": "LINE_ITEM_ID",
                  "name": "Dinner reservation",
                  "description": "A world of flavors all in one destination.",
                  "reservation": {
                    "status": "PENDING",
                    "userVisibleStatusLabel": "Reservation is pending.",
                    "type": "RESTAURANT",
                    "reservationTime": {
                      "timeIso8601": "2020-01-16T01:30:15.01Z"
                    },
                    "userAcceptableTimeRange": {
                      "timeIso8601": "2020-01-15/2020-01-17"
                    },
                    "partySize": 6,
                    "staffFacilitators": [
                      {
                        "name": "John Smith"
                      }
                    ],
                    "location": {
                      "zipCode": "94086",
                      "city": "Sunnyvale",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94086",
                        "administrativeArea": "CA",
                        "locality": "Sunnyvale",
                        "addressLines": [
                          "222, Some other Street"
                        ]
                      }
                    }
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "followUpActions": [
              {
                "type": "VIEW_DETAILS",
                "title": "View details",
                "openUrlAction": {
                  "url": "https://example.com"
                }
              },
              {
                "type": "CALL",
                "title": "Call us",
                "openUrlAction": {
                  "url": "tel:+16501112222"
                }
              },
              {
                "type": "EMAIL",
                "title": "Email us",
                "openUrlAction": {
                  "url": "mailto:person@example.com"
                }
              }
            ],
            "termsOfServiceUrl": "https://www.example.com"
          },
          "orderOptions": {
            "requestDeliveryAddress": false,
            "userInfoOptions": {
              "userInfoProperties": [
                "EMAIL"
              ]
            }
          },
          "presentationOptions": {
            "actionDisplayName": "RESERVE"
          }
        }
      }
    }
  }
}

3. เสนอคำสั่งซื้อ

แสดงคำสั่งการจองให้ผู้ใช้ยืนยันหรือปฏิเสธ ขอ Intent actions.intent.TRANSACTION_DECISION และระบุ Order ที่คุณสร้างไว้

ประสบการณ์ของผู้ใช้

เมื่อคุณขอ Intent actions.intent.TRANSACTION_DECISION Assistant จะเริ่มต้นประสบการณ์การใช้งานในตัวโดยการแสดงผล Order ลงใน "การ์ดตัวอย่างรถเข็น" โดยตรง ผู้ใช้พูดว่า "กำหนดเวลาการจอง" ปฏิเสธธุรกรรม หรือขอเปลี่ยนรายละเอียดการจองได้

ผู้ใช้ยังอาจขอเปลี่ยนแปลงคำสั่งซื้อในขั้นตอนนี้ ในกรณีนี้ คุณควรตรวจสอบว่าการดำเนินการตามคำสั่งซื้อสามารถจัดการคำขอเปลี่ยนแปลงคำสั่งซื้อได้หลังจากที่ดำเนินการประกอบรถเข็นเสร็จแล้ว

การดำเนินการตามคำสั่งซื้อ

เมื่อคุณขอ Intent actions.intent.TRANSACTION_DECISION ให้สร้าง TransactionDecision ที่มี Order และ orderOptions

โค้ดต่อไปนี้แสดงตัวอย่าง TransactionsDecision สําหรับคําสั่งซื้อ

Node.js
conv.ask(new TransactionDecision({
  orderOptions: {
    requestDeliveryAddress: 'false',
  },
  presentationOptions: {
    actionDisplayName: 'RESERVE',
  },
  order: order,
}));
Java
// Create order options
OrderOptionsV3 orderOptions = new OrderOptionsV3()
    .setRequestDeliveryAddress(false)
    .setUserInfoOptions(new UserInfoOptions()
        .setUserInfoProperties(Collections.singletonList("EMAIL")));

// Create presentation options
PresentationOptionsV3 presentationOptions = new PresentationOptionsV3()
    .setActionDisplayName("RESERVE");

// Ask for transaction decision
return getResponseBuilder(request)
    .add("Placeholder for transaction decision text")
    .add(new TransactionDecision()
        .setOrder(order)
        .setOrderOptions(orderOptions)
        .setPresentationOptions(presentationOptions)
    )
    .build();
Dialogflow JSON

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": "false"
          },
          "presentationOptions": {
            "actionDisplayName": "RESERVE"
          },
          "order": {
            "createTime": "2019-07-17T18:25:30.184Z",
            "lastUpdateTime": "2019-07-17T18:25:30.184Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
            "transactionMerchant": {
              "id": "https://www.example.com",
              "name": "Example Merchant"
            },
            "contents": {
              "lineItems": [
                {
                  "id": "LINE_ITEM_ID",
                  "name": "Dinner reservation",
                  "description": "A world of flavors all in one destination.",
                  "reservation": {
                    "status": "PENDING",
                    "userVisibleStatusLabel": "Reservation is pending.",
                    "type": "RESTAURANT",
                    "reservationTime": {
                      "timeIso8601": "2020-01-16T01:30:15.01Z"
                    },
                    "userAcceptableTimeRange": {
                      "timeIso8601": "2020-01-15/2020-01-17"
                    },
                    "partySize": 6,
                    "staffFacilitators": [
                      {
                        "name": "John Smith"
                      }
                    ],
                    "location": {
                      "zipCode": "94086",
                      "city": "Sunnyvale",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94086",
                        "administrativeArea": "CA",
                        "locality": "Sunnyvale",
                        "addressLines": [
                          "222, Some other Street"
                        ]
                      }
                    }
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "followUpActions": [
              {
                "type": "VIEW_DETAILS",
                "title": "View details",
                "openUrlAction": {
                  "url": "https://example.com"
                }
              },
              {
                "type": "CALL",
                "title": "Call us",
                "openUrlAction": {
                  "url": "tel:+16501112222"
                }
              },
              {
                "type": "EMAIL",
                "title": "Email us",
                "openUrlAction": {
                  "url": "mailto:person@example.com"
                }
              }
            ],
            "termsOfServiceUrl": "https://www.example.com"
          }
        }
      }
    }
  }
}
API ของ Actions SDK

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TRANSACTION_DECISION",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
            "orderOptions": {
              "requestDeliveryAddress": "false"
            },
            "presentationOptions": {
              "actionDisplayName": "RESERVE"
            },
            "order": {
              "createTime": "2019-07-17T18:25:30.057Z",
              "lastUpdateTime": "2019-07-17T18:25:30.057Z",
              "merchantOrderId": "UNIQUE_ORDER_ID",
              "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
              "transactionMerchant": {
                "id": "https://www.example.com",
                "name": "Example Merchant"
              },
              "contents": {
                "lineItems": [
                  {
                    "id": "LINE_ITEM_ID",
                    "name": "Dinner reservation",
                    "description": "A world of flavors all in one destination.",
                    "reservation": {
                      "status": "PENDING",
                      "userVisibleStatusLabel": "Reservation is pending.",
                      "type": "RESTAURANT",
                      "reservationTime": {
                        "timeIso8601": "2020-01-16T01:30:15.01Z"
                      },
                      "userAcceptableTimeRange": {
                        "timeIso8601": "2020-01-15/2020-01-17"
                      },
                      "partySize": 6,
                      "staffFacilitators": [
                        {
                          "name": "John Smith"
                        }
                      ],
                      "location": {
                        "zipCode": "94086",
                        "city": "Sunnyvale",
                        "postalAddress": {
                          "regionCode": "US",
                          "postalCode": "94086",
                          "administrativeArea": "CA",
                          "locality": "Sunnyvale",
                          "addressLines": [
                            "222, Some other Street"
                          ]
                        }
                      }
                    }
                  }
                ]
              },
              "buyerInfo": {
                "email": "janedoe@gmail.com",
                "firstName": "Jane",
                "lastName": "Doe",
                "displayName": "Jane Doe"
              },
              "followUpActions": [
                {
                  "type": "VIEW_DETAILS",
                  "title": "View details",
                  "openUrlAction": {
                    "url": "https://example.com"
                  }
                },
                {
                  "type": "CALL",
                  "title": "Call us",
                  "openUrlAction": {
                    "url": "tel:+16501112222"
                  }
                },
                {
                  "type": "EMAIL",
                  "title": "Email us",
                  "openUrlAction": {
                    "url": "mailto:person@example.com"
                  }
                }
              ],
              "termsOfServiceUrl": "https://www.example.com"
            }
          }
        }
      ]
    }
  ]
}
จัดการการตัดสินใจของผู้ใช้

หลังจากที่ผู้ใช้ตอบกลับคำสั่งซื้อที่เสนอ การดำเนินการของคุณจะได้รับ Intent actions_intent_TRANSACTION_DECISION ด้วยอาร์กิวเมนต์ที่มี TransactionDecisionValue โดยค่านี้จะมีข้อมูลต่อไปนี้

  • transactionDecision - การตัดสินใจของผู้ใช้เกี่ยวกับคำสั่งซื้อที่เสนอ ค่าที่เป็นไปได้คือ ORDER_ACCEPTED, ORDER_REJECTED, CART_CHANGE_REQUESTED และ USER_CANNOT_TRANSACT

หากต้องการจัดการคำขอนี้ ให้ประกาศ Intent ของ 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;
}
Java
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");
}
if ((transactionDecision != null && transactionDecision.equals("ORDER_ACCEPTED"))) {
  OrderV3 order = ((OrderV3) extension.get("order"));
}
Dialogflow JSON

โปรดทราบว่า JSON ด้านล่างอธิบายคำขอเว็บฮุค

{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "reservation_get_transaction_decision_df",
      "displayName": "reservation_get_transaction_decision_df"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": []
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}
API ของ Actions SDK

โปรดทราบว่า JSON ด้านล่างอธิบายคำขอเว็บฮุค

{
  "user": {},
  "device": {},
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "conversation": {},
  "inputs": [
    {
      "rawInputs": [],
      "intent": "reservation_get_transaction_decision_asdk",
      "arguments": []
    }
  ],
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

4. ดำเนินการจองให้เสร็จสิ้นและส่งใบเสร็จ

เมื่อ Intent actions.intent.TRANSACTION_DECISION กลับมาพร้อม transactionDecision ของ ORDER_ACCEPTED ให้ดำเนินการตามขั้นตอนที่จำเป็นเพื่อกำหนดเวลาการจอง (เช่น ยืนยันในฐานข้อมูลของคุณเอง)

ส่งคำตอบง่ายๆ เพื่อให้การสนทนาดำเนินต่อไป ผู้ใช้จะได้รับ "การ์ดใบเสร็จแบบยุบ" พร้อมกับคำตอบของคุณ

การดำเนินการตามคำสั่งซื้อ

Node.js
// Set lastUpdateTime and update status of reservation
order.lastUpdateTime = new Date().toISOString();
order.reservation.status = 'CONFIRMED';
order.reservation.userVisibleStatusLabel = 'Reservation confirmed';
order.reservation.confirmationCode = '123ABCDEFGXYZ';

// Send synchronous order update
conv.ask(`Transaction completed! You're all set!`);
conv.ask(new OrderUpdate({
  type: 'SNAPSHOT',
  reason: 'Reason string',
  order: order,
}));
Java
ResponseBuilder responseBuilder = getResponseBuilder(request);
order.setLastUpdateTime(Instant.now().toString());

// Set reservation status to confirmed and provide confirmation code
LineItemV3 lineItem = order.getContents().getLineItems().get(0);
ReservationItemExtension reservationItemExtension = lineItem.getReservation();
reservationItemExtension.setStatus("CONFIRMED");
reservationItemExtension.setUserVisibleStatusLabel("Reservation confirmed.");
reservationItemExtension.setConfirmationCode("123ABCDEFGXYZ");
lineItem.setReservation(reservationItemExtension);
order.getContents().getLineItems().set(0, lineItem);

// Order update
OrderUpdateV3 orderUpdate = new OrderUpdateV3()
    .setType("SNAPSHOT")
    .setReason("Reason string")
    .setOrder(order);

responseBuilder
    .add("Transaction completed! You're all set! Would you like to do anything else?")
    .add(new StructuredResponse().setOrderUpdateV3(orderUpdate));
return responseBuilder.build();
Dialogflow JSON

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Transaction completed! You're all set!"
            }
          },
          {
            "structuredResponse": {
              "orderUpdateV3": {
                "type": "SNAPSHOT",
                "reason": "Reason string",
                "order": {
                  "merchantOrderId": "UNIQUE_ORDER_ID",
                  "reservation": {
                    "status": "CONFIRMED",
                    "userVisibleStatusLabel": "Reservation confirmed",
                    "confirmationCode": "123ABCDEFGXYZ"
                  },
                  "lastUpdateTime": "2019-07-17T18:25:30.187Z"
                }
              }
            }
          }
        ]
      }
    }
  }
}
API ของ Actions SDK

โปรดทราบว่า JSON ด้านล่างอธิบายการตอบสนองของเว็บฮุค

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Transaction completed! You're all set!"
              }
            },
            {
              "structuredResponse": {
                "orderUpdateV3": {
                  "type": "SNAPSHOT",
                  "reason": "Reason string",
                  "order": {
                    "merchantOrderId": "UNIQUE_ORDER_ID",
                    "reservation": {
                      "status": "CONFIRMED",
                      "userVisibleStatusLabel": "Reservation confirmed",
                      "confirmationCode": "123ABCDEFGXYZ"
                    },
                    "lastUpdateTime": "2019-07-17T18:25:30.059Z"
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}

5. ส่งข้อมูลอัปเดตการสั่งซื้อ

สถานะการจองจะเปลี่ยนแปลง ตลอดอายุการใช้งาน ส่งการอัปเดตคำสั่งซื้อการจองของผู้ใช้ด้วยคำขอ HTTP PATCH ไปยัง Orders API สถานะและรายละเอียดของคำสั่งซื้อ

ตั้งค่าคำขอแบบไม่พร้อมกันไปยัง Orders API

คำขออัปเดตคำสั่งซื้อไปยัง Orders API จะได้รับอนุญาตจากโทเค็นเพื่อการเข้าถึง หากต้องการแพตช์การอัปเดตคำสั่งซื้อไปยัง Orders API ให้ดาวน์โหลดคีย์บัญชีบริการ JSON ที่เชื่อมโยงกับโปรเจ็กต์คอนโซล Actions ของคุณ จากนั้นแลกเปลี่ยนคีย์บัญชีบริการกับโทเค็นสำหรับผู้ถือซึ่งส่งผ่านไปยังส่วนหัว Authorization ของคำขอ HTTP ได้

หากต้องการเรียกข้อมูลคีย์บัญชีบริการ ให้ทำตามขั้นตอนต่อไปนี้

  1. ในคอนโซล Google Cloud ให้ไปที่เมนู ☰ > 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 และ Java สำหรับตัวอย่างการแลกเปลี่ยนคีย์

ส่งข้อมูลอัปเดตการสั่งซื้อ

เมื่อแลกเปลี่ยนคีย์บัญชีบริการกับโทเค็นสำหรับผู้ถือ OAuth แล้ว ให้ส่งการอัปเดตคำสั่งซื้อเป็นคำขอ Patch ที่ได้รับอนุญาตไปยัง Orders API

URL ของ API คำสั่งซื้อ: PATCH https://actions.googleapis.com/v3/orders/${orderId}

ระบุส่วนหัวต่อไปนี้ในคำขอของคุณ

  • "Authorization: Bearer token" ด้วยโทเค็นสำหรับผู้ถือ OAuth ที่คุณแลกเปลี่ยนคีย์บัญชีบริการให้
  • "Content-Type: application/json".

คำขอ Patch ควรมีเนื้อหา JSON ในรูปแบบต่อไปนี้

{ "orderUpdate": OrderUpdate }

ออบเจ็กต์ OrderUpdate ประกอบด้วยช่องระดับบนสุดต่อไปนี้

  • updateMask - ช่องของคำสั่งซื้อที่คุณกำลังอัปเดต หากต้องการอัปเดตสถานะการจอง ให้ตั้งค่าเป็น reservation.status, reservation.userVisibleStatusLabel
  • order - เนื้อหาของอัปเดต หากกำลังอัปเดตเนื้อหาของการจอง ให้ตั้งค่าเป็นออบเจ็กต์ Order ที่อัปเดตแล้ว หากคุณแค่อัปเดตสถานะการจอง (เช่น จาก "PENDING" เป็น "FULFILLED") ออบเจ็กต์จะมีช่องต่อไปนี้

    • merchantOrderId - รหัสเดียวกับที่ตั้งค่าไว้ในออบเจ็กต์ Order
    • lastUpdateTime - การประทับเวลาของการอัปเดตนี้
    • purchase - ออบเจ็กต์ที่มีสิ่งต่อไปนี้
      • status - สถานะของคำสั่งซื้อเป็น ReservationStatus เช่น "CONFIRMED" หรือ "CANCELLED"
      • userVisibleStatusLabel - ป้ายกำกับที่ผู้ใช้เห็นซึ่งมีรายละเอียดเกี่ยวกับสถานะการสั่งซื้อ เช่น "ยืนยันการจองของคุณแล้ว"
  • userNotification ที่แสดงในอุปกรณ์ของผู้ใช้ได้เมื่อส่งการอัปเดตนี้ โปรดทราบว่าการรวมออบเจ็กต์นี้ไม่ได้รับประกันว่าการแจ้งเตือนจะปรากฏในอุปกรณ์ของผู้ใช้

โค้ดตัวอย่างต่อไปนี้แสดงตัวอย่าง OrderUpdate ที่อัปเดตสถานะของคำสั่งซื้อการจองเป็น FULFILLED

Node.js
// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request' module for sending an HTTP POST request.
const request = require('request');
// 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. Replace the string path with a path to your service account key.
const key = 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(
    key.client_email,
    null,
    key.private_key,
    ['https://www.googleapis.com/auth/actions.order.developer'],
    null
);
// Authorize the client asynchronously, passing in a callback to run upon authorization.
jwtClient.authorize((err, tokens) => {
    if (err) {
        console.log(err);
        return;
    }
    // Declare the ID of the order to update.
    const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';

    const orderUpdateJson = new OrderUpdate({
        updateMask: [
          'lastUpdateTime',
          'contents.lineItems.reservation.status',
          'contents.lineItems.reservation.userVisibleStatusLabel',
      ].join(','),
        order: {
          merchantOrderId: orderId,
          lastUpdateTime: new Date().toISOString(),
          contents: {
            lineItems: [
              {
                reservation: {
                  status: 'FULFILLED',
                  userVisibleStatusLabel: 'Reservation fulfilled',
                },
              }
            ]
          }
        },
        reason: 'Reservation status was updated to fulfilled.',
    });

    // Set up the PATCH request header and body, including the authorized token
    // and order update.
    const bearer = 'Bearer ' + tokens.access_token;
    const options = {
        method: 'PATCH',
        url: `https://actions.googleapis.com/v3/orders/${orderId}`,
        headers: {
          'Authorization': bearer,
        },
        body: {
          header: {
            'isInSandbox': true,
          },
          orderUpdate: orderUpdateJson,
        },
        json: true,
      };
    // Send the PATCH request to the Orders API.
    request.patch(options, (err, httpResponse, body) => {
        if (err) {
            console.log('There was an error...');
            console.log(err);
            return;
        }
    });
});
Java
// Create order update
FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList(
    "lastUpdateTime",
    "contents.lineItems.reservation.status",
    "contents.lineItems.reservation.userVisibleStatusLabel"))
    .build();

OrderUpdateV3 orderUpdate = new OrderUpdateV3()
    .setOrder(new OrderV3()
        .setMerchantOrderId(orderId)
        .setLastUpdateTime(Instant.now().toString())
        .setContents(new OrderContents()
        .setLineItems(Collections.singletonList(new LineItemV3()
            .setReservation(new ReservationItemExtension()
                .setStatus("FULFILLED")
                .setUserVisibleStatusLabel("Reservation fulfilled."))))))
    .setUpdateMask(FieldMaskUtil.toString(fieldMask))
    .setReason("Reservation status was updated to fulfilled.");

// 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());
request.setEntity(entity);

// Make request
HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse response = httpClient.execute(request);
ตั้งค่าสถานะการจอง

ReservationStatus ของการอัปเดตคำสั่งซื้อต้องอธิบายสถานะปัจจุบันของคำสั่งซื้อ ในช่อง order.ReservationStatus ของการอัปเดต ให้ใช้ค่าใดค่าหนึ่งต่อไปนี้

  • PENDING - การดำเนินการของคุณได้ "สร้าง" การจองไว้ แต่ต้องมีการประมวลผลเพิ่มเติมในส่วนหลังของคุณ
  • CONFIRMED - การจองได้รับการยืนยันในส่วนหลังของกำหนดการ
  • CANCELLED - ผู้ใช้ยกเลิกการจอง
  • FULFILLED - บริการดำเนินการตามการจองของผู้ใช้แล้ว
  • CHANGE_REQUESTED - ผู้ใช้ขอให้เปลี่ยนแปลงการจอง ซึ่งระบบกำลังประมวลผลการเปลี่ยนแปลง
  • REJECTED - หากคุณไม่สามารถดำเนินการหรือยืนยันการจอง

ส่งการอัปเดตคำสั่งซื้อสำหรับแต่ละสถานะที่เกี่ยวข้องกับการจองของคุณ เช่น หากการจองของคุณกำหนดให้ดำเนินการด้วยตนเองเพื่อยืนยันการจองหลังจากที่ขอไปแล้ว ให้ส่งการอัปเดตคำสั่งซื้อ PENDING ไปจนกว่าจะประมวลผลเพิ่มเติมเสร็จ การจองบางรายการไม่จำเป็นต้องมีค่าสถานะทุกรายการ

การแก้ปัญหา

หากพบปัญหาระหว่างการทดสอบ โปรดอ่านขั้นตอนการแก้ปัญหาสำหรับธุรกรรม