Crea transacciones físicas con Google Pay

En esta guía, se explica el proceso de desarrollo de un proyecto de Actions que incorpore transacciones de bienes físicos y use Google Pay para los pagos

Flujo de transacción

Cuando tu proyecto de Acciones maneja transacciones físicas mediante pagos administrados por el comercio, usa el siguiente flujo:

  1. Recopilar información (opcional): Según la naturaleza de por cada transacción, te recomendamos que recopiles la siguiente información del usuario al inicio de la conversación:
    1. Valida los requisitos de las transacciones: Al comienzo de la conversación, validen que el usuario cumpla con los requisitos para realizar una transacción, como tener la información de pago configurada y disponible correctamente antes de para construir su carrito.
    2. Solicitar una dirección de entrega: Si la transacción requiere una entrega del usuario, solicita una.
  2. Crea el orden: explícale al usuario “montaje de carrito” en la que eligen los artículos que quieren comprar.
  3. Proponer el pedido: Una vez que el carrito esté completo, propone el pedido a al usuario para que pueda confirmar que es correcto. Si se confirma el pedido, recibir una respuesta con los detalles del pedido y un token de pago.
  4. Finalizar el pedido y enviar el recibo: Una vez confirmado el pedido, actualiza seguimiento del inventario u otros servicios de entrega y, luego, enviar un recibo para el usuario.
  5. Enviar actualizaciones de pedidos: Durante el ciclo de vida del pedido, proporcionar al usuario actualizaciones sobre el pedido enviando solicitudes PATCH al equipo de Pedidos en la API de Cloud.

Restricciones y lineamientos de revisión

Ten en cuenta que se aplican políticas adicionales a las Acciones con transacciones. Integra La revisión de acciones con transacciones puede tardar hasta seis semanas, así que ese tiempo a la hora de planificar tu programa de lanzamientos. Para facilitar el proceso de revisión, asegúrate de cumplir con las políticas y lineamientos para las transacciones antes de enviar tu Acción para su revisión.

Solo puedes implementar Acciones que vendan bienes físicos en los siguientes países:

Australia
Brasil
Canadá
Indonesia
Japón
México
Rusia
Singapur
Tailandia
Türkiye
Reino Unido
Estados Unidos

Cómo compilar un proyecto

Para ver ejemplos exhaustivos de conversaciones transaccionales, consulta las transacciones de Node.js de muestra.

Configuración

Cuando crees tu Acción, debes especificar que quieres realizar transacciones en la Consola de Actions.

Para configurar tu proyecto y entrega, haz lo siguiente:

  1. Crea un proyecto nuevo o importa uno existente.
  2. Navega a Implementar > Información del directorio.
  3. En Información adicional > Transacciones > marca la casilla que dice "Realiza tus acciones usar la API de Transactions para realizar transacciones de bienes físicos?".

1. Recopila información (opcional)

1a. Valida los requisitos de las transacciones (opcional).

En cuanto el usuario indique que desea realizar una compra, debes verificar para asegurarte de que podrá realizar una transacción. Por ejemplo, cuando se invoca, tu Action podría preguntar: "¿Te gustaría pedir zapatos, o verificar el saldo de tu cuenta?". Si el usuario dice "pedir zapatos", debes asegurarte de que puede continuar y darle la oportunidad de corregir cualquier parámetro de configuración que impida su continuar con la transacción. Para ello, debes hacer la transición a un que realiza una verificación de los requisitos de la transacción.

Crea una escena de verificación de requisitos de la transacción
  1. En la pestaña Escenas, agrega una escena nueva con el nombre TransactionRequirementsCheck.
  2. En Relleno de ranuras, haz clic en + para agregar un espacio nuevo.
  3. En Seleccionar tipo, selecciona actions.type.TransactionRequirementsCheckResult. como el tipo de ranura.
  4. En el campo del nombre del espacio, asígnale el nombre TransactionRequirementsCheck.
  5. Habilita la casilla de verificación Personalizar la reescritura del valor del espacio (Customize slot value writeback) (habilitada de forma predeterminada).
  6. Haz clic en Guardar.

Una verificación de requisitos de transacción dará como resultado uno de los siguientes resultados:

  • Si se cumplen los requisitos, el parámetro de sesión se establece con éxito. y puedes continuar con la creación del orden del usuario.
  • Si no se pueden cumplir uno o más de los requisitos, se establece el parámetro de sesión. con una condición de falla. En este caso, debes desviar la conversación de la experiencia transaccional o finalizar la conversación.
    • Si el usuario puede corregir algún error que genere el estado de falla, se le solicitará que resuelva esos problemas en su dispositivo. Si el botón conversación sobre una superficie de solo voz, se realizará un traspaso en el teléfono del usuario.

Resultado de la verificación de requisitos de la transacción

  1. En la pestaña Scenes, selecciona Escena TransactionRequirementsCheck.
  2. En Condición, haz clic en + para agregar una condición nueva.
  3. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condición de éxito:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  5. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. que están listos para realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                You are ready to purchase physical goods.
    
  6. En Transition, selecciona otra escena para que el usuario continúe con la conversación y procede a realizar la transacción.

  7. Selecciona la condición else if scene.slots.status == "FINAL".

  8. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. no pueden realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. En Transición, selecciona Finalizar conversación para finalizar la conversación en los siguientes casos: un usuario no puede realizar transacciones.

Solicita una dirección de entrega

Si la transacción requiere la dirección de entrega de un usuario, debes solicitarla del usuario. Esto puede ser útil para determinar el precio total, de entrega o retiro, o bien para garantizar que el usuario esté dentro de la región de servicio. Para ello, debes pasar a una escena que le solicite al usuario su dirección de entrega de Google.

Crear escena de dirección de entrega

  1. En la pestaña Scenes, agrega una escena nueva con el nombre DeliveryAddress.
  2. En Relleno de ranuras, haz clic en + para agregar un espacio nuevo.
  3. En Seleccionar tipo, selecciona actions.type.DeliveryAddressValue como tipo de ranura.
  4. En el campo del nombre del espacio, asígnale el nombre TransactionDeliveryAddress.
  5. Habilita la casilla de verificación Personalizar la reescritura del valor del espacio (Customize slot value writeback) (habilitada de forma predeterminada).
  6. Haz clic en Guardar.

Cuando configuras el espacio, puedes proporcionar un reason que te permita realizar las siguientes acciones: antes de la solicitud del Asistente para obtener una dirección con una cadena. La cadena de motivo es "para saber dónde enviar el pedido". Por lo tanto, el Asistente Podría preguntar al usuario: “Para saber dónde enviar el pedido, necesito tu dirección de entrega”.

  • En las superficies con pantalla, el usuario elegirá la dirección que desea usar para la transacción. Si no proporcionó una dirección anteriormente, será ingresar una nueva dirección.
  • En las plataformas que solo usan voz, el Asistente le pedirá permiso al usuario para realizar las siguientes acciones: compartir su dirección predeterminada para la transacción. Si no lo han hecho antes dada una dirección, la conversación se pasará a un teléfono para que la ingrese.

Para procesar el resultado de la dirección de entrega, sigue estos pasos:

  1. En la pestaña Scenes, selecciona la escena DeliveryAddress que acabas de crear.
  2. En Condición, haz clic en + para agregar una condición nueva.
  3. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condición de éxito:

    scene.slots.status == "FINAL" && session.params.TransactionDeliveryAddress.userDecision == "ACCEPTED"
    
  4. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  5. Habilita la opción Send prompts y proporciona una instrucción simple al usuario. saber que recibiste su dirección:

    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. En Transition, selecciona otra escena para que el usuario continúe. la conversación.

  7. Selecciona la condición else if scene.slots.status == "FINAL".

  8. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. no pueden realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: I failed to get your delivery address.
    
  9. En Transición, selecciona Finalizar conversación para finalizarla. si un usuario no puede realizar transacciones.

Crea el pedido

Una vez que tengas la información del usuario necesaria, crearás un carrito ensamblado" experiencia que guía al usuario a crear un pedido. Todas las Acción tienen un flujo de montaje de carro ligeramente diferente según corresponda para su producto o servicio.

En la experiencia más básica de ensamblado de carritos, el usuario elige artículos de una lista para agregarlos a su orden, aunque puedes diseñar la conversación para simplificar el proceso la experiencia del usuario. Podrías crear una experiencia de ensamblado de carro que permita que la que vuelva a ordenar su compra más reciente mediante una simple pregunta de sí o no. También puedes presentar al usuario un carrusel o una tarjeta de lista de los principales "destacados" o "recomendado" elementos.

Recomendamos usar elementos respuestas para presentar las opciones del usuario sino también diseñar la conversación, de modo que el usuario pueda construir carrito solo con su voz. Para ver algunas prácticas recomendadas y ejemplos experiencias de alta calidad en el armado de carritos, consulta la Lineamientos de diseño

Crea un pedido

A lo largo de la conversación, deberás reunir los elementos que el usuario quiere para comprar y, luego, construye un objeto Order.

Como mínimo, tu Order debe contener lo siguiente:

  • buyerInfo: Es la información sobre el usuario que realiza la compra.
  • transactionMerchant: información sobre el comercio que facilitó el pedido.
  • contents: Es el contenido real del pedido que aparece como lineItems.
  • priceAttributes: Detalles de precios del pedido, incluido el total el costo del pedido con impuestos y descuentos.

Consulta Order. la documentación de respuesta para construir tu carrito. Ten en cuenta que posiblemente debas incluir diferentes campos según el orden.

El siguiente código de muestra muestra un pedido completo, incluidos los campos opcionales:

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

Crear opciones de orden y presentación

Antes de que el usuario confirme su pedido, se le presentará una propuesta del pedido de compra. Puedes personalizar la forma en que se presenta esta tarjeta al usuario. Para ello, haz lo siguiente: estableciendo varias opciones de orden y presentación.

A continuación te indicamos las opciones de pedido y presentación para realizar un pedido que requiera una dirección de entrega, incluido el correo electrónico del usuario en la tarjeta de confirmación del pedido:

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

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

Crea parámetros de pago

Tu objeto paymentParameters incluirá parámetros de asignación de token que cambiará según el procesador de Google Pay que planees usar (como Stripe, Braintree, ACI, etcétera).

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

El contenido del objeto tokenizationSpecification será diferente para cada uno la puerta de enlace de pago. En la siguiente tabla, se muestran los parámetros que usa cada puerta de enlace:

EJEMPLO
"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"
}
.
.
CONFIRMACIÓN DE LA COMPRA
"parameters": {
  "gateway": "checkoutltd",
  "gatewayMerchantId": "YOUR_PUBLIC_KEY"
}
.
.
CLOUDPAYMENTS
"parameters": {
  "gateway": "cloudpayments",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
.
.
CYBERSOURCE
"parameters": {
  "gateway": "cybersource",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
.
.
TRANS DE DATOS
"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"
}
.
.
HITRUST
"parameters": {
  "gateway": "hitrustpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
.
.
IMSOLUCIONES
"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"
}
.
.
PAGAR
"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 DINERO
"parameters": {
  "gateway": "rbkmoney",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
.
.
SBERBANK
"parameters": {
  "gateway": "sberbank",
  "gatewayMerchantId": "YOUR_ORGANIZATION_NAME"
}
.
.
CUADRO
"parameters": {
  "gateway": "square",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
.
.
TIRA
"parameters": {
  "gateway": "stripe",
  "stripe:version": "2018-10-31",
  "stripe:publishableKey": "YOUR_PUBLIC_STRIPE_KEY"
}
.
.
TAPPAY
"parameters": {
  "gateway": "tappay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
.
.
TÍTULO
"parameters": {
  "gateway": "tinkoff",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
.
.
UNIDADES
"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"
}
.
.
PAGAR WORLDPAY
"parameters": {
  "gateway": "worldpay",
  "gatewayMerchantId": "YOUR_WORLDPAY_MERCHANT_ID"
}
.
.
YANDEX
"parameters": {
  "gateway": "yandexcheckout",
  "gatewayMerchantId": "YOUR_SHOP_ID"
}

Guardar datos del pedido en el parámetro de sesión

Desde tu entrega, guarda los datos del pedido en un parámetro de sesión. El pedido se usará en varias escenas de la misma sesión.

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

Proponer el pedido

Una vez que hayas creado un pedido, debes presentárselo al usuario para que lo confirme o lo rechace. Para hacerlo, debes pasar a una escena que realice una decisión de transacción.

Crea una escena de decisión de la transacción

  1. En la pestaña Scenes, agrega una escena nueva con el nombre TransactionDecision.
  2. En Relleno de ranuras, haz clic en + para agregar un espacio nuevo.
  3. En Seleccionar tipo, selecciona actions.type.TransactionDecisionValue como la opción el tipo de ranura.
  4. En el campo del nombre del espacio, asígnale el nombre TransactionDecision.
  5. Habilita la casilla de verificación Personalizar la reescritura del valor del espacio (Customize slot value writeback) (habilitada de forma predeterminada).
  6. En Configurar ranura, selecciona Usar parámetro de sesión en el menú desplegable.
  7. En Configura el espacio,ingresa el nombre del parámetro de sesión que se usa. para almacenar el pedido en el campo de texto (es decir, $session.params.order).
  8. Haz clic en Guardar.

Para llenar un espacio de TransactionDecisionValue, Asistente inicia una experiencia integrada en la que el Order que pasaste se renderiza directamente en una "tarjeta de vista previa del carrito". El usuario puede decir “Realizar pedido”, rechazar la transacción. cambiar una opción de pago, como la tarjeta de crédito o la dirección, o una solicitud de cambio los contenidos del pedido.

En este punto, el usuario también puede solicitar cambios en el pedido. En este caso, debe asegurarse de que su entrega pueda controlar las solicitudes de cambio de pedidos después la experiencia de armado del carrito.

Resultado de la decisión de la transacción del controlador

Cuando se llena un espacio de TransactionDecisionValue, la respuesta del usuario al la decisión de transacción se almacenará en un parámetro de sesión. Este valor contiene lo siguiente:

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

Para controlar el resultado de una decisión de transacción, haz lo siguiente:

  1. En la pestaña Scenes, selecciona la escena TransactionDecision que acabas de crear.
  2. En Condición, haz clic en + para agregar una condición nueva.
  3. En el campo de texto, ingresa la siguiente sintaxis de condición para verificar si la condición se realizó correctamente:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  5. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. se completa el pedido:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your order
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. En Transición, selecciona Finalizar conversación para finalizarla.

  7. En Condición, haz clic en + para agregar una condición nueva.

  8. En el campo de texto, ingresa la siguiente sintaxis de condición para comprobar la condiciones de falla:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Coloca el cursor sobre la condición que acabas de agregar y haz clic en la flecha hacia arriba. para colocarla antes de if scene.slots.status == "FINAL".

  10. Habilita la opción Send prompts y proporciona un mensaje simple para informar al usuario. se rechaza el pedido:

    candidates:
      - first_simple:
          variants:
            - speech: Look like you don't want to order anything. Goodbye.
    
  11. En Transición, selecciona Finalizar conversación para finalizarla.

  12. Selecciona la condición else if scene.slots.status == "FINAL".

  13. Habilita la opción Send prompts y proporciona una instrucción simple al usuario. saber que no puede realizar una transacción:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. En Transición, selecciona Finalizar conversación para finalizarla. si un usuario no puede realizar transacciones.

Finalizar el pedido y enviar un recibo

Cuando el espacio TransactionDecisionValue muestra un resultado de ORDER_ACCEPTED, debe realizar de inmediato el procesamiento necesario para “confirmar” el (como mantenerlos en tu propia base de datos y cobrar al usuario).

Puedes terminar la conversación con esta respuesta, pero debes incluir una respuesta respuesta para mantener la conversación. Cuando proporciones esta orderUpdate, el usuario verá una "tarjeta de recibo contraída" junto con el resto de tu respuesta. Esta tarjeta replicará el recibo que el usuario encuentre en su Historial de pedidos.

Durante la confirmación del pedido, tu objeto de pedido puede incluir una userVisibleOrderId, que es el ID que el usuario ve para el pedido. Puedes reutilizar tus merchantOrderId para este campo.

Parte del objeto OrderUpdate deberá contener un objeto de acción de seguimiento. que se manifiestan como botones de URL en la parte inferior de los detalles del pedido que el usuario que pueden encontrar en el historial de pedidos de Asistente.

  • Debes proporcionar, como mínimo, un VIEW_DETAILS Acción de seguimiento con cada pedido. Debe contener un vínculo directo al del pedido en tu sitio web o aplicación para dispositivos móviles.
  • También debes enviar por correo electrónico un recibo formal que cumpla con todos los requisitos legales requisitos para realizar una transacción, además de la tarjeta del recibo en la conversación de tu acción.

Para enviar una actualización inicial del pedido, sigue estos pasos:

  1. En la pestaña Scenes, selecciona tu escena TransactionDecision.
  2. En Condición, selecciona la condición que verifica que el resultado sea correcto. ORDER_ACCEPTED:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. Para esta condición, habilita Llamar a tu webhook y proporciona un intent nombre del controlador, como update_order.

  4. En el código de tu webhook, agrega un controlador de intents para enviar un pedido inicial. actualización:

    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
      }));
    });
    

Cómo enviar actualizaciones de pedidos

Deberás mantener informado al usuario sobre el estado del pedido en el transcurso de a lo largo de su vida útil. Enviar a los usuarios actualizaciones de pedidos con HTTP Solicitudes PATCH a la API de Orders con el estado y los detalles del pedido

Configura solicitudes asíncronas para la API de Orders

Las solicitudes de actualización de pedidos a la API de Orders están autorizadas por un usuario token. Para realizar PATCH en la actualización de un pedido en la API de Orders, descarga un archivo JSON clave de la cuenta de servicio asociada a tu proyecto de la Consola de Actions y, luego, intercambiar la clave de la cuenta de servicio para un token del portador que se puede pasar al Encabezado Authorization de la solicitud HTTP.

Para recuperar la clave de tu cuenta de servicio, sigue estos pasos:

  1. En la consola de Google Cloud, ve a Menú ☰ > APIs y Servicios > Credenciales > Crear credenciales > Clave de cuenta de servicio.
  2. En Cuenta de servicio, selecciona Nueva cuenta de servicio.
  3. Configura la cuenta de servicio como service-account.
  4. Configura el Rol como Proyecto > Propietario:
  5. Establece el tipo de clave en JSON.
  6. Selecciona Crear.
  7. Se descargará una clave privada de cuenta de servicio JSON en tu máquina local.

En el código de actualizaciones de tu pedido, puedes intercambiar tu clave de servicio por un token del portador con la biblioteca cliente de las APIs de Google y la "https://www.googleapis.com/auth/actions.order.developer". Puedes encontrar pasos de instalación y ejemplos en la biblioteca cliente de la API Página de GitHub.

También puedes hacer referencia a order-update.js en nuestro Muestra de Node.js de un intercambio de claves de ejemplo.

Cómo enviar actualizaciones de pedidos

Una vez que hayas intercambiado la clave de tu cuenta de servicio por un token del portador de OAuth, puede enviar actualizaciones de pedidos como solicitudes PATCH autorizadas a la API de Orders.

URL de la API de Orders: PATCH https://actions.googleapis.com/v3/orders/${orderId}

Proporciona los siguientes encabezados en tu solicitud:

  • "Authorization: Bearer token" por el token del portador de OAuth por la que intercambiaste la clave de tu cuenta de servicio.
  • "Content-Type: application/json".

La solicitud PATCH debe tomar un cuerpo JSON con el siguiente formato:

{ "orderUpdate": OrderUpdate }

La OrderUpdate consta de los siguientes campos de nivel superior:

  • updateMask: son los campos del pedido que actualizas. Para actualizar el estado del pedido, establece el valor en purchase.status, purchase.userVisibleStatusLabel.
  • order: el contenido de la actualización. Si quieres actualizar Contenido del pedido, establece el valor en el objeto Order actualizado. Si quieres actualizar el estado del pedido (por ejemplo, de "CONFIRMED" a "SHIPPED"), el objeto contiene el siguientes campos:

    • merchantOrderId: Es el mismo ID que estableciste en tu objeto Order.
    • lastUpdateTime: Es la marca de tiempo de esta actualización.
    • purchase: Un objeto que contiene lo siguiente:
      • status: Es el estado del pedido como PurchaseStatus. como "SHIPPED" o "DELIVERED".
      • userVisibleStatusLabel: Es una etiqueta para el usuario que proporciona detalles sobre el estado del pedido, como "Tu pedido se envió y se encuentra en el ".
  • userNotification (opcional) - A userNotification que se puede mostrar en el dispositivo del usuario cuando se envía esta actualización. Nota que incluir este objeto no garantiza que una notificación aparezca en el dispositivo del usuario.

En el siguiente código de muestra, se observa un OrderUpdate de ejemplo que actualiza la estado del pedido a 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}`);
}
Establece el estado de compra

El status de una actualización de pedido debe describir el estado actual del pedido. En el order.purchase.status de tu actualización utiliza uno de los siguientes valores:

  • CREATED: El usuario acepta el pedido y lo "crea". desde la perspectiva de tu Action, pero requiere procesamiento manual en tu backend.
  • CONFIRMED: El pedido está activo y se está procesando para su entrega.
  • IN_PREPARATION: El pedido se está preparando para el envío o la entrega, por ejemplo, la comida. la cocción o el empaquetado de un artículo.
  • READY_FOR_PICKUP: El pedido está disponible para que el destinatario lo retire.
  • DELIVERED: el pedido se entregó al destinatario
  • OUT_OF_STOCK: Uno o más artículos del pedido están agotados.
  • CHANGE_REQUESTED: El usuario solicitó un cambio en el pedido, y el cambio se mientras se procesan.
  • RETURNED: El usuario devolvió el pedido después de la entrega.
  • REJECTED (si no pudiste procesar, cargar o hacer cualquier otra acción) "activar" el pedido.
  • CANCELLED: El usuario canceló el pedido.

Debes enviar actualizaciones de pedidos para cada estado que sea relevante para tu transacción. Por ejemplo, si tu transacción requiere procesamiento manual para registrar el pedido una vez realizado, enviar una actualización del pedido de CREATED hasta que se realice un procesamiento adicional. No todos los pedidos requieren todos los valores de estado.

Cómo probar tu proyecto

Cuando pruebes tu proyecto, puedes habilitar el modo de zona de pruebas en la Consola de Actions para probar tu Acción sin cobrar una forma de pago. Para habilitar el modo de zona de pruebas, sigue estos pasos:

  1. En la Consola de Actions, haz clic en Test, en el menú de navegación.
  2. Haz clic en Configuración.
  3. Habilita la opción Zona de pruebas de desarrollo.

Para las transacciones físicas, también puedes establecer el campo isInSandbox en true, en tu muestra. Esta acción equivale a habilitar el parámetro de configuración del modo de zona de pruebas en en la Consola de Actions. Para ver un fragmento de código que usa isInSandbox, consulta la Sección Envía actualizaciones de pedidos.

Soluciona problemas

Si tienes algún problema durante la prueba, consulta nuestros pasos para solucionar problemas. para las transacciones.