iap如何初始化_IAP超级详解
在程序中添加Store功能
本章為添加購(gòu)買功能的指導(dǎo)
詳細(xì)流程:
準(zhǔn)備工作當(dāng)然是添加StoreKit.framework了。
然后是具體的步驟:
1. 決定在程序內(nèi)出售的商品的類型。
之前提到過,程序內(nèi)可以出售的新feature類型是有限制的。 Store Kit不允許我們下載新的代碼。 你的商品要么可以通過當(dāng)前的代碼工作(bundle類型),要么可以通過服務(wù)器下載(當(dāng)然,這里下載的為數(shù)據(jù)文件,代碼是不可以的)。 如果要修改源代碼,就只能老實(shí)的升級(jí)了。
2. 通過iTunes Connect注冊(cè)商品
每次添加新商品的時(shí)候都需要執(zhí)行這一步驟。 每個(gè)商品都需要一個(gè)唯一的商品標(biāo)識(shí)。 App Store通過這個(gè)標(biāo)識(shí)來(lái)查找商品信息并處理支付流程。 注冊(cè)商品標(biāo)識(shí)的方法和注冊(cè)程序的方法類似。
要了解如何創(chuàng)建和注冊(cè)商品信息,請(qǐng)參考“iTunes Connect Developer Guide”文檔。
3. 檢測(cè)是否可以進(jìn)行支付
用戶可以禁用在程序內(nèi)部支付的功能。在發(fā)送支付請(qǐng)求之前,程序應(yīng)該檢查該功能是否被開啟。程序可在顯示商店界面之前就檢查該設(shè)置(沒啟用就不顯示商店界面了),也可以在用戶發(fā)送支付請(qǐng)求前再檢查,這樣用戶就可以看到可購(gòu)買的商品列表了。
例子:
if([SKPaymentQueue canMakePayments])
{
...//Display a store to the user
}
else
{
...//Warn the user that purchases are disabled.
}
4. 獲得商品的信息
程序創(chuàng)建SKProductsRequest對(duì)象,用想要出售的商品的標(biāo)識(shí)來(lái)初始化, 然后附加上對(duì)應(yīng)的委托對(duì)象。 該請(qǐng)求的響應(yīng)包含了可用商品的本地化信息。
//這里發(fā)送請(qǐng)求
- (void)requestProductData
{
SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:
[NSSet setWithObject: kMyFeatureIdentifier]];
request.delegate = self;
[request start];
}
//這個(gè)是響應(yīng)的delegate方法
- (void)productsRequest: (SKProductsRequest *)request
didReceiveResponse: (SKProductsResponse *)response
{
NSArray *myProduct = response.products;
//生成商店的UI
[request autorelease];
}
5. 添加一個(gè)展示商品的界面
Store Kit不提供界面的類。 這個(gè)界面需要我們自己來(lái)設(shè)計(jì)并實(shí)現(xiàn)。
6. 為支付隊(duì)列(payment queue)注冊(cè)一個(gè)觀察者對(duì)象
你的程序需要初始化一個(gè)transaction observer對(duì)象并把它指定為payment queue的觀察者。
上代碼:
MyStoreObserver *observer = [[MyStoreObserver alloc]init];
[[SKPaymentQueue defaultQueue]addTransactionObserver: observer];
應(yīng)該在程序啟動(dòng)的時(shí)候就添加好觀察者,原因前面說過,重啟后程序會(huì)繼續(xù)上次未完的交易,這時(shí)就添加觀察者對(duì)象就不會(huì)漏掉之前的交易信息。
7. 在MyStoreObserver類中執(zhí)行paymentQueue: updatedTransactions: 方法。
這個(gè)方法會(huì)在有新的交易被創(chuàng)建,或者交易被更新的時(shí)候被調(diào)用。
- (void)paymentQueue: (SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions
{
for(SKPaymentTransaction * transaction in transactions)
{
switch(transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction: transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction: transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction: transaction];
default:
break;
}
}
}
上面的函數(shù)針對(duì)不同的交易返回狀態(tài),調(diào)用對(duì)應(yīng)的處理函數(shù)。
8. 觀察者對(duì)象在用戶成功購(gòu)買一件商品時(shí),提供相應(yīng)的內(nèi)容,以下是在交易成功后調(diào)用的方法
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
//你的程序需要實(shí)現(xiàn)這兩個(gè)方法
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
//將完成后的交易信息移出隊(duì)列
[[SKPaymentQueue defaultQueue]finishTransaction: transaction];
}
交易成功的信息包含transactionIdentifier和transactionReceipt的屬性。其中,transactionReceipt記錄了支付的詳細(xì)信息,這個(gè)信息可以幫助你跟蹤、審(我們的)查交易,如果你的程序是用服務(wù)器來(lái)交付內(nèi)容,transactionReceipt可以被傳送到服務(wù)器,然后通過App Store驗(yàn)證交易。(之前提到的server模式,可以參考以前的圖)
9. 如果交易是恢復(fù)過來(lái)的(restore),我們用這個(gè)方法來(lái)處理:
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
這個(gè)過程完成購(gòu)買的過程類似。 恢復(fù)的購(gòu)買內(nèi)容提供一個(gè)新的交易信息,這個(gè)信息包含了新的transaction的標(biāo)識(shí)和receipt數(shù)據(jù)。 如果需要的話,你可以把這些信息單獨(dú)保存下來(lái),供追溯審(我們的)查之用。但更多的情況下,在交易完成時(shí),你可能需要覆蓋原始的transaction數(shù)據(jù),并使用其中的商品標(biāo)識(shí)。
10. 交易過程失敗的話,我們調(diào)用如下的方法:
- (void)failedTransaction: (SKPaymentTransaction *)transaction
{
if(transaction.error.code != SKErrorPaymentCancelled)
{
//在這類顯示除用戶取消之外的錯(cuò)誤信息
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
通常情況下,交易失敗的原因是取消購(gòu)買商品的流程。 程序可以從error中讀出交易失敗的詳細(xì)信息。
顯示錯(cuò)誤信息不是必須的,但在上面的處理方法中,需要將失敗的交易從支付隊(duì)列中移除。 一般來(lái)說,我們用一個(gè)對(duì)話框來(lái)顯示錯(cuò)誤信息,這時(shí)就應(yīng)避免將用戶取消購(gòu)買這個(gè)error顯示出來(lái)。
11. 組織好程序內(nèi)“商店”的UI。當(dāng)用戶選擇一件商品時(shí), 創(chuàng)建一個(gè)支付對(duì)象,并放到隊(duì)列中。
SKPayment *payment = [SKPayment paymentWithProductIdentifier: kMyFeatureIdentifier];
[[SKPaymentQueue defaultQueue] addPayment: payment];
如果你的商店支持選擇同一件商品的數(shù)量,你可以設(shè)置支付對(duì)象的quantity屬性
SKMutablePayment *payment = [SKMutablePayment paymentWithProductIdentifier: kMyFeatureIdentifier];
payment.quantity = 3;
[[SKPaymentQueue defaultQueue] addPayment: payment];
下一步:
本章中所示代碼可用于內(nèi)置型商品模式(Built-in)。 如果你的程序要使用服務(wù)器來(lái)發(fā)布商品,你需要負(fù)責(zé)設(shè)計(jì)和執(zhí)行iPhone程序和你的服務(wù)器之間的通信。服務(wù)器應(yīng)該驗(yàn)證數(shù)據(jù)并為程序提供內(nèi)容。
驗(yàn)證store的收據(jù)
使用服務(wù)器來(lái)交付內(nèi)容,我們還需要做些額外的工作來(lái)驗(yàn)證從Store Kit發(fā)送的收據(jù)信息。
重要信息:來(lái)自Store的收據(jù)信息的格式是專用的。 你的程序不應(yīng)直接解析這類數(shù)據(jù)。可使用如下的機(jī)制來(lái)取出其中的信息。
驗(yàn)證App Store返回的收據(jù)信息
當(dāng)交易完成時(shí),Store Kit告知payment observer這個(gè)消息,并返回完成的transaction。 SKPaymentTransaction的transactionReceipt屬性就包含了一個(gè)經(jīng)過簽名的收據(jù)信息,其中記錄了交易的關(guān)鍵信息。你的服務(wù)器要負(fù)責(zé)提交收據(jù)信息來(lái)確定其有效性,并保證它未經(jīng)過篡改。 這個(gè)過程中,信息被以JSON數(shù)據(jù)格式發(fā)送給App Store,App Store也以JSON的格式返回?cái)?shù)據(jù)。
(大家可以先了解一下JSON的格式)
驗(yàn)證收據(jù)的過程:
1. 從transaction的transactionReceipt屬性中得到收據(jù)的數(shù)據(jù),并以base64方式編碼。
2. 創(chuàng)建JSON對(duì)象,字典格式,單鍵值對(duì),鍵名為"receipt-data", 值為上一步編碼后的數(shù)據(jù)。效果為:
{
"receipt-data"????: "(編碼后的數(shù)據(jù))"
}
3. 發(fā)送HTTP POST的請(qǐng)求,將數(shù)據(jù)發(fā)送到App Store,其地址為:
https://buy.itunes.apple.com/verfyReceipt
4. App Store的返回值也是一個(gè)JSON格式的對(duì)象,包含兩個(gè)鍵值對(duì), status和receipt:
{
"status"????: 0,
"receipt"????: { … }
}
如果status的值為0, 就說明該receipt為有效的。 否則就是無(wú)效的。
App Store的收據(jù)
發(fā)送給App Store的收據(jù)數(shù)據(jù)是通過對(duì)transaction中對(duì)應(yīng)的信息編碼而創(chuàng)建的。 當(dāng)App Store驗(yàn)證收據(jù)時(shí), 將從其中解碼出數(shù)據(jù),并以"receipt"的鍵返回。 返回的響應(yīng)信息是JSON格式,被包含在SKPaymentTransaction的對(duì)象中(transactionReceipt屬性)。Server可通過這些值來(lái)了解交易的詳細(xì)信息。 Apple建議只發(fā)送receipt數(shù)據(jù)到服務(wù)器并使用receipt數(shù)據(jù)驗(yàn)證和獲得交易詳情。 因?yàn)锳pp Store可驗(yàn)證收據(jù)信息,返回信息,保證信息不被篡改,這種方式比同時(shí)提交receipt和transaction的數(shù)據(jù)要安全。(這段得再看看)
表5-1為交易信息的所有鍵,很多的鍵都對(duì)應(yīng)SKPaymentTransaction的屬性。
備注:一些鍵取決于你的程序是鏈接到App Store還是測(cè)試用的Sandbox環(huán)境。更多關(guān)于sandbox的信息,請(qǐng)查看"Testing a Store"一章。
Table 5-1 購(gòu)買信息的鍵:
鍵名????????描述
quantity???? 購(gòu)買商品的數(shù)量。對(duì)應(yīng)SKPayment對(duì)象中的quantity屬性
product_id????商品的標(biāo)識(shí),對(duì)應(yīng)SKPayment對(duì)象的productIdentifier屬性。
transaction_id????????交易的標(biāo)識(shí),對(duì)應(yīng)SKPaymentTransaction的transactionIdentifier屬性
purchase_date????交易的日期,對(duì)應(yīng)SKPaymentTransaction的transactionDate屬性
original_-transaction_id????對(duì)于恢復(fù)的transaction對(duì)象,該鍵對(duì)應(yīng)了原始的transaction標(biāo)識(shí)
original_purchase_-date????對(duì)于恢復(fù)的transaction對(duì)象,該鍵對(duì)應(yīng)了原始的交易日期
app_item_id????App Store用來(lái)標(biāo)識(shí)程序的字符串。一個(gè)服務(wù)器可能需要支持多個(gè)server的支付功能,可以用這個(gè)標(biāo)識(shí)來(lái)區(qū)分程序。鏈接sandbox用來(lái)測(cè)試的程序的不到這個(gè)值,因此該鍵不存在。
version_external_-identifier????用來(lái)標(biāo)識(shí)程序修訂數(shù)。該鍵在sandbox環(huán)境下不存在
bid????iPhone程序的bundle標(biāo)識(shí)
bvrs????iPhone程序的版本號(hào)
測(cè)試Store功能
開發(fā)過程中,我們需要測(cè)試支付功能以保證其工作正常。然而,我們不希望在測(cè)試時(shí)對(duì)用戶收費(fèi)。 Apple提供了sandbox的環(huán)境供我們測(cè)試。
備注:Store Kit在模擬器上無(wú)法運(yùn)行。 當(dāng)在模擬器上運(yùn)行Store Kit的時(shí)候,訪問payment queue的動(dòng)作會(huì)打出一條警告的log。測(cè)試store功能必須在真機(jī)上進(jìn)行。
Sandbox環(huán)境
使用Sandbox環(huán)境的話,Store Kit并沒有鏈接到真實(shí)的App Store,而是鏈接到專門的Sandbox環(huán)境。 SandBox的內(nèi)容和App Store一致,只是它不執(zhí)行真實(shí)的支付動(dòng)作。 它會(huì)返回交易成功的信息。 Sandbox使用專門的iTunes Connect測(cè)試 賬戶。不能使用正式的iTunes Connect賬戶來(lái)測(cè)試。
要測(cè)試程序,需要?jiǎng)?chuàng)建一個(gè)專門的測(cè)試賬戶。你至少需要為程序的每個(gè)區(qū)域創(chuàng)建至少一個(gè)測(cè)試賬戶。詳細(xì)信息,請(qǐng)查看iTunes Connect Developer Guide文檔。
在Sandbox環(huán)境中測(cè)試
步驟:
1. 在測(cè)試的iPhone上退出iTunes賬戶
Settings中可能會(huì)記錄之前登錄的賬戶,進(jìn)入并退出。
重要信息:不能在Settings 程序中通過測(cè)試賬戶登錄。
2. 運(yùn)行程序
當(dāng)你在程序的store中購(gòu)買商品后,Store kit提示你去驗(yàn)證交易。用測(cè)試賬戶登錄,并批準(zhǔn)支付。 這樣虛擬的交易就完成了。
在Sandbox中驗(yàn)證收據(jù)
驗(yàn)證的URL不同了:
NSURL *sandboxStoreURL = [[NSURL alloc]initWithString:
@"https://sandbox.itunes.apple.com/verifyReceipt"];
總結(jié)
以上是生活随笔為你收集整理的iap如何初始化_IAP超级详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qmenubar无边框 qt_Qt UI
- 下一篇: python性能优化之函数执行时间分析_