mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-13 17:51:57 +00:00
handle new subscriptions
This commit is contained in:
parent
3734ad3197
commit
83bb7c3b6c
8 changed files with 151 additions and 9 deletions
|
|
@ -1,11 +1,14 @@
|
||||||
package com.habitrpg.android.habitica;
|
package com.habitrpg.android.habitica;
|
||||||
|
|
||||||
|
import com.habitrpg.android.habitica.events.UserSubscribedEvent;
|
||||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes;
|
import com.habitrpg.android.habitica.helpers.PurchaseTypes;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
|
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
|
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
|
||||||
|
import com.magicmicky.habitrpgwrapper.lib.models.SubscriptionValidationRequest;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.Transaction;
|
import com.magicmicky.habitrpgwrapper.lib.models.Transaction;
|
||||||
import com.playseeds.android.sdk.Seeds;
|
import com.playseeds.android.sdk.Seeds;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.solovyev.android.checkout.BasePurchaseVerifier;
|
import org.solovyev.android.checkout.BasePurchaseVerifier;
|
||||||
import org.solovyev.android.checkout.Purchase;
|
import org.solovyev.android.checkout.Purchase;
|
||||||
import org.solovyev.android.checkout.RequestListener;
|
import org.solovyev.android.checkout.RequestListener;
|
||||||
|
|
@ -51,12 +54,11 @@ public class HabiticaPurchaseVerifier extends BasePurchaseVerifier {
|
||||||
|
|
||||||
requestListener.onSuccess(verifiedPurchases);
|
requestListener.onSuccess(verifiedPurchases);
|
||||||
} else {
|
} else {
|
||||||
PurchaseValidationRequest validationRequest = new PurchaseValidationRequest();
|
|
||||||
validationRequest.transaction = new Transaction();
|
|
||||||
validationRequest.transaction.receipt = purchase.data;
|
|
||||||
validationRequest.transaction.signature = purchase.signature;
|
|
||||||
|
|
||||||
if (PurchaseTypes.allGemTypes.contains(purchase.sku)) {
|
if (PurchaseTypes.allGemTypes.contains(purchase.sku)) {
|
||||||
|
PurchaseValidationRequest validationRequest = new PurchaseValidationRequest();
|
||||||
|
validationRequest.transaction = new Transaction();
|
||||||
|
validationRequest.transaction.receipt = purchase.data;
|
||||||
|
validationRequest.transaction.signature = purchase.signature;
|
||||||
apiHelper.apiService.validatePurchase(validationRequest).subscribe(purchaseValidationResult -> {
|
apiHelper.apiService.validatePurchase(validationRequest).subscribe(purchaseValidationResult -> {
|
||||||
purchasedOrderList.add(purchase.orderId);
|
purchasedOrderList.add(purchase.orderId);
|
||||||
|
|
||||||
|
|
@ -92,7 +94,36 @@ public class HabiticaPurchaseVerifier extends BasePurchaseVerifier {
|
||||||
requestListener.onError(purchases.indexOf(purchase), new Exception());
|
requestListener.onError(purchases.indexOf(purchase), new Exception());
|
||||||
});
|
});
|
||||||
} else if (PurchaseTypes.allSubscriptionTypes.contains(purchase.sku)) {
|
} else if (PurchaseTypes.allSubscriptionTypes.contains(purchase.sku)) {
|
||||||
|
SubscriptionValidationRequest validationRequest = new SubscriptionValidationRequest();
|
||||||
|
validationRequest.transaction = new Transaction();
|
||||||
|
validationRequest.transaction.receipt = purchase.data;
|
||||||
|
validationRequest.transaction.signature = purchase.signature;
|
||||||
|
validationRequest.sku = purchase.sku;
|
||||||
|
apiHelper.apiService.validateSubscription(validationRequest).subscribe(purchaseValidationResult -> {
|
||||||
|
purchasedOrderList.add(purchase.orderId);
|
||||||
|
|
||||||
|
verifiedPurchases.add(purchase);
|
||||||
|
|
||||||
|
requestListener.onSuccess(verifiedPurchases);
|
||||||
|
|
||||||
|
EventBus.getDefault().post(new UserSubscribedEvent());
|
||||||
|
}, throwable -> {
|
||||||
|
if (throwable.getClass().equals(HttpException.class)) {
|
||||||
|
HttpException error = (HttpException) throwable;
|
||||||
|
APIHelper.ErrorResponse res = apiHelper.getErrorResponse((HttpException) throwable);
|
||||||
|
if (error.code() == 401) {
|
||||||
|
if (res.message.equals("RECEIPT_ALREADY_USED")) {
|
||||||
|
purchasedOrderList.add(purchase.orderId);
|
||||||
|
|
||||||
|
verifiedPurchases.add(purchase);
|
||||||
|
|
||||||
|
requestListener.onSuccess(verifiedPurchases);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestListener.onError(purchases.indexOf(purchase), new Exception());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.habitrpg.android.habitica.events;
|
||||||
|
|
||||||
|
public class UserSubscribedEvent {
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.APIHelper;
|
||||||
import com.habitrpg.android.habitica.R;
|
import com.habitrpg.android.habitica.R;
|
||||||
import com.habitrpg.android.habitica.components.AppComponent;
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
import com.habitrpg.android.habitica.events.BoughtGemsEvent;
|
import com.habitrpg.android.habitica.events.BoughtGemsEvent;
|
||||||
|
import com.habitrpg.android.habitica.events.UserSubscribedEvent;
|
||||||
import com.habitrpg.android.habitica.helpers.PurchaseTypes;
|
import com.habitrpg.android.habitica.helpers.PurchaseTypes;
|
||||||
import com.habitrpg.android.habitica.proxy.ifce.CrashlyticsProxy;
|
import com.habitrpg.android.habitica.proxy.ifce.CrashlyticsProxy;
|
||||||
import com.habitrpg.android.habitica.ui.SubscriptionDetailsView;
|
import com.habitrpg.android.habitica.ui.SubscriptionDetailsView;
|
||||||
|
|
@ -13,6 +14,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.SubscriptionPlan;
|
import com.magicmicky.habitrpgwrapper.lib.models.SubscriptionPlan;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
import org.solovyev.android.checkout.ActivityCheckout;
|
import org.solovyev.android.checkout.ActivityCheckout;
|
||||||
import org.solovyev.android.checkout.BillingRequests;
|
import org.solovyev.android.checkout.BillingRequests;
|
||||||
import org.solovyev.android.checkout.Checkout;
|
import org.solovyev.android.checkout.Checkout;
|
||||||
|
|
@ -80,7 +82,6 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
||||||
|
|
||||||
private GemPurchaseActivity listener;
|
private GemPurchaseActivity listener;
|
||||||
private BillingRequests billingRequests;
|
private BillingRequests billingRequests;
|
||||||
private Inventory inventory;
|
|
||||||
|
|
||||||
private HabitRPGUser user;
|
private HabitRPGUser user;
|
||||||
private boolean hasLoadedSubscriptionOptions;
|
private boolean hasLoadedSubscriptionOptions;
|
||||||
|
|
@ -92,12 +93,22 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
||||||
|
|
||||||
super.onCreateView(inflater, container, savedInstanceState);
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
|
||||||
apiHelper.apiService.getUser().compose(apiHelper.configureApiCallObserver())
|
fetchUser(null);
|
||||||
.subscribe(this::setUser, throwable -> {});
|
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_subscription, container, false);
|
return inflater.inflate(R.layout.fragment_subscription, container, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void fetchUser(@Nullable UserSubscribedEvent event) {
|
||||||
|
apiHelper.apiService.getUser().compose(apiHelper.configureApiCallObserver())
|
||||||
|
.subscribe(this::setUser, throwable -> {});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
@ -120,7 +131,7 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
||||||
public void setupCheckout() {
|
public void setupCheckout() {
|
||||||
final ActivityCheckout checkout = listener.getActivityCheckout();
|
final ActivityCheckout checkout = listener.getActivityCheckout();
|
||||||
if (checkout != null) {
|
if (checkout != null) {
|
||||||
inventory = checkout.makeInventory();
|
Inventory inventory = checkout.makeInventory();
|
||||||
|
|
||||||
inventory.load(Inventory.Request.create()
|
inventory.load(Inventory.Request.create()
|
||||||
.loadAllPurchases().loadSkus(ProductTypes.SUBSCRIPTION, PurchaseTypes.allSubscriptionTypes),
|
.loadAllPurchases().loadSkus(ProductTypes.SUBSCRIPTION, PurchaseTypes.allSubscriptionTypes),
|
||||||
|
|
@ -236,11 +247,13 @@ public class SubscriptionFragment extends BaseFragment implements GemPurchaseAct
|
||||||
this.subscriptionDetailsView.setVisibility(View.VISIBLE);
|
this.subscriptionDetailsView.setVisibility(View.VISIBLE);
|
||||||
this.subscriptionDetailsView.setPlan(plan);
|
this.subscriptionDetailsView.setPlan(plan);
|
||||||
this.subscribeBenefitsTitle.setText(R.string.subscribe_prompt_thanks);
|
this.subscribeBenefitsTitle.setText(R.string.subscribe_prompt_thanks);
|
||||||
|
this.subscriptionOptions.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
if (!hasLoadedSubscriptionOptions) {
|
if (!hasLoadedSubscriptionOptions) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.subscriptionOptions.setVisibility(View.VISIBLE);
|
this.subscriptionOptions.setVisibility(View.VISIBLE);
|
||||||
|
this.subscriptionDetailsView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
this.loadingIndicator.setVisibility(View.GONE);
|
this.loadingIndicator.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.Quest;
|
import com.magicmicky.habitrpgwrapper.lib.models.Quest;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.Shop;
|
import com.magicmicky.habitrpgwrapper.lib.models.Shop;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.Status;
|
import com.magicmicky.habitrpgwrapper.lib.models.Status;
|
||||||
|
import com.magicmicky.habitrpgwrapper.lib.models.SubscriptionValidationRequest;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.Tag;
|
import com.magicmicky.habitrpgwrapper.lib.models.Tag;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.TaskDirectionData;
|
import com.magicmicky.habitrpgwrapper.lib.models.TaskDirectionData;
|
||||||
import com.magicmicky.habitrpgwrapper.lib.models.UserAuth;
|
import com.magicmicky.habitrpgwrapper.lib.models.UserAuth;
|
||||||
|
|
@ -243,6 +244,9 @@ public interface ApiService {
|
||||||
@POST("/iap/android/verify")
|
@POST("/iap/android/verify")
|
||||||
Observable<HabitResponse<PurchaseValidationResult>> validatePurchase(@Body PurchaseValidationRequest request);
|
Observable<HabitResponse<PurchaseValidationResult>> validatePurchase(@Body PurchaseValidationRequest request);
|
||||||
|
|
||||||
|
@POST("/iap/android/subscribe")
|
||||||
|
Observable<HabitResponse<Void>> validateSubscription(@Body SubscriptionValidationRequest request);
|
||||||
|
|
||||||
@POST("user/custom-day-start")
|
@POST("user/custom-day-start")
|
||||||
Observable<HabitResponse<HabitRPGUser>> changeCustomDayStart(@Body Map<String, Object> updateObject);
|
Observable<HabitResponse<HabitRPGUser>> changeCustomDayStart(@Body Map<String, Object> updateObject);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.magicmicky.habitrpgwrapper.lib.models;
|
||||||
|
|
||||||
|
|
||||||
|
public class SubscriptionValidationRequest {
|
||||||
|
|
||||||
|
public Transaction transaction;
|
||||||
|
public String sku;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.habitrpg.android.habitica;
|
||||||
|
|
||||||
|
import com.habitrpg.android.habitica.components.AppComponent;
|
||||||
|
import com.habitrpg.android.habitica.components.DaggerAppComponent;
|
||||||
|
import com.habitrpg.android.habitica.modules.AppModule;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class HabiticaApplication extends HabiticaBaseApplication {
|
||||||
|
@Override
|
||||||
|
protected AppComponent initDagger() {
|
||||||
|
return DaggerAppComponent.builder()
|
||||||
|
.appModule(new AppModule(this))
|
||||||
|
.developerModule(new ReleaseDeveloperModule())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.habitrpg.android.habitica;
|
||||||
|
|
||||||
|
|
||||||
|
import com.habitrpg.android.habitica.modules.DeveloperModule;
|
||||||
|
import com.habitrpg.android.habitica.proxy.CrashlyticsProxyImpl;
|
||||||
|
import com.habitrpg.android.habitica.proxy.ifce.CrashlyticsProxy;
|
||||||
|
|
||||||
|
//change debug proxy here by override methods
|
||||||
|
public class ReleaseDeveloperModule extends DeveloperModule {
|
||||||
|
@Override protected CrashlyticsProxy provideCrashlyticsProxy() {
|
||||||
|
return new CrashlyticsProxyImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.habitrpg.android.habitica.proxy;
|
||||||
|
|
||||||
|
|
||||||
|
import com.crashlytics.android.Crashlytics;
|
||||||
|
import com.crashlytics.android.core.CrashlyticsCore;
|
||||||
|
import com.habitrpg.android.habitica.proxy.ifce.CrashlyticsProxy;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import io.fabric.sdk.android.Fabric;
|
||||||
|
|
||||||
|
public class CrashlyticsProxyImpl implements CrashlyticsProxy {
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
Crashlytics crashlytics = new Crashlytics.Builder()
|
||||||
|
.core(new CrashlyticsCore.Builder().build())
|
||||||
|
.build();
|
||||||
|
Fabric.with(context, crashlytics);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logException(Throwable t) {
|
||||||
|
Crashlytics.logException(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setString(String key, String value) {
|
||||||
|
Crashlytics.setString(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserIdentifier(String identifier) {
|
||||||
|
if (Crashlytics.getInstance().core != null && identifier != null) {
|
||||||
|
Crashlytics.getInstance().core.setUserIdentifier(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUserName(String name) {
|
||||||
|
if (Crashlytics.getInstance().core != null && name != null) {
|
||||||
|
Crashlytics.getInstance().core.setUserName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fabricLogE(String s1, String s2, Exception e) {
|
||||||
|
Fabric.getLogger().e(s1,s2,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue