[汇文教育]iOS内支付(IAP)研究

本文介绍了iOS内支付(IAP)的实现过程,包括前提条件和开发步骤。首先,需要拥有发布产品的开发者账号和运行应用的开发环境。然后,通过iTunes Connect创建Product ID,用于标识购买产品。在代码实现中,需导入storekit框架,并在ViewController中设置正确的Product ID。若Product ID正确,Buy按钮将启用,否则保持禁用状态。
摘要由CSDN通过智能技术生成

关于iOS内支付(简称IAP,全称In App Purchase)的demo可以从以下链接下载:点击打开链接

一、实现支付功能的前提条件:

1.有一个可以发布产品的开发者账号,有一个可以运行应用的开发环境,IAP只能真机测试。

2.自己开发的IAP内支付APP的支付功能实现是需要有Product ID才能实现的,Product ID就是你要购买的产品的标识,可以由以下途径获得:登陆到iTunes Connect,用申请开发者账号的APP ID创建一个新的应用,创建应用内付费项目,设置好价格和Product ID等等。主要是要记住你自己设置好的所有Product ID。

二、iOS内支付开发步骤:

拿以上demo作为实例,其运行成功出现的界面有以下两个按钮:


如果Product ID是错误的话,上面第一个Buy按钮的buyButton.enabled属性为NO。只有当Product ID提供正确,其属性改为YES,才能点击进行购买操作。

此demo的主要流程如下:

1.先在工程导入storekit.frame框架,在EBPurchase.h里#import<StoreKit/StoreKit.h>

2.在ViewController.m文件里将"Your.IAP.Product.ID"改成你自己在上面创建应用时设置好的一个Product ID

#define SUB_PRODUCT_ID @"Your.IAP.Product.ID"
3.在Product ID成功的前提下进行讲解:

1)程序运行后到ViewController.m以下方法:

-(void) viewWillAppear:(BOOL)animated
{   
    buyButton.enabled = NO; // Only enable after populated with IAP price.
    
    // Request In-App Purchase product info and availability.
    
    if (![demoPurchase requestProduct:SUB_PRODUCT_ID]) 
    {
        // Returned NO, so notify user that In-App Purchase is Disabled in their Settings.
        
        [buyButton setTitle:@"Purchase Disabled in Settings" forState:UIControlStateNormal];
    }
}

从此方法buyButton.enabled = NO能看出一开始上面界面的第一个按钮是不能点击的。

2)在以上方法的 [demoPurchase requestProduct:SUB_PRODUCT_ID] 方法将Product ID传进程序,并跳转到EBPurchase.m以下方法:

-(bool) requestProduct:(NSString*)productId 
{
    if (productId != nil) {

        NSLog(@"EBPurchase requestProduct: %@", productId);
        
        if ([SKPaymentQueue canMakePayments]) {
            // Yes, In-App Purchase is enabled on this device.
            // Proceed to fetch available In-App Purchase items.
            
            // Initiate a product request of the Product ID.
            SKProductsRequest *prodRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productId]];
            prodRequest.delegate = self;
            [prodRequest start];
            [prodRequest release];
            
            return YES;
            
        } else {
            // Notify user that In-App Purchase is Disabled.
            
            NSLog(@"EBPurchase requestProduct: IAP Disabled");
            
            return NO;
        }
        
    } else {
        
        NSLog(@"EBPurchase requestProduct: productId = NIL");
        
        return NO;
    }
    
    	
}
此方法最重要的是以下这一段代码:里面的 [SKPaymentQueue canMakePayments] 方法是查询用户是否允许应用内付费,如果不允许就不用进行下面的操作了

if ([SKPaymentQueue canMakePayments]) {
            // Yes, In-App Purchase is enabled on this device.
            // Proceed to fetch available In-App Purchase items.
            
            // Initiate a product request of the Product ID.
            SKProductsRequest *prodRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productId]];
            prodRequest.delegate = self;
            [prodRequest start];
            [prodRequest release];
            
            return YES;
            
        } else {
            // Notify user that In-App Purchase is Disabled.
            
            NSLog(@"EBPurchase requestProduct: IAP Disabled");
            
            return NO;
        }
3)由以上代码里的 [prodRequest start ]方法会由系统调SKProductsRequestDelegate协议里以下方法:

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    
	// Parse the received product info.
	self.validProduct = nil;
	int count = [response.products count];
	if (count>0) {
        // Grab the first product in the array.
		self.validProduct = [response.products objectAtIndex:0];
	}
	if (self.validProduct) {
        // Yes, product is available, so return values.
        
		[delegate requestedProduct:self identifier:self.validProduct.productIdentifier name:self.validProduct.localizedTitle price:[self.validProduct.price stringValue] description:self.validProduct.localizedDescription];
        
	} else {
        // No, product is NOT available, so return nil values.
        
		[delegate requestedProduct:self identifier:nil name:nil price:nil description:nil];
    }
}

上面提供的Product ID如果不正确,以上方法查询会失败,count为0.如果正确,在以上方法里由 [delegate requestedProduct:self identifier:self.validProduct.productIdentifier name:self.validProduct.localizedTitle price:[self.validProduct.price stringValue] description:self.validProduct.localizedDescription] 调ViewController.m里EBPurchaseDelegate协议里的以下方法:

-(void) requestedProduct:(EBPurchase*)ebp identifier:(NSString*)productId name:(NSString*)productName price:(NSString*)productPrice description:(NSString*)productDescription 
{
    NSLog(@"ViewController requestedProduct");
    
    if (productPrice != nil) 
    {
        // Product is available, so update button title with price.
        
        [buyButton setTitle:[@"Buy Game Levels Pack " stringByAppendingString:productPrice] forState:UIControlStateNormal];
        buyButton.enabled = YES; // Enable buy button.
        
    } else {
        // Product is NOT available in the App Store, so notify user.
        
        buyButton.enabled = NO; // Ensure buy button stays disabled.
        [buyButton setTitle:@"Buy Game Levels Pack" forState:UIControlStateNormal];
        
        UIAlertView *unavailAlert = [[UIAlertView alloc] initWithTitle:@"Not Available" message:@"This In-App Purchase item is not available in the App Store at this time. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [unavailAlert show];
        [unavailAlert release];
    }
}
从上面方法代码能看到 buyButton.enabled = YES 现在点击界面里的Buy按钮进行购买操作

跳转到以下方法:

-(IBAction)purchaseProduct<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">由此方法里的</span><span style="font-family: Arial, Helvetica, sans-serif;">[demoPurchase purchaseProduct:demoPurchase.validProduct]</span><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">跳转到EBPurchase.m里的以下方法:</span>

-(bool) purchaseProduct:(SKProduct*)requestedProduct 
{
    if (requestedProduct != nil) {
        
        NSLog(@"EBPurchase purchaseProduct: %@", requestedProduct.productIdentifier);
        
        if ([SKPaymentQueue canMakePayments]) {
            // Yes, In-App Purchase is enabled on this device.
            // Proceed to purchase In-App Purchase item.
            
            // Assign a Product ID to a new payment request.
            SKPayment *paymentRequest = [SKPayment paymentWithProduct:requestedProduct]; 
            
            // Assign an observer to monitor the transaction status.
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
            
            // Request a purchase of the product.
            [[SKPaymentQueue defaultQueue] addPayment:paymentRequest];
            
            return YES;
当购买有结果时会由系统调用SKPaymentTransactionObserver协议里的以下方法:

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
	for(SKPaymentTransaction *transaction in transactions) {
		switch ((int)transaction.transactionState) {
				
			case SKPaymentTransactionStatePurchasing:
				// Item is still in the process of being purchased
				break;
				
			case SKPaymentTransactionStatePurchased:
				// Item was successfully purchased!
				
				// Return transaction data. App should provide user with purchased product.
                
                [delegate successfulPurchase:self identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];
				
				// After customer has successfully received purchased content,
				// remove the finished transaction from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
				
			case SKPaymentTransactionStateRestored:
				// Verified that user has already paid for this item.
				// Ideal for restoring item across all devices of this customer.
				
				// Return transaction data. App should provide user with purchased product.
				
                [delegate successfulPurchase:self identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];
                
				// After customer has restored purchased content on this device,
				// remove the finished transaction from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
				
			case SKPaymentTransactionStateFailed:
				// Purchase was either cancelled by user or an error occurred.
				
				if (transaction.error.code != SKErrorPaymentCancelled) {
					// A transaction error occurred, so notify user.
                    
                    [delegate failedPurchase:self error:transaction.error.code message:transaction.error.localizedDescription];
				}
				// Finished transactions should be removed from the payment queue.
				[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
				break;
		}
	}
}

购买成功后进行移除监听:

- (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray *)transactions
{
    NSLog(@"EBPurchase removedTransactions");
    
    // Release the transaction observer since transaction is finished/removed.
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值