I want to create a chatbot with Dialogflow and Google Assistant along with Google Transactions API for enabling a user to order some items. For now my agent contains the following four intents:
Default Welcome Intent (text response: Hello, do you want to buy a chocolate box?)
Default Fallback Intent
Int3 (training phrase: Yes, I want, fulfilment: enabled webhook)
Int4 (event: actions_intent_TRANSACTION_DECISION, fulfilment: enabled webhook)
I am using Dialogflow Json instead of Node.js to connect my agent with Transactions API. I want to build a cart and an order for the user by using finally that the user meets the transaction requirements by using the actions.intent.TRANSACTION_DECISION action of Google actions. For this reason, following Google docs, when Int3 is triggered I am using a webhook which connect Google Assistant my back-end which sends back the following json (to trigger actions.intent.TRANSACTION_DECISION) :
{
"fulfillmentText": "This is your order preview:",
"payload": {
"google": {
"expectUserResponse": true,
"isSsml": false,
"noInputPrompts": [],
"systemIntent": {
"data": {
"#type": "type.googleapis.com/google.actions.v2.TransactionDecisionValueSpec",
"orderOptions": {
"requestDeliveryAddress": true
},
"paymentOptions": {
"actionProvidedOptions": {
"displayName": "VISA **** **** **** 3235",
"paymentType": "PAYMENT_CARD"
}
},
"proposedOrder": {
"cart": {
"lineItems": [
{
"description": "Book",
"id": "1",
"name": "Book",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 31
},
"type": "ACTUAL"
},
"quantity": 2,
"subLines": [],
"type": "REGULAR"
}
],
"merchant": {
"id": "Amazon",
"name": "Amazon"
},
"otherItems": []
},
"id": "<UNIQUE_ORDER_ID>",
"otherItems": [
{
"id": "Subtotal",
"name": "Subtotal",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 62
},
"type": "ACTUAL"
},
"type": "SUBTOTAL"
},
{
"id": "Delivery fees",
"name": "Delivery fees",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 10
},
"type": "ACTUAL"
},
"type": "FEE"
}
],
"totalPrice": {
"amount": {
"currencyCode": "USD",
"units": 72
},
"type": "ACTUAL"
}
}
},
"intent": "actions.intent.TRANSACTION_DECISION"
}
}
}
}
However, I am getting the following errors on Google Assistant simulator:
MalformedResponse
expected_inputs[0].possible_intents[0].input_value_data.transaction_decision_value_spec.proposed_order: subtotal price is not sum of regular lineItems. Expected-> Sum of line item price: units: 31 nanos: 0 currency: USD Actual-> Provided total price: units: 62 nanos: 0 currency: USD.
MalformedResponse
expected_inputs[0].possible_intents[0].input_value_data.transaction_decision_value_spec.proposed_order: total price is not sum of lineItems and otherItems. Expected-> Sum of line item price: units: 42 nanos: 0 currency: USD Actual-> Provided total price: units: 72 nanos: 0 currency: USD.
Why I am getting this error since I have specified that "quantity": 2 in the respective lineItem?
It is very obvious that the subtotal should be units: 62 since I have ordered "quantity": 2 products of units: 31 price each...
The final order preview looks like this (this is borrowed from Google docs examples):
The answer seems to be in the error message: the API expects a each line item's price to be a sum of the total items in that line item instead of a quantity price (relevant error phrase: "Sum of line item price"). The corrected JSON should look something like this:
{
"fulfillmentText": "This is your order preview:",
"payload": {
"google": {
"expectUserResponse": true,
"isSsml": false,
"noInputPrompts": [],
"systemIntent": {
"data": {
"#type": "type.googleapis.com/google.actions.v2.TransactionDecisionValueSpec",
"orderOptions": {
"requestDeliveryAddress": true
},
"paymentOptions": {
"actionProvidedOptions": {
"displayName": "VISA **** **** **** 3235",
"paymentType": "PAYMENT_CARD"
}
},
"proposedOrder": {
"cart": {
"lineItems": [
{
"description": "Book",
"id": "1",
"name": "Book",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 62
},
"type": "ACTUAL"
},
"quantity": 2,
"subLines": [],
"type": "REGULAR"
}
],
"merchant": {
"id": "Amazon",
"name": "Amazon"
},
"otherItems": []
},
"id": "<UNIQUE_ORDER_ID>",
"otherItems": [
{
"id": "Subtotal",
"name": "Subtotal",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 62
},
"type": "ACTUAL"
},
"type": "SUBTOTAL"
},
{
"id": "Delivery fees",
"name": "Delivery fees",
"price": {
"amount": {
"currencyCode": "USD",
"nanos": 0,
"units": 10
},
"type": "ACTUAL"
},
"type": "FEE"
}
],
"totalPrice": {
"amount": {
"currencyCode": "USD",
"units": 72
},
"type": "ACTUAL"
}
}
},
"intent": "actions.intent.TRANSACTION_DECISION"
}
}
}
}
Related
Using PayPal's current API I've created a simple Product:
{
"id" : "A-001",
"name": "A Service",
"description": "Video streaming service",
"type": "SERVICE",
"category": "SOFTWARE"
}
Also created a Plan, which is tiered based on Quantity
{
"product_id" : "A-001",
"name": "Default Plan",
"description": "Plan with regular and trial payment definitions.",
"quantity_supported" : true,
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "TRIAL",
"sequence": 1,
"total_cycles": 1
},
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 2,
"total_cycles": 12,
"pricing_scheme": {
"pricing_model" : "TIERED",
"version" : 1,
"tiers": [{
"starting_quantity": 1,
"ending_quantity": 499,
"amount": { "currency_code":"USD", "value":0.55}
},
{
"starting_quantity": 500,
"ending_quantity": 999,
"amount": { "currency_code":"USD", "value":0.5}
},
{
"starting_quantity": 1000,
"ending_quantity": 2499,
"amount": { "currency_code":"USD", "value":0.46}
},
{
"starting_quantity": 2500,
"amount": { "currency_code":"USD", "value":0.37}
}
]
}
}
],
"payment_preferences": {
"auto_bill_outstanding": true,
"setup_fee": {
"value": "10",
"currency_code": "USD"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
},
"taxes": {
"percentage": "10",
"inclusive": false
}
}
Now, I try to create a Subscription to the Plan:
{
"plan_id": "P-16786052YT8021220MAMUCDY",
"start_time": "2021-03-01T00:00:00Z",
"quantity": "20",
"shipping_amount": {
"currency_code": "USD",
"value": "0.00"
},
"subscriber": {
"name": {
"given_name": "John",
"surname": "Doe"
},
"email_address": "customer#example.com",
"shipping_address": {
"name": {
"full_name": "John Doe"
},
"address": {
"address_line_1": "2211 N First Street",
"address_line_2": "Building 17",
"admin_area_2": "San Jose",
"admin_area_1": "CA",
"postal_code": "95131",
"country_code": "US"
}
}
},
"application_context": {
"brand_name": "walmart",
"locale": "en-US",
"shipping_preference": "SET_PROVIDED_ADDRESS",
"user_action": "SUBSCRIBE_NOW",
"payment_method": {
"payer_selected": "PAYPAL",
"payee_preferred": "IMMEDIATE_PAYMENT_REQUIRED"
},
"return_url": "https://example.com/returnUrl",
"cancel_url": "https://example.com/cancelUrl"
}
}
But I get an Error response:
{
"name": "UNPROCESSABLE_ENTITY",
"message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id": "658174d246c0b",
"details": [
{
"issue": "SUBSCRIPTION_CANNOT_HAVE_QUANTITY",
"description": "Subscription can't have quantity as the plan does not support quantity."
}
],
"links": [
{
"href": "https://developer.paypal.com/docs/api/v1/billing/subscriptions#UNPROCESSABLE_ENTITY",
"rel": "information_link",
"method": "GET"
}
]
}
Why do I get this error when my Plan clearly states "quantity_supported" : true, ?
In my case I had forgotten to modify the PayPal-Request-Id from a previous Plan creation (which didn't allow Quantity), so the Plan with details above wasn't being created
Since two weeks we are trying to implement transaction api v3. with Google
payment option. Once we did a transaction the receipt has been displayed.
When we pressed "order" button we got confirmation that the transaction is
being confirmed but in developer Dotpay panel there were no visible
payments.
After a few transactions action stopped displaying the receipt and it
informed that "something went wrong. Try again later". When we removed googlePaymentOption from
TransactionDecision the receipt has been displayed but we were still not
able to make any transactions.
It lasted for a few days and after that we were able to make transactions again but there were
still no payments visible.
Can you please have a look?
Hereby you can find our transaction logs:
{
"conversationToken": "[\"_actions_on_google\",\"podsumowanie\",\"rezerwuj_dostawe\",\"zmien_zamowienie_lista\",\"start_index\",\"modyfikuj_koszyk\",\"dodaj_produkt\"]",
"expectUserResponse": true,
"expectedInputs": [{
"inputPrompt": {
"richInitialPrompt": {
"items": [{
"simpleResponse": {
"textToSpeech": "Transaction Decision Placeholder."
}
}]
}
},
"possibleIntents": [{
"intent": "actions.intent.TRANSACTION_DECISION",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
"order": {
"merchantOrderId": "9g1blj8rmvo",
"userVisibleOrderId": "9g1blj8rmvo",
"buyerInfo": {
"email": "janedoe#gmail.com",
"firstName": "Jane",
"lastName": "Doe",
"displayName": "Jane Doe"
},
"createTime": "2020-06-09T14:02:08.812Z",
"lastUpdateTime": "2020-06-09T14:02:08.812Z",
"transactionMerchant": {
"id": "book_store_1",
"name": "Book Store"
},
"contents": {
"lineItems": [{
"id": "memoirs_4",
"name": "Our memoirs",
"priceAttributes": [{
"type": "REGULAR",
"name": "Item Price",
"state": "ACTUAL",
"amount": {
"currencyCode": "PLN",
"amountInMicros": "1000000"
},
"taxIncluded": true
}, {
"type": "TOTAL",
"name": "Total Price",
"state": "ACTUAL",
"amount": {
"currencyCode": "PLN",
"amountInMicros": "1000000"
},
"taxIncluded": true
}],
"notes": ["Special introduction by author."],
"purchase": {
"quantity": 1
}
}]
},
"priceAttributes": [{
"type": "SUBTOTAL",
"name": "Subtotal",
"state": "ESTIMATE",
"amount": {
"currencyCode": "PLN",
"amountInMicros": "1000000"
},
"taxIncluded": true
}, {
"type": "DELIVERY",
"name": "Delivery",
"state": "ACTUAL",
"amount": {
"currencyCode": "PLN"
},
"taxIncluded": true
}, {
"type": "TAX",
"name": "Tax",
"state": "ESTIMATE",
"amount": {
"currencyCode": "PLN"
},
"taxIncluded": true
}, {
"type": "TOTAL",
"name": "Total Price",
"state": "ESTIMATE",
"amount": {
"currencyCode": "PLN",
"amountInMicros": "1000000"
},
"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": "The Memoir collection",
"purchase": {
"status": "CREATED",
"type": "RETAIL",
"returnsInfo": {
"daysToReturn": 1,
"policyUrl": "http://www.example.com"
},
"fulfillmentInfo": {
"id": "FULFILLMENT_SERVICE_ID",
"fulfillmentType": "DELIVERY",
"expectedFulfillmentTime": {
"timeIso8601": "2025-09-25T18:00:00.877Z"
},
"price": {
"type": "REGULAR",
"name": "Delivery Price",
"state": "ACTUAL",
"amount": {
"currencyCode": "PLN"
},
"taxIncluded": true
},
"fulfillmentContact": {
"email": "janedoe#gmail.com",
"firstName": "Jane",
"lastName": "Doe",
"displayName": "Jane Doe"
}
},
"purchaseLocationType": "ONLINE_PURCHASE",
"userVisibleStatusLabel": "CREATED"
}
},
"orderOptions": {
"userInfoOptions": {
"userInfoProperties": ["EMAIL"]
}
},
"paymentParameters": {
"googlePaymentOption": {
"facilitationSpec": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"Frisco\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"MASTERCARD\",\"VISA\"]},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gateway\":\"dotpay\",\"gatewayMerchantId\":\"705777\"}}}],\"transactionInfo\":{\"totalPriceStatus\":\"FINAL\",\"totalPrice\":\"1.00\",\"currencyCode\":\"PLN\"}}"
}
},
"presentationOptions": {
"actionDisplayName": "PLACE_ORDER"
}
}
}],
"speechBiasingHints": ["$usun", "$dalej", "$events", "$wroc", "$product", "$deleteProduct", "$sztuka", "$dodaj", "$ilosc", "$produkty", "$deleteOrder"]
}],
"responseMetadata": {
"status": {
"message": "Success (200)"
},
"queryMatchInfo": {
"queryMatched": true,
"intent": "777d19a8-c59a-46d2-ae22-212827b5726e"
}
}
} ```
Currently, Google is working with a limited number of partners that can get access to the production Google Pay API. If you're not one of those partners, you're welcome to read the documentation and test the integration using the sandbox environment.
https://developers.google.com/assistant/transactions/physical/dev-guide-physical-gpay
If you are indeed one of these partners, please reach out to your Google contact.
Question updated - more details added.
I get a 500 (INTERNAL_SERVICE_ERROR) error from PayPal when I try to pay for an order.
I get ok from create order, and get the orderID - order status CREATED.
The order is approved by buyer - successfully and order status become APPROVED.
Order created by https://api.sandbox.paypal.com/v1/checkout/orders
Approved using paypal https://www.paypalobjects.com/api/checkout.js
{
"id": "53T50821FM697283T",
"gross_total_amount": {
"value": "26.66",
"currency": "ILS"
},
"purchase_units": [
{
"reference_id": "20180318-64466",
"amount": {
"currency": "ILS",
"total": "26.66"
},
"payee": {
"email": "d0535318380-classeeks#gmail.com"
},
"items": [
{
"name": "Meeting",
"sku": "20180318-64466",
"description": "Meeting 1/26/2018 1:00 AM-1/26/2018 2:20 AM. aaaaa",
"price": "26.66",
"currency": "ILS",
"quantity": 1
}
],
"shipping_address": {
"recipient_name": "Andrey Dyachenko",
"line1": "ישראליס 5 דירה 4",
"city": "תל-אביב",
"country_code": "IL",
"postal_code": "61014",
"state": "",
"type": "HOME_OR_WORK"
},
"partner_fee_details": {
"receiver": {
"email": "d0535318380-reciver#gmail.com"
},
"amount": {
"value": "12.66",
"currency": "ILS"
}
}
}
],
"payer_info": {
"email": "d0535318380-buyer#gmail.com",
"first_name": "Andrey",
"last_name": "Dyachenko",
"payer_id": "BZDA9RCZXKYQY",
"country_code": "IL",
"shipping_address": {
"recipient_name": "Andrey Dyachenko",
"line1": "ישראליס 5 דירה 4",
"city": "תל-אביב",
"country_code": "IL",
"postal_code": "61014",
"state": "",
"type": "HOME_OR_WORK"
}
},
"metadata": {
"supplementary_data": [
{
"name": "risk_correlation_id",
"value": "53T50821FM697283T"
},
{
"name": "buyer_ipaddress",
"value": "109.65.134.129"
},
{
"name": "external_channel",
"value": "WEB"
}
]
},
"redirect_urls": {
"return_url": "https://classeeks.com/order/details/70368c93-90db-4a8e-bd82-6d611acc2d17",
"cancel_url": "https://classeeks.com/order/details/70368c93-90db-4a8e-bd82-6d611acc2d17"
},
"create_time": "2018-03-18T19:49:11Z",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T/capture",
"rel": "capture",
"method": "POST"
}
],
"status": "APPROVED"
}
Next step pay with https://api.sandbox.paypal.com/v1/checkout/orders/53T50821FM697283T/pay
{ "disbursement_mode":"DELAYED" }
Response
{
"name": "INTERNAL_SERVICE_ERROR",
"message": "The server encountered an internal error that prevented it from fulfilling this request.",
"information_link": "https://developer.paypal.com/docs/api/#INTERNAL_SERVICE_ERROR",
"debug_id": "be0c6976ab17a"
}
Based https://demo.paypal.com/us/demo/go?page=cart
If you have created the order successfully, then you can either capture the order directly or create the authorization which places the fund on hold and later you can capture the authorization. Check the doc for PayPal order APIs.
I have been following this guide to work on Domino 9.0.1
Domino Calendar services
I am using JSON and the POST command works but creates an appointment, what I want to do is create a meeting. I have tried setting other fields like event['x-lotus-appttype'].data or event.AppointmentType = 3 but I still get an appointment.
JSON I am sending
{
"events": [
{
"summary":"Meeting 1",
"location":"Location 1",
"start": {
"date":"2013-12-01",
"time":"13:00:00",
"utc":true
},
"end": {
"date":"2013-12-01",
"time":"14:00:00",
"utc":true
}
}
]
}
What is the correct JSON format to create a meeting ?
Take a look at the following documentation: Event with attendees represented in JSON format
EXAMPLE 4. Event with attendees and time zone array:
{
"x-lotus-charset": {
"data": "UTF-8"
},
"timezones": [
{
"tzid": "Eastern",
"standard": {
"start": {
"date": "1950-11-05",
"time": "02:00:00"
},
"offsetFrom": "-0400",
"offsetTo": "-0500",
"recurrenceRule": "FREQ=YEARLY;BYMONTH=11;BYDAY=1SU;BYHOUR=2;BYMINUTE=0"
},
"daylight": {
"start": {
"date": "1950-03-12",
"time": "02:00:00"
},
"offsetFrom": "-0500",
"offsetTo": "-0400",
"recurrenceRule": "FREQ=YEARLY;BYMONTH=3;BYDAY=2SU;BYHOUR=2;BYMINUTE=0"
}
}
],
"events": [
{
"href": "/mail/dlawson.nsf/api/calendar/events/DB7E0BAC21EC322A85257BD200756E26-Lotus_Notes_Generated",
"id": "DB7E0BAC21EC322A85257BD200756E26-Lotus_Notes_Generated",
"summary": "Staff meeting",
"location": "Ray's office",
"description": "Please email your status update 24 hours before the meeting.",
"start": {
"date": "2013-09-12",
"time": "09:00:00",
"tzid": "Eastern"
},
"end": {
"date": "2013-09-12",
"time": "10:00:00",
"tzid": "Eastern"
},
"class": "public",
"transparency": "opaque",
"sequence": 0,
"last-modified": "20130825T212457Z",
"attendees": [
{
"role": "chair",
"status": "accepted",
"rsvp": false,
"displayName": "Duke Lawson/Peaks",
"email": "DukeLawson#swg.usma.ibm.com"
},
{
"role": "req-participant",
"status": "needs-action",
"rsvp": true,
"displayName": "Dean Melnyk/Peaks",
"email": "DeanMelnyk#swg.usma.ibm.com"
},
{
"role": "req-participant",
"status": "needs-action",
"rsvp": true,
"displayName": "Raymond Chan/Peaks",
"email": "RaymondChan#swg.usma.ibm.com"
}
],
"organizer": {
"displayName": "Duke Lawson/Peaks",
"email": "DukeLawson#swg.usma.ibm.com"
},
"x-lotus-broadcast": {
"data": "FALSE"
},
"x-lotus-notesversion": {
"data": "2"
},
"x-lotus-appttype": {
"data": "3"
}
}
]
}
I hope this can help :)
I have followed setting up Broadleaf to make it running by following its documentation (http://docs.broadleafcommerce.org/current/REST-Tutorials.html). I wanted to do checking out the cart using REST Api; that's, /cart/checkout. Therefore, I looked inside the code in order to understand how the JSON format being sent will look alike. By looking through the code, I found that it is required to pass the JSON data as shown following:
{
"paymentInfo": {
"id": ,
"orderId": ,
"type": ,
"address": {
"id":
"firstname":
"lastname":
"addressLine1":
"addressLine2":
"city":
"state":
"country":
"postalCode":
},
"phone": "",
"additionalFields": "",
"amount": "",
"amountItems": "",
"customerIpAddress": "",
"referenceNumber": ""
},
"referenced": {
"id": "",
"referenceNumber": "",
"type": "",
"pan": "",
"cvvCode:" "",
"expirationMonth": "",
"expirationYear": "",
"accountNumber": "",
"routingNumber": "",
"pin": ""
}
}
However, I have no idea such the JSON data looks like. Therefore, if anyone who has ever used the api, please help me by showing an example of data in order to make the request. Looking forward to the answers.
Thanks in advance.
All of our REST APIs are exposed through a 'wrapper' concept. For instance, there is a CustomerWrapper, OrderWrapper, etc. These wrappers define which properties are serialized back and forth with the REST APIs.
For your specific case, you should look at PaymentReferenceMapWrapper.
{
"id": 1751,
"status": "IN_PROCESS",
"totalTax": {
"amount": "0.00",
"currency": "INR"
},
"totalShipping": {
"amount": "0.00",
"currency": "INR"
},
"subTotal": {
"amount": "860.00",
"currency": "INR"
},
"total": {
"amount": "860.00",
"currency": "INR"
},
"customer": {
"id": 2600
},
"orderItems": [
{
"id": 1752,
"name": "abc",
"quantity": 2,
"retailPrice": {
"amount": "430.00",
"currency": "INR"
},
"salePrice": {
"amount": "430.00",
"currency": "INR"
},
"orderId": 1751,
"categoryId": 10300,
"skuId": 10212,
"productId": 10212,
"isBundle": false,
"orderItemPriceDetails": [
{
"id": 1752,
"totalAdjustmentValue": {
"amount": "0.00",
"currency": "INR"
},
"totalAdjustedPrice": {
"amount": "860.00",
"currency": "INR"
},
"quantity": 2,
"adjustments": []
}
],
"isDiscountingAllowed": true
}
],
"fulfillmentGroups": [
{
"id": 1502,
"orderId": 1751,
"total": {
"amount": "860.00",
"currency": "INR"
},
"fulfillmentGroupItems": [
{
"id": 1752,
"fulfillmentGroupId": 1502,
"orderItemId": 1752,
"totalTax": {
"amount": "0.00",
"currency": "INR"
},
"quantity": 2,
"totalItemAmount": {
"amount": "860.00",
"currency": "INR"
}
}
]
}
],
"payments": [
{
"id": 601,
"orderId": 1751,
"type": "COD",
"amount": "860.00",
"currency": "INR",
"gatewayType": "Passthrough",
"transactions": [
{
"id": 601,
"orderPaymentId": 601,
"type": "AUTHORIZE_AND_CAPTURE",
"success": true,
"amount": "860.00",
"currency": "INR"
}
]
}
]
}
This is the same json you will get from /cart?customerId="" with method GET after successfully executing /cart/checkout/payment