Hi,
Everyone,
Everyone,
Here, I'm going to start the explanation for In-App Purchase for non-consumable product in iPhone/iPad.
You have to follow the below steps before you implement the code given below:
After Creating new APP Id and making In-App Purchase Enabled , You have to create product identifier for non-consumable purchase and need to fill all required information .
After completion all process to itunesconnect.apple.com, you can implement the below code into you project file.
#define kMyFeatureIdentifier @"" //Product Identifier in In-App Purchase
@interface AppDelegate : UIResponder <UIApplicationDelegate,SKPaymentTransactionObserver ,SKRequestDelegate, SKProductsRequestDelegate>
{
NSArray *arrPurchaseProducts;
SKProduct *product;
}
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([SKPaymentQueue canMakePayments])
{
if (![[NSUserDefaults standardUserDefaults] valueForKey:@"isPurchased"])
{
// restarts any purchases if they were interrupted last time the app was open
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[self requestProductData];
}
NSLog(@"IN-APP:can make payments");
}
else {
NSLog(@"IN-APP:can't make payments");
}
}
#pragma mark -
#pragma User-Defined Method for Restore product functionality
-(void)checkPurchasedItems
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
#pragma mark -
#pragma mark In-App Purchase Delegate Methods
- (void)requestProductData
{
NSLog(@"IN-APP:requestProductData");
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kMyFeatureIdentifier]];
request.delegate = self;
[request start];
NSLog(@"IN-APP:requestProductData END");
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(@"IN-APP:productsRequest");
NSArray *myProduct = [[NSArray alloc]initWithArray:response.products];
if ([myProduct count]>0)
{
SKProduct *product = [myProduct 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", [myProduct count]);
[request autorelease];
NSLog(@"IN-APP:productsRequest END");
}
[myProduct release];
myProduct = nil;
}
-(void)buyProduct
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:kMyFeatureIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
payment = nil;
// if (arrPurchaseProducts.count>0)
// {
// SKProduct *selectedProduct = [arrPurchaseProducts objectAtIndex:0];
// SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
// [[SKPaymentQueue defaultQueue] addPayment:payment];
// selectedProduct = nil;
// payment = nil;
// }
}
#pragma mark -
#pragma mark SKPaymentTransactionObserver methods
// called when the transaction status is updated
- (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;
}
}
}
#pragma -
#pragma Purchase helpers
// saves a record of the transaction by storing the receipt to disk
- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
if ([transaction.payment.productIdentifier isEqualToString:kMyFeatureIdentifier])
{
// save the transaction receipt to disk
[[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"proUpgradeTransactionReceipt"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
// enable pro features
- (void)provideContent:(NSString *)productId
{
if ([productId isEqualToString:kMyFeatureIdentifier])
{
// enable the pro features
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isPurchased"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
// removes the transaction from the queue and posts a notification with the transaction result
- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
// 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
[[NSNotificationCenter defaultCenter] postNotificationName:@"PurchaseSuccess" object:self userInfo:userInfo];
}
else
{
// send out a notification for the failed transaction
// [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
}
}
// called when the transaction was successful
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
// 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 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.");
}
}
else {
// this is fine, the user just cancelled, so don’t notify
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
//Then this delegate Funtion 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;
}
}