in-app Purchase asking old account password while restoring - ios

When I opened app it's popup's iTunes login with out any interaction of user.That popup contains my old test user account mail id sometimes my current testuser mail id aslo.I heard that i have to call
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
I called it several times where ever I thought it's needed.But still it's asking password.
And here is my code:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for(SKPaymentTransaction *transaction in transactions)
{
NSLog(#"Updated transaction %#",transaction);
switch (transaction.transactionState)
{
case SKPaymentTransactionStateFailed:
[self errorWithTransaction:transaction];
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
NSLog(#"Purchasing...");
break;
case SKPaymentTransactionStatePurchased:
{
if(no need to download)
{
// I will download the content later by restoring transactions.
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
}
else
{
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
}
case SKPaymentTransactionStateRestored:
{
if(no need to download content)
{
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
}
else
{
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
}
break;
default:
break;
}
}
-(void) paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads
{
for (SKDownload *download in downloads)
{
switch (download.downloadState)
{
case SKDownloadStateActive:
{
// showing download progress
}
case SKDownloadStateCancelled:
{
[[SKPaymentQueue defaultQueue] finishTransaction:download.transaction];
}
case SKDownloadStateFailed:
{
// showing alert and finish transactions
[[SKPaymentQueue defaultQueue] finishTransaction:download.transaction];
}break;
case SKDownloadStateFinished:
{
// processing content and finished the transactions
[[SKPaymentQueue defaultQueue] finishTransaction:download.transaction];
}break;
}
}
}
Is this correct and is there any place to call finishTransaction: method.Please let me know is any...
thanks in advance..

Related

how to Restore IAP for non-consumable product in iOS

I want to know that
do one have to put two buttons separate one for Upgrade and Other for Restore for restore previous transactions??
What steps should be taken by my self to avoid reject chances of App for Restore transaction.
I used below code for restore non-consumable In App Purchase.
If any changes in below code please let me know.
- (void)buyProduct:(SKProduct *)product {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
//[[SKPaymentQueue defaultQueue] addPayment:payment];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState)
{
// Call the appropriate custom method for the transaction state.
case SKPaymentTransactionStatePurchasing:
[self showTransactionAsInProgress:transaction deferred:NO];
break;
case SKPaymentTransactionStateDeferred:
[self showTransactionAsInProgress:transaction deferred:YES];
break;
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
// For debugging
NSLog(#"Unexpected transaction state %#", #(transaction.transactionState));
break;
}
};
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
NSLog(#"Restore Completed Transactions Failed WithError...%#",error);
[self failedMessage:#"Restore Completed Transactions Failed"];
[self stopIndicator];
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSMutableArray *arrPurchasedItemIDs = [[NSMutableArray alloc] init];
for (SKPaymentTransaction *transaction in queue.transactions)
{
NSString *productID = transaction.payment.productIdentifier;
[arrPurchasedItemIDs addObject:productID];
NSLog(#"arrPurchasedItemIDs : %#",arrPurchasedItemIDs);
}
NSLog(#"Restore Completed");
[self completeMessage:#"Restore Completed"];
[self stopIndicator];
}
Here how you can separate the Restore purchase code :
-(void)doClickRestore {
[APP_DEL doStartSpinner];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
// Purchase success Transaction
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
// Purchase fail Transaction
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
{
[self doStopSpinner];
[self restoreTransaction:transaction];
}
default:
break;
}
}
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction {
[self doStopSpinner];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
Note :
Clicking on Restore purchases will restore all purchased non consumable inApp purchases
Hope it will helps.
These below two mehods are optional but if you want you can use it.
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue

unable to finishTransaction in app purchase

I have a problem which either allows me to download apple hosted content or finishTransaction but not both;
#pragma mark -
#pragma mark SKPaymentTransactionObserver methods
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchasing:
NSLog(#"Purchasing");
break;
case SKPaymentTransactionStatePurchased:
NSLog(#"Transaction State Purchased");
[[SKPaymentQueue defaultQueue]startDownloads:transaction.downloads];
break;
case SKPaymentTransactionStateFailed:
NSLog(#"Transaction State Failed");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(#"Transaction State Restored");
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
buyButton.enabled = NO;
[buyButton setTitle:#"Purchased"
forState:UIControlStateDisabled];
//break;
default:
break;
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads;
{
for (SKDownload *download in downloads) {
switch (download.downloadState) {
case SKDownloadStateFinished:
NSLog(#"Completing transaction-B");
[self processDownload:download];
[queue finishTransaction:download.transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:download.transaction];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
break;
case SKDownloadStateActive:
NSLog(#"%f", download.progress);
NSLog(#"%f remaining", download.timeRemaining);
break;
default:
break;
}
}
}
-(void)completeTransaction:(SKPaymentTransaction *)transaction
{ //checked!!
NSLog(#"Complete transaction");
//[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
buyButton.enabled = NO;
[buyButton setTitle:#"Purchased"
forState:UIControlStateDisabled];
}
generally the code works fine;
the product is displayed
I can select to buy
login request
then as per the code above the download works and is processed (moved to the Document directory).
However, if i finishTransaction in updatedTransactions then the download will not occur. (makes sense!)
if I call [self completeTransaction:transaction] to finishTransaction from updatedTransactions I get the same.
If i neglect to call completeTransaction (as per the code) then content is downloaded but then I can't seem to call finish transaction.
where/how do I call finish transaction?
so close but so far!!!
I was calling finish transaction too early and my download was not able to finish.

SKPaymentTransactionObserver - transaction fail

I am working on an app with in-app-purchase up to the transaction part.
I have a purchaseViewController to call up getProductInfo while launch:
-(void)getProductInfo: (CC3DeviceCameraOverlayUIViewController *) viewController
{
_homeViewController = viewController;
if ([SKPaymentQueue canMakePayments])
{
SKProductsRequest *request = [[SKProductsRequest alloc]
initWithProductIdentifiers:
[NSSet setWithObject:self.productID]];
request.delegate = self;
[request start];
}
else
_productDescription.text =
#"Please enable In App Purchase in Settings";
}
which is successful. Then I have a button to call buyProduct:
- (IBAction)buyProduct:(id)sender {
SKPayment *payment = [SKPayment paymentWithProduct:_product];
if(_myQueue == nil) {
_myQueue = [SKPaymentQueue defaultQueue];
}
[_myQueue addPayment:payment];
NSLog(#"buyproduct happening %#", _product.localizedTitle);
}
which also successful because I see the NSLog and the product title.
But after this, I always get a transaction failed! when the purchasing process up to
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
// [self unlockFeature];
NSLog(#"Transaction purchased");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if (_product.downloadable) {
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
break;
case SKPaymentTransactionStateRestored:
if (transaction.downloads) {
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
NSLog(#"Transaction downloading now...");
} else {
// unlock features
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"Transaction finish");
}
break;
case SKPaymentTransactionStateFailed:
NSLog(#"Transaction Failed");
[[SKPaymentQueue defaultQueue]
finishTransaction:transaction];
break;
default:
break;
}
}
}
What seems to be wrong and how can I debug this part? Is there a way for me to clear previous transaction test or check if there is any pending transaction interfere with the current test? I am still testing it in sandbox mode. The error was thrown in a quite immediate manner that give me the impression that it did not really go through Apple server and the transaction error happen locally, some sort of previous transaction test conflict or something that I still yet to find out.
One more point to mention is that I am purchasing non-consumable item, which if transaction successful, it will trigger the download(I hope.).

Transaction isn't being completed

I want the payment transaction to complete once the download transaction has completed but when the download finishes for some reason the transaction state is not completed. Do i have to put the payment transaction back in the queue after the download is complete here is more code.
- (void)buyProduct:(SKProduct *)product {
NSLog(#"Buying %#...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for (SKPaymentTransaction * transaction in transactions) {
if(transaction.downloads){
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}else{
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads;
{
for (SKDownload *download in downloads) {
if (download.downloadState == SKDownloadStateFinished) {
[self processDownload:download]; //handle download
// now we're done
NSLog(#"Download finished");
[[SKPaymentQueue defaultQueue] finishTransaction:download.transaction];
//Do I need to add the payment transaction back in the queue? Im worried the payment will go through twice?
} else if (download.downloadState == SKDownloadStateActive) {
NSString *productID = download.contentIdentifier; // in app purchase identifier
NSTimeInterval remaining = download.timeRemaining; // secs
float progress = download.progress; // 0.0 -> 1.0
NSLog(#"Product ID:%#", productID);
NSLog(#"Time remaining: %f", remaining);
NSLog(#"Download progress percent: %f", progress);
} else { // waiting, paused, failed, cancelled
NSLog(#"Warn: not handled: %d", download.downloadState);
}
}
}
These are my methods I created for my transaction state if it matters at all? None of them are being executed anyways so I don't think it matter but here it is.
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
if(transaction.downloads){
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
NSLog(#"Download exists");
}else{
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(#"Transaction error: %#", transaction.error.localizedDescription);
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

Restore transaction doesn't download the content IAP IOS

I have been struggling with this issue since 2 days. I have implemented In App purchase successfully with downloadable content . But whenever I delete app and restore the purchase , restore doesn't actually download the content. But if I add download code in restoreTransaction it never calls finish transaction which cause the app to behave weirdly(which is resonable) , every time I delete app and reinstall it. Any help is appreciated!!
Please let me know if anyone needs further explanation. Thanks!!
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
if(transaction.downloads)
[self download:transaction];
else
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
if(transaction.downloads)
[self restoreDownload:transaction];
else
[self restoreTransaction:transaction];
default:
break;
}
};
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads
{
for (SKDownload *download in downloads)
{
switch (download.downloadState) {
case SKDownloadStateActive:
NSLog(#"Download progress = %f",
download.progress);
NSLog(#"Download time = %f",
download.timeRemaining);
break;
case SKDownloadStateFinished:
{
NSLog(#"URL %#",download.contentURL);
}
break;
default:
break;
}
}
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)restoreDownload:(SKPaymentTransaction *)transaction {
NSLog(#"restoreDownload...");
//[self validateReceiptForTransaction:transaction];
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
- (void)download:(SKPaymentTransaction *)transaction {
NSLog(#"Download Content...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
//[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

Resources