Build Transaction API for your Action with Jovo framework

Gautam Ajani

Nov 06, 2020 | 4 min read

Today, I am going to explain how to integrate transactions API into your Action and sell your goods to users through Google Assistant. Transaction functionality lets your users place tangible orders and reservations with physical transactions, or instantly purchase your digital goods from the Google Play store with digital transactions. In this tutorial, I have covered build reservations with physical transactions.

Prerequisite

  • Google Developer console account
  • Dialogflow account
  • Basic knowledge of invocation, intent and slots
  • Basic knowledge of Jovo

Transaction flow
If you want to integrate reservation in your project, you have to follow below steps:

  • Check Requirements
  • ON_TRANSACTION
    • TRANSACTION_REQUIREMENTS_CHECK
    • DELIVERY_ADDRESS
    • TRANSACTION_DECISION

Install Jovo
First of all, you have to install Jovo CLI by using the following command:

$ npm install -g jovo-cli

After successful installation, you should be able to see the Jovo CLI menu by just typing the following into your command line:

jovo

Creating a new Project
After installing the Jovo CLI, you can create a new project with the following command:

$ jovo new transaction-demo

follow the link for more detail Jovo folder structure.

Setup

When you are creating your Action for transaction, You must specify that you want to perform transactions in the Actions console. For that, you have to follow below steps:

  1. Create a new project.
  2. Navigate to Deploy > Directory information.
  3. Under Additional information > Transactions > check the box that says Do your Actions use the Transactions API to perform transactions of physical goods?

Set invocation
I have set invocation name Test Transaction. You can set your invocation name as your wish.

Create Intent
Create the intent TransactionCheckNoPayment in Dialogflow and add the utterances for TransactionCheckNoPayment Intent.

Screenshot-from-2020-09-23-16-45-07

Once you have added successful utterances, Click on Fulfillment > Enabled webhook toggle button and add Jovo webhook URL in the textbox and save it.

Now, write for this intent or lunch intent inside the handler.

src/app.js
app.setHandler({
    LAUNCH() {
        this.$googleAction.showSuggestionChips(['Check no payment']);
        this.ask("Welcome to transaction sample. try say check transaction without payment")
      }
})

When you invoke action with an invocation name, It will call LUNCH() Intent with a response.

Screenshot-from-2020-09-23-17-17-40

After the user can click on a suggestion or say an utterance as you have saved. Like, here I have said check transaction without payment or check no payment

Check Requirements
We have to check the requirement for the transaction using the checkRequirements() function.

Transaction_Check_No_Payment() {
    this.$googleAction.$transaction.checkRequirements();
    this.ask('Check requirement');
  }

While most reservations don't require payment. You can include paymentParameters if a user needs to pay a fee to schedule their reservation. For more detail of paymentParameter please refer to this link.

This function will check that the user can perform a transaction or not. If a user can do a transaction, It will call the next method the ON_TRANSACTION story.

ON_TRANSACTION

To handle transaction events, add the ON_TRANSACTION element to your handler:

ON_TRANSACTION needs to include the following three elements:

  • TRANSACTION_REQUIREMENTS_CHECK()
  • DELIVERY_ADDRESS()
  • TRANSACTION_DECISION()

TRANSACTION_REQUIREMENTS_CHECK()

TRANSACTION_REQUIREMENTS_CHECK() {
      if (this.$googleAction.$transaction.canTransact()) {
         this.$googleAction.$transaction.askForDeliveryAddress('Address?');
      } else {
        this.tell('Further action is required')
      }
    }

In this, an intent we will check, the transaction can perform or not using the canTrasact() function. This function will return true, it means we can do the transaction and go-ahead to the next step. Here I have asked for a delivery address.

Screenshot-from-2020-09-23-17-50-05
The next request will go into the DELIVERY_ADDRESS() handler.

Create an order
Throughout your conversation, gather the user's reservation details and then construct an Order object.

At a minimum, your Order must contain the following:

  • buyerInfo - Information about the user making the purchase.
  • transactionMerchant - Information about the merchant that facilitated the order.
  • contents - The actual contents of the order listed as lineItems.
const reservation = {
  transactionMerchant: {
    id: 'http://www.example.com',
    name: 'Test transaction',
  },
  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: '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'
}

DELIVERY_ADDRESS()

After the user accepted the delivery address this.$googleAction.$transaction.isDeliveryAddressAccepted(), you can as them to make a transaction decision using buildReservation() function.


DELIVERY_ADDRESS() {
 if(this.$googleAction.$transaction.isDeliveryAddressAccepted()) {
   this.$googleAction.$transaction.buildReservation(reservation)
     } else if (this.$googleAction.$transaction.isDeliveryAddressRejected()) {
     this.tell('We need your address to proceed.')
  }
}

Screenshot-from-2020-09-23-18-34-30

The next request will go into the TRANSACTION_DECISION() handler.

TRANSACTION_DECISION

If the reservation is accepted by the user (this.$googleAction.$transaction.isReservationAccepted()), you can create the reservation.

TRANSACTION_DECISION() {
  if (this.$googleAction.$transaction.isReservationAccepted()) {
    const reservation = this.$googleAction.$transaction.getReservation()
    
    reservation.lastUpdateTime = new Date().toISOString()
    reservation.contents.lineItems[0].reservation.status = 'CONFIRMED'
    reservation.contents.lineItems[0].reservation.userVisibleStatusLabel =     'Reservation confirmed';
  this.$googleAction.$transaction.updateReservation(reservation,'Reservation created')
  this.ask('Reservation confirmed!')
 }
}

Screenshot-from-2020-09-23-18-48-22

Troubleshooting physical transactions

if any troubleshooting during implmentation you can check here.

Get the sample code
You can clone the sample code set by typing the following command:

git clone https://github.com/GautamAjani/google-transaction-api-with-Jovo.git

Conclusion
In this blog, we have learned how to implement google transaction API with Jovo.