결제 호출 후 사용자는 세금, 배송비, 할인, 판매자가 반환한 기타 청구 항목이 포함된 업데이트된 장바구니를 검토합니다. 사용자가 주문을 확인하고 제출하면 Google에서 처리 엔드포인트로 주문 정보가 포함된 JSON 요청을 전송합니다. 웹 서비스는 이 주문을 수신하고 처리한 후 주문 상태를 포함하여 Google에 응답해야 합니다.
이 섹션에서는 Google에서 전송하는 주문 요청 메시지 형식(SubmitOrderRequestMessage
)과 개발자가 제공해야 하는 응답 메시지 형식(SubmitOrderResponseMessage
)을 설명합니다.
주문 처리 수명 주기에 관한 자세한 내용은 처리 개요를 참고하세요.
주문 처리 구현
엔드 투 엔드 순서 지정과 호환되도록 빌드하는 엔드 투 엔드 순서 지정 웹 서비스에는 Google에서 주문 메시지를 수신하기 위한 URL 엔드포인트가 포함되어야 합니다. 주문 처리의 경우 웹 서비스는 Google에서 JSON 형식의 SubmitOrderRequestMessage
를 POST 요청으로 수신합니다. 이 요청에는 세금, 수수료, 결제 정보를 포함한 고객 주문이 포함됩니다. 주문 제출 요청을 수신하면 웹 서비스는 다음을 실행해야 합니다.
- 카드 확인 또는 사기 감지와 같은 거래 자격 요건을 확인합니다.
- 시스템에서 주문을 만듭니다.
- 결제 수단을 승인하고 해당하는 경우 결제 대행업체의 charge API를 호출합니다.
- 주문의 적절한 상태(
CREATED
,CONFIRMED
또는REJECTED
)로 응답합니다.
주문을 처리한 후 처리 코드는 SubmitOrderResponseMessage
JSON 메시지의 형식으로 Google에 응답을 제공해야 합니다.
주문 엔드 투 엔드 처리 웹 서비스 구현 요구사항에 관한 자세한 내용은 처리 개요를 참고하세요.
주문 요청 메시지
고객이 주문 엔드 투 엔드 흐름 중에 주문하기를 선택하면 Google은 다음 데이터가 포함된 SubmitOrderRequestMessage
라는 JSON 메시지와 함께 웹 서비스에 요청을 전송합니다.
- 의도: 모든 주문 제출 요청 본문의
inputs[0].intent
필드에actions.intent.TRANSACTION_DECISION
문자열 값이 포함됩니다. - 주문: 주문 제출 요청의
inputs[0].arguments[0].transactionDecisionValue
필드에는 결제 세부정보와 함께 고객의 주문을 나타내는Order
객체가 포함됩니다. - 샌드박스 플래그: 주문 제출 요청의
isInSandbox
필드는 거래에서 샌드박스 결제를 사용하는지 여부를 나타냅니다.
주문 요청 예시
다음은 SubmitOrderRequestMessage
예시입니다.
{ "user": {}, "conversation": { "conversationId": "CTKbKfUlHCyDEdcz_5PBJTtf" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "arguments": [ { "transactionDecisionValue": { "order": { "finalOrder": { "cart": { "merchant": { "id": "restaurant/Restaurant/QWERTY", "name": "Tep Tep Chicken Club" }, "lineItems": [ { "name": "Spicy Fried Chicken", "type": "REGULAR", "id": "299977679", "quantity": 2, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "39", "nanos": 600000000 } }, "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P0M" } } }, "location": { "coordinates": { "latitude": -33.8376441, "longitude": 151.0868736 }, "formattedAddress": "Killoola St, 1, Concord West NSW 2138", "zipCode": "2138", "city": "Concord West", "postalAddress": { "regionCode": "AU", "postalCode": "2138", "administrativeArea": "NSW", "locality": "Concord West", "addressLines": [ "Killoola St", "1" ] } }, "contact": { "displayName": "Hab Sy", "email": "hab9878.sy@gmail.com", "phoneNumber": "+61000000000", "firstName": "Hab", "lastName": "Sy" } } }, "otherItems": [ { "name": "Delivery fee", "type": "DELIVERY", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "3", "nanos": 500000000 } } }, { "name": "Subtotal", "type": "SUBTOTAL", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "39", "nanos": 600000000 } } } ], "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "43", "nanos": 100000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension" } }, "googleOrderId": "01412971004192156198", "orderDate": "2020-10-22T09:02:06.173Z", "paymentInfo": { "displayName": "Pay when you get your food", "paymentType": "ON_FULFILLMENT" } } } } ] } ], "directActionOnly": true, "isInSandbox": true }
주문 응답 메시지
요청을 받은 후 주문 엔드 투 엔드 웹 서비스는 요청을 처리하고 다음 데이터가 포함된 SubmitOrderResponseMessage
를 다시 전송합니다.
OrderUpdate
: 주문 상태와 사용자가 사용할 수 있는 모든 주문 후 작업(예: 지원팀에 문의, 주문 세부정보 보기)이 포함된 객체로, 응답의finalResponse.richResponse.items[0].structuredResponse.orderUpdate
필드에서 정의합니다.
주문 업데이트 필드
웹 서비스가 SubmitOrderResponseMessage
를 전송할 때 다음 필드가 포함된 OrderUpdate
필드가 포함됩니다.
actionOrderId
: 주문의 고유 ID로, 시스템에서 주문을 고유하게 식별하고 후속 주문 업데이트를 보낼 때 참조하는 데 사용됩니다.orderState
: 주문 상태를 나타내는OrderState
객체입니다.orderManagementActions
: 고객 지원팀에 문의하고 주문 세부정보를 확인하는 등 사용자가 사용할 수 있는 주문 후 작업입니다.totalPrice
: 주문의 총 가격입니다. 이는 선택사항입니다. 주문이 제출된 후 주문 총 가격이 변경된 경우에만 전송합니다.
주문 상태는 다음 중 하나일 수 있습니다.
CREATED
: 처리 엔드포인트에서 주문을 처리했지만 제공업체에서 아직 주문을 확인하지 않았습니다.CONFIRMED
: 처리 엔드포인트에서 주문을 처리했으며 제공업체에서 주문을 확인했습니다.REJECTED
: 문제가 발생하여 처리 엔드포인트에서 주문을 생성하거나 확인할 수 없습니다. 여기에는 결제 문제가 포함될 수 있습니다.
주문을 REJECTED
상태로 설정하는 경우 OrderUpdate
의 rejectionInfo
필드에 이유를 지정합니다. UNKNOWN
유형의 rejectionInfo
와 함께 FoodOrderUpdateExtension.FoodOrderErrors
값을 사용하고 설명을 제공합니다.
주문 응답 예시
다음은 SubmitOrderResponseMessage
예시입니다.
{ "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "1603357328160", "orderState": { "state": "CONFIRMED", "label": "Pending" }, "updateTime": "2020-10-22T02:02:08-07:00", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Call customer service", "openUrlAction": { "url": "tel:+61234561000" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order details", "openUrlAction": { "url": "https://partner.com/view/orderstatus" } } } ], "receipt": { "userVisibleOrderId": "BXZ-1603357328" } } } } ] } } }
요청 실패
제출 요청이 실패하면 SubmitOrderResponseMessage
는 OrderState.state
를 REJECTED
로 설정해야 합니다. 응답에는 오류 유형을 설명하는 RejectionType
객체가 포함된 RejectionInfo도 포함되어야 합니다.
실패한 응답 예시
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "PAYMENT_DECLINED", "reason": "Insufficient funds" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
주문 구현 제출
submit order API를 구현할 때는 다음 단계를 따라야 합니다.
유효성 검사
- 결제 설정에서와 같이 서비스, 장바구니, 프로모션 유효성 검사를 실행합니다.
- 필요한 경우 다음 유형 중 하나를 사용하여 RejectionInfo를 반환합니다.
RejectionInfoType | 사용 사례 |
---|---|
UNAVAILABLE_SLOT |
처리 시간이 더 이상 유효하지 않습니다. |
PROMO_USER_INELIGIBLE |
요청의 연락처 객체에 있는 이메일을 사용하여 사용자의 프로모션 자격요건을 확인합니다. 프로모션이 포함된 주문 제출 구현의 예를 참고하세요. |
INELIGIBLE |
|
PAYMENT_DECLINED |
결제를 처리할 수 없습니다. 예를 들어 잔액이 부족할 수 있습니다. |
UNKNOWN |
기타 유효성 검사 오류 |
유효성 검사 오류가 발생하면 OrderState.state
를 REJECTED
로 설정합니다. 원하는 경우 FoodOrderUpdateExtension.foodOrderErrors
을 사용하여 구체적인 거부 사유를 제공할 수 있습니다. 주문 검증 제출에서 예시를 확인하세요.
결제 처리
- 장바구니 가격, 수수료, 할인, 세금, 팁을 더하여
totalPrice
를 계산합니다.totalPrice
는 CheckoutResponseMessage에서 반환된totalPrice
와 동일해야 하며, 사용자가 팁을 수정할 수 있는 경우 팁 금액의 변경사항을 더해야 합니다. 자세한 내용은 주문 제출 중 가격 변경을 참고하세요. - 주문 상태가
CREATED
또는CONFIRMED
인 응답을 반환하면 주문 및 결제를 처리합니다. - 클라이언트 라이브러리 생성에 설명된 대로 스키마에서 생성된 유형을 사용하여 유효한 응답 형식이 반환되는지 확인합니다.
- GoogleProvidedPaymentInstrument를 사용하여
instrumentToken
결제를 처리합니다. 결제를 처리할 수 없는 경우 유형이PAYMENT_DECLINED
인 RejectionInfo를 반환합니다. 자세한 내용은 결제 처리를 참고하세요. - 주문이 처리된 후 즉시 이메일 또는 SMS로 사용자에게 알립니다.
응답 반환
- 오류가 없으면 OrderState.
state
를CREATED
또는CONFIRMED
로 설정합니다. - 오류가 발생하면 OrderState.
state
를REJECTED
로 설정하고 상응하는 RejectionInfoType과 함께 RejectionInfo 객체를 포함합니다. - OrderUpdate.
orderManagementActions
를 설정합니다.