I want to get Auto renew subscription detail for that i can follow this official DOCUMENT:
In this document first step is Authorization. and i complete all steps and i get refresh_token AND access_token.
Now main part is there is one API to get renew subscription detail:
API: https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/products/productId/tokens/token
In this api there is three data required:
PackageName - Which i add from AndroidManifest.xml
SubscriptionId : Where to i get Subscription ID?
Token : Which i can get from Authorization steps.
Main problem is Where to i get subscription ID. Is Product Id is Subscription ID or What??
If SubscriptionId is ProductId then my API not working. API response is:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
Anyone have solution? or information about Subscription ID?
subscription ID is another term for SKU. You may also see it listed as product ID. They are the ID that you entered in the Play Developer Console when you first listed your products
https://play.google.com >> [choose an app] >> Store presence >> In-app products >> subscriptions >> Name & ID
The ID that you see there is the subscription ID.
Another way to find your SKU (aka subscription ID, product ID), is through SkuDetails#getSku() on the list of SkuDetails you get from querySkuDetailsAsync(params) in your Android client.
update with javascript/typescript snippet
async function getSubscriptionPurchaseFromPlay(sku: string, purchaseToken: string) {
const params = {
packageName: PACKAGE_NAME,
subscriptionId: sku,
token: purchaseToken
};
const response = await playDeveloperApi.purchases.subscriptions.get(params);
console.log("getSubsPurchaseFromPlay response:: ", response);
return response.data;
}
You must use the SKU in all places where you are requested to provide productId or subscriptionId. For example:
https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/products/productId/tokens/token
https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/subscriptions/subscriptionId/tokens/token
Related
i am trying to add a login with google to my android app. i installed nativescript-google-login ant did everything as i should and i redirected to the login window of google. but after i insert my details instead of getting the token and the info of the user i get this:
{
"provider": "google",
"code": 1
}
my google init looks like that:
google.GoogleLogin.init({
google: {
initialize: true,
serverClientId: "<client id of a web client for oauth 2.0>",
clientId: "<cient id for android>",
isRequestAuthCode: true
},
activity: application.android.foregroundActivity
})
what am i missing?
I've been going through the AWS Amplify docs and tutorials for how to use Amplify and Cognito identity pools together with UNauthenticated users. The example given by the Amplify docs is:
Amplify.Auth.fetchAuthSession(
result -> {
AWSCognitoAuthSession cognitoAuthSession = (AWSCognitoAuthSession) result;
switch(cognitoAuthSession.getIdentityId().getType()) {
case SUCCESS:
Log.i("AuthQuickStart", "IdentityId: " + cognitoAuthSession.getIdentityId().getValue());
break;
case FAILURE:
Log.i("AuthQuickStart", "IdentityId not present because: " + cognitoAuthSession.getIdentityId().getError().toString());
}
},
error -> Log.e("AuthQuickStart", error.toString())
);
But in practice when I use this code - I get an error printed out in LogCat:
AuthQuickStart: FAILURE IdentityId not present because: AmplifyException {message=You are currently signed out., cause=null, recoverySuggestion=Please sign in and reattempt the operation.}
Note: I did configure AWS Cognito to support Unauthenticaed users!
I've also looked everywhere for the Amplify Android API doc to see what other APIs are supported - couldn't find any Android API docs.
And looking into the AWS Amplify.Auth methods i could not find ANY function that deals with unauthenticated users
Question:
Any clue how can i use Amplify (Android) and have AWS credentials via AWS Cognito for unauthenticated users ???
This is David from the Amplify Android team. I was actually just looking into this the other day and currently there's a hack that's required to make unauth users work.
After setting up unauth/guest users through the CLI (as you mentioned you had) you have to call the getAWSCredentials method on the underlying escape hatch once for the app to get it to work.
Here's a code snippet I'd written that you can run after Amplify.configure (and again, this only needs to be run once per app install):
AWSMobileClient mobileClient = (AWSMobileClient) Amplify.Auth.getPlugin("awsCognitoAuthPlugin").getEscapeHatch();
mobileClient.getAWSCredentials(new Callback<AWSCredentials>() {
#Override
public void onResult(AWSCredentials result) {
// Now you'll see the Identity ID and AWSCredentials in the resulting auth session object.
Amplify.Auth.fetchAuthSession(
result2 -> Log.i(TAG, result2.toString()),
error -> Log.e(TAG, error.toString()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void onError(Exception e) {
// Handle the error however is best for your app
}
});
I'm working on a solution to avoid this hack right now and adding a documentation section on Unauth users to our site but in the meantime this should get it working for you.
Again note you only have to do this once and from then on out, it should just work when you call fetchAuthSession.
UPDATE: The non patched (official) version:
Amplify.Auth.fetchAuthSession(
result -> {
AWSCognitoAuthSession cognitoAuthSession = (AWSCognitoAuthSession) result;
switch (cognitoAuthSession.getIdentityId().getType()) {
case SUCCESS:
Log.i(TAG, "identity: " + cognitoAuthSession.getIdentityId().getValue());
Log.i(TAG, "credentials: " + cognitoAuthSession.getAWSCredentials().getValue(););
break;
case FAILURE:
Log.i(TAG, "FAILURE IdentityId not present because: " + cognitoAuthSession.getIdentityId().getError().toString());
}
},
error -> Log.e(TAG, "UNAUTH USERS ERR: " + error.toString()));
You wont be able to retrieve an authenticated session unless you have a logged in user.
If your Identity Pool (not User Pool) is configured for unauthenticated or guest users you can make a simple call to the GetId endpoint:
GetId
Generates (or retrieves) a Cognito ID. Supplying multiple logins will create an implicit linked account.
This is a public API. You do not need any credentials to call this API.
Request Syntax
{
"AccountId": "string",
"IdentityPoolId": "string",
"Logins": {
"string" : "string"
}
}
https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html
You should then be able to use the ID to retrieve a token using:
GetOpenIdToken
Gets an OpenID token, using a known Cognito ID. This known Cognito ID is returned by GetId. You can optionally add additional logins for the identity. Supplying multiple logins creates an implicit link.
The OpenID token is valid for 10 minutes.
This is a public API. You do not need any credentials to call this API.
Request Syntax
{
"IdentityId": "string",
"Logins": {
"string" : "string"
}
}
https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html
I'm using google REST Api to retrieve list of spreadsheets.
Everything works when it is accessed by my account.
But when I try to use foreign account, I'm getting this error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden {
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "The caller does not have permission",
"reason" : "forbidden"
} ],
"message" : "The caller does not have permission",
"status" : "PERMISSION_DENIED"
}
It says I have no access to my google script, but the script is set as visible and shared for anyone.
Code:
private Object getDataFromApi(ExecutionRequest request)
throws IOException
{
if (BuildConfig.DEBUG) {
request.setDevMode(true); // it will take saved version of script and not the published one
}
// Make the request.
Operation op =
mService.scripts().run(SCRIPT_ID, request).execute();
Change the SCOPE from SheetsScopes.SPREADSHEETS_READONLY to SheetsScopes.SPREADSHEETS.
private static final List SCOPES = Arrays.asList(SheetsScopes.SPREADSHEETS);
I found the problem was in code:
if (BuildConfig.DEBUG) {
request.setDevMode(true); // it will take saved version of script and not the published one
}
It looks like it alway force to access saved version and not the published. Then the foreign account had no access to saved version and returns error 403.
When I disable this dev mode or install release version, then everything is ok.
I'm using the Fovea.cc purchase plugin for an Android Cordova app. The plugin initializes, but cannot find my in-app purchase products - I get the same "Product could not be found" error I would if the product didn't exist or if the app was not published. I'm looking for more troubleshooting steps.
Here's the relevant code, which is called on app launch:
store.register({
id: "com.ineptech.wn.unlockgame",
alias: "unlockgame",
type: store.NON_CONSUMABLE
});
store.ready(function() {
console.log("\\o/ STORE READY \\o/"); // This does get called
});
store.when("unlockgame").approved(function (order) {
UnlockContent();
order.finish();
});
store.refresh();
var p = store.get("unlockgame");
popup("Title = " + p.title);
// this displays "Title = null"
And here's the code for the purchase button:
store.order("unlockgame");
// Results in "The item you were attempting to purchase
// could not be found" error from Play Store
Here's what a purchase attempt displays in logcat:
I/ActivityManager(424): Displayed com.android.vending/com.google.android.finsky.billing.lightpurchase.IabV3Activity: +80ms
E/Volley(22062): [1009] BasicNetwork.performRequest: Unexpected response code 500 for https://android.clients.google.com/fdfe/preparePurchase
And here's what I've already double-checked:
"unlockgame" is the correct product ID
The product is defined in the Play console and is Active
The app is published and active
The app is built in release mode and running on a real device
The device can reach the Play store okay
My app's license key is stored in res/values/billing_key.xml
What else might be keeping the plugin from getting the products?
The issue is most probably with your configuration, but first I see is that you're trying to access the product title right after doing store.refresh()
store.refresh();
var p = store.get("unlockgame");
However, store.refresh() method is asynchronous and will just trigger a request to the server. You can monitor changes to your product this way:
store.when("unlockgame").updated(function(p) {
alert("product is " + p.state + ", title is " + p.title);
});
Then call:
store.refresh();
Also check that the product ID on the play console is com.ineptech.wn.unlockgame, not just unlockgame, and that it's of type Managed.
I refered google play android api to check the purchase and consumption status of an in-app item.
For some orders, I can get right result,but some return the error as below:
error: {
errors: [
{
domain: "global",
reason: "purchaseTokenNotFound",
message: "The purchase token was not found.",
locationType: "parameter",
location: "token"
}
],
code: 404,
message: "The purchase token was not found."
}
Purchase token is provided by google, does it can be faked?
I found if I cancel the google order, then check the purchase status,it will return the purchase token was not found. if not, i will get the right purchase status.
Hope somebody can help.
If you are selling the same INAPP product to the same user muliple times within a short period, then it's very likely that all access tokens except the last purchase will return a 404 code.
For example:
john#example.com went to your app and purchased com.example.test.product a few times, you will probaly notice within your records (or Google Wallet Merchant account) that it's the same user buying the product.
When you go to check the last purchase from this user, then the following is likely to appear
{
kind: "androidpublisher#inappPurchase",
purchaseTime: "1409823171827",
purchaseState: "0",
consumptionState: "1",
developerPayload: "My Product | Ref | 1409823162466"
}
and yet if you were to check his previous tokens, then it's very likely that his purchases will return 404!
I had read somewhere (can't remember where) that the purchase token created for each purchase is basically based on the inapp product and google user. Therefore, it's very likely that each purchase will "destroy" any previous purchase token created for the same user.
Hope this explanation helps. I am constantly having this problem everyday when my server is attempting to connect to the Google API and check the transactions. Perhaps one day somebody will read this and provide a solution :)
The documents are misleading. You don't need to use this API to verify purchases.
Mobile app have INAPP_PURCHASE_DATA and INAPP_DATA_SIGNATURE from getBuyIntent method.
You can verify the purchase with the signature and your public key.
https://developer.android.com/google/play/billing/billing_reference.html#getBuyIntent
You can find the public key on Google Play Developer Console -> YOUR_APP -> service and API
package main
import (
"crypto"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
//replace const below with your own.
const (
pubKeyPEM=`-----BEGIN PUBLIC KEY-----
Some thing like this
-----END PUBLIC KEY-----`
data = `purchase data from getBuyIntent API`
sign = `purchase data signature from getBuyIntent API`
)
func Panic(err error) {
if err != nil {
panic(err)
}
}
func main() {
PEMBlock, _ := pem.Decode([]byte(pubKeyPEM))
if PEMBlock == nil {
Panic(fmt.Errorf("Could not parse Public Key PEM"))
}
if PEMBlock.Type != "PUBLIC KEY" {
Panic(fmt.Errorf("Found wrong key type"))
}
pubkey, err := x509.ParsePKIXPublicKey(PEMBlock.Bytes)
if err != nil {
Panic(err)
}
// compute the sha1
h := sha1.New()
h.Write([]byte(data))
// decode b64 signature
signature, err := base64.StdEncoding.DecodeString(sign)
Panic(err)
// Verify
err = rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), crypto.SHA1, h.Sum(nil), signature)
Panic(err)
// It verified!
fmt.Println("OK")
}