Comments (26)
@nemoryoliver, did you manage to solve this? I'm facing the same behaviour.
Hi @arthurdenner the solution they suggested to me was to manually delete the user in RC. But they're also working on a better solution they said.
from purchases-flutter.
I've enabled logging. Here are the logs
D/[Purchases] - DEBUG(16550): POST /receipts
D/[Purchases] - DEBUG(16550): POST /receipts 200
D/[Purchases] - DEBUG(16550): Consuming purchase with token **CONCEALED_TOKEN**
D/[Purchases] - DEBUG(16550): Purchase PurchaseHistoryRecordWrapper(isConsumable=true, purchaseToken=**CONCEALED_TOKEN**, purchaseTime=1588991694728, sku=**CONCEALED_PRODUCT_ID**, purchaseHistoryRecord=PurchaseHistoryRecord. Json: {"productId":"**CONCEALED_PRODUCT_ID**","purchaseToken":"**CONCEALED_TOKEN**","purchaseTime":1588991694728,"developerPayload":null}, type=INAPP) restored
W/BillingClient(16550): Error consuming purchase with token. Response code: 8
D/[Purchases] - DEBUG(16550): Error consuming purchase. Will retry next queryPurchases. DebugMessage: Item is not owned by the user.. ErrorCode: ITEM_NOT_OWNED.
It even logs the item is not owned but still, it's returning the wrong entitlement active value
from purchases-flutter.
Google refunds can't be detected programmatically, so RevenueCat never removes the entitlement.
There's the option to revoke subscriptions through the dashboard that RevenueCat can then pick up but this doesn't apply to non-subscriptions: https://docs.revenuecat.com/docs/customer-history#refunding-subscriptions
We may be able to add some support on the server to grant non-subscription refunds in the future.
The revenuecat sdk detects the item is not owned flag through logs so I guess it's possible in the future this will be detetected by the sdk soon?
from purchases-flutter.
@nemoryoliver, I'm still a bit confused about how to accomplish this as the ITEM_NOT_OWNED
error is logged but not thrown - so I could do something about it, like deleting the user through RevenueCat's API. Dealing with this manually doesn't sound simple and scalable, especially if you don't have accounts in the app - to link user ids in RevenueCat, which is exactly my use case.
I'll investigate it a bit further as I'm implementing in-app purchases for the first time and create a new issue/discussion if needed.
Sorry for jumping on your issue and thank you for the quick reply! 😃
from purchases-flutter.
Are there any updates on this?
from purchases-flutter.
@javier-textmei if you're refunding through the Google API, you may not necessarily be revoking so the user may still have access. RevenueCat never generates an ITEM_ALREADY_OWNED error directly, it's only forwarded from Google.
I'm going to close this out since it's not a Flutter SDK issue exactly. There should be a dashboard UI and REST API available to support non-subscription purchases by the end of the month.
from purchases-flutter.
@aboedo I have the same problem : Users still has the entitlement active when the refund goes straight through Google (no action from our part).
You are saying there's no way to detect it programmatically but why Revenuecat doesn't manage that through Google Real-time developer notifications ?
After a subscription is refunded two realtime-events get sent. First, a SUBSCRIPTION_CANCELED event is sent, followed by a SUBSCRIPTION_REVOKED event.
https://developer.android.com/google/play/billing/rtdn-reference
from purchases-flutter.
The Realtime developer notifications do allow us to revoke the entitlement, but we can't unequivocally distinguish a regular cancellation from a refund by relying on those events, unfortunately.
@manuhook do you have Google Realtime Developer Notifications set up with RevenueCat for your app? If so I would have expected the entitlement to be removed, perhaps there's something in the setup that we can take a look at?
from purchases-flutter.
Same here 👍 . follow
from purchases-flutter.
Google refunds can't be detected programmatically, so RevenueCat never removes the entitlement.
There's the option to revoke subscriptions through the dashboard that RevenueCat can then pick up but this doesn't apply to non-subscriptions: https://docs.revenuecat.com/docs/customer-history#refunding-subscriptions
We may be able to add some support on the server to grant non-subscription refunds in the future.
from purchases-flutter.
Google refunds can't be detected programmatically, so RevenueCat never removes the entitlement.
There's the option to revoke subscriptions through the dashboard that RevenueCat can then pick up but this doesn't apply to non-subscriptions: https://docs.revenuecat.com/docs/customer-history#refunding-subscriptions
We may be able to add some support on the server to grant non-subscription refunds in the future.
Sorry for my late response. So what is best to do to remove the entitlement after refunding the user?
from purchases-flutter.
@nemoryoliver, did you manage to solve this? I'm facing the same behaviour.
from purchases-flutter.
I have been facing this same issue, the problem detecting refunds from the Google Play Android Developer API, it's that the in-app billing API will be getting the ITEM_ALREADY_OWNED, so if we remove the pro features, the user won't be able to purchase the item again.
from purchases-flutter.
Any updates on this? I used just bought lifetime and then google refunded them, still has the entitlement on RV
from purchases-flutter.
@armandojimenez I believe we forgot to update the ticket, but you should now be able to use the Dashboard or our REST API to do this.
See:
- Our documentation on Canceling Subscriptions
- The relevant REST API endpoint
from purchases-flutter.
Do you mean for non-renewal purchases? Users still has the entitlement after refund by google or me in the dashboard
from purchases-flutter.
🤔 Well, when the refund goes straight through Google, there's unfortunately no way to detect it programmatically. If it goes through the dashboard, though, we should be revoking the entitlement, so if you're seeing something different, that's unexpected.
Would you mind contacting [email protected] so we can dig into this further? That way we'll also avoid pinging everyone else subscribed to this 2-year old thread.
They might ask you for an appUserID that has received a refund through Google Play and one through the Dashboard so we can dig through the history and see what's going on.
from purchases-flutter.
@aboedo why is it important to distinguish between a regular cancellation and a refund? In both cases, shouldn't the entitlement be revoked?
from purchases-flutter.
@fotiDim re-reading my previous response I don't think I was clear.
We do revoke the entitlement in both cases, so the only annoying part here would be that in analytics it won't correctly show up as a refund unless the refund was started through our dashboard or API endpoint.
from purchases-flutter.
@aboedo do you refer to subscriptions or non-subscriptions? Based on your [documentation],(https://www.revenuecat.com/docs/refunds) If a non-subscription refund is granted by Google or initiated through the Google Play console, it will not be detected as a refund in RevenueCat, and the purchase will remain active
. Is that not accurate?
from purchases-flutter.
Sorry, my comment was for subscriptions. We don't revoke access for non-subscriptions, but you can revoke from the dashboard or API endpoint.
from purchases-flutter.
@aboedo the OP talked about a lifetime entitlement so I guess this is the scope of this issue. This was closed as a non Flutter SDK issue which indeed it isn't but the proposed solution to use the dashboard or API endpoint only covers a fraction of the use cases as users can be granted refunds directly through Google. Therefore I think the issue should be revisited either here or in the native Android SDK.
The question that I have in my head is, since Google provides a way to verify purchases why isn't that adopted by RevenueCat?
In the scenario that I filled this gap myself, is there a way to revoke an entitlement through the SDK or API?
from purchases-flutter.
Hi @fotiDim, we do verify purchases to revoke entitlements when a user cancels or receives a refund. For analytics, a refund through Google looks the same as a cancellation on our end.
You cannot directly revoke an entitlement if the user paid for it, but you can offer a refund of a purchase through our dashboard. Alternatively, you can use this API endpoint.
from purchases-flutter.
we do verify purchases to revoke entitlements when a user cancels or receives a refund.
@rglanz-rc thanks for the clarification. It seems contradicting though to your documentation: If a non-subscription refund is granted by Google or initiated through the Google Play console, it will not be detected as a refund in RevenueCat, and the purchase will remain active.
Which one holds true?
from purchases-flutter.
Both are correct. For subscriptions, we handle the entitlement.
For non-subscription purchases we leave handling the entitlement to the developer, as there are many ways to design non-subscription purchase logic (lifetime unlocks, tokens, etc).
from purchases-flutter.
@rglanz-rc I thought the scope of the topic was lifetime unlocks as per the original post... Anyway, if we are to verify the receipt ourselves this would require a server-side component which kind of defeats the whole purpose of using RevenueCat.
Let's assume that we do go though that trouble and setup a service that our app calls to verify receipts and we find out that a certain purchase has been refunded. Is the go to strategy to revoke the entitlement using the refund endpoint?
from purchases-flutter.
Related Issues (20)
- no built in Android HOT 3
- MacOS two factor window is sized wrong and is jumpy, see video HOT 5
- Expiration date is same as purchase date (macOS) HOT 4
- logOut() throws "user is anonymous" error even if I check Purchases.isAnonymous first HOT 5
- CustomerInfo == / hashCode aren't working HOT 3
- late initialization crashes the app HOT 3
- RevenueCatUi.framework is 4 MB in my executable for iOS, and I do not even use it, wassup? HOT 7
- Use default localization if app store localization for the device language is null or empty HOT 2
- ios 12 app crashing on startup for purchases_flutter 6.15.0 and above HOT 7
- Deprecated purchaseProduct HOT 2
- App crashes on reopen from homescreen due to PurhcasesHybridCommon error HOT 5
- entitlement info does not contain info about the base plan (Google Play) HOT 3
- Inclusion of Unidentified 0.5MB JPG Image in purchases_ui_flutter Dependency HOT 3
- The price returned is incorrect HOT 5
- Paywall Result should return the correct status HOT 3
- Exception: _TypeError (type 'Null' is not a subtype of type 'String' in type cast) on allPurchaseDates field on iOS for Android Prepaid Subscriptions HOT 5
- Support custom Paywall view modes HOT 3
- Android is all of a sudden DEAD - getCustomerInfo doesn't work and getOfferings HOT 7
- Paywall doesn't show trial text HOT 3
- Paywall doesn't have configurable close button color HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from purchases-flutter.