Reputation: 377
i am really confused, I dont know how can add In-app purchase to my existing app. When in 'Capabilities' i choose on In-app purchase it show me only error add the in app purchase entitlement to your app id
. I added app id in dev center and in-app purchase in itunesconnect. My Bundle ID is sk.freetech.zatracenacestina.intro
and in-app purchase i set up to sk.freetech.zatracenacestina.intro.package
but I dont know where can I fill it?
Thank you
Upvotes: 1
Views: 7822
Reputation: 127
I know this is really old, but I just had the same issue (I was following a Ray W. tutorial https://www.raywenderlich.com/122144/in-app-purchase-tutorial)... When I added my signing team (Targets > General > Signing > Team) it was resolved. This is not mentioned in the tutorial (no slight on Ray W. - they're generally great)
Upvotes: 0
Reputation: 1
For me this error appears because of having NO registered device in member center. Here is the case that help for me.
Upvotes: 0
Reputation: 1201
you can follow these tutorial 1. http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial 2. http://www.tutorialspoint.com/ios/ios_in_app_purchase.htm 3. http://code4app.net/ios/In-App-Purchase/4fc85be56803fa4a49000000
Create a class name it IAPHelper subclass NSObject
#import <StoreKit/StoreKit.h>
UIKIT_EXTERN NSString *const IAPHelperProductPurchasedNotification;
typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products);
@protocol inAppPurchaseDelegate <NSObject>
@optional
-(void)transactionSucsess:(NSString *)transactionId;
-(void)transactionOnRestore:(NSString *)transactionId;
-(void)transactionOnFail;
@end
@interface IAPHelper : NSObject
@property(nonatomic,readwrite)id<inAppPurchaseDelegate> delegate;
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers;
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler;
- (void)buyProduct:(SKProduct *)product;
- (BOOL)productPurchased:(NSString *)productIdentifier;
- (void)restoreCompletedTransactions;
@end
in IAPHelper.m
#import <StoreKit/StoreKit.h>
NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification";
@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end
@implementation IAPHelper {
SKProductsRequest * _productsRequest;
RequestProductsCompletionHandler _completionHandler;
NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
}
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
if ((self = [super init])) {
// Store product identifiers
_productIdentifiers = productIdentifiers;
// Check for previously purchased products
_purchasedProductIdentifiers = [NSMutableSet set];
for (NSString * productIdentifier in _productIdentifiers) {
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased) {
[_purchasedProductIdentifiers addObject:productIdentifier];
NSLog(@"Previously purchased: %@", productIdentifier);
} else {
NSLog(@"Not purchased: %@", productIdentifier);
}
}
// Add self as transaction observer
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
_completionHandler = [completionHandler copy];
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
- (BOOL)productPurchased:(NSString *)productIdentifier {
return [_purchasedProductIdentifiers containsObject:productIdentifier];
}
- (void)buyProduct:(SKProduct *)product {
NSLog(@"Buying %@...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
#pragma mark SKPaymentTransactionOBserver
- (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...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if(_delegate)
[_delegate transactionSucsess:transaction.payment.productIdentifier];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
if(_delegate)
[_delegate transactionOnRestore:transaction.payment.productIdentifier];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
if(_delegate)
[_delegate transactionOnFail];
}
- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {
[_purchasedProductIdentifiers addObject:productIdentifier];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
@end
Create a class RageIAPHelper subclass of IAPHelper
#import "IAPHelper.h"
@interface RageIAPHelper : IAPHelper
+ (RageIAPHelper *)sharedInstance;
@end
In RageIAPHelper.m
#import "RageIAPHelper.h"
@implementation RageIAPHelper
+ (RageIAPHelper *)sharedInstance {
static dispatch_once_t once;
static RageIAPHelper * sharedInstance;
dispatch_once(&once, ^{
NSSet * productIdentifiers = [NSSet setWithObjects:
@"your identifier",@"your identifier",
nil];
sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers];
});
return sharedInstance;
}
@end
[[RageIAPHelper sharedInstance] setDelegate:(id)self];
[[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) {
if (success) {
totalProduct_Arr =products;
for (SKProduct *s in totalProduct_Arr) {
NSLog(@"product Identifier %@",[s productIdentifier]);
if ([[s productIdentifier]isEqualToString:FULLVERSION]) {
[self.btnFullVersion setEnabled:YES];
}
else if ([[s productIdentifier]isEqualToString:REMOVE_ADS]) {
[self.btnRemoveAd setEnabled:YES];
}
}
}
else{
UIAlertView *alertFail=[[UIAlertView alloc] initWithTitle:@"Product Not Found" message:@"Fails to load product.." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alertFail show];
}
}];
and to buy product
[[RageIAPHelper sharedInstance] buyProduct:product];
Upvotes: 3
Reputation: 307
This link will help you. Follow this link step by step.
You can use this code also.
Now In .m class copy this code for in-app purchase
-(void)startpurching
{
NSArray *arrPackageproductIdentifier=[NSArray arrayWithObjects:@"Your Product Id",nil];
NSString *strPrductIdentifier=[arrPackageproductIdentifier objectAtIndex:0];
request= [[SKProductsRequest alloc]
initWithProductIdentifiers: [NSSet setWithObject:strPrductIdentifier]];
NSLog(@"%@",request);
request.delegate = self;
[request start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
NSArray *myProduct = response.products;
if ([myProduct count]==0) {
UIAlertView *alt=[[UIAlertView alloc]initWithTitle:nil message:@"Cannot connect !! Please check your internet connection." delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
[alt show];
} else {
NSLog(@"pro...%@",[[myProduct objectAtIndex:0] productIdentifier]);
SKPayment *newPayment = [SKPayment paymentWithProduct:[myProduct objectAtIndex:0]];
[[SKPaymentQueue defaultQueue] addPayment:newPayment];
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
NSLog(@"Transaction....%@",transactions);
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
NSLog(@"%d",transaction.transactionState);
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
NSLog(@"=======%@",transactions);
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
NSLog(@"Transaction Completed");
NSUserDefaults *remvAddSttr = [NSUserDefaults standardUserDefaults];
// saving an NSString
NSString *chkRemVal=@"10";
[remvAddSttr setObject:chkRemVal forKey:@"revAdd"];
UIAlertView *alrt=[[UIAlertView alloc]initWithTitle:@"" message:@"Transaction completed" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alrt show];
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"Transaction Restored");
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
if (transaction.error.code != SKErrorPaymentCancelled) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Purchase Unsuccessful"
message:@"Your purchase failed. Please try again."
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
Now need to design a Restore button for non-consumable product. For Restore button clicked copy this code.
//*****************************************************************************
//*****************************************************************************
-(void)restoreBtnClicked
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
if (error.code == SKErrorPaymentCancelled) {
NSLog(@"error.code");
}
}
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
// NSMutableArray* purchasableObjects = [[[NSMutableArray alloc] init] autorelease];
for (SKPaymentTransaction *transaction in queue.transactions) {
NSString *productID = transaction.payment.productIdentifier;
NSLog(@"productID...%@",productID);
if ([productID isEqualToString:@"Your Product Id"]) {
UIAlertView *alt12=[[UIAlertView alloc]initWithTitle:nil message:@"Product Restored" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
[alt12 show];
}
}
//Block Call to access the products
}
Upvotes: 0