開(kāi)篇:關(guān)于iOS內(nèi)購(gòu)整體流程網(wǎng)上能找到很多。我抽絲剝繭羹蚣,著重說(shuō)一下二次驗(yàn)證及收據(jù)回傳的數(shù)據(jù)問(wèn)題。
二次驗(yàn)證
關(guān)于二次驗(yàn)證乱凿,其實(shí)有兩種做法顽素,第一種是在app端驗(yàn)證,第二種也是安全防盜的一種徒蟆,在服務(wù)端進(jìn)行驗(yàn)證胁出。
具體區(qū)別不一一表述,可以查看下面的鏈接段审。
iOS二次驗(yàn)證兩種做法的區(qū)別
我要著重說(shuō)的是二次驗(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í)際開(kāi)發(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)行購(gòu)買驗(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)證購(gòu)買過(guò)程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription);
return;
}
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
二甘畅、收據(jù)回傳得到的數(shù)據(jù)分析
上文得到的dic就是我們通過(guò)收據(jù)得到的所有數(shù)據(jù)
在這里有個(gè)坑埂蕊,我相信有很多同學(xué)都踩過(guò)。
就是你支付成功了疏唾,但是在這個(gè)數(shù)組里卻找不到你想要的數(shù)據(jù)蓄氧。
我們可以看下面一張圖,然后再分析分析槐脏。
可以看到有四種類型喉童,但是具體到我們項(xiàng)目中我們?cè)撊绾芜x擇和操作呢。
1.消耗型:比如我們游戲里的金幣顿天,6元600個(gè)金幣堂氯,你使用完了就失效了。比如現(xiàn)在各大視頻app推出的電影購(gòu)買牌废,6元買完一張影片之后咽白,你如果想買下一張影片就必須再次購(gòu)買。
2.非消耗型:比如某app推出永久會(huì)員鸟缕,購(gòu)買一次終身使用晶框,就是非消耗型。再比如游戲過(guò)關(guān)時(shí)app的某關(guān)懂从,你一直過(guò)不去授段,花錢購(gòu)買過(guò)去了,等你下次再打開(kāi)app時(shí)番甩,他這關(guān)默認(rèn)是已經(jīng)通過(guò)的畴蒲。
3.自動(dòng)續(xù)訂型:具體可以看愛(ài)奇藝視頻開(kāi)通會(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è),不然像愛(ài)奇藝的自動(dòng)續(xù)訂补胚,用戶不知情時(shí)码耐,會(huì)被罵死,哈哈
說(shuō)了這么多溶其,來(lái)看看訂單數(shù)據(jù)長(zhǎng)啥樣
{
product_id = "lalalalahahaha",//商品的標(biāo)識(shí)骚腥,和產(chǎn)品定,隨便寫但是不能重復(fù)
quantity = "1",//購(gòu)買商品的數(shù)量
transaction_id = "1000000357637984",//交易的標(biāo)識(shí)
purchase_date_ms = "1512613065000",//購(gòu)買時(shí)間毫秒
original_purchase_date_pst = "2017-12-06 18:17:45 America/Los_Angeles",//購(gòu)買時(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",//原始購(gòu)買時(shí)間
original_transaction_id = "1000000357637984",//原始交易ID
purchase_date = "2017-12-07 02:17:45 Etc/GMT"http://購(gòu)買時(shí)間
},
我們得到的字典里如果有多條數(shù)據(jù)瓶逃,就會(huì)有一個(gè)數(shù)組in_app束铭。
如果只有一條數(shù)據(jù),或者沒(méi)有數(shù)據(jù)厢绝,就沒(méi)有in_app契沫。
in_app里的數(shù)據(jù)格式就如上文代碼所書。
所有的訂單信息都在in_app里昔汉。所以我們要找到最新成功的那條數(shù)據(jù)懈万,就需要在這里面去找。
注:
1.消耗性的和其他的有區(qū)別靶病,消耗性的下一次購(gòu)買的钞速,會(huì)覆蓋上一次購(gòu)買的,所以只有一條消耗性的訂單信息嫡秕,當(dāng)然也是最新的渴语。
2.其他三種每次購(gòu)買,都會(huì)生成新的訂單信息昆咽,不會(huì)覆蓋原來(lái)的驾凶,所以你購(gòu)買多少次,上面就會(huì)顯示多少條掷酗。
三调违、內(nèi)購(gòu)二次驗(yàn)證實(shí)際開(kāi)發(fā)中具體做法
1.我們把收據(jù)信息傳給服務(wù)器
2.服務(wù)器自行處理所有的訂單信息,返回一個(gè)成功與失敗的狀態(tài)給我們泻轰。所有的操作技肩,后臺(tái)都已經(jīng)記錄在案了,我們不再需要管浮声。我們只需要知道虚婿,此次購(gòu)買是否成功就行了。
結(jié)語(yǔ):內(nèi)購(gòu)其實(shí)很簡(jiǎn)單泳挥,只是有時(shí)候不經(jīng)意就會(huì)入坑然痊,在此特意記錄下困惑的地方,幫助自己深刻記憶屉符,也希望幫助到其他遇到該問(wèn)題的童鞋剧浸。