1. Create an application
First go to iTunes connect and then press manage your applications
Next, click Add new application to create an application.
2. Create an IAP in the Application
After the application is created, click the application icon in the Manage Your applications to enter the application
Click Manage in app purchases to go to The IAP management screen.
Note the bundle ID on the left. In the xcode project, the settings in info. plist must be the same as those in this bundle.
(This bundle ID will be filled in when the application is created)
This is the IAP management screen. You only need to press the create new button to create an IAP.
In this figure, three IAP instances have been created.
Pay attention to the product ID. You only need to use the product ID to request information and transactions of the IAP.
Consumable
Consumable, paid for each download
Non-consumable
One-time payment, usually used to upgrade the Pro version or remove advertisements.
Auto-renewable subscriptions
Auto Update Subscription
Free subdomains
Free Subscription
Non-renewing subgraphs
Non-automatic Update Subscription
3. How to Create a sandbox test user
Go to iTunes connect and Click Manage Users.
In this screen, click test user
Press add new user. Email address is the username used to log on to the sandbox for testing.
You can create the password when adding a new user.
4. Code
/* * CBiOSStoreManager.h * CloudBox Cross-Platform Framework Project * * Created by Cloud on 2012/10/30. * Copyright 2011 Cloud Hsu. All rights reserved. * */#import <UIKit/UIKit.h> #import <StoreKit/StoreKit.h>@interface CBiOSStoreManager : NSObject<SKProductsRequestDelegate,SKPaymentTransactionObserver>{ NSString* _buyProductIDTag;}+ (CBiOSStoreManager*) sharedInstance;- (void) buy:(NSString*)buyProductIDTag;- (bool) CanMakePay;- (void) initialStore;- (void) releaseStore;- (void) requestProductData:(NSString*)buyProductIDTag;- (void) provideContent:(NSString *)product;- (void) recordTransaction:(NSString *)product;- (void) requestProUpgradeProductData:(NSString*)buyProductIDTag;- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;- (void) purchasedTransaction: (SKPaymentTransaction *)transaction;- (void) completeTransaction: (SKPaymentTransaction *)transaction;- (void) failedTransaction: (SKPaymentTransaction *)transaction;- (void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;- (void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;- (void) restoreTransaction: (SKPaymentTransaction *)transaction;@end
/* * CBiOSStoreManager.mm * CloudBox Cross-Platform Framework Project * * Created by Cloud on 2012/10/30. * Copyright 2011 Cloud Hsu. All rights reserved. * */#import "CBiOSStoreManager.h"@implementation CBiOSStoreManagerstatic CBiOSStoreManager* _sharedInstance = nil;+(CBiOSStoreManager*)sharedInstance{@synchronized([CBiOSStoreManager class]){if (!_sharedInstance)[[self alloc] init]; return _sharedInstance;}return nil;}+(id)alloc{@synchronized([CBiOSStoreManager class]){NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of a singleton.\n");_sharedInstance = [super alloc];return _sharedInstance;}return nil;}-(id)init {self = [super init];if (self != nil) {// initialize stuff here}return self;}-(void)initialStore{ [[SKPaymentQueue defaultQueue] addTransactionObserver:self];}-(void)releaseStore{ [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];}-(void)buy:(NSString*)buyProductIDTag{ [self requestProductData:buyProductIDTag];}-(bool)CanMakePay{ return [SKPaymentQueue canMakePayments];} -(void)requestProductData:(NSString*)buyProductIDTag{ NSLog(@"---------Request product information------------\n"); _buyProductIDTag = [buyProductIDTag retain]; NSArray *product = [[NSArray alloc] initWithObjects:buyProductIDTag,nil]; NSSet *nsset = [NSSet setWithArray:product]; SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset]; request.delegate=self; [request start]; [product release];}- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSLog(@"-----------Getting product information--------------\n"); NSArray *myProduct = response.products; NSLog(@"Product ID:%@\n",response.invalidProductIdentifiers); NSLog(@"Product count: %d\n", [myProduct count]); // populate UI for(SKProduct *product in myProduct){ NSLog(@"Detail product info\n"); NSLog(@"SKProduct description: %@\n", [product description]); NSLog(@"Product localized title: %@\n" , product.localizedTitle); NSLog(@"Product localized descitption: %@\n" , product.localizedDescription); NSLog(@"Product price: %@\n" , product.price); NSLog(@"Product identifier: %@\n" , product.productIdentifier); } SKPayment *payment = nil; payment = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]]; NSLog(@"---------Request payment------------\n"); [[SKPaymentQueue defaultQueue] addPayment:payment]; [request autorelease]; }- (void)requestProUpgradeProductData:(NSString*)buyProductIDTag{ NSLog(@"------Request to upgrade product data---------\n"); NSSet *productIdentifiers = [NSSet setWithObject:buyProductIDTag]; SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; productsRequest.delegate = self; [productsRequest start]; }- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ NSLog(@"-------Show fail message----------\n"); UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription] delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView show]; [alerView release];} -(void) requestDidFinish:(SKRequest *)request{ NSLog(@"----------Request finished--------------\n"); } -(void) purchasedTransaction: (SKPaymentTransaction *)transaction{ NSLog(@"-----Purchased Transaction----\n"); NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil]; [self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions]; [transactions release];} - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{ NSLog(@"-----Payment result--------\n"); for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; NSLog(@"-----Transaction purchased--------\n"); UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"Congratulation" message:@"Transaction suceed!" delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView show]; [alerView release]; break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; NSLog(@"-----Transaction Failed--------\n"); UIAlertView *alerView2 = [[UIAlertView alloc] initWithTitle:@"Failed" message:@"Sorry, your transcation failed, try again." delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView2 show]; [alerView2 release]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; NSLog(@"----- Already buy this product--------\n"); case SKPaymentTransactionStatePurchasing: NSLog(@"-----Transcation puchasing--------\n"); break; default: break; } }}- (void) completeTransaction: (SKPaymentTransaction *)transaction { NSLog(@"-----completeTransaction--------\n"); // Your application should implement these two methods. NSString *product = transaction.payment.productIdentifier; if ([product length] > 0) { NSArray *tt = [product componentsSeparatedByString:@"."]; NSString *bookid = [tt lastObject]; if ([bookid length] > 0) { [self recordTransaction:bookid]; [self provideContent:bookid]; } } // Remove the transaction from the payment queue. [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } -(void)recordTransaction:(NSString *)product{ NSLog(@"-----Record transcation--------\n"); // Todo: Maybe you want to save transaction result into plist.} -(void)provideContent:(NSString *)product{ NSLog(@"-----Download product content--------\n");} - (void) failedTransaction: (SKPaymentTransaction *)transaction{ NSLog(@"Failed\n"); if (transaction.error.code != SKErrorPaymentCancelled) { } [[SKPaymentQueue defaultQueue] finishTransaction: transaction];}-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction{ }- (void) restoreTransaction: (SKPaymentTransaction *)transaction{ NSLog(@"-----Restore transaction--------\n");}-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{ NSLog(@"-------Payment Queue----\n");}#pragma mark connection delegate- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSLog(@"%@\n", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ switch([(NSHTTPURLResponse *)response statusCode]) { case 200: case 206: break; case 304: break; case 400: break; case 404: break; case 416: break; case 403: break; case 401: case 500: break; default: break; }} - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"test\n");} -(void)dealloc{ [super dealloc];}@end
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
Because transactions are permanently valid, we recommend that you listen to addtransactionobserver after the application is started, rather than when users want to buy things.
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
The transaction result is displayed here.
It may take some time for Apple to prepare a sandbox test environment. If you can obtain information after creating an IAP, but the transaction fails, you have to wait a moment.
In addition, if the simulator can be purchased, but the real machine purchase fails, you can do hard reset. Keep holding the Home Key and power key for hard reset.
After you press and hold it down, the screen will be shut down, ignore it, and wait until the white apple appears, you can open it and wait until it is restarted before testing.
5. IAP operation Flowchart
6. Sample download
Download link