Online receipt validation for Mac App Store In-App Purchases - macos

For in-app purchases for iOS we can use an online API for validation, meaning that we can validate the purchase on our own server.
Is there any way (API) for such validation of in app purchases for OS X?
I've found only this snippet about in-app validation for Mac and it seems that Apple doesn't provide any API for online validation.
Or maybe there is some plan from Apple to support online validation for OS X?

My app EasyBooks provides an online component that users pay yearly for. It wouldn't make sense to provide this as a non-consumable type as it only really works as a consumable (however it's really a non-repeating subscription in iOS). I would like to offer this in-app and I think I have a solution finally...
I used one of my Apple DTS tickets to query a statement made in the StoreKitGuide document. It says ...
"OS X supports both the server validation method described in this
chapter and the local validation method..."
I got a reply from Apple saying ...
"The steps for verifying your In-App Purchase products for Mac
applications are the same used for iOS applications. The difference is that you will be assigning your base 64 encoded app receipt (rather than the content of the transactionReceipt property) to the receipt-data field. Retrieve the full Mac App Store receipt for your application, then encode it using base64 encoding. Create a JSON object with a single key named receipt-data and assign your encoded receipt to it. Proceed as outlined in the Verifying a Receipt with the App Store section of the In-App Purchase Programming Guide.
Note: In App Purchases receipt are included in the associated Mac app's receipt. You must check the receipt associated with your app to verify the validity of the In-App Purchase receipts that it contains. Doing so also allows you to enable the appropriate functionality in your app."
So after some failed attempts, I did manage to get this working with the caveat that the receipt data returned by Apple's servers does not contain the 'hash of the GUID' and therefore does not tie the receipt data to any particular hardware.
This can be tested on your Mac quite easily using these steps:
Find the Mac app receipt file (it's in your app's bundle once you've run the app and entered your (test) Apple ID and password.
At the command line, base64 -i receipt will base64 encode the receipt with no line breaks (that's important)
Again at the command line, curl -d '{ "receipt-data": "<your b64 string here>" }' https://sandbox.itunes.apple.com/verifyReceipt
This returns JSON data in the format
{"status":0,
"environment":"Sandbox",
"receipt":{"adam_id":"0",
"bundle_id":"uk.co.geode.easybooks",
"application_version":"2.2.7",
"download_id":"0",
"in_app":[ {"quantity":"1",
"product_id":"uk.co.geode.easybooks.syncing",
"transaction_id":"1000000034508678",
"purchase_date":"2012-09-05 12:00:17 Etc/GMT",
"original_transaction_id":"1000000034508678",
"original_purchase_date":"2012-01-24 10:16:17 Etc/GMT"} ]}}
I have not confirmed it yet, but apparently (according to the Apple engineer) any consumable types of in-app purchase will be added to the receipt when first purchased, but removed after any further purchases or restore operations. I wonder whether it might be a good idea to make the code running in the app make a copy of the receipt file after each purchase just in case our own servers are down at the time the app tries to validate the receipt. Users may otherwise try to restore purchases, not realising this will remove any consumable product receipts.
I hope that helps.
(ORIGINAL COMMENTS FOLLOW)
I have the same issue. I have an iOS app in the store that has a mix of consumable and non-consumable products that can be purchased in-app. The consumable product is a service, which is fulfilled by my webserver. In the StoreKit delegate method paymentQueue:updatedTransactions:, I use the transactionReceipt property, which is an NSData object. I encode this to base64 and send it to the server. Out on the server I pass the receipt to Apple's servers for validation.
But for Mac OS, there is no transactionReceipt property on the SKPaymentTransaction, so we cannot validate receipts in the same way.
We can do the non-consumable products, which may help you. When an in-app purchase is made on Mac OS, the receipt is updated in the app bundle. It is then possible to parse the receipt file looking for each in-app receipt, which are all stored in the receipt file in the main bundle. For more about that see http://developer.apple.com/library/mac/#releasenotes/General/ValidateAppStoreReceipt/_index.html
This works fine for me when I use the non-consumable product, but I have one consumable and this is not updated into the app's receipt file. Without the transactionReceipt property, I don't see any way for my server to validate that the receipt is genuine. If anyone else has any other experience please let us know!
Anyone with an Apple developer account can also read about this on the Apple developer forum:
https://devforums.apple.com/message/548411#548411

SwiftyStoreKit is popular:
https://github.com/bizz84/SwiftyStoreKit
InAppReceipt for local receipt validation:
https://github.com/tikhop/TPInAppReceipt

Related

Empty build after upload app to Test Flight App Store Connect

I try upload new version of my app and I do it directly from XCode. After succesfull upload I do not see new build online on AppStore connect, but XCode says that upload is done.
As You see, 1.0.52 is created by Xcode but empty. 1.0.38 is my old build when all was ok. Any idea how to fix it? I can manually create iOS build on AppStore Connect and add package from my computer?
AppStore Connect didn't return any error, but now I found email on my developers email account. I missed one value at info.plist, similar problem like there: NSAppleMusicUsageDescription - Missing Info.plist key
But about it I didn't have any information on AppStore Connect, only on email.
Part of email:
Dear Developer,
We identified one or more issues with a recent delivery for your app, "**** ***" (***** ***). Please correct the following issues, then upload again.
ITMS-90683: Missing Purpose String in Info.plist - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSAppleMusicUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more (https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).

In-App Purchase / On-Demand Resources

Using on-demand resources in conjuction with iOS in-app purchases is understandable when resources are included with the application. But how do I add additional in-app purchases after the application is on the store? I'm not referring to the process of creating a new in-app purchase in iTunesConnect.
I'm trying to understand if I create a target for a new in-app purchase on the original app and upload the target to the app store if that data will be available for use as an in-app purchase. The WWDC videos indicate there two ways to host in-app purchases: on-demand resources and hosted content. Is the process for uploading the same for both?
There are several ways you could do this.
1) You could use the SKProductRequest to check for some programatically generated product identifiers (ex: com.company.app.inappItem1, ''2, ''3). The response will include the products you've actually defined in itunes connect. Usually though your app will have to do something with those purchases so you will need to know about all the available products ahead of time anyways. I guess you don't necessarily need to expose them all immediately.
2) You expose a web service somewhere (could just be a website that lists the product id's) that could tell your application what the currently available products ids are. Your application could then check with your backend for the list of product ids to use in the SKProductRequest.
In either case you need to keep in mind that you will probably update your app with new functionality at some time. Old versions of the app may not be able to handle your newer data assets, so you will need to handle this somehow.
You will need to resubmit your app to the store if your in app purchase requires new code to work. If it just a data asset they are buying (not executable code), however, the in app purchase can trigger a download to get that data.

How to track UTM tags in App Store URLs

I'm working on implementing my own analytics system. One part of it consists of tracking where users originated from. I use UTM tags for this. Reading UTM tags from the query parameters is quite easy in Android, iOS and web. However, I also want to track app installs.
I want to be able to share URLs to the Play/App store with UTM tags and mark the user's first session in the app with those tags. Android has a great solution for this: pass the referrer query parameter containing the UTM tags to the Play Store URL and after installation, the UTM tags will be available. (source: https://developers.google.com/analytics/devguides/collection/android/v4/campaigns)
However, the App store doesn't support this kind of tracking. I'm trying to figure out what the industry standard is for tracking app installs. I've seen the following solution:
Share a URL to your own domain. (e.g. myredirectdomain.com?utm_campaign=test)
Save the client ip, screen resolution and UTM tags in a DB table if the client is an iOS device
Redirect the user to the App Store
Once the user installs the app, the app will send the client ip and screen resolution to your server which checks if those are recently added in the DB.
If so, the corresponding UTM tags are returned and the user's session will be marked with those.
Of course, this will most definitely result in some false positives. I've been trying to figure how other companies do this. I've stumbled upon Google Analytics' implementation which utilizes the iPhones IDFA (source: https://developers.google.com/analytics/solutions/ios-install-tracking). However, the IDFA doesn't seem to be available to the mobile browser.
Do you know what the industry standard is for tracking app install campaigns?
Short answer: there is no industry standard in attribution tracking for iOS. Just google the term "app attribution tracking" and see how many service providers show up. They all use some kind of device fingerprinting and call it their "secret sauce". I've used different services in parallel in the past and results were most of the time very different. (Localytics, Flurry, Tapstream)
The "official" recommended way from Apple is to use their own App Analytics attribution tracking. For that you add a provider token(pt=) and a campaign token (ct=) to your store links. You can get your provider token directly in iTunes Connect. You can nicely combine this with the App Store Affiliate program. The only downside is getting the information out of Apple's App Analytics/iTunes Connect. There are no official APIs to get your hands automatically on the raw data.
Sources:
https://developer.apple.com/app-store/user-acquisition-marketing/
https://developer.apple.com/app-store/app-analytics/
App Store Connect gives you the possibility to create Campaign Link that you can use to track Install. I can't remember when it was release but you can find it in :
App analysis -> Sources -> Campaigns -> Generate Campaign Link.
Of course, this is not a classic UTM to track it in Google Analytics, but it can help
There is a solution for IOS apps to track campaign via Google Analytics.
For IOS you do not need to add UTM parameter but you have to make URL as below:
http://click.google-analytics.com/redirect?
tid=UA-1234-1 // Google Analytics Tracking ID.
&idfa=BBA44F63-E469-42BA-833A-2AC550310CB3 // Identifier for Advertising (IDFA)
&aid=com.bundle.myapp // App ID.
&cs=network // Campaign source.
&cm=cpc // Campaign medium.
&cn=campaign_name // Campaign name.
&url=https%3A//itunes.apple.com/us/app/myApp/id123%3Fmt%3D8 // Redirect URL to iTunes.
For reference please view the link:
https://developers.google.com/analytics/solutions/ios-install-tracking

Parse app for clients

I have made a Parse-based app that allows the user to send a push notification to everyone who downloads the app. It's a kind of quick public address system for a congregation, school, club, etc.
Other leaders have expressed an interest in my app for their communities. But these people are not tech-savvy and have no interest in becoming Apple developers for $100 a year, so building custom apps for them is not an option. Even if I did it for them, I would be concerned that they would mess something up that would require a lot of time on my part to repair. They just want to use the app for their communities.
My question: Could I make custom apps for these groups, keep them on my iTunesConnect account, and simply make a new Parse account for each app? That way, the group leaders would only need to know how to log into Parse and send a push notification on the Parse website.
Thank you,
Eli
You could. It could be done with a single app that everyone downloads and then configures to connect it to their specific parse app.
It's possible that you could write the app so it doesn't know the parse account details and they need to be entered on the device. It's also possible that you could supply that detail with an invite e-mail that opens the app and has the details in the URL query.

Receipt validation issue in App Purchases Mac Store "Receipt validation should be presented..."

My applications uses the Store Kit API to purchases in app purchases. I am getting the following store rejection issue, has anyone ever encountered this?
2.3 Apps that do not perform as advertised by the developer will be rejected
The app is not using the Store Kit API properly. The application needs to use receipt validation in order for Store Kit to properly
process In App Purchases.
I inquired further and they said:
Receipt validation should be presented on launch of the app.
Anyone have any idea what the issue is?
See the following:
Mac App Store Receipt Validation Code?
This app is helpful as well but to pricy IMO:
http://receigen.etiemble.com/

Resources