TRANSACTION_REQUIREMENTS_CHECK not working - actions-on-google

Since 2 weeks I trying to figure out how the Transaction Requirement Check is working.
I copy pasted exactely the same exemple you have provided in the documentation which is this one :
app.intent('verify_transaction_requirements', (conv) => {
console.log("am I entering in this intent ?");
conv.ask(new TransactionRequirements({
orderOptions: {
requestDeliveryAddress: false,
},
paymentOptions: {
googleProvidedOptions: {
prepaidCardDisallowed: false,
supportedCardNetworks: ['VISA', 'AMEX'],
// These will be provided by payment processor,
// like Stripe, Braintree, or Vantiv.
tokenizationParameters: {}
}
}
}));
});
When trying this bit of code on my mobile phone, I am receiving an error saying that my application is not responding anymore.
How error, looking at the log, my Google Function seems to send a 200 status code.
No error has been printed at all.
I have also enabled the transactions on Google Action Console.
Do you have an idea about where the problem could come from ?
Regards,

I believe the issue is because the tokenizationParameters field is empty, but it expecting some data.
Try using placeholder information in it's place, or setting up a sandbox payment processor using Stripe or Braintree:
tokenizationParameters: {
tokenizationType: 'PAYMENT_GATEWAY',
parameters: {
"gateway": 'stripe',
"stripe:publishableKey" : "pk_1234",
"stripe:version" : "1.5"
}
},

Related

WooCommerce REST API PUT on Variations does not work

I have logged this issue on GitHub but I understand it will take time to get attention. Is there another way of updating Product Variations?
https://github.com/woocommerce/woocommerce/issues/35555
When I PUT a stock_quantity or price update for a product variation nothing changes. This however works 100% on a product but not a variation. The below will have no effect even though I receive an OK status 200.
PUT: wp-json/wc/v3/products/6360/variations/6361
{
"stock_quantity": 7
}
I also tried using the batch endpoint but also nothing gets updated.
/wp-json/wc/v3/products/6360/variations/batch
"update": [
{
"id":6361,
"stock_quantity": 4
}
]
This is not a bug, I was using Postman and the 200 OK returned confused the issue.
Once I added the required Content-Type:application/json header, the record successfully updated.
I also made use of a deprecated NodeJS library woocommerce-api and later tried with the replacement woocommerce-rest-api but both does not seem to handle this correctly.
I can suggest to rather just axios directly to the woocommerce rest api:
const baseUrl = `${process.env.WOOCOMMERCE_URI}/wp-json/wc/v3/`;
const instance = {
headers: {'Content-Type': 'application/json'},
auth: {
username: process.env.WOOCOMMERCE_KEY,
password: process.env.WOOCOMMERCE_SECRET
}
};
let putUrl = `products/${woocommerceImport.onlineProductId}/variations/${woocommerceImport.onlineVariantId}`;
await axios.put(`${baseUrl}${putUrl}`, {
stock_quantity: stock
}, instance);

Testing Cloud Function - Cannot read property 'data' of undefined

I've got a Raspberry Pi and setup a weather (and soil moisture) rig.
I found this guide: https://codelabs.developers.google.com/codelabs/iot-data-pipeline which I followed and got stuck around Step 6-7.
From what I understand - when I send data to PubSub - nothing happens. On the Raspberry End I sort of get the idea that data is being sent but it doesn't get passed into BigQuery. I did some print statements at various points to try and see where it got stuck.
As I was trying to find the error I slowly backtracked to Step 5 (Create a Cloud Function).
Step 5 along with associated code I copied can be seen here: https://codelabs.developers.google.com/codelabs/iot-data-pipeline/#4
In GCP - I click into Cloud Function -> function-weatherPubSubToBQ -> Testing (tab)
Under the heading - Trigger event - I filled out the JSON below:
{
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
}
When I click on - Test the function - the output is as below
**Error: function execution failed. Details:
Cannot read property 'data' of undefined**
Screen capture of JSON and error message
I am guessing one of these two things are causing the problem.
event.data or PubSubMessage.data
I tried to make some changes to the code but I am just shooting in the dark.
I was wondering if:
I did something wrong which means there might be some other
issues somewhere else.
This guide is slightly old and there have
been some updates which make the older code in the guide not
function as desired. (not step/image in the guide matches with what
I saw online, as of Sep 2020)
If someone knows what is wrong in
the code and is able to let me know how to solve it that would be
much appreciated.
Thanks in advance.
TLDR: The tutorial is outdated, don't use it, unless you want to face multiple problems and want to learn in the hard way
I went through the tutorial and I was able to replicate the issue.. and many more. As you already mentioned it, the tutorial is outdated and many things have changed, you can infer that by looking at the images and noticing that the UI is even different, so I wouldn't recommend this tutorial to anyone who is new to GCP.
The first issue:
**Error: function execution failed. Details: Cannot read property 'data' of undefined**
Can be easily resolved by looking at the structure of what it's expected from a pub/sub message:
{
"data": string,
"attributes": {
string: string,
...
},
"messageId": string,
"publishTime": string,
"orderingKey": string
}
So easy right? However once you mimic the structure of the message with your own variables as I did:
{
"data": "",
"attributes": {
"sensorID":"Raspberry",
"timecollected":"2020-09-11 06:45:19",
"zipcode":"00000",
"latitude":"0.0",
"longitude":"0.0",
"temperature":"-273",
"humidity":"-1",
"dewpoint":"-273",
"pressure":"0"
},
"messageId": "id_1",
"publishTime": "2014-10-02T15:01:23Z",
"orderingKey": ""
}
You will get an error regarding the JSON:
SyntaxError: Unexpected token ' in JSON at position 1
This error is due to the use of ' on the construction of the JSON inside the variable incomingData so you have to change the first variable declaration, I did it by using template literals:
const incomingData = PubSubMessage.data ? Buffer.from(PubSubMessage.data, 'base64').toString() : `{"sensorID": "na","timecollected":"01/01/1970 00:00:00","zipcode":"00000","latitude":"0.0","longitude":"0.0","temperature":"-273","humidity":"-1","dewpoint":"-273","pressure":"0"}`;
But this is not the end of the issues, after doing some tests while trying to insert into BigQuery, I got an error regarding the insertion, but didn't get a clue of what was really happening, so I isolated the consult in an external script and found that the error handling was wrong, the first thing I recommend you to change is the BigQuery version in the package.json from:
"#google-cloud/bigquery": "^0.9.6"
Into
"#google-cloud/bigquery": "5.2.0"
Which is the last version at the time of writing this answer. The next part is to redefine the way you're using BigQuery constructor into:
const bigquery = new BigQuery({
projectId: projectId
});
Then after many tests I found that the catch wasn't doing it's job as expected, so have to rewrite that part into:
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
if(err.name=='PartialFailureError'){
if (err && err.response.insertErrors != undefined) {
err.response.insertErrors.forEach((errors) => {
console.log(errors);
})
}
}else{
console.log("GENERIC ERROR:",err)
}
});
});
After this you will finally notice that the error is due to (again) the incomingData variable:
Could not parse \'01/01/1970 00:00:00\' as a timestamp. Required format is YYYY-MM-DD HH:MM[:SS[.SSSSSS]]'
You have to change the date from 01/01/1970 00:00:00 into 1970-01-01 00:00:00.
Still here with me? Well there's another error coming from the usage of callback at the end of the CF:
This is due to the fact that Cloud Functions now require three parameters and callback is the last one, so change the function declaration into:
exports.subscribe = function (event, context, callback)
After all of this you have been able to insert data into BigQuery, however we're using the local variable and not the data coming from pub/sub, at this point I gave up, since I will need to practically rewrite the full function in order to make it work by using Attributes instead of the data.
So as mentioned it before don't follow this tutorial if you're beginning in the GCP world.

Check subscription validity using Flutters in-app-purchase plugin?

I'm trying to implement in-app purchases using the official Flutter In-App-Purchase plugin. I've got things working, except I can't figure out how to tell if a users subscription is still active or if it expired. Even after I canceled my test subscription, the values I get after connecting and doing queryPastPurchases() are the same as when the subscription was active:
productId: test_subscription_1
transactiondate: 1565682346568
status: null
verificationData
source: IAPSource.GooglePlay
localVerificationData: {
"orderId":"GPA.1234-1234-1234-12345",
"packageName":"com.example.myapp",
"productId":"test_subscription_1",
"purchaseTime":1565682346568,
"purchaseState":0,
"purchaseToken":"<long string>",
"autoRenewing":false
}
serverVerificationData: "<long string>"
Am I supposed to simply hard code my subscription period and compare the current time to purchaseTime + the subscription period? Will that even work across auto-renewals? What if the user changes the date on his phone to a year ago? It seems like there should be some value that should either give me the expiration time or at least a boolean true/false to indicate if the subscription is still valid?
The official in-app purchase plugin handles making the purchase but doesn't supply all of the backend infrastructure you need to handle auto-renewing subscriptions specifically.
The short answer to your question is send this purchase info up to your server and manage subscription status there. Alternatively you can look into a managed solution like purchases_flutter: https://pub.dev/packages/purchases_flutter/
I have used ‘purchases_flutter‘ and the process is straightforward. You can check the status of the subscription by calling the methods which comes with the plugin. Check out this article which includes an example https://medium.com/flutter-community/in-app-purchases-with-flutter-a-comprehensive-step-by-step-tutorial-b96065d79a21
For anyone still having issues, there's a simple solution to validate the receipt on iOS
Here's a simple js snippet that you can use to fetch the actual receipt from Apple and use it to validate the subscription
Note
You will need to generate app specific password for the app from with apple developer account
Further help
https://developer.apple.com/documentation/appstorereceipts/expiration_intent
const axios = require('axios');
const iosValidateReceipt = async (transactionReceipt, isTest = true) =>
new Promise(async (resolve, reject) => {
const url = isTest ? 'https://sandbox.itunes.apple.com/verifyReceipt' : 'https://buy.itunes.apple.com/verifyReceipt';
const data = {
'receipt-data': transactionReceipt,
password: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
};
console.log('iosValidateReceipt - input - ', { url, data });
try {
const response = await axios.post(url, data);
console.log('iosValidateReceipt - success - ', JSON.stringify(response.data, null, 2));
resolve(response.data);
} catch (err) {
console.log('iosValidateReceipt - error -', err);
reject(err);
}
});

Network error with axios and android emulator

I got a React-Native application working with a NodeJS backend which serves an API.
My React-Native front is using Expo and Axios to hit on a route of my NodeJS API (using Hapi, Joi, Knex), which will (for the example) update my DB (MySQL).
Everything works properly with my iOS simulator. However, on Android Emulator, SOME of my hits on route ""does not work"" with the following error message : Network Error - node_modules/axios/lib/core/createError.js:16:24 in createError (actually, it worked, but the front does not detect it...)
This is strange, because like I said, this is ONLY for some of my route. I changed the http://localhost:8000/api to http://10.0.2.2:8000/api to be sure that Android Emulator access my API, and it is ok for this part.
The buggy route is working properly on iOS, and is working properly on Insomnia / Postman ( localhost:8000/api/sendMail ). It is working on Android Emulator, but the application does not detect it.
This is an example of my code :
FRONT -- On press of my button "SendEmail" :
/* Button.js */
const sendAndEmailPromise = await sendEmail(this.state.email);
console.log(sendAndEmailPromise); // Output : NOTHING (not undefined, not null, N O T H I N G).
if (sendAndEmailPromise.status === 200) {
// handle it
} else (sendAndEmailPromise.status === 403) {
// etc. for each of my codeStatus that can be returned by my API
}
/* MyAPI.js */
export function sendEmail(mail) {
return axiosInstance
.post(`/sendEmail`, null, {
params: {
mail
},
})
.then(response => response) // Will not enter here
.catch(error => {
console.log(error); // Will output : NETWORK ERROR
});
}
BACK -- This is the sendEmail promise :
// Will return true of false :
const isMailSend = await sendTheEmail(mail);
console.log(isMailSend); // Output : TRUE and I receive the email on my gmail, so Android Emulator HIT the route.
if (isMailSend) {
return handler
.response({
data: {
message: "Email sent.",
},
})
.code(200);
} else {
// Handle it and return another response
}
I expect my front to now that everything works fine (which actually happened...) and get the code status of that, instead of a "Network error".
More, is it possible with Axios to get another level of error ? Something more specific.
A GitHub issue which is not totally the same but seems to relate something equivalent : https://github.com/axios/axios/issues/973
Thank you.
You are dealing with two problems here:
1) your emulator doesnt work because it cannot resolve the word "localhost" to an ip. is like using localhost2.com it will not resolve to something. This must be pointed to the local ip of your server 192.x.x.x
2) you server must be binded to 0.0.0.0 because by binding it to localhost it cannot resolve to local requests like 192.x.x.x. If you fix the binding your emulator would have the possibility to see the server and postman will too.
Adding these parameter in header resolved my issue
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json"

Not able to get data using MessengerExtensions.requestPaymentCredentials

Has anyone tried MessengerExtensions.requestPaymentCredentials using the facebook messenger extension sdk (refer documentation) ?
I am trying to call this in my client side javascript code and I am not getting any data. Below code doesn't alert me neither with email nor with error.
Here is my client side javascript code :
window.extAsyncInit = function() {
MessengerExtensions.requestPaymentCredentials(function success(name, email, cardType, cardLastFourDigits, shippingAddress) {
alert("Email" +email);
}, function error(err) {
alert("Messenger Extension error in getting payment credentials" + err);
});
};
Note : I am able to get user profile data using MessengerExtensions.getUserID by similar code.