Question

I have problems with restoring purchases on Mac. I've set up Itunesconnect app, in-app purchases, test user. I can buy items. If I buy the same non-consumable item multiple times, system will say that it has already bought and I will get it for free. But the problem in restoring.

Here is the code:

AppDelegate.h

#import <Cocoa/Cocoa.h>
#import <StoreKit/StoreKit.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, SKProductsRequestDelegate,   SKPaymentTransactionObserver>
{
NSArray *m_productIdentifiers;
NSArray* m_products;
}
-(IBAction)Press1:(id)sender;
-(IBAction)Press2:(id)sender;
@property (assign) IBOutlet NSWindow *window;
@end

AppDelegate.m

#import "AppDelegate.h" 

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString *receiptPath = [[[NSBundle mainBundle] appStoreReceiptURL] path];
if (![[NSFileManager defaultManager] fileExistsAtPath:receiptPath])
{
    exit(173);
}

NSURL *url = [[NSBundle mainBundle] URLForResource:@"products"
                                     withExtension:@"plist"];
m_productIdentifiers = [NSArray arrayWithContentsOfURL:url];

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}

-(IBAction)Press1:(id)sender
{
[self validateProductIdentifiers:m_productIdentifiers];
return;
}

-(IBAction)Press2:(id)sender
{
[self restorePurchases];
}


- (void)validateProductIdentifiers:(NSArray *)productIdentifiers
{
SKProductsRequest *productsRequest = [[SKProductsRequest alloc]
                                      initWithProductIdentifiers:[NSSet   setWithArray:productIdentifiers]];
productsRequest.delegate = self;
[productsRequest start];
}


- (void)productsRequest:(SKProductsRequest *)request
 didReceiveResponse:(SKProductsResponse *)response
{
m_products = response.products;

for (NSString *dentifier in response.products)
{
    NSLog(@"%@",dentifier);
}
}

- (void)requestDidFinish:(SKRequest *)request
{
NSLog(@"requestDidFinish");
return;
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(@"request");
return;
}

- (void)restorePurchases
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray    *)transactions
{
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;
    }
};
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");

NSLog(@"completeTransaction... %@",transaction.payment.productIdentifier);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"restoreTransaction...");

NSLog(@"restoreTransaction... %@",transaction.payment.productIdentifier);
[[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];
}

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
NSLog(@"restoreCompletedTransactionsFailedWithError: %@", error);
}

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"paymentQueueRestoreCompletedTransactionsFinished");
}
@end

Press1 working great. I retrieve all my product ids. But after activating Press2 (Restoring) system asks password, and then the function - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error is called.

The Console says:

11/27/13 4:19:00.022 PM storeagent: promptResponse: <CKSignInPromptResponse:0x7fdefca0b950 returnCode:1>
11/27/13 4:19:00.552 PM storeagent: LoadCompletedMicroPaymentsOperation: Could not install receipt after fetching completed purchases - Error Domain=ISErrorDomain Code=2 "No receipt." UserInfo=0x7fdefca183f0 {NSLocalizedDescription=No receipt., NSLocalizedFailureReason=receiptAsString was nil}
11/27/13 4:19:00.554 PM ***mac: restoreCompletedTransactionsFailedWithError: Error Domain=SKErrorDomain Code=0 "Unknown Error." UserInfo=0x1001e7190 {NSLocalizedDescription=Unknown Error.}

I've signed app with Distribution cert (3rd Party Mac Developer Application: ***). Sandbox mode disabled, but I don't think that it is a source of the problem. I haven't included embedded.provisionprofile in the build, but I don't think I need it now.

  • Xcode 4.6.3 + Mac OS 10.7.4
  • Xcode 5.0 + Mac OS 10.8.4
Was it helpful?

Solution

So, I've finally found the solution. The problem was in test users. Maybe, because they were created when we didn't have Mac developer program (only ios), but after creating new test user, problem dissappeared.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top