use of net.osmand.plus.inapp.InAppPurchases.PurchaseInfo in project Osmand by osmandapp.
the class InAppPurchaseHelperImpl method onPurchaseFinished.
// Call when a purchase is finished
private void onPurchaseFinished(@NonNull String sku, @NonNull PurchaseResponse response) {
Receipt receipt = response.getReceipt();
logDebug("Purchase finished: " + receipt.getSku());
PurchaseInfo info = getPurchaseInfo(sku, receipt);
UserData userData = response.getUserData();
if (userData != null) {
info.setPurchaseToken(userData.getUserId());
} else {
info.setPurchaseToken(getUserId());
}
onPurchaseDone(info);
}
use of net.osmand.plus.inapp.InAppPurchases.PurchaseInfo in project Osmand by osmandapp.
the class InAppPurchaseHelperImpl method getRequestInventoryCommand.
@Override
protected InAppCommand getRequestInventoryCommand(boolean userRequested) {
return new InAppCommand() {
@Override
protected void commandDone() {
super.commandDone();
inventoryRequested = false;
}
@Override
public void run(InAppPurchaseHelper helper) {
logDebug("Setup successful. Querying inventory.");
try {
productInfos = new ArrayList<>();
obtainOwnedSubscriptions();
} catch (Exception e) {
logError("queryInventoryAsync Error", e);
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
stop(true);
commandDone();
}
}
private void obtainOwnedSubscriptions() {
if (uiActivity != null) {
IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_SUBSCRIPTION, null, new IapApiCallback<OwnedPurchasesResult>() {
@Override
public void onSuccess(OwnedPurchasesResult result) {
ownedSubscriptions = result;
obtainOwnedInApps(null);
}
@Override
public void onFail(Exception e) {
logError("obtainOwnedSubscriptions exception", e);
ExceptionHandle.handle((Activity) uiActivity, e);
commandDone();
}
});
} else {
commandDone();
}
}
private void obtainOwnedInApps(final String continuationToken) {
if (uiActivity != null) {
// Query users' purchased non-consumable products.
IapRequestHelper.obtainOwnedPurchases(getIapClient(), IapClient.PriceType.IN_APP_NONCONSUMABLE, continuationToken, new IapApiCallback<OwnedPurchasesResult>() {
@Override
public void onSuccess(OwnedPurchasesResult result) {
ownedInApps.add(result);
if (result != null && !TextUtils.isEmpty(result.getContinuationToken())) {
obtainOwnedInApps(result.getContinuationToken());
} else {
obtainSubscriptionsInfo();
}
}
@Override
public void onFail(Exception e) {
logError("obtainOwnedInApps exception", e);
ExceptionHandle.handle((Activity) uiActivity, e);
commandDone();
}
});
} else {
commandDone();
}
}
private void obtainSubscriptionsInfo() {
if (uiActivity != null) {
Set<String> productIds = new HashSet<>();
List<InAppSubscription> subscriptions = purchases.getSubscriptions().getAllSubscriptions();
for (InAppSubscription s : subscriptions) {
productIds.add(s.getSku());
}
productIds.addAll(ownedSubscriptions.getItemList());
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), IapClient.PriceType.IN_APP_SUBSCRIPTION, new IapApiCallback<ProductInfoResult>() {
@Override
public void onSuccess(final ProductInfoResult result) {
if (result != null && result.getProductInfoList() != null) {
productInfos.addAll(result.getProductInfoList());
}
obtainInAppsInfo();
}
@Override
public void onFail(Exception e) {
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
if (ExceptionHandle.SOLVED != errorCode) {
LOG.error("Unknown error");
}
commandDone();
}
});
} else {
commandDone();
}
}
private void obtainInAppsInfo() {
if (uiActivity != null) {
Set<String> productIds = new HashSet<>();
for (InAppPurchase purchase : getInAppPurchases().getAllInAppPurchases(false)) {
productIds.add(purchase.getSku());
}
for (OwnedPurchasesResult result : ownedInApps) {
productIds.addAll(result.getItemList());
}
IapRequestHelper.obtainProductInfo(getIapClient(), new ArrayList<>(productIds), IapClient.PriceType.IN_APP_NONCONSUMABLE, new IapApiCallback<ProductInfoResult>() {
@Override
public void onSuccess(ProductInfoResult result) {
if (result != null && result.getProductInfoList() != null) {
productInfos.addAll(result.getProductInfoList());
}
processInventory();
}
@Override
public void onFail(Exception e) {
int errorCode = ExceptionHandle.handle((Activity) uiActivity, e);
if (ExceptionHandle.SOLVED != errorCode) {
LOG.error("Unknown error");
}
commandDone();
}
});
} else {
commandDone();
}
}
private void processInventory() {
logDebug("Query sku details was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct!
*/
List<String> allOwnedSubscriptionSkus = ownedSubscriptions.getItemList();
for (InAppSubscription s : getSubscriptions().getAllSubscriptions()) {
if (hasDetails(s.getSku())) {
InAppPurchaseData purchaseData = getPurchaseData(s.getSku());
ProductInfo liveUpdatesInfo = getProductInfo(s.getSku());
if (liveUpdatesInfo != null) {
fetchInAppPurchase(s, liveUpdatesInfo, purchaseData);
}
allOwnedSubscriptionSkus.remove(s.getSku());
}
}
for (String sku : allOwnedSubscriptionSkus) {
InAppPurchaseData purchaseData = getPurchaseData(sku);
ProductInfo liveUpdatesInfo = getProductInfo(sku);
if (liveUpdatesInfo != null) {
InAppSubscription s = getSubscriptions().upgradeSubscription(sku);
if (s == null) {
s = new InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesInfo);
}
fetchInAppPurchase(s, liveUpdatesInfo, purchaseData);
}
}
InAppPurchase fullVersion = getFullVersion();
if (hasDetails(fullVersion.getSku())) {
InAppPurchaseData purchaseData = getPurchaseData(fullVersion.getSku());
ProductInfo fullPriceDetails = getProductInfo(fullVersion.getSku());
if (fullPriceDetails != null) {
fetchInAppPurchase(fullVersion, fullPriceDetails, purchaseData);
}
}
InAppPurchase depthContours = getDepthContours();
if (hasDetails(depthContours.getSku())) {
InAppPurchaseData purchaseData = getPurchaseData(depthContours.getSku());
ProductInfo depthContoursDetails = getProductInfo(depthContours.getSku());
if (depthContoursDetails != null) {
fetchInAppPurchase(depthContours, depthContoursDetails, purchaseData);
}
}
InAppPurchase contourLines = getContourLines();
if (hasDetails(contourLines.getSku())) {
InAppPurchaseData purchaseData = getPurchaseData(contourLines.getSku());
ProductInfo contourLinesDetails = getProductInfo(contourLines.getSku());
if (contourLinesDetails != null) {
fetchInAppPurchase(contourLines, contourLinesDetails, purchaseData);
}
}
if (getPurchaseData(fullVersion.getSku()) != null) {
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
}
if (getPurchaseData(depthContours.getSku()) != null) {
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
}
if (getPurchaseData(contourLines.getSku()) != null) {
ctx.getSettings().CONTOUR_LINES_PURCHASED.set(true);
}
// Do we have the live updates?
boolean subscribedToLiveUpdates = false;
boolean subscribedToOsmAndPro = false;
boolean subscribedToMaps = false;
List<InAppPurchaseData> subscriptionPurchases = new ArrayList<>();
for (InAppSubscription s : getSubscriptions().getAllSubscriptions()) {
InAppPurchaseData purchaseData = getPurchaseData(s.getSku());
if (purchaseData != null || s.getState().isActive()) {
if (purchaseData != null) {
subscriptionPurchases.add(purchaseData);
}
if (!subscribedToLiveUpdates && purchases.isLiveUpdatesSubscription(s)) {
subscribedToLiveUpdates = true;
}
if (!subscribedToOsmAndPro && purchases.isOsmAndProSubscription(s)) {
subscribedToOsmAndPro = true;
}
if (!subscribedToMaps && purchases.isMapsSubscription(s)) {
subscribedToMaps = true;
}
}
}
if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false);
} else if (subscribedToLiveUpdates) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
}
if (!subscribedToOsmAndPro && ctx.getSettings().OSMAND_PRO_PURCHASED.get()) {
ctx.getSettings().OSMAND_PRO_PURCHASED.set(false);
} else if (subscribedToOsmAndPro) {
ctx.getSettings().OSMAND_PRO_PURCHASED.set(true);
}
if (!subscribedToMaps && ctx.getSettings().OSMAND_MAPS_PURCHASED.get()) {
ctx.getSettings().OSMAND_MAPS_PURCHASED.set(false);
} else if (subscribedToMaps) {
ctx.getSettings().OSMAND_MAPS_PURCHASED.set(true);
}
if (!subscribedToLiveUpdates && !subscribedToOsmAndPro && !subscribedToMaps) {
onSubscriptionExpired();
}
lastValidationCheckTime = System.currentTimeMillis();
logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") + " live updates purchased.");
logDebug("User " + (subscribedToOsmAndPro ? "HAS" : "DOES NOT HAVE") + " OsmAnd Pro purchased.");
logDebug("User " + (subscribedToMaps ? "HAS" : "DOES NOT HAVE") + " Maps purchased.");
OsmandSettings settings = ctx.getSettings();
settings.INAPPS_READ.set(true);
List<InAppPurchaseData> tokensToSend = new ArrayList<>();
if (subscriptionPurchases.size() > 0) {
List<String> tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";"));
for (InAppPurchaseData purchase : subscriptionPurchases) {
if ((Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) && !Algorithms.isEmpty(purchase.getDeveloperPayload())) {
String payload = purchase.getDeveloperPayload();
if (!Algorithms.isEmpty(payload)) {
String[] arr = payload.split(" ");
if (arr.length > 0) {
settings.BILLING_USER_ID.set(arr[0]);
}
if (arr.length > 1) {
token = arr[1];
settings.BILLING_USER_TOKEN.set(token);
}
}
}
if (!tokensSent.contains(purchase.getProductId())) {
tokensToSend.add(purchase);
}
}
}
List<PurchaseInfo> purchaseInfoList = new ArrayList<>();
for (InAppPurchaseData purchase : tokensToSend) {
purchaseInfoList.add(getPurchaseInfo(purchase));
}
onSkuDetailsResponseDone(purchaseInfoList, userRequested);
}
private void onSubscriptionExpired() {
if (!isDepthContoursPurchased(ctx)) {
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false);
}
}
};
}
use of net.osmand.plus.inapp.InAppPurchases.PurchaseInfo in project Osmand by osmandapp.
the class InAppPurchaseHelper method sendTokens.
protected void sendTokens(@NonNull final List<PurchaseInfo> purchaseInfoList, final OnRequestResultListener listener) {
final String userId = ctx.getSettings().BILLING_USER_ID.get();
final String token = ctx.getSettings().BILLING_USER_TOKEN.get();
final String email = ctx.getSettings().BILLING_USER_EMAIL.get();
try {
String url = "https://osmand.net/subscription/purchased";
String userOperation = "Sending purchase info...";
final List<Request> requests = new ArrayList<>();
for (PurchaseInfo info : purchaseInfoList) {
Map<String, String> parameters = new HashMap<>();
parameters.put("userid", userId);
parameters.put("sku", info.getSku());
parameters.put("orderId", info.getOrderId());
parameters.put("purchaseToken", info.getPurchaseToken());
parameters.put("email", email);
parameters.put("token", token);
addUserInfo(parameters);
requests.add(new Request(url, parameters, userOperation, true, true));
}
AndroidNetworkUtils.sendRequestsAsync(ctx, requests, new OnSendRequestsListener() {
@Override
public void onRequestSending(@NonNull Request request) {
}
@Override
public void onRequestSent(@NonNull RequestResponse response) {
}
@Override
public void onRequestsSent(@NonNull List<RequestResponse> results) {
for (RequestResponse rr : results) {
String sku = rr.getRequest().getParameters().get("sku");
PurchaseInfo info = getPurchaseInfo(sku);
if (info != null) {
updateSentTokens(info);
String result = rr.getResponse();
if (result != null) {
try {
JSONObject obj = new JSONObject(result);
if (obj.has("error")) {
complain("SendToken Error: " + obj.getString("error") + " (response=" + result + " google=" + info.toString() + ")");
}
} catch (JSONException e) {
logError("SendToken", e);
complain("SendToken Error: " + (e.getMessage() != null ? e.getMessage() : "JSONException") + " (response=" + result + " google=" + info.toString() + ")");
}
}
}
}
if (listener != null) {
listener.onResult("OK", null, null);
}
}
private void updateSentTokens(@NonNull PurchaseInfo info) {
String tokensSentStr = ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.get();
Set<String> tokensSent = new HashSet<>(Arrays.asList(tokensSentStr.split(";")));
tokensSent.add(info.getSku());
ctx.getSettings().BILLING_PURCHASE_TOKENS_SENT.set(TextUtils.join(";", tokensSent));
}
@Nullable
private PurchaseInfo getPurchaseInfo(String sku) {
for (PurchaseInfo info : purchaseInfoList) {
if (info.getSku().equals(sku)) {
return info;
}
}
return null;
}
});
} catch (Exception e) {
logError("SendToken Error", e);
if (listener != null) {
listener.onResult("Error", null, null);
}
}
}
use of net.osmand.plus.inapp.InAppPurchases.PurchaseInfo in project Osmand by osmandapp.
the class InAppPurchaseHelperImpl method getSkuDetailsResponseListener.
// Listener that's called when we finish querying the items and subscriptions we own
private SkuDetailsResponseListener getSkuDetailsResponseListener(boolean userRequested) {
return new SkuDetailsResponseListener() {
@NonNull
private List<String> getAllOwnedSubscriptionSkus() {
List<String> result = new ArrayList<>();
BillingManager billingManager = getBillingManager();
if (billingManager != null) {
for (Purchase p : billingManager.getPurchases()) {
if (getInAppPurchases().getInAppSubscriptionBySku(p.getSku()) != null) {
result.add(p.getSku());
}
}
}
for (Entry<String, SubscriptionStateHolder> entry : subscriptionStateMap.entrySet()) {
SubscriptionState state = entry.getValue().state;
if (state == SubscriptionState.PAUSED || state == SubscriptionState.ON_HOLD) {
String sku = entry.getKey();
if (!result.contains(sku)) {
result.add(sku);
}
}
}
return result;
}
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, List<SkuDetails> skuDetailsList) {
logDebug("Query sku details finished.");
// Have we been disposed of in the meantime? If so, quit.
if (getBillingManager() == null) {
stop(true);
return;
}
// Is it a failure?
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
logError("Failed to query inventory: " + billingResult.getResponseCode());
notifyError(InAppPurchaseTaskType.REQUEST_INVENTORY, billingResult.getDebugMessage());
stop(true);
return;
}
logDebug("Query sku details was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
List<String> allOwnedSubscriptionSkus = getAllOwnedSubscriptionSkus();
for (InAppSubscription s : getSubscriptions().getAllSubscriptions()) {
if (hasDetails(s.getSku())) {
Purchase purchase = getPurchase(s.getSku());
SkuDetails liveUpdatesDetails = getSkuDetails(s.getSku());
if (liveUpdatesDetails != null) {
fetchInAppPurchase(s, liveUpdatesDetails, purchase);
}
allOwnedSubscriptionSkus.remove(s.getSku());
}
}
for (String sku : allOwnedSubscriptionSkus) {
Purchase purchase = getPurchase(sku);
SkuDetails liveUpdatesDetails = getSkuDetails(sku);
if (liveUpdatesDetails != null) {
InAppSubscription s = getSubscriptions().upgradeSubscription(sku);
if (s == null) {
s = new InAppPurchaseLiveUpdatesOldSubscription(liveUpdatesDetails);
}
fetchInAppPurchase(s, liveUpdatesDetails, purchase);
}
}
InAppPurchase fullVersion = getFullVersion();
if (hasDetails(fullVersion.getSku())) {
Purchase purchase = getPurchase(fullVersion.getSku());
SkuDetails fullPriceDetails = getSkuDetails(fullVersion.getSku());
if (fullPriceDetails != null) {
fetchInAppPurchase(fullVersion, fullPriceDetails, purchase);
}
}
InAppPurchase depthContours = getDepthContours();
if (hasDetails(depthContours.getSku())) {
Purchase purchase = getPurchase(depthContours.getSku());
SkuDetails depthContoursDetails = getSkuDetails(depthContours.getSku());
if (depthContoursDetails != null) {
fetchInAppPurchase(depthContours, depthContoursDetails, purchase);
}
}
InAppPurchase contourLines = getContourLines();
if (hasDetails(contourLines.getSku())) {
Purchase purchase = getPurchase(contourLines.getSku());
SkuDetails contourLinesDetails = getSkuDetails(contourLines.getSku());
if (contourLinesDetails != null) {
fetchInAppPurchase(contourLines, contourLinesDetails, purchase);
}
}
Purchase fullVersionPurchase = getPurchase(fullVersion.getSku());
boolean fullVersionPurchased = fullVersionPurchase != null;
if (fullVersionPurchased) {
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
}
Purchase depthContoursPurchase = getPurchase(depthContours.getSku());
boolean depthContoursPurchased = depthContoursPurchase != null;
if (depthContoursPurchased) {
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
}
// Do we have the live updates?
boolean subscribedToLiveUpdates = false;
boolean subscribedToOsmAndPro = false;
boolean subscribedToMaps = false;
List<Purchase> subscriptionPurchases = new ArrayList<>();
for (InAppSubscription s : getSubscriptions().getAllSubscriptions()) {
Purchase purchase = getPurchase(s.getSku());
if (purchase != null || s.getState().isActive()) {
if (purchase != null) {
subscriptionPurchases.add(purchase);
}
if (!subscribedToLiveUpdates && purchases.isLiveUpdatesSubscription(s)) {
subscribedToLiveUpdates = true;
}
if (!subscribedToOsmAndPro && purchases.isOsmAndProSubscription(s)) {
subscribedToOsmAndPro = true;
}
if (!subscribedToMaps && purchases.isMapsSubscription(s)) {
subscribedToMaps = true;
}
}
}
if (!subscribedToLiveUpdates && ctx.getSettings().LIVE_UPDATES_PURCHASED.get()) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(false);
} else if (subscribedToLiveUpdates) {
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
}
if (!subscribedToOsmAndPro && ctx.getSettings().OSMAND_PRO_PURCHASED.get()) {
ctx.getSettings().OSMAND_PRO_PURCHASED.set(false);
} else if (subscribedToOsmAndPro) {
ctx.getSettings().OSMAND_PRO_PURCHASED.set(true);
}
if (!subscribedToMaps && ctx.getSettings().OSMAND_MAPS_PURCHASED.get()) {
ctx.getSettings().OSMAND_MAPS_PURCHASED.set(false);
} else if (subscribedToMaps) {
ctx.getSettings().OSMAND_MAPS_PURCHASED.set(true);
}
if (!subscribedToLiveUpdates && !subscribedToOsmAndPro && !subscribedToMaps) {
onSubscriptionExpired();
}
lastValidationCheckTime = System.currentTimeMillis();
logDebug("User " + (subscribedToLiveUpdates ? "HAS" : "DOES NOT HAVE") + " live updates purchased.");
logDebug("User " + (subscribedToOsmAndPro ? "HAS" : "DOES NOT HAVE") + " OsmAnd Pro purchased.");
logDebug("User " + (subscribedToMaps ? "HAS" : "DOES NOT HAVE") + " Maps purchased.");
OsmandSettings settings = ctx.getSettings();
settings.INAPPS_READ.set(true);
List<Purchase> tokensToSend = new ArrayList<>();
if (subscriptionPurchases.size() > 0) {
List<String> tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";"));
for (Purchase purchase : subscriptionPurchases) {
if (needRestoreUserInfo()) {
restoreUserInfo(purchase);
}
if (!tokensSent.contains(purchase.getSku())) {
tokensToSend.add(purchase);
}
}
}
List<PurchaseInfo> purchaseInfoList = new ArrayList<>();
for (Purchase purchase : tokensToSend) {
purchaseInfoList.add(getPurchaseInfo(purchase));
}
onSkuDetailsResponseDone(purchaseInfoList, userRequested);
}
private void onSubscriptionExpired() {
if (!isDepthContoursPurchased(ctx)) {
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(false);
}
}
};
}
Aggregations