Actions on google reservations for transaction API - actions-on-google

We are building boot using action on builder SDK. In bot we have transaction related feature so we want to implement reservation feature to make appointment reservation. In our Bot we just need reservation. user can't cancel/delete reservation (As our member can contact the user for next 3 4 days, we are just asking user free time so we can contact user). (We did't have reservation feature yet but google team force us to do so). My Question is while implementing reservation we have https://developers.google.com/assistant/transactions/physical/dev-guide-physical-reservations#validate_transaction_requirements_optional this feature optional we are not implementing this, for second step we have to build Order like this https://developers.google.com/assistant/transactions/physical/dev-guide-physical-reservations#build_the_order
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: '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'
};
According to doc we have to create order object like above, but we are unable to find any doc what are optional filed in above object and what value to pass for reservationTime and userAcceptableTimeRange.
reservationTime: {
timeIso8601: '2020-01-16T01:30:15.01Z',
},
userAcceptableTimeRange: {
timeIso8601: '2020-01-15/2020-01-17',
}
Further more do we need to implement Set up asynchronous requests to the Orders API (https://developers.google.com/assistant/transactions/physical/dev-guide-physical-reservations#set_up_asynchronous_requests_to_the_orders_api) as we don't need to update user appoint time and user can't cancel appointment.
Is there any other way we can avoid reservation? please guide me, thanks in advance.

Related

Moongose: Insert Many Docs then get Id and Update another Doc in another Collection

I have a collection of Users and Payments, and I need to add the Payments Id to their respective Users after they're created, but I don't find a eficient way of doing it.
const users = [
{
documentId: '123456789',
fullname: 'John Doe',
email: 'john#gmail.com',
payments: []
},
{
documentId: '987654321',
fullname: 'Fred Flinstone',
email: 'fred#gmail.com',
payments: []
},
{
documentId: '101010101',
fullname: 'Mary Poppins',
email: 'mary#gmail.com',
payments: []
}
]
const payments = [
{
billId: 1,
concept: 'Groceries',
amount: 10,
amountWithSymbol: '10$',
payHolder: 'John Doe'
},
{
billId: 2,
concept: 'Dinner',
amount: 15,
amountWithSymbol: '15$',
payHolder: 'John Doe'
}
{
billId: 3,
concept: 'Meal',
amount: 8,
amountWithSymbol: '8$',
payHolder: 'Fred Flinstone'
}
]
/*
I need to insert each payment get their Id and then add it to a User document.
This is the only way I found.
*/
payments.forEach(async pay => {
const paymentRecorded = await paymentsModel.create(pay);
const paymentUser = await usersModel.findOneAndUpdate(
{ fullname: pay.payHolder },
{ payments: [paymentRecorded._id] }
);
});
I know the way I do it, overwrites the previous recorded payments, so if you can solve that part too, I'd really appreciate it.

How to search and update multiple levels of a document in mongodb

I have a model in mongodb that looks something like this...
{
username: 'bob',
user_id: '12345',
post: 'Hey everyone, this is my post',
photoID: RANDOM_GENERATED_NUMBER, // each user has their own photoID
comments: [
{
username: 'tom',
user_id: '54321',
post: 'Hey everyone, this is comment 1',
photoID: RANDOM_GENERATED_NUMBER, // each user has their own photoID
responses: [
{
username: 'bob',
user_id: '12345',
post: 'Hey everyone, this is response 2',
photoID: RANDOM_GENERATED_NUMBER, // each user has their own photoID
},
{
username: 'will',
user_id: '35791',
post: 'Hey everyone, this is response 2',
photoID: RANDOM_GENERATED_NUMBER, // each user has their own photoID
}
]
},
{
username: 'bob',
user_id: '12345',
post: 'Hey everyone, this is comment 2',
photoID: RANDOM_GENERATED_NUMBER, // each user has their own photoID
responses: []
}
]
}
On my site, everytime a user changes their profile picture, they get a new 'photoID', referencing the picture, so it can easily be displayed with their username above any posts they make. Because of this, when a user updates their profile picture and gets a new 'photoID', I need to be able to make a query to this 'Post' model that searches for any 'posts', 'comments' or 'responses' that were posted by 'bob'. I then need to update the photoID for that 'post', 'comment' or 'response'.
Is there a query I can use to do this?
You need two queries to do that task:
Update photoID in subdocuments:
https://mongoplayground.net/p/jTb3qDxIHL1
db.collection.update({},
{
$set: {
"comments.$[c].photoID": "NEW_RANDOM_GENERATED_NUMBER",
"comments.$[].responses.$[r].photoID": "NEW_RANDOM_GENERATED_NUMBER",
},
},
{
multi: true,
arrayFilters: [
{
"c.user_id": "12345",
},
{
"r.user_id": "12345",
},
],
})
Update photoID in document root:
https://mongoplayground.net/p/-Bm4Oykz-1E
db.collection.update({
user_id: "12345"
},
{
$set: {
photoID: "NEW_RANDOM_GENERATED_NUMBER",
}
},
{
multi: true,
})

Payment token not in response

==== SOLVED ====
Problem is solved. Adyen wants you to send the whole string as an object. JSON.parse(token). Make sure Google pay is enabled in the Adyen platform.
================
I'm working on transactions with Actions on Google and integration Google Pay. I followed all steps according to the documentation of Actions on Google.
To propose an order I send the following snippet seen below.
Notes:
gateway value is replaced for security reasons.
gatewayMerchantId value is replaced for security reasons.
I'm using a registered gateway.
I have not yet registered as Google partner though the business console so I have no access to the production API.
// Handle order with Google Pay.
conv.ask(new TransactionDecision({
orderOptions: {
requestDeliveryAddress: true,
userInfoOptions: {
userInfoProperties: [
'EMAIL',
],
},
},
paymentParameters: {
googlePaymentOption: {
facilitationSpec: JSON.stringify({
apiVersion: 2,
apiVersionMinor: 0,
environment: 'TEST',
merchantInfo: {
merchantName: 'Example Merchant',
merchantId: '12345678901234567890',
},
allowedPaymentMethods: [
{
type: 'CARD',
parameters: {
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks: [
'AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA',
],
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'my_gateway',
'gatewayMerchantId': 'my_gateway_id',
},
},
},
],
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: prodPriceInclBtwInMicros.toString(),
currencyCode: 'EUR',
},
}),
},
},
presentationOptions: {
actionDisplayName: 'PLACE_ORDER',
},
order: order,
}));
The intent that handles the transaction decision value obtains the following arg value:
const arg = conv.arguments.get('TRANSACTION_DECISION_VALUE');
{
'#type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValue',
transactionDecision: 'ORDER_ACCEPTED',
order: {
googleOrderId: '02458320178127324049',
merchantOrderId: 'example',
userVisibleOrderId: 'example',
buyerInfo: {
email: 'example#example.com',
firstName: 'example',
lastName: 'example',
displayName: 'example example'
},
createTime: '2020-07-21T10:59:16.624Z',
lastUpdateTime: '2020-07-21T10:59:16.624Z',
transactionMerchant: { name: 'Example Merchant' },
contents: { lineItems: [Array] },
priceAttributes: [ [Object], [Object], [Object] ],
paymentData: { paymentResult: [Object], paymentInfo: [Object] },
purchase: {
status: 'CREATED',
type: 'RETAIL',
userVisibleStatusLabel: 'CREATED'
},
vertical: {
'#type': 'type.googleapis.com/google.actions.orders.v3.verticals.purchase.PurchaseOrderExtension',
status: 'CREATED',
type: 'RETAIL',
userVisibleStatusLabel: 'CREATED'
}
}
}
According to [Adyen][1] I should provide the payment token: 'Get the token from PaymentData response from the Google Pay API.' [Google][2] states that the token will be returned in a response object after the user approves the payment. This is certainly not the case as can be seen in the `arg` object.
By digging deeper into the paymentData, we get the following values:
{
paymentResult: {
googlePaymentData: '{"signature":"MEYCIQDS8Tiu9bprWqamQ24oNx+Wa43Wg6Vi3sP5PArDeOtOEAIhAOBqe4sQvN5tD390qWzDn9DIgwA8gjS8ajynrusOix6O","protocolVersion":"ECv1","signedMessage":"{\\"encryptedMessage\\":\\"Some_tokens_IUHASIDHUSAGFUAHS\\",\\"ephemeralPublicKey\\":\\"SOMEKEYSASD\\\\u003d\\",\\"tag\\":\\"SOMETAG_OIASJDJSOIJ\\\\u003d\\"}"}'
},
paymentInfo: {
paymentMethodDisplayInfo: {
paymentType: 'PAYMENT_CARD',
paymentMethodDisplayName: 'Visa •••• 1234'
},
paymentMethodProvenance: 'PAYMENT_METHOD_PROVENANCE_GOOGLE'
}
}
Still no token returned in the response... This will be necessary for the gateway.
Does anyone know how to resolve this? Or does this have to with the production Transaction API?
Any help is appreciated.
[1]: https://docs.adyen.com/payment-methods/google-pay/api-only
[2]: https://developers.google.com/pay/api/web/reference/response-objects#PaymentData

Paypal Express Checkout - More details for the customer

I use Paypal Express checkout with checkout.js
with the standard javascript code provided by paypal.
Everything works fine and the payment popup looks like this:
Now my question: Is it possible to add more details about the product to this popup?
Like for example, the name and description for the product?
(This code is not working).
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [
{
amount: { total: '{{ entry.itemPreis }}', currency: 'CHF' },
description: 'this is some description',
// description: works and shows up in the paypal backend
// but is not visible to the customer
title: 'this would be the title' // doesn't work
}
],
});
I find the paypal docs to be quite messy.
This works for me
transactions: [
{
amount: { total: '100', currency: 'CHF' },
item_list: {
items: [
{
name: 'Whateveryoufancy',
description: 'Lorem ipsum',
quantity: '1',
price: '100',
currency: 'CHF'
}
]
}
}
]

What is the best way to search through a Meteor collection using React?

I've got a collection that I'd like users to be able to search through and display the results accordingly. A while ago I was achieving this with the easy-search package, which uses blaze.
What are the most common approaches to this kind of problem with React? How do people search through their collections and display data accordingly?
I have a component for a book, which has images, author, title, etc. Each entry in the Books collection can be represented with this Book component, so what I'd like to do with this search is allow users to type in a title, or author name, or ISBN, etc, and display the matched results as one of these Book components.
Here's the collection:
Books = new Mongo.Collection('books');
BooksSchema = new SimpleSchema({
isbn: {
type: String,
label: 'ISBN'
},
title: {
type: String,
label: 'Title'
},
author: {
type: String,
label: 'Author'
},
condition: {
type: Number,
label: 'Condition'
},
conditionNotes: {
type: String,
label: 'Condition notes'
},
price: {
type: Number,
label: 'Price'
},
images: {
type: String,
label: 'Images',
autoform: {
afFieldInput: {
type: 'cloudinary'
}
}
},
postedOn: {
type: Date,
label: 'Posted on',
autoValue: function() {
return new Date();
},
autoform: {
type: 'hidden'
}
}
});
The Book component just renders the title, isbn, author, price etc in a presentable way. What I'm looking to do, again, is have a component that contains a search bar that can connect to this Mongo collection and query it, presenting results that match whatever the user typed in.