I'm developing an app with non-consumable products. My app need to register and log in for service.
I figure out that the products that user has bought are tied with Apple ID. If user use same Apple ID but different accounts from my server, how will I verify them whether the account buy the product or not?
I have used original_transaction_id to validate it.
Steps-
When any user make a payment, validate the receipt on server.
If a valid payment then update paid in your database and store
original_transaction_id of that receipt.
Next time if the user use same Apple ID, after validating the receipt, check if the original_transaction_id exists in the database or not. If already
exists means user is using same Apple ID for other accounts too,
else its using its Apple ID to make payment first time.
Related
I am developing cross-platform mobile app and using InAppBiling Plugin for my app's in app purchase feature but I have a question about below scenario on iOS:
Scenario:
User A gets the subscription with his app credentials and his Apple ID.
User B uses User A's device and login with User B app credentials but uses User A's Apple ID to buy a subscription.
Currently, it allows that User B to purchase this item but it says that there is a subscription with this user and asks for a permission to modify this subscription.
My question is how to prevent User B to modify User A's subscription? I could not find any solution before the receipt creation. I do not want to allow User B that modifies User A's subscription. I want to inform User B about using different Apple ID to continue to buy a subscription.
Thanks in advance
Your question is related to this one
You have to have backend that is your source of truth about subscriptions.
The situation that you have provided would look like this:
User A gets the subscription with his app credentials and his Apple ID.
You send receipt to your backend to validate it as described here
Your server stores information about subscription and link it with user A
User B uses User A's device and login with User B app credentials but uses User A's Apple ID to buy a subscription.
You send that receipt to your backend as in point 2
Your backend responds that this subscription is already connected with user A
Edit:
As mentioned in apple docs:
Send a copy of the receipt to your server along with some kind of
credentials or identifier so you can keep track of which receipts
belong to a particular user. For example, let users identify
themselves to your server with an email or user name, plus a password.
The logic of the app.
You register with login password. Then if you doesn't have subscription (checked by server) you go to "Buy subscription page".
Problem.
I register user1. buy subscription. token1 goes to server.
I register user2. as he doesn't have subscription he goes to "Buy subscription page", clicks "Buy", apple says "You already bought subscription" and gives token2 (why does it give different token?)
var receiptUrl = NSData.FromUrl(NSBundle.MainBundle.AppStoreReceiptUrl);
return receiptUrl.GetBase64EncodedString(NSDataBase64EncodingOptions.None);
token2 goes to server. As a result we have 1 bought subscription but 2 users that use the same subscription.
Is there any way to identify itunes of user? to save along the token and be able to check if that itunes user already bought subscription for some server side account
This is a fundamental problem in StoreKit receipts and I think most developers don't realize it.
The problem is that Apple doesn't give developers a way to identify which iTunes account a receipt belongs to. This makes it trivial for a user to share their iTunes credentials with other users and unlock subscriptions.
The correct way to handle this is to, in your database, store the actual transaction_id from the Apple verifyReceipt response, and ensure it is unique in your database. This is a lot of work, so it may not be worth it.
It is further complicated by the fact that sometimes, you want an iTunes account to be usable with different app side accounts. For example if a user creates an account and purchases a subscription, lets the subscription expire, then later creates a new account and tries to purchase again, it should be permitted, even though the same receipt is now being used by multiple accounts.
If you don't want to deal with it, I have a service that handles all these edge cases automatically.
I am facing one issue. I have integrated iOS in-app purchase plugin in my Cordova phone-gap app. In-app purchase plugin is working fine but sometimes due to some issues subscription will be paid but I am not able to get return response on server side because it will not hit my server side file where I have add API to fetch response but its subscription will be paid and user will receive receipt with order ID, Document Number.
Now the question is how do I verify from my iTunes developer account that user is subscribed or not. In my sales report I will get only subscriber ID field and not getting any order ID, receipt Number etc.
So is there any alternate way to verify user's subscription status?
Thanks
I have a backend api that accepts the receipt hash data from client ios devices when an iTunes subscription is purchased. I use https://buy.itunes.apple.com/verifyReceipt to verify the receipt data from Apple and to get the subscription details such as transaction id, expiration date etc.
It seems based on this post that I need to refresh such receipts to discover whether or not there is a cancellation_date. Other than doing this from an ios device as described in the developer docs, is there any other way to call an itunes endpoint from the server-side?
Send the receipt itself and have the server store it. Then, re-send the receipt from the server as often as needed to check for subscription updates.
Apple docs:
Persisting Using Your Own Server
Send a copy of the receipt to your server along with some kind of credentials or identifier so you can keep track of which receipts belong to a particular user. For example, let users identify themselves to your server with an email or user name, plus a password. Don’t use the identifierForVendor property of UIDevice—you can’t use it to identify and restore purchases made by the same user on a different device, because different devices have different values for this property.
The documentation for how to validate a receipt on the server side may be helpful here as well.
In my application users can make purchases linked to their accounts in the system, not apple ID. As usual iOS app sends App Store receipt to server, which validates it. I want to know, that each transaction inside receipt belongs to specific user account. One way to do this, is sending additional parameters further to receipt like:
receipt: String, login: String, platform: String
Receipt digital signature validation make sure that the data inside is valid and not replaced by hacker. If parameters (login and platform) will be inside receipt, validation will be completely safe, and valid digital signature tells that all purchases are valid and belongs to account. Otherwise, one receipt can be sent with different logins and allows multiple users to have purchases without paying. To prevent this, for instance, all bundle (receipt, login, platform) can be additionally signed and added check for unique pairs transactionID, userId.
My question is there any way to put additional transaction parameters to receipt, or another common way to archive linkage between purchases in receipt and user account?