How do I read receipt data with existing paid iOS app? - ios

I have a paid app that I'm thinking about making free with in app purchases. If I make the switch I'll need to check if the user has already paid for the app and then enable the paid features.
I think the below code should do what I need but I'm not sure how to test it. I built the app and ran it using my development provisioning profile on my device and receitpData is empty. So I built the app with a distribution provisioning profile and submitted it to the app store then downloaded the app using test flight but I'm still having the same problem.
How do I get the receipt data from an existing app?
Do I need to enable in-app purchases for this app to get this data?
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];

I figured it out:
#import <StoreKit/StoreKit.h>
Don't forget to add its delegates
<SKPaymentTransactionObserver, SKProductsRequestDelegate>
Here's the code:
SKReceiptRefreshRequest* request = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
request.delegate = self;
[request start];
and then:
-(void)requestDidFinish:(SKRequest*)request{
if([request isKindOfClass:[SKReceiptRefreshRequest class]]){
NSLog(#"YES, You purchased this app");
}
}
- (void)request:(SKRequest*)request didFailWithError:(NSError *)error{
NSLog(#"NO, you need to buy it");
}

Related

iOS - See contents of a receipt

I'm working on handling a scenario, where my app was paid on the app store and now I'm making free to download with in app purchase.
However anyone who has previously purchased I want it to be unlocked for them so they don't pay again.
I have the following code which actually gets the receipt:
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (!receipt) {
NSLog(#"NO RECP");
} else {
NSLog(#"GOTACH");
}
However looking at that NDData receipt its all binary data. How can I actually see whats inside that? I've seen various posts about making requests to some url - do I need to do that? I just want to see whatever in that file (hoping for something like version/bundle id when purchased or even date when first purchased).
And my second question, will that receipt only get the receipt for my app, or does it return all receipts on the device?
Thanks.

subscription receipt not received after reinstall app

I am implement renewing subscription in my application.
When I purchase pack then I get receipt from app store by following code
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
Question : When I reinstall my app. I get nil from receipt In iPhoneX(11.4.1) But working fine in iPod(9.3.5)
Thanks in advance

Lost connectivity before receiving purchase receipt from apple In-app purchase

I have implemented In-app purchase in my app. So what I do is, after user completes payment with app store & the control goes to
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
then I update the purchase receipt to our server. Rest of the operations are done by server.
But one of our users faced an issue where he completed the payment but he lost internet connection before the above method was called. Resulting, our app does not know about the payment.
I know that the receipt is stored in the device. But is it the right way to send the receipt to the server from device every time user uses app??
Well, What i did to avoid this was, Keep a Check (like a boolean : transactionInProgress) when the transaction begin and when I have sent data to the server I change the value to "NO".
In this way the next time the app connects. just check if the transactionInProgress was checked, if it is then there was a transaction on going and you can fetch the receipt that must be stored by SKPaymentTransactions using
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (!receipt) { /* No local receipt -- handle the error. */ }

iOS - Validation for consumable products

I am wondering where I should store the receipt data when the validation for a consumable item failed.
To validate the receipt, we have to send a receipt data which is gained from below code to our server, but for some reasons it might be failed.
// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
if (!receipt) { /* No local receipt -- handle the error. */ }
/* ... Send the receipt data to your server ... */
In case for that, we have to store the receipt data in the app to send the receipt data again.
I tried using NSUserDefaults but I found that the data will disappear when the user delete the app itself.
How do you deal with the case?

Testing In App Purchase issues. IAP iOS

I have got one big problem with an IAP purchase testing.
There are next steps which I have made:
Create App ID (com.domainname.appname)
Create Development Provisioning Profile with an App ID (com.domainname.appname)
Create App on iTunes Connect (Bundle ID com.domainname.appname)
Manage IAP. Create non-consumable products with Product ID com.testitem1, com.testitem2, com.testitem3 (there is Ready to Submit status for each products)
Configurate XCode project settings
Bundle identifier: com.domainname.appname
Code Signing Identity: Development Provisioning Profile that I have made on the step 2
Deployment target: 4.0
Device
iPod Touch 4gen iOS 5.1.1
Write source code
My class support SKProductsRequestDelegate
in - viewDidLoad callback method I have wrote these lines:
if ([SKPaymentQueue canMakePayments])
{
NSLog(#"YES, I CAN MAKE PAYMENTS");
}
else
{
NSLog(#"NO, I CAN NOT MAKE PAYMENTS");
}
On this stage everything is okay. I can make payments.
Next, I'm try to create request for my products:
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObjects:#"com.testitem1", #"com.testitem2", #"com.testitem3", nil]];
request.delegate = self;
[request start];
On this stage everything is okay also and on next stage my request object invoke callback method below:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *myProduct = response.products;
NSLog(#"%#", myProduct);
}
But there are not any products in response and I can not understand why.
I already have this problem before (i just reset my device and everything worked good), but in this case I can not figure out what's wrong.
I have went through this guide:
https://developer.apple.com/library/ios/#technotes/tn2259/_index.html
In my case this is was related that I have not got Banking Information. If you want to test your IAP you must have an iOS Paid Applications contract (iOS) with a your tax information.
This happens because you haven't yet uploaded the app's binary in iTunes Connect. Go to iTunes Connect, upload the app's binary. Once it's uploaded, reject it straight away so that it's marked as "Developer Rejected".
This is a necessary step for you to receive SKProductResponse if it's the first version of your app. It won't affect your app's review.

Resources