I am trying to get the OAuth2 Playground to return a receipt for a purchase made on our flutter app, however I've been unable to successfully get it to work.
I have all the required information
ProjectID = com.myorg.myapp
ProductID = myapp.funds.five
PurchaseToken = TokenValueGoesHere
I authorize, get to the point of "Configure request to API", I fill out the appropriate url
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/[ProjectID]/purchases/products/[ProductID]/tokens/[PurchaseToken]
however, the playground returns with
HTTP/1.1 403 Forbidden
Content-length: 423
X-xss-protection: 0
X-content-type-options: nosniff
Transfer-encoding: chunked
Vary: Origin, X-Origin, Referer
Server: ESF
-content-encoding: gzip
Cache-control: private
Date: Thu, 26 Jan 2023 12:52:26 GMT
X-frame-options: SAMEORIGIN
Alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Content-type: application/json; charset=UTF-8
{
"error": {
"message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console.",
"code": 403,
"errors": [
{
"reason": "projectNotLinked",
"message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console.",
"domain": "androidpublisher"
}
]
}
}
We double and triple checked to ensure that the API is linked. I've created new products after the linking because I've seen others have to do that. We believe the service account has the correct permissions.
What am I missing and how do I fix this so I can verify the receipt of a purchase?
Alright so the project WAS linked properly and the error was at best vague as to what the actual problem was, in being that the OAUTH credential I was providing the playground wasn't sufficient to pull the information.
I ended up solving the issue in code.
#GetMapping("/verifyPurchase/app/appName={appName}&productId={productId}&purchaseToken={purchaseToken}")
public boolean isPurchaseSuccessful(#PathVariable(value = "appName") String appName,
#PathVariable(value = "productId") String productId,
#PathVariable(value = "purchaseToken") String purchaseToken) throws GeneralSecurityException, IOException {
// Build service account credentials, important to include the scope which you can get from googles documentation
GoogleCredentials serviceAccountCredentials =
ServiceAccountCredentials.fromStream(new FileInputStream("src/main/resources/auth.json")) // Service Account Credentials json file from Google cloud
.createScoped(Collections.singleton("https://www.googleapis.com/auth/androidpublisher"));
// Android publisher object, slightly older version but does operate as of 2023-Jan-26
AndroidPublisher androidPublisher = new AndroidPublisher.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
new HttpCredentialsAdapter(serviceAccountCredentials)
).setApplicationName(appName).build(); // Give it the application to build the publisher for.
// At this point we're authorized. We can pull down the receipt from the API, and provide the publisher
// with the appropriate product information and purchase token that we got when we made the purchase from the
// flutter application side of things.
var receipt = androidPublisher.purchases().products().get(appName, productId, purchaseToken).execute();
// return if the purchase was successful, may need error handling here testing to come.
return PURCHASED.equals(receipt.getPurchaseState());
}
Related
here is the link
https://developer.amazon.com/en-US/docs/alexa/account-linking/app-to-app-account-linking-starting-from-your-app.html
Steps that I followed in my Android App.
I completed the LWA fallback url setup , in fallback URL I have used client ID that is received from Account linking page of Alexa custom skill.
After open the LWA url in browser , page asked to Login in Amazon after that I can see the page where my skill asked to access the lwa details with an Allow and Cancel button
After Allow My Application is getting Auth-Token , From that Auth-Token I am calling token API and getting Access Token.
after that I am calling below activation skill api
POST /v1/users/~current/skills/{skillId}/enablement HTTP/1.1
Host: api.amazonalexa.com, api.eu.amazonalexa.com,
api.fe.amazonalexa.com
Content-Type: application/json
Authorization: "Bearer {Amazon Access Token}"
{
"stage": "skill stage",
"accountLinkRequest": {
"redirectUri": "https://yourRedirectURI",
"authCode": "Your user's authorization code from your authorization
server",
"type": "AUTH_CODE"
}
}
I have used parameters values like below
Amazon access token - Got that from Amazon token API.
redirectUri = https://pitangui.amazon.com/api/skill/link/XXXXXXXXXXX
authCode = got after perform successful login with amazon.
But I got 400 bad request error with Message
{"message":"Invalid account linking credentials"}
I am not able to get what I am doing wrong . Help me out if anyone have some suggestions.
The 400 bad request "Invalid account linking credentials" it's because you are receiving wrong credentials, so make sure that you are using correct client ID and secret to use skill Activation API.
I would recommend following this article.
https://amazon.developer.forums.answerhub.com/articles/240817/app-to-app-account-linking-debugging-tips.html
My goal is to validate user purchases on google server as described here > Purchases.products: get
but i need to authorise the request > Authorisation Documentation
According to Google Play Developer API Authorization Doccumentation in order to generate access and refresh token :
"... sending a POST request to https://accounts.google.com/o/oauth2/token with the following fields set:
grant_type=authorization_code
code=<the code from the previous step>
client_id=<the client ID token created in the APIs Console>
client_secret=<the client secret corresponding to the client ID>
redirect_uri=<the URI registered with the client ID>
A successful response will contain your tokens in JSON format:
{
"access_token" : "ya29.ZStBkRnGyZ2mUYOLgls7QVBxOg82XhBCFo8UIT5gM",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/zaaHNytlC3SEBX7F2cfrHcqJEa3KoAHYeXES6nmho"
}
"
i successfully generated code, client_id, client_secret, redirect_uri from console.developers.google.com but when i send the POST request
https://accounts.google.com/o/oauth2/token?grant_type=authorization_code&code=my_generated_codeA&client_id=generated_client_id&client_secret=generated_client_secret&redirect_uri=my_redirect_uri
i get the the following response when i used Postman:
{
"error": "invalid_request",
"error_description": "Missing header: Content-Type"
}
with status code = 400
i get the the following response when i used Chrome :
{
"error": "invalid_request"
}
How can i get the right response?
The https://accounts.google.com/o/oauth2/token?grant_type=authorization_code&code=my_generated_codeA&client_id=generated_client_id&client_secret=generated_client_secret&redirect_uri=my_redirect_uri is GET request, it's not POST request because there is no request body.
Also, when using Postman the response
{
"error": "invalid_request",
"error_description": "Missing header: Content-Type"
}
means that you select the wrong header. You should select application/x-www-form-urlencoded option in Bodytab in Postman. Then write down key pair value. You will get something like this:
After a lot of reading and Googling it seems I have made a complete setup for Google Cloud Messaging to send push-notifications. My missing link is the Reference_Ids that I must use to target apps. I have created a project and also added my apps to it.
When I send a push-request to GCM I get the following response:
{"multicast_id":7952352701122753715,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Alt-Svc: quic=":443"; ma=2592000; v="35,34"
Vary: Accept-Encoding
Transfer-Encoding: chunked
Accept-Ranges: none
Cache-Control: max-age=0, private
Date: Wed, 21 Dec 2016 16:12:43 GMT
Server: GSE
Content-Type: application/json; charset=UTF-8
Expires: Wed, 21 Dec 2016 16:12:43 GMT
}
And the error reads "InvalidRegistration".
So my questions are:
Where do I find my registration Ids?
And as a related follow-up question, where do I find Registration_Ids for everyone using an app or a specific group or user?
BTW: I found a related question, but it does not seem to have an answer to as where to find these Ids. StackOverflow post.
InvalidRegistration means that the registration token (registration id) you used is invalid (doesn't exist, wrong format):
Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
Make sure that you are using the correct and corresponding registration token to the device you intend to send the message to. For testing, I would suggest to make use of the Firebase Console too, so that you can see if the error still occurs from there.
For Android, you can retrieve the registration token by calling:
FirebaseInstanceID.getToken()
You may then choose to store the token to your App Server.
You should use Api server_key .
Go to firebase console -> click on your project -> click on gear icon -> project_setting -> cloud_messaging
I'm building an app which needs to retrieve personal informations (specifically, complete name, profile picture and cover picture) from the logged google account and I'm trying to do this without implementing the Google+ Sign In, which I think is an overkill in my specific case.
This is the GoogleAccountCredential object I'm using to authenticate
credential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff())
.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
whereas SCOPES is
private static final String[] SCOPES = {CalendarScopes.CALENDAR_READONLY, CalendarScopes.CALENDAR, "profile", "email", "https://www.googleapis.com/auth/plus.login" };
now, when I launch the application I get correctly asked permissions to use the requested informations:
https://www.dropbox.com/s/e11y0gnnemfgu02/Screenshot_2015-08-11-19-41-08~01.png?dl=0
When I want to retrieve the required data, I execute an AsyncTask where I make the following GET request
CloseableHttpResponse response = httpClient.execute(new HttpGetHC4("https://www.googleapis.com/plus/v1/people/me"));
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
Log.d("ProfileTask", result.toString() );
and I get as a response this
{ "error":
{ "errors":
[ { "domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console" } ],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup." }}
Now:
I have enabled in my Google Developer Console the Google+ API (I actually tried enabling it and disabling it to see if it makes any difference: it doesn't) with an OAuth credential tied to the SHA1 fingerprint of the application
I have also enabled the Calendar API and I don't get any error from its requests
I also tried making GET requests using a Public API key created, such as
GET https://www.googleapis.com/plus/v1/people/me?key={MY_API_KEY}
just to have the same result or even getting an error where it said "ipRefererBlocked There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed."
What am I doing wrong? Have I misunderstood the functioning of these APIs? How else can I retrieve these data without signing with Google+?
Thanks a lot for your help.
EDIT: I tried accessing also using the accessToken got from credentials.getToken() in http request:
GET https://www.googleapis.com/plus/v1/people/me?accesstoken={ACCESS_TOKEN}
to no avail, same error as before.
After you have the client ID and client secret, you send an HTTP POST to the OAuth 2.0 device endpoint at https://accounts.google.com/o/oauth2/device/code with your client_id and a list of scopes. Unlike the other OAuth 2.0 flows, response_type and redirect_uri are not needed in the device flow. The following is an example request for a user code:
POST /o/oauth2/device/code HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=812741506391-h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com&
scope=email%20profile
I have tried but it results all time:
{
"error" : "invalid_scope",
"error_description" : "Some requested scopes were invalid. {invalid=[rad365rad#gmail.com]}",
"error_uri" : "http://code.google.com/apis/accounts/docs/OAuth2.html"
}
can anyone solve this..where i am wrong please
You can start from here, this should help get you the device code
curl -d "client_id=xxxxxxxxxxxxxxxxx.apps.googleusercontent.com&scope=email profile" https://accounts.google.com/o/oauth2/device/code