標籤:server 介面 super end with 就會 修改 測試的 自己
一、介紹:
在個人開發的app上架到AppStore後,蘋果官方允許我們將自己的app在appstore上進行付費使用,也就是所謂的內購。其中,支付方式規定的必須是蘋果的支付方式:應用內支付。
二、流程:
1、後台設定
(1)配置Developer.apple.com,為應用建立一個不帶萬用字元的App ID
(2)用該應用的App ID產生和安裝相應的Provisioning Profile檔案
2、配置iTunes Connect
(1)用該App ID建立一個新的應用;
(2)在該應用中,建立應用內付費項目,選擇付費類型,通常可選的是可重複消費的(Consumenable)和永久有效(Non-Consumenable)兩種,然後設定好價格、Product ID、購買介紹和,這裡的Product ID是必須記住的,後面開發的時候要用到;
(3)添加一個用於在sandbox付費的測試使用者,注意蘋果對測試使用者的密碼要求和正是帳號一樣,至少8位,並且包包含數字和大小寫字母;
(4)填寫相關的稅務。銀行和連絡人
3、iOS端開發
(1)在工程中引入storeKit.framework和#import <storeKit/storeKit.h>;
(2)擷取所有的付費Product ID列表。這個可以用常量儲存到本地,也可以由自己的伺服器返回;
(3)製作一個介面(如tableView),顯示所有的應用內付費項目。這些應用內付費項目的價格和介紹資訊可以是自己的伺服器返回。但如果是不帶伺服器的單機遊戲應用或者工具類應用,則可以通過向App Store查詢所得;
(4)當使用者點擊一個IAP項目,我們需要先查詢使用者是否允許應用內付費,如果不允許則不進行接下來的步驟;
(5)先通過該IAP的ProductID向AppStore查詢,擷取SKPayment執行個體,然後通過SKPaymentQueue的addPayment方法發起一個購買的操作;
(6)在ViewdidLoad方法中,將購買版面設定成購買額observe;
(7)當使用者購買的操作有結果時,就會觸發調用回呼函數,相應的進行處理;
(8)伺服器驗證憑證(可選項)。如果購買成功,我們需要將憑證發送到伺服器上進行驗證。考慮到網路異常情況,iOS端的發送憑證操作應該可以持久化,如果程式退出、崩潰或者網路異常,可以恢複重試。
4、服務端開發
(1)接收iOS端發過來的購買憑證;
(2)判斷憑證是否已經存在,是否驗證過,然後進行儲存;
(3)將該憑證發送到蘋果的伺服器驗證,並將結果返回給用戶端;
(4)如果需要,修改使用者相應的會員許可權。
注意:考慮到網路異常的情況,伺服器的驗證應該是一個可恢複的隊列,如果失敗了,應該進行重試。
蘋果AppStore線上的購買憑證驗證地址:htpps://buy.itunes.apple.com/verifyreceipt
測試的驗證地址:htpps://sandbox.itunes.apple.com/verifyreceipt
三、iOS基本代碼如下:
// ViewController.m//// Created by 夏遠全 on 16/11/20.// Copyright ? 2016年 廣州市東德網路科技有限公司. All rights reserved.//#import "ViewController.h"#import <StoreKit/StoreKit.h>@interface ViewController ()<SKProductsRequestDelegate,SKPaymentTransactionObserver>@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //監聽購買結果 [[SKPaymentQueue defaultQueue] addTransactionObserver:self];}-(void)dealloc{ //移除購買監聽 [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];}//使用者點擊一個IAP項目時,首先查詢使用者是否允許應用內付費(tableViewCell點擊時,傳遞內購商品ProductId,ProductID可以提前儲存到本地,用到時直接擷取即可)-(void)validateIsCanBought{ if ([SKPaymentQueue canMakePayments]) { [self getProductInfo:@[@"ProductIds"]]; }else{ NSLog(@"失敗,使用者禁止應用內付費購買"); }}//通過該IAP的Product ID向App Store查詢,擷取SKPayment執行個體,接著通過SKPaymentQueue的addPayment方法發起一個購買的操作//下面的ProductId應該是事先在itunesConnect中添加好的,已存在的付費項目,否則會查詢失敗-(void)getProductInfo:(NSArray *)productIds{ NSSet *set = [NSSet setWithArray:productIds]; SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:set]; request.delegate = self; [request start];}#pragma mark - SKProductsRequestDelegate//查詢的回呼函數-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ //擷取到的所有內購商品 NSArray *myProducts = response.products; //判斷個數 if (myProducts.count==0) { NSLog(@"無法擷取產品資訊,購買失敗。"); return; } //發起一個購買操作 SKPayment *payment = [SKPayment paymentWithProduct:myProducts[0]]; [[SKPaymentQueue defaultQueue] addPayment:payment];}#pragma mark - SKPaymentTransactionObserver//當使用者購買的操作有結果時,就會觸發下面的回呼函數,相應進行處理-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{ for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: //交易完成 NSLog(@"transactionIdentifier = %@",transaction.transactionIdentifier); [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: //交易失敗 [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: //已經購買過該商品 [self restoreTransaction:transaction]; break; case SKPaymentTransactionStatePurchasing: //商品添加進列表 NSLog(@"商品添加進列表"); break; default: break; } }}//交易完成後的操作-(void)completeTransaction:(SKPaymentTransaction *)transaction{ NSString *productIdentifier = transaction.payment.productIdentifier; NSData *transactionReceiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]]; NSString *receipt = [transactionReceiptData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; if ([productIdentifier length]>0) { //向自己的伺服器驗證購買憑證 NSLog(@"%@",receipt); } //移除transaction購買操作 [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}//交易失敗後的操作-(void)failedTransaction:(SKPaymentTransaction *)transaction{ if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"購買失敗"); }else{ NSLog(@"使用者取消交易"); } //移除transaction購買操作 [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}//已經購買過該商品-(void)restoreTransaction:(SKPaymentTransaction *)transaction{ //對於已購買商品,處理恢複購買的邏輯 //移除transaction購買操作 [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}@end
參考書籍:唐巧《iOS開發進階》
iOS: 實現蘋果的內購