Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get check if a product is already purchased using in app purchase in iOS?

I have an application with in app integration in it. In my app I have two buttons for paid app buy and subscribe. When the user clicks on buy it goes check for apple validation and the buy the product.

This works properly but when the product is purchased my buy button should change to 'done' and when the application is next time run the buy button should not be visible for that particular product. Instead 'done' button should be shown. My problem is when a product is purchased the buy button is shown instead of done button.

This is my code:

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

//Then this delegate Function Will be fired
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
    NSLog(@"received restored transactions: %i", queue.transactions.count);
    for (SKPaymentTransaction *transaction in queue.transactions)
    {
        NSString *productID = transaction.payment.productIdentifier;
        NSLog(@"%@",productID);
    }

}

// called when a transaction has failed
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        // error!
        [self finishTransaction:transaction wasSuccessful:NO];
        if (transaction.error.code == SKErrorClientInvalid) {
            //[self showAlert:@"In-App Purchase" withMessage:INVALID_CLIENT];
        }
        else if (transaction.error.code == SKErrorPaymentInvalid) {
            //[self showAlert:@"In-App Purchase" withMessage:PAYMENT_INVALID];
        }
        else if (transaction.error.code == SKErrorPaymentNotAllowed) {
            //[self showAlert:@"In-App Purchase" withMessage:PAYMENT_NOT_ALLOWED];
        }
        else if (transaction.error.code == SKErrorPaymentCancelled) {
            // [self showAlert:@"In-App Purchase" withMessage:@"This device is not allowed to make the payment."];
            NSLog(@"User Cancellation.");
        }
        else {
            // SKErrorUnknown
            NSLog(@"Unknown Reason.");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Transaction Status" message:@"Transaction Failed due to unknown reason" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];

        }
    }
    else {
        // this is fine, the user just cancelled, so don’t notify
        //        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Transaction Status" message:@"Transaction failed due to some reason" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        //        [alert show];
        //        return;
        //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
}

- (void)provideContent:(NSString *)productId
{
    if ([productId isEqualToString:kMyFeatureIdentifier4])
    {
        // enable the pro features
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isStorePurchased"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    else if([productId isEqualToString:kMyFeatureIdentifier3])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isStoreSubscribed"];
        [[NSUserDefaults standardUserDefaults]synchronize];

    }
}



- (void)recordTransaction:(SKPaymentTransaction *)transaction
{

    NSData *receiptData = [NSData dataWithData:transaction.transactionReceipt];

    transactionreceipt = [Base64 encode:receiptData];
    NSLog(@"encoded String :%@",transactionreceipt);
    if ([transaction.payment.productIdentifier isEqualToString:kMyFeatureIdentifier4])
    {
        // save the transaction receipt to disk
        [[NSUserDefaults standardUserDefaults] setValue:transactionreceipt forKey:@"proUpgradeTransactionReceipt"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    if ([transaction.payment.productIdentifier isEqualToString:kMyFeatureIdentifier3])
    {
        [[NSUserDefaults standardUserDefaults] setValue:transactionreceipt forKey:@"proUpgradeTransactionReceipt"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
    NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
    transactionreceipt = [userdefaults valueForKey:@"proUpgradeTransactionReceipt"];
    NSLog(@"%@",transactionreceipt);
    // remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
    if (wasSuccessful)
    {
        // send out a notification that we’ve finished the transaction
        [self sendRequest];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PurchaseSuccess" object:self userInfo:userInfo];

        [easytblView reloadData];
    }
    else
    {
        // send out a notification for the failed transaction
        // [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
    }
}

- (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];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"Purchasing...");
                break;
            default:
                break;
        }
    }
}

// called when a transaction has been restored and and successfully completed
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction.originalTransaction];
    [self provideContent:transaction.originalTransaction.payment.productIdentifier];
    [self finishTransaction:transaction wasSuccessful:YES];
}


// called when the transaction was successful
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction];
    [self provideContent:transaction.payment.productIdentifier];
    [self finishTransaction:transaction wasSuccessful:YES];
}
    -(void)buyProduct
    {
        if (arrPurchaseProducts.count>0)
        {
            SKProduct *selectedProduct = [arrPurchaseProducts objectAtIndex:0];
            SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
            [[SKPaymentQueue defaultQueue] addPayment:payment];
            //selectedProduct = nil;
            // payment = nil;
        }

    }

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSLog(@"IN-APP:productsRequest");
    arrPurchaseProducts = [[NSArray alloc]initWithArray:response.products];
    if ([arrPurchaseProducts count] == 1)
    {
        SKProduct *selectedProduct = [arrPurchaseProducts objectAtIndex:0];
        SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
        //responseStatus = 1;
        //        if ([purchaseButton.title isEqualToString:@"   "])
        //        {
        NSLog(@"Purchase had been attempted already.");

        // }
    }

    if ([arrPurchaseProducts count]>0)
    {
        product = [arrPurchaseProducts objectAtIndex:0];
        NSLog(@"Price: %.2f",product.price.floatValue);
        NSLog(@"Price Locale: %@",product.priceLocale.localeIdentifier);
        NSLog(@"Product Identifier: %@",product.productIdentifier);
        NSLog(@"IN-APP:array count: %i", [arrPurchaseProducts count]);
        [request autorelease];
        NSLog(@"IN-APP:productsRequest END");
    }
    //[arrPurchaseProducts release];
    // arrPurchaseProducts = nil;
}

- (void)requestProductData
{

    NSLog(@"IN-APP:requestProductData");
    SKProductsRequest *request;
    if (isSubscribe==YES)
    {
        request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kMyFeatureIdentifier3]];
    }
    else{
        request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kMyFeatureIdentifier3]];
    }
    request.delegate = self;
    [request start];
    NSLog(@"IN-APP:requestProductData END");
}

-(IBAction)buynow:(id)sender
{
    isSubscribe=NO;
    isviewloadedforfirsttime=NO;
        if([SKPaymentQueue canMakePayments])
        {
//            if (![[NSUserDefaults standardUserDefaults] valueForKey:@"isStorePurchased"])
//            {
                [self requestProductData];

            //}
            NSLog(@"IN-APP:can make payments");
        }
        else {
            NSLog(@"IN-APP:can't make payments");
    }

       [self performSelector:@selector(buyProduct) withObject:nil afterDelay:2.0];


}
like image 515
Rani Avatar asked Jun 11 '13 13:06

Rani


1 Answers

- (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];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"Purchasing...");
                break;
            default:
                break;
        }
    }
}

you yourself have inside your code the case of SKPaymentTransactionStateRestored which tells when a product is being restored.

like image 79
Shubhank Avatar answered Oct 01 '22 23:10

Shubhank