一垫蛆、IAP
In-App Purchase禽最,應(yīng)用內(nèi)購(gòu)買。注意袱饭,IAP與ApplePay不是同一回事川无,ApplePay純粹是一種支付方式,同微信支付虑乖、支付寶類似懦趋;而IAP是一種App內(nèi)部購(gòu)買的方式,購(gòu)買時(shí)付款的方式是需要提前在蘋果帳戶中設(shè)置的决左,可以選擇微信支付愕够、支付寶、ApplePay佛猛、銀行卡等。
二坠狡、4種商品類型
(1)消耗性商品:使用后就被消耗掉继找,需要再購(gòu)買的商品。比如逃沿,釣魚(yú)App中的魚(yú)食,App中的金幣;
(2)非消耗性商品:購(gòu)買后可永久使用的商品沸伏。比如须尚,讀書(shū)App中的書(shū)籍,購(gòu)買后可永久閱讀假消;游戲App中的賽道柠并;
(3)自動(dòng)續(xù)期訂閱商品:允許在固定時(shí)間段內(nèi)購(gòu)買動(dòng)態(tài)內(nèi)容的商品,如果購(gòu)買后不手動(dòng)取消富拗,將自動(dòng)續(xù)期自動(dòng)付費(fèi)臼予。比如,每月訂閱提供流媒體服務(wù)的App啃沪;
(4)非自動(dòng)續(xù)期訂閱商品:有時(shí)限性服務(wù)的商品粘拾,不自動(dòng)續(xù)期。比如创千,App提供的VIP特權(quán)服務(wù)缰雇;
三入偷、開(kāi)發(fā)步驟:
(1)在iTunesConnect中填寫協(xié)議、稅務(wù)械哟、銀行等信息疏之,創(chuàng)建配置內(nèi)購(gòu)商品,將商品添加到App中戒良;
(2)Xcode中配置內(nèi)購(gòu)
(3)編寫代碼
(4)沙箱測(cè)試
(5)提審上線
四体捏、內(nèi)購(gòu)流程:
(1)從本地或服務(wù)器獲取可購(gòu)買的商品ID列表;
(2)從App Store獲取商品ID對(duì)應(yīng)的商品信息糯崎;
(3)用戶選擇某一商品點(diǎn)擊購(gòu)買按鈕后几缭,請(qǐng)求服務(wù)端生成訂單
(4)應(yīng)用獲取訂單號(hào)后,向App Store發(fā)起交易請(qǐng)求沃呢,并監(jiān)聽(tīng)交易狀態(tài)年栓;
(5)App Store處理交易請(qǐng)求,從蘋果賬戶扣款薄霜;
(6)App Store交易成功某抓,應(yīng)用監(jiān)聽(tīng)到交易成功狀態(tài);交易失敗惰瓜,則移除交易并提示購(gòu)買失敺窀薄;
(7)應(yīng)用獲取到交易票據(jù)崎坊;
(8)應(yīng)用將票據(jù)和訂單號(hào)提交到服務(wù)器备禀,由服務(wù)器向App Store請(qǐng)求驗(yàn)證票據(jù)。注意對(duì)于沙盒環(huán)境和正式環(huán)境奈揍,App Store驗(yàn)證票據(jù)的URL是不同的曲尸;
(9)服務(wù)器判斷訂單號(hào)不存在,或票據(jù)中的交易號(hào)已存在男翰,則通知應(yīng)用移除交易另患,購(gòu)買失敗蛾绎;
(9)驗(yàn)證成功后昆箕,服務(wù)器保存用戶購(gòu)買記錄(訂單號(hào)、交易號(hào)秘通、用戶賬號(hào)等)为严,并向用戶發(fā)放相應(yīng)商品,即修改服務(wù)器上用戶的數(shù)據(jù)肺稀,并通知應(yīng)用購(gòu)買成功更新界面第股;如果驗(yàn)證失敗,也通知應(yīng)用话原;
(10)應(yīng)用收到票據(jù)驗(yàn)證成功的反饋后夕吻,標(biāo)記該交易完成狀態(tài)诲锹,提示用戶購(gòu)買成功,并更新界面涉馅,并刪除本地票據(jù)归园;
(11)應(yīng)用收到票據(jù)驗(yàn)證失敗的反饋后,如果錯(cuò)誤碼為21007稚矿,說(shuō)明當(dāng)前票據(jù)為沙盒測(cè)試票據(jù)庸诱,但卻連接App Store正式環(huán)境進(jìn)行了票據(jù)驗(yàn)證,故需要連接App Store沙盒環(huán)境再次驗(yàn)證票據(jù)晤揣;
(12)應(yīng)用收到票據(jù)驗(yàn)證失敗的反饋桥爽,如果確定票據(jù)無(wú)效,可提示購(gòu)買失敗昧识,并標(biāo)記交易完成钠四,以便將交易移出交易隊(duì)列;對(duì)于需要重新驗(yàn)證的票據(jù)跪楞,可以隔一段時(shí)間或者App重啟時(shí)重新請(qǐng)求驗(yàn)證缀去,直到驗(yàn)證成功才標(biāo)記交易完成。
10票據(jù)驗(yàn)證:
(1)兩種票據(jù)內(nèi)容甸祭。一種是付費(fèi)下載的App的票據(jù)缕碎;另一種是App內(nèi)部購(gòu)買商品的票據(jù);
(2)從App Store安裝App后池户,會(huì)自動(dòng)在App的沙盒的StoreKit目錄下創(chuàng)建票據(jù)文件receipt阎曹;
(3)票據(jù)文件receipt中,內(nèi)購(gòu)項(xiàng)目可能為空煞檩,也可能同時(shí)存在多個(gè)內(nèi)購(gòu)項(xiàng)目,只要數(shù)據(jù)正確栅贴,驗(yàn)證票據(jù)都會(huì)成功斟湃;
(4)對(duì)于購(gòu)買的訂閱類商品、非消耗性商品檐薯,購(gòu)買信息會(huì)永久保存在票據(jù)文件中凝赛;
(5)對(duì)于消耗性商品,購(gòu)買信息在交易付款后保存到票據(jù)中坛缕,一旦交易被標(biāo)識(shí)為完成墓猎,該信息會(huì)在請(qǐng)求刷新票據(jù),或者下次交易更新票據(jù)時(shí)被清除掉赚楚;
(6)iOS7以后毙沾,票據(jù)數(shù)據(jù)可以從沙盒中讀取宠页;iOS7以前左胞,票據(jù)數(shù)據(jù)可以從交易對(duì)象的transactionReceipt屬性中獲瓤懿帧;如果本地沒(méi)有票據(jù)數(shù)據(jù)烤宙,可以向App Store請(qǐng)求票據(jù)數(shù)據(jù)遍烦;
App Store票據(jù)驗(yàn)證接口參數(shù):
(1)"receipt-data":base64編碼的票據(jù)數(shù)據(jù)data;
(2)"password": 共享密碼躺枕,僅在購(gòu)買自動(dòng)續(xù)期訂閱商品時(shí)需要服猪;
App Store票據(jù)驗(yàn)證返回JSON格式:
(1)"status": 0為驗(yàn)證成功;
(2)"receipt": 提交的票據(jù)原數(shù)據(jù)拐云;
Receipt票據(jù)數(shù)據(jù)格式:
{
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = 1;
"bundle_id" = "com.test.xxx";
"download_id" = 0;
"in_app" = (
{
"is_trial_period" = false;
"original_purchase_date" = "2017-12-14 07:18:56 Etc/GMT";
"original_purchase_date_ms" = 1513235936000;
"original_purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
"original_transaction_id" = 1000000359369424;
"product_id" = "com.test.product1";
"purchase_date" = "2017-12-14 07:18:56 Etc/GMT";
"purchase_date_ms" = 1513235936000;
"purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000359369424;
},
...
);
"original_application_version" = "1.0";
"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
"original_purchase_date_ms" = 1375340400000;
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
"receipt_creation_date" = "2017-12-14 07:18:56 Etc/GMT";
"receipt_creation_date_ms" = 1513235936000;
"receipt_creation_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2017-12-14 07:19:23 Etc/GMT";
"request_date_ms" = 1513235963829;
"request_date_pst" = "2017-12-13 23:19:23 America/Los_Angeles";
"version_external_identifier" = 0;
};
服務(wù)端驗(yàn)證接口參數(shù):
(1)base64編碼的票據(jù)數(shù)據(jù)字符串罢猪;
(2)服務(wù)端訂單號(hào);
(3)驗(yàn)證環(huán)境標(biāo)識(shí)(沙盒環(huán)境或正式環(huán)境)慨丐;
(4)用戶ID坡脐;
(5)所有接口參數(shù)應(yīng)該加密后傳輸;
服務(wù)端驗(yàn)證邏輯:
(1)解密接口參數(shù)房揭,提取出票據(jù)數(shù)據(jù)备闲、訂單號(hào)、驗(yàn)證環(huán)境捅暴、用戶ID恬砂;
(2)如果票據(jù)數(shù)據(jù)為空,或驗(yàn)證環(huán)境參數(shù)錯(cuò)誤蓬痒,返回參數(shù)錯(cuò)誤的錯(cuò)誤碼泻骤;否則進(jìn)行下一步;
(3)查詢訂單是否存在:
(3.1)如果訂單存在且已完成(訂單對(duì)應(yīng)交易ID已存在)梧奢,則無(wú)需再驗(yàn)證票據(jù)數(shù)據(jù)狱掂。如果用戶ID與訂單所屬用戶相同,則返回用戶的所有商品信息和重復(fù)驗(yàn)證票據(jù)的返回碼亲轨,否則只返回重復(fù)驗(yàn)證票據(jù)的返回碼而不返回用戶所有商品信息趋惨;
(3.2)如果訂單存在且未完成(訂單對(duì)應(yīng)交易ID不存在),則進(jìn)入下一步驗(yàn)證票據(jù)數(shù)據(jù)惦蚊;
(3.3)如果訂單不存在器虾,則查詢票據(jù)中交易ID是否已有對(duì)應(yīng)訂單。如果沒(méi)有訂單蹦锋,則返回訂單不存在的錯(cuò)誤碼兆沙;如果有訂單,則進(jìn)入下一步驗(yàn)證票據(jù)數(shù)據(jù)莉掂;
(4)驗(yàn)證票據(jù)數(shù)據(jù)葛圃。調(diào)用蘋果提供的票據(jù)驗(yàn)證接口進(jìn)行驗(yàn)證。沙盒環(huán)境驗(yàn)證接口:https://sandbox.itunes.apple.com/verifyReceipt,正式環(huán)境驗(yàn)證接口:https://buy.itunes.apple.com/verifyReceipt装悲。如果驗(yàn)證失敗昏鹃,將蘋果返回的狀態(tài)碼作為錯(cuò)誤碼返回給客戶端,如果驗(yàn)證成功诀诊,則向訂單對(duì)應(yīng)用戶發(fā)放商品洞渤;如果驗(yàn)證成功(狀態(tài)碼為0)且用戶ID與訂單所屬用戶相同,則同時(shí)返回用戶所有商品信息属瓣;
服務(wù)端驗(yàn)證接口返回?cái)?shù)據(jù):
(1)用戶當(dāng)前已購(gòu)買的所有商品信息载迄;
(2)接口錯(cuò)誤信息;
(3)錯(cuò)誤碼:一類是服務(wù)器自身的報(bào)錯(cuò)抡蛙;另一類是App Store返回的錯(cuò)誤碼护昧。
漏單處理:
漏單,即用戶付款成功粗截,但沒(méi)有收到購(gòu)買的商品的情況惋耙。如果交易在App Store中尚未完成,則應(yīng)用定時(shí)或重啟后會(huì)繼續(xù)處理該交易熊昌。如果交易已完成绽榛,則用戶只能向客服反饋,提供蘋果賬號(hào)和單號(hào)婿屹,確認(rèn)漏單后補(bǔ)發(fā)商品灭美。
注意點(diǎn):
(1)內(nèi)購(gòu)必須使用真機(jī)測(cè)試,測(cè)試時(shí)先退出真機(jī)上的AppleID昂利,在App內(nèi)購(gòu)買時(shí)填寫沙箱測(cè)試賬號(hào)届腐;
(2)游客模式下,App中不要出現(xiàn)商品相關(guān)信息蜂奸;
(3)等待請(qǐng)求交易的時(shí)候犁苏,如果App重啟,則重啟后App Store仍會(huì)向監(jiān)聽(tīng)對(duì)象發(fā)送交易狀態(tài)反饋扩所;如果交易成功后沒(méi)有被標(biāo)識(shí)為finished傀顾,App Store仍會(huì)向監(jiān)聽(tīng)對(duì)象發(fā)送交易狀態(tài);