iOS- 給App添加內購& 驗證購買iOS7新特性


1. 內購——應用內購買  

我所說的內購——也可以說是應用內購買

大家都知道通過蘋果應用程序商店有三種主要賺錢的方式:
1.直接收費(與國內大部分用戶的消費習慣相悖,如果要收費,直接收高的,別收6塊錢)
2.廣告(降低用戶體驗 應用程序名稱帶Lite可以添加廣告)
3.內購
至於設計哪些賣錢?產品經理需要認真考慮和調研的。記錄用戶行為是可以幫助產品經理確認哪些收費!
所以要做好游戲,一定要研究心理,要研究哲學,哈哈。
 

2.內購的類別有哪幾種呢?  

在游戲中我們經常用到的主要由分兩種:
 
非消耗品(Nonconsumable)買了就有,頭銜,功能
指的是在游戲中一次性購買並擁有永久訪問權的物品或服務。非消耗品物品可以被用戶再次下載,並且能夠在用戶的所有設備上使用
消耗品(Consumable),買了就用,用了就沒
專為支持可消耗的物品或服務設計的,消耗品購買不可被再次下載,根據其特點,消耗品不能在用戶的設備之間跨設備使用,除非自定義服務在用戶的賬號之間共享這些信息
 
 

3.添加內購功能   

3.1iTunes Connect中給自己的應用添加消耗品定義  

 

 

3.2在iTunes Connect中給自己的應用添加 定義的商品 

 

 

 

3.3要使用內購,需要導入StoreKit框架  

 定義好的商品

#define kIAPBomb @"airplay.10bombs"

#define kIAPBullet @"airplay.laserBullet"

1. 實例化請求時,必須指定有效的identifiers集合,之所以如此處理,主要是為了確保提交的內購商品真的通過了蘋果的審批,處於可用狀態!

2. 要想獲取到准確的可用產品集合,需要通過代理方法實現

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response

3. 越獄用戶無法測試內購,但是可以購買

1 @interface ITViewController () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
2 {
3     // 產品字典
4     NSMutableDictionary *_productDict;
5 }
1 - (void)viewDidLoad
2 {
3     [super viewDidLoad];
4     
5     [self requestProducts];
6     
7     // 設置購買隊列的監聽器
8     [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
9 }

 

 

3.4.詢問蘋果的服務器能夠銷售哪些商品 

  

#pragma mark 詢問蘋果的服務器能夠銷售哪些商品
- (void)requestProducts
{
    // 能夠銷售的商品
    NSSet *set = [[NSSet alloc] initWithObjects:kIAPBomb, kIAPBullet, nil];
    
    // "異步"詢問蘋果能否銷售
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    
    request.delegate = self;
    
    // 啟動請求
    [request start];
}

 

3.5.獲取詢問結果,成功采取操作把商品加入可售商品字典里  

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    if (_productDict == nil) {
        _productDict = [NSMutableDictionary dictionaryWithCapacity:response.products.count];
    }
    
    for (SKProduct *product in response.products) {
        // 激活了對應的銷售操作按鈕,相當於商店的商品上架允許銷售
        NSLog(@"%@", product.productIdentifier);
        
        if ([product.productIdentifier isEqualToString:kIAPBullet]) {
            _bulletButton.enabled = YES;
        }
        
        if ([product.productIdentifier isEqualToString:kIAPBomb]) {
            _bombButton.enabled = YES;
        }
        
        // 填充商品字典
        [_productDict setObject:product forKey:product.productIdentifier];
    }
}

 

3.6.用戶決定購買商品   

 1 #pragma mark - 用戶決定購買商品
 2 - (void)buyProduct:(SKProduct *)product
 3 {
 4     // 要購買產品(店員給用戶開了個小票)
 5     SKPayment *payment = [SKPayment paymentWithProduct:product];
 6     
 7 //    // 設置購買隊列的監聽器
 8 //    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
 9     
10     // 去收銀台排隊,准備購買(異步網絡)
11     [[SKPaymentQueue defaultQueue] addPayment:payment];
12 }
1 - (IBAction)purchaseProducts
2 {
3     [self buyProduct:_productDict[kIAPBullet]];
4 }
5 
6 - (IBAction)purchaseBomb:(id)sender
7 {
8     [self buyProduct:_productDict[kIAPBomb]];
9 }

 

 

3.7.判斷購買狀態是否成功  

#pragma mark - SKPaymentTransaction Observer
#pragma mark 購買隊列狀態變化
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    // 調試
    for (SKPaymentTransaction *transaction in transactions) {
        NSLog(@"隊列狀態變化 %@", transaction);
        // 如果小票狀態是購買完成
        if (SKPaymentTransactionStatePurchased == transaction.transactionState) {
            NSLog(@"購買完成 %@", transaction.payment.productIdentifier);
            
            // 更新界面或者數據,把用戶購買得商品交給用戶
            // ...
            // 驗證購買憑據
            [self verifyPruchase];
            
            // 將交易從交易隊列中刪除
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        } else if (SKPaymentTransactionStateRestored == transaction.transactionState) {
            NSLog(@"恢復成功 %@", transaction.payment.productIdentifier);

            // 更新界面或者數據,把用戶購買得商品交給用戶
            // ...

            // 將交易從交易隊列中刪除
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
    }
}

 

3.8.給用戶提供恢復功能(因為在不同設備上永久性商品可能會出現需要恢復購買的情況)

#pragma mark - 恢復商品
- (void)restorePurchase
{
    // 恢復已經完成的所有交易.(僅限永久有效商品)
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}

 

 

3.9.驗證購買(防止第三方插件漏洞)iOS7新特性  

提示:雖然蘋果在iOS7提升了購買憑據的安全性,但是處於金錢考慮,購買完成后,一定要做憑據的驗證工作。

 1 #pragma mark 驗證購買憑據
 2 - (void)verifyPruchase
 3 {
 4     // 驗證憑據,獲取到蘋果返回的交易憑據
 5     // appStoreReceiptURL iOS7.0增加的,購買交易完成后,會將憑據存放在該地址
 6     NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
 7     // 從沙盒中獲取到購買憑據
 8     NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
 9     
10     // 發送網絡POST請求,對購買憑據進行驗證
11     NSURL *url = [NSURL URLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL];
12     // 國內訪問蘋果服務器比較慢,timeoutInterval需要長一點
13     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
14     
15     request.HTTPMethod = @"POST";
16     
17     // 在網絡中傳輸數據,大多情況下是傳輸的字符串而不是二進制數據
18     // 傳輸的是BASE64編碼的字符串
19     /**
20      BASE64 常用的編碼方案,通常用於數據傳輸,以及加密算法的基礎算法,傳輸過程中能夠保證數據傳輸的穩定性
21      BASE64是可以編碼和解碼的
22      */
23     NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
24     
25     NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
26     NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
27 
28     request.HTTPBody = payloadData;
29     
30     // 提交驗證請求,並獲得官方的驗證JSON結果
31     NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
32 
33     // 官方驗證結果為空
34     if (result == nil) {
35         NSLog(@"驗證失敗");
36     }
37     
38     NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
39     
40     NSLog(@"%@", dict);
41     
42     if (dict != nil) {
43         // 比對字典中以下信息基本上可以保證數據安全
44         // bundle_id&application_version&product_id&transaction_id
45         NSLog(@"驗證成功");
46     }
47 }

3.9.說說整個購買流程結構   

1.蘋果APP(商家)——— 2.告訴蘋果Store服務器要賣的商品 ——— 3.蘋果審核完(告訴你是否可以賣)

4.用戶(買商品)——— 5.蘋果APP(商家)——— 6.開發票給(用戶)————

7.用戶(拿着發票去蘋果Store服務器付款)——8.付款成功(用戶在APP里獲得服務商品)

 

(注意:如果要模擬測試內購,需要用真機才可以測試)

 

作者: 清澈Saup
出處: http://www.cnblogs.com/qingche/
本文版權歸作者和博客園共有,歡迎轉載,但必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM