開篇:關(guān)于iOS內(nèi)購整體流程網(wǎng)上能找到很多。我抽絲剝繭,著重說一下二次驗(yàn)證及收據(jù)回傳的數(shù)據(jù)問題。
二次驗(yàn)證
關(guān)于二次驗(yàn)證,其實(shí)有兩種做法,第一種是在app端驗(yàn)證,第二種也是安全防盜的一種,在服務(wù)端進(jìn)行驗(yàn)證。
具體區(qū)別不一一表述,可以查看下面的鏈接。
iOS二次驗(yàn)證兩種做法的區(qū)別
我要著重說的是二次驗(yàn)證的實(shí)際做法和收到的數(shù)據(jù)是什么。
一、二次驗(yàn)證具體如何驗(yàn)證
在這分為測(cè)試地址和實(shí)際上線地址
測(cè)試:https://sandbox.itunes.apple.com/verifyReceipt
已上線Appstore:https://buy.itunes.apple.com/verifyReceipt
在沙箱測(cè)試時(shí),我們使用測(cè)試地址。
// 從沙盒中獲取交易憑證(收據(jù))
NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
// 轉(zhuǎn)化為base64字符串
NSString *receiptString = [receiptData base64EncodedStringWithOptions:0];
為了方便拿到數(shù)據(jù),我們?cè)赼pp端上進(jìn)行驗(yàn)證,注意??實(shí)際開發(fā)中都是在服務(wù)端進(jìn)行驗(yàn)證的。
// 拼接請(qǐng)求數(shù)據(jù)
NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];
NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
// 創(chuàng)建請(qǐng)求到蘋果官方進(jìn)行購買驗(yàn)證
NSURL *url = [NSURL URLWithString:verifyReceipt_url];
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
requestM.HTTPBody = bodyData;
requestM.HTTPMethod = @"POST";
// 創(chuàng)建連接并發(fā)送同步請(qǐng)求
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
if (error) {
NSLog(@"驗(yàn)證購買過程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription);
return;
}
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
二、收據(jù)回傳得到的數(shù)據(jù)分析
上文得到的dic就是我們通過收據(jù)得到的所有數(shù)據(jù)
在這里有個(gè)坑,我相信有很多同學(xué)都踩過。
就是你支付成功了,但是在這個(gè)數(shù)組里卻找不到你想要的數(shù)據(jù)。
我們可以看下面一張圖,然后再分析分析。

可以看到有四種類型,但是具體到我們項(xiàng)目中我們?cè)撊绾芜x擇和操作呢。
1.消耗型:比如我們游戲里的金幣,6元600個(gè)金幣,你使用完了就失效了。比如現(xiàn)在各大視頻app推出的電影購買,6元買完一張影片之后,你如果想買下一張影片就必須再次購買。
2.非消耗型:比如某app推出永久會(huì)員,購買一次終身使用,就是非消耗型。再比如游戲過關(guān)時(shí)app的某關(guān),你一直過不去,花錢購買過去了,等你下次再打開app時(shí),他這關(guān)默認(rèn)是已經(jīng)通過的。
3.自動(dòng)續(xù)訂型:具體可以看愛奇藝視頻開通會(huì)員(騰訊app也類似),里面就有一個(gè)自動(dòng)續(xù)訂會(huì)員。也就是到期了,它會(huì)自動(dòng)從你的蘋果賬號(hào)上扣錢。這個(gè)慎點(diǎn)慎點(diǎn),他們這樣搞很坑錢。
4.非自動(dòng)續(xù)訂型:這個(gè)就是1個(gè)月優(yōu)酷會(huì)員啦,或者3個(gè)月季度會(huì)員啥的。有期限,到期時(shí)也不會(huì)自動(dòng)扣錢。一般的都是選擇這個(gè),不然像愛奇藝的自動(dòng)續(xù)訂,用戶不知情時(shí),會(huì)被罵死,哈哈
說了這么多,來看看訂單數(shù)據(jù)長啥樣
{
product_id = "lalalalahahaha",//商品的標(biāo)識(shí),和產(chǎn)品定,隨便寫但是不能重復(fù)
quantity = "1",//購買商品的數(shù)量
transaction_id = "1000000357637984",//交易的標(biāo)識(shí)
purchase_date_ms = "1512613065000",//購買時(shí)間毫秒
original_purchase_date_pst = "2017-12-06 18:17:45 America/Los_Angeles",//購買時(shí)間,太平洋標(biāo)準(zhǔn)時(shí)間
purchase_date_pst = "2017-12-06 18:17:45 America/Los_Angeles",//太平洋標(biāo)準(zhǔn)時(shí)間
original_purchase_date_ms = "1512613065000",//毫秒
is_trial_period = "false",
original_purchase_date = "2017-12-07 02:17:45 Etc/GMT",//原始購買時(shí)間
original_transaction_id = "1000000357637984",//原始交易ID
purchase_date = "2017-12-07 02:17:45 Etc/GMT"http://購買時(shí)間
},
我們得到的字典里如果有多條數(shù)據(jù),就會(huì)有一個(gè)數(shù)組in_app。
如果只有一條數(shù)據(jù),或者沒有數(shù)據(jù),就沒有in_app。
in_app里的數(shù)據(jù)格式就如上文代碼所書。
所有的訂單信息都在in_app里。所以我們要找到最新成功的那條數(shù)據(jù),就需要在這里面去找。
注:
1.消耗性的和其他的有區(qū)別,消耗性的下一次購買的,會(huì)覆蓋上一次購買的,所以只有一條消耗性的訂單信息,當(dāng)然也是最新的。
2.其他三種每次購買,都會(huì)生成新的訂單信息,不會(huì)覆蓋原來的,所以你購買多少次,上面就會(huì)顯示多少條。
三、內(nèi)購二次驗(yàn)證實(shí)際開發(fā)中具體做法
1.我們把收據(jù)信息傳給服務(wù)器
2.服務(wù)器自行處理所有的訂單信息,返回一個(gè)成功與失敗的狀態(tài)給我們。所有的操作,后臺(tái)都已經(jīng)記錄在案了,我們不再需要管。我們只需要知道,此次購買是否成功就行了。
結(jié)語:內(nèi)購其實(shí)很簡(jiǎn)單,只是有時(shí)候不經(jīng)意就會(huì)入坑,在此特意記錄下困惑的地方,幫助自己深刻記憶,也希望幫助到其他遇到該問題的童鞋。