Question

TransactionsFactory.nonSubscriptionTransactions loses sandbox state

  • 16 March 2024
  • 3 replies
  • 28 views

Badge +1

I have both subscriptions and in-app purchases (lifetime unlock). All use the same entitlement (unlock). 

I would like to differentiate between sandbox and non-sandbox purchases. Specifically, if someone buys in production, that should overrule anything bought in the sandbox, and Sandbox purchases should not be used in Production.

The entitlement info provides that information but because it’s a dictionary, it only stores one purchase for the unlock entitlement. 

Problem 1: If someone buys something in production and later buys something in the sandbox, I believe the entitlement could be “inSandbox” because it’s the most recent transaction, even though there is also a production one (and I prioritize production purchases over sandbox)

Problem 2: Non-subscription purchases have a sandbox flag, but TransactionsFactory.nonSubscriptionTransactions() discards that information, so that it is not possible to determine if a non-subscription transaction was purchased in the sandbox (even though that data is present in the subscriber data via CustomerInfoResponse.Transaction).

 

Question 1: am I correct about the ordering problem with the entitlements dictionary?

Question 2: is there a way to get the inSandbox property for a non subscription transaction?


This post has been closed for comments

3 replies

Userlevel 3
Badge +8

Hi,

Happy to help here. We would actually provide both entitlements. But I’m confused as to how users would be able to make sandbox transactions? If they download the app from the App Store, they can only make production purchases.

If you have a TestFlight build, it will only be valid for 90 days, so users will have to download the production version of the app, and they will lose their entitlements awarded through sandbox purchases (sandbox and production apps use different receipts).

Badge +1

Thanks for your response.

> We would actually provide both entitlements

Can you please clarify that? How do both entitlements get provided if the dictionary is keyed by entitlement?

Beta testers have been telling me that when they use the production version of the app, their sandbox transactions seem to follow them. One of those transactions is the lifetime unlock. The app somehow gets that transaction in the production app, and then unlocks the app even though it’s a sandbox purchase.

Also, I read the following post, which confused me (relative to what you wrote about having different receipts): 

https://community.revenuecat.com/sdks-51/sandbox-and-production-interaction-1988

“yes, this is allowed, and you would find both subscriptions in the subscriptions payload (one with `is_sandbox` true, and one false)”

If they have different receipts, why would I get both subscriptions in the payload?

Is there a best practice for dealing with unlocks like this?

Badge +1

I’m also unclear about the “they will lose their entitlements awarded through sandbox purchases” - I took my receipt from the production copy and put it in my debug build. I moved the debug build out DerivedData so that RevenueCat goes through the production path. I still see the sandbox purchase and it is from July of last year (it’s not a subscription, so it doesn’t have an expiration date).