Turning off an in-app purchase? - iphone

We currently have a live app that features episodic content in the App store.
We're re-working our pricing, and instead of offering individual episodes for purchase, we want to have it as simply an entire pack of episodes.
My question is this: If I set my old identifiers to NOT cleared for sale, would a user who previously purchased that content still be allowed access to it? (Meaning if I query whether they've purchased it, will it return true)
I'm new to the in-app purchase side of apps, and I'm not entirely sure how that works.
Also, if I delete the identifier from iTunesConnect, what happens? Should this even be done?
Thanks in advance for any insight

When using [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];, Apple will return all completed transactions in a SKPaymentQueue which is a collection of transactions. The transaction will contain the the payment object. The payment object will contain the productIdentifier. This info is available despite your deletion. Thus you may honor past purchases that are no longer for purchase.
Here is some example code:
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
#pragma mark SKPayment Observer Delegate methods
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
NSLog(#"tran for product: %# of state: %i", [[transaction payment] productIdentifier], [transaction transactionState]);
switch ([transaction transactionState])
{
case SKPaymentTransactionStateRestored:
NSLog(#"found restored transaction: %# productIdentifier: %#", transaction.transactionIdentifier, transaction.payment.productIdentifier);
[self yourRestoreProcessSelector:transaction];
break;
default:
break;
}
}
}

Related

completeTransaction:(SKPaymentTransaction *)transaction runs multiple times

I am using below typed code to handle in app purchases in my app. In completeTransaction I unlock premium content by calling provideContentForProductIdentifier. Mostly it runs only one time but, some times it runs multiple times.
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
NSLog(#"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[self validateReceiptForTransaction:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
Please help!
I've had this same problem. In my case I forgot to removeTransactionObserver. So it still contained the earlier product id. Add this to remove the purchased product id after finishing the transaction.
- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
NSLog(#"Purchase removedTransactions");
// Release the transaction observer since transaction is finished/removed.
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

What to do if Apple hosted in-app purchase content download fails?

Sometimes the download fails and my app finishes the transaction upon failure, as recommended everywhere. But if I finish the transaction then Store Kit fails to resume the failed download. And it also seems Store Kit doesn't automatically retry to download content once download failed, and there also seems to be no way to trigger download.
Has someone figured out what to do in such cases? Go against all recommendation and not finish the transaction until the content has fully been downloaded and installed?
Or must I programmatically restore transactions and ignore all other product identifiers?
You can add a button of restore purchase via this way in your app :-
//inside of an IBaction
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue]restoreCompletedTransactions];
// Then this is called
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
NSLog(#"%#",queue );
NSLog(#"Restored Transactions are once again in Queue for purchasing %#",[queue transactions]);
NSMutableArray *purchasedItemIDs = [[NSMutableArray alloc] init];
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions) {
NSString *productID = transaction.payment.productIdentifier;
[purchasedItemIDs addObject:productID];
NSLog (#"product id is %#" , productID);
// here put an if/then statement to write files based on previously purchased items
// example if ([productID isEqualToString: #"youruniqueproductidentifier]){write files} else { nslog sorry}
}
}
OR
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Hope this help you...!!

Obj-C, Storekit restoreCompletedTransactions returns zero transactions?

I'm having some problems restoring completed transactions.
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
I've added the observer mentioned in several examples, I've tried adding paymentQueueRestoreCompletedTransactionsFinished and already have updatedTransactions. paymentQueueRestoreCompletedTransactionsFinished says I have zero transactions.
I can buy a product and if I try to buy again, it stops me and says I've already bought the product, using this code.
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
I thought maybe I had a problem with my bundle identifier, but that seems fine and the buy wouldn't work if it wasn't.
I have been trying this on the device as well as the simulator, but this has the same result. Also, it doesn't make a difference If I'm using UK or US store.
I'm really grasping at straws to find out why this doesn't work for me ?
try to do it like this and check the array count is it return zero also ?
- (void) checkPurchasedItems
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}//You Call This Function
//Then this delegate Function Will be fired
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
purchasedItemIDs = [[NSMutableArray alloc] init];
NSLog(#"received restored transactions: %i", queue.transactions.count);
for (SKPaymentTransaction *transaction in queue.transactions)
{
NSString *productID = transaction.payment.productIdentifier;
[purchasedItemIDs addObject:productID];
}
}
According to the docs:
When you create a new product to be sold in your store, you choose whether that product can be restored or not.
So the question is, is your product configured to allow restores?

Consumable In-App Purchase

Hi I'm trying to make an in-app store in my game for players to buy virtual currencies, which is consumables. But I am a bit unsure if my approach is correct or not. So I think it might be good to ask for help here.
After pressing the Buy Button, buyProductIdentifier is called
- (void)buyProductIdentifier:(NSString *)productIdentifier {
NSLog(#"Buying %#...", productIdentifier);
SKPayment *payment = [SKPayment paymentWithProductIdentifier: productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
and then followed up by paymentQueue
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
CCLOG(#"PAYMENT QUEUE CALLED!");
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
// case SKPaymentTransactionStateRestored:
// [self restoreTransaction:transaction];
default:
break;
}
}
}
I tried by commenting out the SKPaymentTransactionStateRestored case in order to make the player complete a purchase every time instead of popping up a message saying that "You've already purchased this but it hasn't been downloaded".
Is this approach correct? if not, can you guys give me some hints?
Many thanks.
I don't think it is a code problem.
Are you sure that you you have created the In-App Purchases in iTunes Connect as "Consumable" ?
If you have chosen "Non-Consumable" it is only possible to buy the item once.

differentiate between different in app purchases iphone paymentQueue

I have just managed to integrate in app purchases into my ios application however i have know run into a problem that i can't really ask google about.
I have an app with 2 products to purchase but once payment is complete i need to differentiate between the 2 products purchased to then fire another method.
please see the paymentQueue method below:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for(SKPaymentTransaction *transaction in transactions)
{
switch(transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
//do crediting here
NSLog(#"transactionid = %#",transaction);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
if(transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(#"Error Encountered");
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
When the SKPaymentStatePurchased is hit it needs to find the initial product that was purchased to then fire the method for the product to credit an account set up on a remote server.
I hope someone can help!
Thanks in advance :)
You can get that from the transaction itself
transaction.payment.productIdentifier
This will give you the product identifier that the user have purchased