1內(nèi)購所需要的資料整理總結(jié)
思維導圖
重點總結(jié):
1.獲取內(nèi)購列表(從App內(nèi)讀取或從自己服務器讀取)
2.App Store請求可用的內(nèi)購列表
3.向用戶展示內(nèi)購列表
4.用戶選擇了內(nèi)購列表跪者,再發(fā)個購買請求棵帽,收到購買完成的回調(diào)(購買完成后會把錢打給申請內(nèi)購的銀行卡內(nèi))
5.購買流程結(jié)束后, 向服務器發(fā)起驗證憑證以及支付結(jié)果的請求
6.自己的服務器將支付結(jié)果信息返回給前端并發(fā)放虛擬產(chǎn)品
7.服務端的工作比較簡單,分4步:
7.1.接收ios端發(fā)過來的購買憑證坑夯。
7.2.判斷憑證是否已經(jīng)存在或驗證過岖寞,然后存儲該憑證。
7.3.將該憑證發(fā)送到蘋果的服務器驗證柜蜈,并將驗證結(jié)果返回給客戶端仗谆。
7.4.如果需要,修改用戶相應的會員權(quán)限淑履。
7.5.考慮到網(wǎng)絡異常情況隶垮,服務器的驗證應該是一個可恢復的隊列,如果網(wǎng)絡失敗了秘噪,應該進行重試狸吞。
簡單來說就是將該購買憑證用Base64編碼,然后POST給蘋果的驗證服務器指煎,蘋果將驗證結(jié)果以JSON形式返回蹋偏。
|
一、使用注意事項及遇到的坑
1.使用注意
1\. 代碼中的_currentProId所填寫的是你的購買項目的的ID至壤,這個和第二步創(chuàng)建的內(nèi)購的productID要一致威始,產(chǎn)品id與_currentProId一致。
2\. 在監(jiān)聽購買結(jié)果后像街,一定要調(diào)用[[SKPaymentQueue defaultQueue] finishTransaction:tran];來允許你從支付隊列中移除交易黎棠。
3\. 真機測試的時候,一定要退出原來的賬號(app store 登錄的賬號退出)镰绎,才能用沙盒測試賬號脓斩。
4\. 請務必使用真機來測試,一切以真機為準畴栖。
5\. 項目的Bundle identifier需要與您申請AppID時填寫的bundleID一致随静,不然會無法請求到商品信息。
6\. 沙盒環(huán)境測試appStore內(nèi)購流程的時候吗讶,請使用沒越獄的設備燎猛。
7\. 二次驗證叼丑,請注意區(qū)分宏, 測試用沙盒驗證扛门,App Store審核的時候也使用的是沙盒購買,所以驗證購買憑證的時候需要判斷返回Status Code決定是否去沙盒進行二次驗證纵寝,為了線上用戶的使用论寨,驗證的順序肯定是先驗證正式環(huán)境,此時若返回值為21007爽茴,就需要去沙盒二次驗證葬凳,因為此購買的是在沙盒進行的。
8.貨幣類型(Bank Account Currency) :填CNY(如果你的app在中國使用的話)室奏。
2.獲取不到商品信息
1.確定配置環(huán)節(jié)正確火焰。
2.確定是真機測試且手機沒有越獄。
3.確定內(nèi)購商品添加到了需要內(nèi)購功能的App中胧沫。
4.確定當前運行的App的Bundle ID和后臺配置的App的Bundle ID是一致的昌简。
5.可以嘗試先刪除舊App,再重新編譯生成新的绒怨,避免新App未覆蓋錯誤纯赎。
6.這里要提一點,沙盒的測試賬號和你請求商品信息沒有關(guān)系南蹂。請求商品信息的流程是犬金,你在后臺配置好了內(nèi)購商品,并且將其添加到了需要集成內(nèi)購功能的App中六剥,然后你請求商品晚顷。請求到商品后的流程是這樣的,蘋果系統(tǒng)會自動彈出登錄框讓你登錄賬號疗疟。然后根據(jù)提示操作進行購買该默,這里的賬號就是你配置的沙盒測試賬號。
二秃嗜、為什么要使用內(nèi)購权均?(why)和內(nèi)購是什么?(what)
1.如果你購買的商品锅锨,是在本app中使用和消耗的叽赊,就一定要用內(nèi)購,否則會被拒絕上線必搞,例如:游戲幣必指,在線書籍
app中使用的道具等。本例中恕洲,就是直播中你用來打賞用的金幣塔橡,那東西可就屬于消耗型的梅割。
2.如果是直接購買商城之類的快遞包郵的那些東東,那就直接調(diào)用支付寶葛家,微信啦户辞,之類的三方支付就好了,淘寶癞谒,京東都玩過哈底燎!
比較坑的一點就是,內(nèi)購的話弹砚,還要和蘋果3/7分成双仍,那就可以說,充值相同的錢桌吃,相對來說朱沃,iOS是比安卓虧的!
三茅诱、怎樣使用內(nèi)購逗物?(how)
1.使用內(nèi)購需要哪些資料<br> 1張visa銀行卡,appid瑟俭,1張銀行卡與蘋果三七分打錢用
(1)協(xié)議敬察、稅務和銀行業(yè)務
聯(lián)系人信息:(appid賬號人)姓名,郵箱尔当,電話號碼莲祸,地址(城市、具體街道分行寫)
visa銀行卡信息:開戶行椭迎,開戶行所在地址锐帜,開戶行的郵政編碼,開戶行持有人卡號畜号,開戶行持有人姓名
稅務信息:1.會問你是不是美國居民選擇NO. 2\. 有沒有在美國從事商業(yè)性活動缴阎,選擇NO. 之后填寫個人或組織名稱,所在國家简软,受益方式(獨立開發(fā)者選擇個人)蛮拔,居住地址,郵寄地址痹升,聲明人建炫,頭銜
(2)內(nèi)購產(chǎn)品id的配置 (開發(fā)人員配置)
如果是金幣或其它消耗品的產(chǎn)品的話用消耗性型項目,參考名稱(內(nèi)購項目疼蛾,比如金幣100),產(chǎn)品id,定價信息肛跌,使用內(nèi)購的快照,顯示名稱,描述衍慎。
(3)用戶職能
測試員:添加水箱測試員及沙箱賬號转唉,水箱測試賬號不能是正常使用的appid賬號,直接使用一個沒有注冊過的郵箱賬號即可稳捆。
姓名赠法,測試賬號密碼,appstore地區(qū)(必須填對)乔夯。
|
四期虾、操作流程圖解與代碼
1.創(chuàng)建app后填寫用戶信息
功能簡介 :
1.我的App主要用于管理自己的App應用,例如編輯資料驯嘱,上架,下架等喳坠。
2.銷售和趨勢主要是來查看App在各個平臺的下載量,收入等方面數(shù)據(jù)鞠评,里面有曲線圖等圖文結(jié)合的方式給我們參考。
3.付款和財務報告顯示的是你的收入以及付款等相關(guān)信息壕鹉。
4.iAd主要是跟廣告有關(guān)剃幌,開發(fā)者可以登錄到Workbench,通過iAd對應用的廣告進行控制晾浴。
5.用戶和職能用于生成相應賬號负乡,例如蘋果沙盒測試賬號。
6.協(xié)議脊凰,稅務和銀行業(yè)務則是你銀行相關(guān)賬戶的信息設置抖棘。
流程
1.注冊app,填寫協(xié)議、稅務和銀行業(yè)務
注冊app,需要設置Bundle identifier狸涌,此個步驟這里就不在寫了
填寫協(xié)議切省、稅務和銀行業(yè)務
|
|
<strong>選擇申請合同類型</strong>
頁面內(nèi)容:
Request Contracts(申請合同)
Contracts In Effect(已生效合同)。
合同類型:
iOS Free Application(免費應用合同)
iOS Paid Application(付費應用合同)
iAd App NetNetwork(廣告合同)
|
1.申請iOS Paid Application合同
2. 設置協(xié)議稅務帕胆、銀行卡信息
當我們點擊申請iOS Paid Application合同后朝捆,該合同的狀態(tài)會變成如下的樣子,我們可以看到其中Status為Contact懒豹, Bank, Pending Tax,
意思是聯(lián)系方式芙盘、銀行和稅務信息沒有填寫。
|
2.1設置聯(lián)系人信息
|
如果你沒有添加過聯(lián)系人脸秽,你需要通過Add New Contact按鈕來添加一個新的聯(lián)系人儒老。然后指定聯(lián)系人的職務,職務如下:
Senior Management:高管
Financial:財務
Technical:技術(shù)支持
Legal:法務
Marketing:市場推廣
如果你是獨立開發(fā)者记餐,可以全部填你自己一個人贷盲。
|
新增聯(lián)系人
通過新增或之前增加的聯(lián)系人設置高管等信息
待完成后點擊Done,返回后狀態(tài)會變成Edit狀態(tài)
2.2設置銀行卡信息(可以通過銀行名稱和地址直接上網(wǎng)查詢CNAPS Code號,不要問我上那查)
確認銀行卡信息
2.3設置稅務信息(1.是美國稅務,只需要這個就行巩剖,后面的澳大利亞和日本的和我們沒的關(guān)系)
選擇U.S Tax Forms铝穷,選擇后會問你兩個問題,第一個問題如下:詢問你是否是美國居民佳魔,有沒有美國伙伴關(guān)系或者美國公司曙聂,如果沒有直接選擇No。
|
|
接下來第二個問題如下:詢問你有沒有在美國的商業(yè)性活動鞠鲜,沒有也直接選No宁脊。
|
然后填寫稅務信息
|
然后填寫你的稅務信息,包括以下幾點:
Individual or Organization Name:個人或者組織名稱
Country of incorporation: 所在國家
Type of Beneficial Owner:受益方式贤姆,獨立開發(fā)者選個人
Permanent Residence:居住地址
Mailing address:郵寄地址
Name of Person Making ``this
Declaration:聲明人
Title:頭銜
當你填寫完所有資料后榆苞,合同狀態(tài)就會變成Processing,筆者凌晨1點左右提交霞捡,下午就通過了坐漏。
|
具體填寫見下圖(以下是確認稅務信息圖)
填寫完成后效果
** 3.配置內(nèi)購產(chǎn)品ID**
|
完成以上操作,并且蘋果審核完畢之后碧信,就可以配置內(nèi)購產(chǎn)品了赊琳。
登錄 iTunesConnect -->我的App 模塊找到需要內(nèi)購的App,最后找到頁面如下:
|
|
填寫沙箱測試員和添加內(nèi)購產(chǎn)品注意事項
1砰碴、郵箱必須是沒有注冊或者說關(guān)聯(lián)過appstore的郵箱躏筏。
2、密碼必須有一個是大寫字母有一個是小寫字母(蘋果規(guī)定的,理解)呈枉。
3趁尼、內(nèi)購屏幕截圖規(guī)格必須是312*290,且最低分辨率是72ppi猖辫。
4弱卡、內(nèi)購的價格是蘋果規(guī)定的不能自定義(坑啊)。
|
4.增加內(nèi)購測試賬號
** 4.1 內(nèi)購測試之前準備**
|
1住册、什么是內(nèi)購測試賬號(what)及為什么使用內(nèi)購測試賬號(why)?
iOS應用里面用到了蘋果應用內(nèi)付費(IAP)功能婶博,在項目上線前一定要進行功能測試。測試肯定是需要的荧飞,何況這個跟money有關(guān)凡人。。叹阔。開發(fā)完成了之后挠轴,如何進行測試呢?難道我測試個內(nèi)購功能要自己掏錢耳幢?就算是也是公司掏錢岸晦,但是蘋果要吃掉3成的啊欧啤,想想如果是99刀的商品,點下購買的時候心里都有點發(fā)慌启上。邢隧。。
蘋果當然沒這么坑了冈在,測試內(nèi)購倒慧,蘋果提供了沙盒賬號(也叫沙箱賬號)的方式。這個沙箱賬號其實是虛擬的AppleID包券,在開發(fā)者賬號后臺的iTune Connect上配置了之后就能使用沙盒賬號測試內(nèi)購纫谅,有了沙盒賬號,就能體驗一把土豪的感覺了溅固,游戲鉆石什么的隨便充付秕,反正不用我的錢。
注意:你可以把沙盒賬號看做是一個虛擬的AppleID侍郭,這個AppleID只有進行內(nèi)購測試的功能询吴。重要,重要励幼,重要,這個虛擬的賬號只能在自己的測試號中使用口柳,如果在其它地方如appstore使用的話會提示賬號無效之類的話苹粟。
2、如何使用內(nèi)購測試賬號(how)跃闹?
2.1作用內(nèi)購賬號的前提
1)內(nèi)購的商品ID嵌削,價格等相關(guān)信息已經(jīng)錄入到開發(fā)者后臺了(不然那你買什么)
2)開發(fā)者后臺已經(jīng)創(chuàng)建好沙盒測試賬號了(下面我們會將如何創(chuàng)建)
3)你要有一部真機(iPhone或iPad都行,別用模擬器就好望艺。而且不能是越獄機)
4)bundleID別搞錯了苛秕,開發(fā)者賬號、證書找默、bundleID要一致
5)如果你是第一次在這個開發(fā)者賬號上集成內(nèi)購功能艇劫,
請先將iTune Connect上的稅務協(xié)議都填寫好,否則內(nèi)購時會發(fā)現(xiàn)商品ID無效惩激。
重要店煞,如果不添加稅務協(xié)議會報錯,找不到商品风钻。
|
選擇用戶和職能就是在協(xié)議顷蟀、稅務和銀行業(yè)務左側(cè)
4.2內(nèi)購測試開始
|
1.在iPhone上安裝測試包(必須是打包簽名證書或者develop簽名證書打的包,不能是從App Store上下載的)
2.退出iPhone的App Store賬號(因為我們需要使用沙盒賬號登錄)骡技。
操作方法一:打開App Store應用首頁滑到最下方--選中AppleID--注銷
操作方法二:設置--iTunes Store與App Store--選中AppleID--注銷
3.不能用沙盒測試帳號來登錄appstore官網(wǎng)或去其它已上線平臺去支付詳見圖4.21
4.運行下面代碼的demo,傳入你創(chuàng)建的產(chǎn)品id(就是在app iTunes Connect ->我的app ->功能 ->app內(nèi)購買項目添加的商品)鸣个,點擊充值跳轉(zhuǎn)開始購買詳見圖4.22
5.再次購買時需要輸入測試沙盒賬號密碼(在用戶和職能->沙箱技術(shù)測試員創(chuàng)建的測試賬號)詳見圖4.23
6.購買成功反饋詳見圖4.24
|
4.21 圖
4.22 圖
4.23 圖
4.24 圖
5.代碼及業(yè)務邏輯
業(yè)務邏輯
獲取內(nèi)購列表(從App內(nèi)讀取或從自己服務器讀取)
App Store請求可用的內(nèi)購列表
向用戶展示內(nèi)購列表
用戶選擇了內(nèi)購列表,再發(fā)個購買請求囤萤,收到購買完成的回調(diào)(購買完成后會把錢打給申請內(nèi)購的銀行卡內(nèi))
購買流程結(jié)束后, 向服務器發(fā)起驗證憑證以及支付結(jié)果的請求
自己的服務器將支付結(jié)果信息返回給前端并發(fā)放虛擬產(chǎn)品
-
服務端的工作比較簡單昼窗,分4步:
- 接收ios端發(fā)過來的購買憑證。
- 判斷憑證是否已經(jīng)存在或驗證過阁将,然后存儲該憑證膏秫。
- 將該憑證發(fā)送到蘋果的服務器驗證,并將驗證結(jié)果返回給客戶端。
- 如果需要,修改用戶相應的會員權(quán)限加叁。
考慮到網(wǎng)絡異常情況剩拢,服務器的驗證應該是一個可恢復的隊列,如果網(wǎng)絡失敗了倚喂,應該進行重試。
簡單來說就是將該購買憑證用Base64編碼,然后POST給蘋果的驗證服務器帅刀,蘋果將驗證結(jié)果以JSON形式返回。
代碼如下 :
/*注意事項:
1.沙盒環(huán)境測試appStore內(nèi)購流程的時候远剩,請使用沒越獄的設備扣溺。
2.請務必使用真機來測試,一切以真機為準瓜晤。
3.項目的Bundle identifier需要與您申請AppID時填寫的bundleID一致锥余,不然會無法請求到商品信息。
4.如果是你自己的設備上已經(jīng)綁定了自己的AppleID賬號請先注銷掉,否則你哭爹喊娘都不知道是怎么回事痢掠。
5.訂單校驗 蘋果審核app時驱犹,仍然在沙盒環(huán)境下測試,所以需要先進行正式環(huán)境驗證足画,如果發(fā)現(xiàn)是沙盒環(huán)境則轉(zhuǎn)到沙盒驗證雄驹。
識別沙盒環(huán)境訂單方法:
1.根據(jù)字段 environment = sandbox。
2.根據(jù)驗證接口返回的狀態(tài)碼,如果status=21007淹辞,則表示當前為沙盒環(huán)境医舆。
蘋果反饋的狀態(tài)碼:
21000App Store無法讀取你提供的JSON數(shù)據(jù)
21002 訂單數(shù)據(jù)不符合格式
21003 訂單無法被驗證
21004 你提供的共享密鑰和賬戶的共享密鑰不一致
21005 訂單服務器當前不可用
21006 訂單是有效的,但訂閱服務已經(jīng)過期象缀。當收到這個信息時彬向,解碼后的收據(jù)信息也包含在返回內(nèi)容中
21007 訂單信息是測試用(sandbox),但卻被發(fā)送到產(chǎn)品環(huán)境中驗證
21008 訂單信息是產(chǎn)品環(huán)境中使用攻冷,但卻被發(fā)送到測試環(huán)境中驗證
*/
import <Foundation/Foundation.h>
typedef enum {
SIAPPurchSuccess = 0, // 購買成功
SIAPPurchFailed = 1, // 購買失敗
SIAPPurchCancle = 2, // 取消購買
SIAPPurchVerFailed = 3, // 訂單校驗失敗
SIAPPurchVerSuccess = 4, // 訂單校驗成功
SIAPPurchNotArrow = 5, // 不允許內(nèi)購
}SIAPPurchType;
typedef void (^IAPCompletionHandle)(SIAPPurchType type,NSData *data);
@interface STRIAPManager : NSObject
- (instancetype)shareSIAPManager;
//開始內(nèi)購
- (void)startPurchWithID:(NSString *)purchID completeHandle:(IAPCompletionHandle)handle;
@end
.m
import "STRIAPManager.h"
import <StoreKit/StoreKit.h>
@interface STRIAPManager()<SKPaymentTransactionObserver,SKProductsRequestDelegate>{
NSString *_purchID;
IAPCompletionHandle _handle;
}
@end
@implementation STRIAPManager
pragma mark - ??life cycle
-
(instancetype)shareSIAPManager{
static STRIAPManager *IAPManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
IAPManager = [[STRIAPManager alloc] init];
});
return IAPManager;
}
(instancetype)init{
self = [super init];
if (self) {
// 購買監(jiān)聽寫在程序入口,程序掛起時移除監(jiān)聽,這樣如果有未完成的訂單將會自動執(zhí)行并回調(diào) paymentQueue:updatedTransactions:方法
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}(void)dealloc{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
pragma mark - ??public
- (void)startPurchWithID:(NSString *)purchID completeHandle:(IAPCompletionHandle)handle{
if (purchID) {
if ([SKPaymentQueue canMakePayments]) {
// 開始購買服務
_purchID = purchID;
_handle = handle;
NSSet *nsset = [NSSet setWithArray:@[purchID]];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
request.delegate = self;
[request start];
}else{
[self handleActionWithType:SIAPPurchNotArrow data:nil];
}
}
}
pragma mark - ??private
- (void)handleActionWithType:(SIAPPurchType)type data:(NSData *)data{
if DEBUG
switch (type) {
case SIAPPurchSuccess:
NSLog(@"購買成功");
break;
case SIAPPurchFailed:
NSLog(@"購買失敗");
break;
case SIAPPurchCancle:
NSLog(@"用戶取消購買");
break;
case SIAPPurchVerFailed:
NSLog(@"訂單校驗失敗");
break;
case SIAPPurchVerSuccess:
NSLog(@"訂單校驗成功");
break;
case SIAPPurchNotArrow:
NSLog(@"不允許程序內(nèi)付費");
break;
default:
break;
}
endif
if(_handle){
_handle(type,data);
}
}
pragma mark - ??delegate
// 交易結(jié)束
-
(void)completeTransaction:(SKPaymentTransaction *)transaction{
// Your application should implement these two methods.
NSString * productIdentifier = transaction.payment.productIdentifier;
NSString * receipt = [transaction.transactionReceipt base64EncodedString];
if ([productIdentifier length] > 0) {
// 向自己的服務器驗證購買憑證
}[self verifyPurchaseWithPaymentTransaction:transaction isTestServer:NO];
}
// 交易失敗
-
(void)failedTransaction:(SKPaymentTransaction *)transaction{
if (transaction.error.code != SKErrorPaymentCancelled) {
[self handleActionWithType:SIAPPurchFailed data:nil];
}else{
[self handleActionWithType:SIAPPurchCancle data:nil];
}[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
} -
(void)verifyPurchaseWithPaymentTransaction:(SKPaymentTransaction *)transaction isTestServer:(BOOL)flag{
//交易驗證
NSURL *recepitURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:recepitURL];if(!receipt){
// 交易憑證為空驗證失敗
[self handleActionWithType:SIAPPurchVerFailed data:nil];
return;
}
// 購買成功將交易憑證發(fā)送給服務端進行再次校驗
[self handleActionWithType:SIAPPurchSuccess data:receipt];NSError *error;
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedStringWithOptions:0]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];if (!requestData) { // 交易憑證為空驗證失敗
[self handleActionWithType:SIAPPurchVerFailed data:nil];
return;
}//In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt
//In the real environment, use https://buy.itunes.apple.com/verifyReceiptNSString *serverString = @"https://buy.itunes.apple.com/verifyReceipt";
if (flag) {
serverString = @"https://sandbox.itunes.apple.com/verifyReceipt";
}
NSURL *storeURL = [NSURL URLWithString:serverString];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setHTTPBody:requestData];NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
// 無法連接服務器,購買校驗失敗
[self handleActionWithType:SIAPPurchVerFailed data:nil];
} else {
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (!jsonResponse) {
// 蘋果服務器校驗數(shù)據(jù)返回為空校驗失敗
[self handleActionWithType:SIAPPurchVerFailed data:nil];
}// 先驗證正式服務器,如果正式服務器返回21007再去蘋果測試服務器驗證,沙盒測試環(huán)境蘋果用的是測試服務器 NSString *status = [NSString stringWithFormat:@"%@",jsonResponse[@"status"]]; if (status && [status isEqualToString:@"21007"]) { [self verifyPurchaseWithPaymentTransaction:transaction isTestServer:YES]; }else if(status && [status isEqualToString:@"0"]){ [self handleActionWithType:SIAPPurchVerSuccess data:nil]; }
if DEBUG
NSLog(@"----驗證結(jié)果 %@",jsonResponse);
endif
}
}];
// 驗證成功與否都注銷交易,否則會出現(xiàn)虛假憑證信息一直驗證不通過,每次進程序都得輸入蘋果賬號
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSArray *product = response.products;
if([product count] <= 0){
if DEBUG
NSLog(@"--------------沒有商品------------------");
endif
return;
}
SKProduct *p = nil;
for(SKProduct *pro in product){
if([pro.productIdentifier isEqualToString:_purchID]){
p = pro;
break;
}
}
if DEBUG
NSLog(@"productID:%@", response.invalidProductIdentifiers);
NSLog(@"產(chǎn)品付費數(shù)量:%lu",(unsigned long)[product count]);
NSLog(@"%@",[p description]);
NSLog(@"%@",[p localizedTitle]);
NSLog(@"%@",[p localizedDescription]);
NSLog(@"%@",[p price]);
NSLog(@"%@",[p productIdentifier]);
NSLog(@"發(fā)送購買請求");
endif
SKPayment *payment = [SKPayment paymentWithProduct:p];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
//請求失敗
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
if DEBUG
NSLog(@"------------------錯誤-----------------:%@", error);
endif
}
- (void)requestDidFinish:(SKRequest *)request{
if DEBUG
NSLog(@"------------反饋信息結(jié)束-----------------");
endif
}
pragma mark - SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
for (SKPaymentTransaction *tran in transactions) {
switch (tran.transactionState) {
case SKPaymentTransactionStatePurchased:
[self completeTransaction:tran];
break;
case SKPaymentTransactionStatePurchasing:
if DEBUG
NSLog(@"商品添加進列表");
endif
break;
case SKPaymentTransactionStateRestored:
if DEBUG
NSLog(@"已經(jīng)購買過商品");
endif
// 消耗型不支持恢復購買
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:tran];
break;
default:
break;
}
}
}
@end
在控制器中調(diào)用娃胆,導入頭文件
調(diào)用方法
-
(void)purchaseAction{
if (!_IAPManager) {
_IAPManager = [STRIAPManager shareSIAPManager];
}
// iTunesConnect 蘋果后臺配置的產(chǎn)品ID
[_IAPManager startPurchWithID:@"com.bb.helper_advisory" completeHandle:^(SIAPPurchType type,NSData *data) {
//請求事務回調(diào)類型,返回的數(shù)據(jù)}];
}