Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application have no way to handle out of band purchases. (Deferred & Auto renewable subscription) #29

Closed
Bartmax opened this issue Mar 17, 2017 · 10 comments
Labels

Comments

@Bartmax
Copy link

Bartmax commented Mar 17, 2017

On iOS, the UpdatedTransactions(SKPaymentQueue queue, SKPaymentTransaction[] transactions) method can be called without an user initiating a purchase process.

This can happen in several scenarios, most notoriously, but not limited, to Deferred purchases and Auto renewable subscriptions.

Deferred:
When a user make a purchase and it needs someone else (lets say parent) to approve it, currently the library returns the purchase as Deferred (this is fine).
Later the parent approves the transaction.
The next time the application launches (and have the PaymentObserver registered) it calls the UpdatedTransactions method.

In this scenario, there won't be any event on event Action<SKPaymentTransaction, bool> TransactionCompleted; and the application don't have any way to process this purchase to enable the content. Only a RestorePurchases will effectively notifies the application (without remote validation see #28 for details)

Auto renewable subscriptions:
A user may purchase an auto renewable subscription, which is processed and remote validated correctly.
When subscription is about to expire, apple starts the process to charge the user for another period. (as explained here Expiration and Renewal

If a new period is successfully charged to the customer, the next time the application launches (and have the PaymentObserver registered) it calls UpdatedTransactions. Just like in the deferred scenario.
Again, since there is no event for what I call out of band purchases the application cannot respond accordingly. (Including validation with the remote server)

Code related to this:
https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.iOS/InAppBillingImplementation.cs#L361

note: there are other scenarios when this may happen, but are more exceptional.

Proposal:
Application code should have a way to define a method to be executed on purchases completed. (being out of band or not.)

I'm very new on how Xamarin manages this types of scenarios but to give some ideas:
an IInAppBillingPostComplete interface that is called from the iOS InAppBillingImplementation from the dependency server and if it find one, execute a method PostComplete.

Another approach will be to require on iOS to EnableInAppPurchases like this:
CrossInAppBilling.EnableInApp(Action<InAppBillingPurchase> purchase) and add this as a default event handler at registration time.

Let me know if this makes sense, I'm going to play around and implement something for this, if you have a different approach or any consideration and want to share, it will be greatly appreciated.

Thanks and this library is really amazing!

@jamesmontemagno
Copy link
Owner

This makes sense, I think we just need an event you can register for. Working with @Redth on this.

@chrisfoulds
Copy link

Sorry just coming to this ?
What is the recommended way on iOS to handle the auto renewable subscriptions ?
I store the subscription end date, but once that occurs I need to call UpdatedTransactions to get a new receipt from Apple with the new expiration date/time.

@Bartmax
Copy link
Author

Bartmax commented Dec 20, 2017

@chrisfoulds

I did a fork long time ago and implemented the auto renewable subscription like this:
https://github.com/dotuy/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.iOS/InAppBillingImplementation.cs#L25

Basically you call EnableInAppPurchase(onSuccess) with a onSuccess being a method to be called for any success transaction, not only the ones initiated by the user (as it works right now)

This fork is based on a previous version of this plugin hope the code may helps you or give some inspirations.

@jamesmontemagno
Copy link
Owner

Did you want to PR this in?

@Bartmax
Copy link
Author

Bartmax commented Dec 20, 2017

@jamesmontemagno sure, let's do this. I'll pick the latest version and will start working on a PR. I'm kinda rusty to this so it wont happen overnight :)

@chrisfoulds
Copy link

Cool @Bartmax , that looks like what we all need. Look forward to it coming into the main library.

@chrisfoulds
Copy link

As the fix is not forthcoming I have made a copy of the library to put it in myself as without I can't do subscriptions

@jamesmontemagno
Copy link
Owner

So, in the latest pre-release you can now do this in your iOS app:

InAppBillingImplementation.OnPurchaseComplete = (t) =>
{
//out of band transaction
};

If you dispose of it it will all go away.

@chrisfoulds
Copy link

chrisfoulds commented Jan 10, 2018

I don't see how this can be used in a forms app ?

My entire IAP flow etc. is all done in my shared code base, this pushes things out into IOS specific.

@jamesmontemagno
Copy link
Owner

You have to put that in your iOS application since it is happening outside of the normal method.

You can just have that reference your shared code that handles it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants