In-App Purchase Refresh receipt

Hi Guys,

I'm implementing Auto-renewebla subscription for my app.

we have a plans for user to access for one month, 3 months, 1 year.While registering user has to choos one of the plan.After registration user can upgrade/downgrade his plan through app.


As per appl guidelines we need to implement restore purchase in app.if i restore the purchase, i'll get all the purchased details, but how i know which plan is purchased recently?


Currently i'm using Receipt Verification API to get all the purchase details. in that response I'll array of purchased records, and last object will be the latest, so that i'll know last one latest and ill give access to the user based on purchased dates and end date.


How can achive this using restore purchase or refreshingreceipt?


Thank you in advance.

Replies

The entries in the receipt are not guaranteed to be in chronological order. You need to check the appropriate date fields. When you restoreCompletedTransactions you get calls to updatedTransactions. Each call will include a transaction and each transaction will have product and date properties to help you determine what and when it was purchased.

Thanks for your answer i checked transaction and paymnet classes there is no purchase date, endDate.it has only transactionDate proprty.

Could you also help me on how to make paymnet with applicationUsername to detect irregular activity?

The receipt will have an expires_date (if it is auto-renewable) and a purchase_date (use thess\e for non-renewing subscriptions).

The transaction will have a transaction.transactionStateRestored. If that is equal to SKPaymentTrasnactionStateRestored then there will be a value for transaction.originalTransaction.


(note - if this is not a transaction with transaction.transactionStateRestored then the follwoing is true with "originalTransaction." deleted)

There will be a value for transaction.originalTransaction.transactionDate

and for transaction.originalTransaction.payment.productIdentifier


You use the starting date (transactionDate) and the productIdentifier to determine whether the subscription for that transaction is still in effect.


applicationUsername is used by Apple, not by you.

Thanks PBK for your help,


Can we use verification Recipet API instead of Refreshing Receipt and Restoring purchases Products?


Could you please help me on below items as well.



0down votefavorite




1.user1 make purchase a plan which is 30 days plan with device1 with his iTunes account and User 2 makes purchase another plan which is 60 days plan with device 2 with his iTunes account, what happens if user1 logged into device2 but device2 still have user2 iTunes account.if i restore purchase or receipt validation in device 2 i'll get User 2 purchase as auto-renewals will work with iTunes Account.

how we can make sure that user1 should get 30 days plan only not 60 days plan?

User 1 will have difficulty entering the password of user 2 when using user 2's device. If user 1 knows user 2's password then user 1 will get all the rights of user 2. I believe that if the App was placed on the device (aka purchased) by user 2 then user 1 will not be able to refresh the receipt under the username of user 1 on that device.


To separate these two users you would need a separate username/password system on your own server or on CloudKit (on CloudKit you could rely on the user's CloudKit account username/passsword. You could associate the transactionIdentifier of each subscription purchase with the username/password account on that system. But nothing will prevent user 1 from sharing their password with user 2 and defeating any system you devise.

Sorry for not providing full details of my question.When i'm sayih user1 looged into device 2 means. he has logged into application with app credentials not logged into itunes connect credentials.



I'll make payments using applicationUsername.

Here User1 and User2 are some how relatives, So Device 2 will have same itunes credentials always of user 2, but user 1 will logged into app with app credentials,If i restore the transactions with ApplictionUserName ,so will i get transactions only for applicationUserName irrespective of ItunesCredentials?



Can we use verification Recipet API instead of Refreshing Receipt and Restoring purchases Products?

Forget about using applicationUserName it will not help you.


If the device being used is logged into an iTunesAccount then it will have a receipt that displays the purchases of that iTunes Account. It really does not care who is holding it or what username the current user is using on your server.


What you want to do is register a purchase only when it is made or restored or the receipt is refreshed. All these require the iTunes Account username/password of the person who is making the cash payment. Before a user can make or restore the purchase tell them that they must be logged into their account on your server. When the purchase or restore goes through, you record that on your server under their account.

Thanks PBK.


I'm trying to store original_Transaction_identifier and Transaction_Identifier of purchase, after purchasing Im gettinng transaction details and from updateTransaction observer method.

I'm also validating receipt from Apple API, I'm getting list of purchase records with original and transaction id of all purchase made y iTunesAccount.From that I'mm searchimg for my transaction id, but i'm unable to find it, but i found my original transaction_id and purchased date and end date for one record but Transaction id is not same as the transaction id that i got from updateTransaction observer method.


Any Idea about this?


If subscriptions auto renews then updateTransaction observer method supposed to be called right?but its not gettig called..

All autorenewable subscription renewals will have the same original_transaction_identifier field. The transaction_identifier depends on the transaction that made that renewal. It should be the transactionID of the updatedTransaction event that loaded that receipt when the transaction was added to the receipt. If you are sending an old receipt to Apple and looking in an undocumented field in that receipt then I do not know what the fields will be.


If subscriptions auto renews then updateTransaction observer method supposed to be called right?but its not gettig called..

It should be being called if the device either made the original purchase or executed a restoreCompletedTransactions with that App Store ID.

You mean to say if i purchased original tranaction in one device, then when purcahse renewals updatedTransaction method will be called,if i logged into another device with same AppstoreId updatedTransaction method will not be called?

>if i purchased original tranaction in one device, then when purcahse renewals updatedTransaction method will be called,if i logged into another device with same AppstoreId updatedTransaction method will not be called?


If you are referring to a non-consumable or an autorenewable IAP, the updatedTransaction method should be called in all devices that:

1) have added a transaction observer

2) are logged into the same iTunes Account as the original purchase

3) have called restoreCompletedTransactions since the original purchase (or purchase in the case of the non-consumable) was made.

Yes
1.I've added Transaction observer in my IAP helper classes while getting all products from iTunes.

2.Yes logged into same account.

3.When i call restoreCompletedTransaction then updatedTransaction method is calling with state restore and purchased also.I have copied purchased transaction original id and purchase id, After execution of the updatedTransaction method I'm validating recipt with APPLE API, there last object contains latest renewal record, purchase id is different from the transaction that i copied from the updatedTransaction method but, purchased_Date,end_Date and all are same.why there is a diff in id?


Below is the flow That I'm fallowing for auto-renewal.


Case 1:New User New device application installed 1st time Appstore a/c 1

When user registering first time app will make purchase with existing App Store credentials.

Every purchase will have transaction Id and original transaction Id.BE will store these details in subscriptionInfo.

When user purchasing we will store Original Transaction Id in defaults.


Every Appstore account will have different original Transaction Id.



*Case 2:Old User New/old device application installed 1st/2nd time Appstore a/c 1 with a existing plan*


When app installed in new device and old user tries to register, as the user already existed in our db, we will skip the subscription flow, old subscription plan will be applied, and will give access to the app if user is in valid subscription plan duration.If user is out of subscription we are showing subscription screen, forcing the user to subscribe again to continue.



App will restore the purchase if they are any purchases with App Store account which is in settings.will save Original Transaction Id in defaults.





*Case 3:*


Two user have two app credentials and two different Appstore Accounts.



User 1 Appstore a/c 1 and plan 30 days original id 1234, purchase id 2345 device 1



User 2 Appstore a/c 2 and plan 6 months originalId 9876 purchase Id 65675 device 2



When User1 Registered in device2 which have iTunesAccount2 in settings, will restore purchases and store the original Transaction Id in device.User1 will have another transactionId in subscriptionInfo, as both are different will show alert to user “Appstore account which is using to purchase a plan seems to be different with App Store account which is used previously to make purchase.Please use the same account or new account.”


Please let me know, if we can restrict the user to purchase, will apple allow this?

To much information.

When a user restores a previous transaction then that restore transaction itself will be a new transaction with a new transactionId. The transaction object for that new transaction will also contain the originalTransactionId

Can you please help me, can we restrict the user to purchase with others appleId with my above scenarios.


will apple allow this?

restoreCompletedTransactions requires that the user have access to the original user's Apple ID and Password. Apple requires that you restore the pruchase to all devices owned by the same user. How will you detect whether device #2 is a second device owned by the first user or a second user who has access to the first user's Apple ID and Password? You can't.


You can sell a consumable IAP and require that the user log into your server (or CloudKit or the iCloud key-value file) to share that consumable IAP with other devices owned by the same user (e.g. a non-renewing subscription). But then how do you prevent a user from sharing their username and password on your system with others? You can restrict the number of copies of a non-renewing subscription to 5 as long as you have some means of responding to a user who contacts you and asks for more copies because they have more than 5 devices.


One thing you can do is require that the user be logged into their iCloud Account to use the app. That means that user 2 must always have access to user 1's Apple ID and Password.