參考借鑒了一下幾篇文章(在這里很感謝各位作者大大做出的總結(jié)和方案):
http://blog.csdn.net/autfish/article/details/52682778?
http://blog.csdn.net/a351945755/article/details/22928491
http://www.cnblogs.com/fengmin/p/5562769.html
iOS游拍 iAP 充值 SDK
一、登錄 App的ItunesConnection,添加內(nèi)購
我們打開創(chuàng)建的App,會(huì)看到左側(cè)的App 內(nèi)購買項(xiàng)目。我們?yōu)锳pp添加內(nèi)購項(xiàng)目。填寫內(nèi)購產(chǎn)品的相關(guān)信息,將內(nèi)購產(chǎn)品送到APPStore審核
二.申請(qǐng)沙盒測(cè)試賬號(hào)(用來測(cè)試購買項(xiàng)目)
首先我們到iTunes Connect中,在這里我們選擇用戶和職能。
然后在上面的沙箱技術(shù)測(cè)試員中添加測(cè)試員。
PS1:所有信息都可以隨意填寫,不用管是否真實(shí)。App Store地區(qū)選擇,一定要選對(duì),它對(duì)應(yīng)的是你創(chuàng)建的App的地區(qū), 你App是中國的話, 在這里我們依然選擇中國。
PS2:此賬號(hào)只能用來測(cè)試,不要在正式的appstore上使用
PS3:填寫完畢,點(diǎn)擊保存后,我們則生成一個(gè)測(cè)試賬號(hào),當(dāng)然這個(gè)賬號(hào)是可以隨時(shí)刪除和添加的。
三、實(shí)現(xiàn)方式(服務(wù)器類型實(shí)現(xiàn)內(nèi)購)
客戶端
程序向服務(wù)器發(fā)送請(qǐng)求,獲得一份產(chǎn)品列表詳細(xì)信息。
程序把返回的產(chǎn)品信息顯示給用戶
用戶選擇某個(gè)產(chǎn)品
程序向App? Store發(fā)送支付請(qǐng)求,同時(shí)向服務(wù)器發(fā)送支付請(qǐng)求
App Store處理支付請(qǐng)求并返回交易完成信息。
程序從信息中獲得數(shù)據(jù)(收據(jù)),并發(fā)送至服務(wù)器。
服務(wù)器驗(yàn)證通過后將返回結(jié)果(購買的內(nèi)容)傳遞給程序。
服務(wù)端
服務(wù)端錄入產(chǎn)品列表(列表信息跟iTunesConnect里添加的購買信息一致)
服務(wù)器接收客戶端請(qǐng)求返回包含產(chǎn)品信息列表。
服務(wù)端接收客戶端的購買請(qǐng)求生成訂單
服務(wù)器接收并紀(jì)錄客戶端發(fā)來的數(shù)據(jù),并進(jìn)行審(我們的)查。
服務(wù)器將數(shù)據(jù)發(fā)給App? Store來驗(yàn)證該交易的有效性。
App Store對(duì)收到的數(shù)據(jù)進(jìn)行解析,返回該數(shù)據(jù)和說明其是否有效的標(biāo)識(shí)。
服務(wù)器讀取返回的數(shù)據(jù),確定用戶購買的內(nèi)容。
服務(wù)端驗(yàn)證收據(jù)流程:
從transaction的transactionReceipt屬性中得到收據(jù)的數(shù)據(jù),并以base64方式編碼。
創(chuàng)建JSON對(duì)象,字典格式,單鍵值對(duì),鍵名為"receipt-data", 值為上一步編碼后的數(shù)據(jù)。效果為:{"receipt-data"? ? : "(編碼后的數(shù)據(jù))"}
發(fā)送HTTP POST的請(qǐng)求,將數(shù)據(jù)發(fā)送到App Store,其地址為:
appStore上線:https://buy.itunes.apple.com/verifyReceipt
沙盒測(cè)試:https://sandbox.itunes.apple.com/verifyReceipt
App Store的返回值也是一個(gè)JSON格式的對(duì)象,包含兩個(gè)鍵值對(duì),
status和receipt:? ? {"status"? ? : 0,"receipt"? ? : { … }}
如果status的值為0, 就說明該receipt為有效的。 否則就是無效的。
```
Status其余狀態(tài)
0recipt有效
?21000AppStore無法讀取你提供的JSON數(shù)據(jù)
21002收據(jù)數(shù)據(jù)不符合格式
21003收據(jù)無法被驗(yàn)證
21004你提供的共享密鑰和賬戶的共享密鑰不一致
?
21005收據(jù)服務(wù)器當(dāng)前不可用
?
21006收據(jù)是有效的,但訂閱服務(wù)已經(jīng)過期。當(dāng)收到這個(gè)信息時(shí),解碼后的收據(jù)信息也包含在返回內(nèi)容中
?
21007收據(jù)信息是測(cè)試用(sandbox),但卻被發(fā)送到產(chǎn)品環(huán)境中驗(yàn)證
?
21008收據(jù)信息是產(chǎn)品環(huán)境中使用,但卻被發(fā)送到測(cè)試環(huán)境中驗(yàn)證
?
receipt中對(duì)應(yīng)的內(nèi)容:
?
鍵名描述
?
quantity購買商品的數(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_idAppStore用來標(biāo)識(shí)程序的字符串。一個(gè)服務(wù)器可能需要支持多個(gè)server的支付功能,可以用這個(gè)標(biāo)識(shí)來區(qū)分程序。鏈接sandbox用來測(cè)試的程序的不到這個(gè)值,因此該鍵不存在。
?
version_external_-identifier用來標(biāo)識(shí)程序修訂數(shù)。該鍵在sandbox環(huán)境下不存在
?
bidiPhone程序的bundle標(biāo)識(shí)
?
bvrsiPhone程序的版本號(hào)
```
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可通過這些值來了解交易的詳細(xì)信息。?
Apple建議只發(fā)送receipt數(shù)據(jù)到服務(wù)器并使用receipt數(shù)據(jù)驗(yàn)證和獲得交易詳情。
因?yàn)锳pp? Store可驗(yàn)證收據(jù)信息,返回信息,保證信息不被篡改,這種方式比同時(shí)提交receipt和transaction的數(shù)據(jù)要安全。
PS:如果用戶退款,在recipt字段中會(huì)接收到cancel_data字段取消日期對(duì)于由Apple客戶支持取消的交易,取消的時(shí)間和日期。
四、漏單等情況預(yù)防與處理方案
1.漏單必須要處理,玩家花RMB購買的東西卻丟失了,是絕對(duì)不能容忍的。所謂的漏單就是玩家已經(jīng)正常付費(fèi),卻沒有拿到該拿的道具。
解決:只要購買成功,便將購買記錄(receipt等賬單信息)保存下來,然后將賬單信息傳送給我們游戲服務(wù)器,游戲服務(wù)器獲得賬單后,和蘋果服務(wù)器驗(yàn)證,賬單有效的話,回饋給游戲服務(wù)器處理,游戲服務(wù)器處理后,返回給游戲客戶端處理,處理完畢,將本地保存的購買記錄刪除。
2.漏單的檢測(cè)位置
解決:
2.1 做法1:在任意購買成功之后,順便檢測(cè)一次漏單,有漏單數(shù)遍處理了。
2.2 做法2:是在游戲登陸的時(shí)候檢測(cè)一次漏單,即循環(huán)檢測(cè)漏單數(shù)據(jù),挨個(gè)發(fā)送給服務(wù)器驗(yàn)證處理,直到將所有的漏單處理完畢。這是原因是購買服務(wù)器未返回結(jié)果而客戶端崩潰的情況下,玩家再次登陸,會(huì)產(chǎn)生漏單。
3.漏單的版本兼容
漏單要做好版本兼容,eg.玩家購買英雄ID為100的英雄,產(chǎn)生了一次漏單,但是一直未再次登陸游戲,由于版權(quán)等原因,這個(gè)英雄在后期版本中被刪除了,如果玩家這是漏單處理,會(huì)在服務(wù)器獲得一個(gè)丟棄的英雄,產(chǎn)生數(shù)據(jù)異常。
處理是,如果是英雄,檢測(cè)英雄在本地hero.csv中是否有效,如果有效,檢測(cè)這個(gè)英雄是否已經(jīng)擁有,如果沒有且數(shù)據(jù)正常,發(fā)送給服務(wù)器處理漏單,否則丟棄掉這條漏單。
4.服務(wù)器和客戶端漏單對(duì)應(yīng)順序
遇到過這種情況,客戶端產(chǎn)生了多個(gè)漏單,發(fā)送給游戲服務(wù)器驗(yàn)證,游戲服務(wù)器請(qǐng)求蘋果服務(wù),蘋果服務(wù)器返回的receipt的json數(shù)據(jù)中包含一個(gè)所有未處理的訂單列表,最后產(chǎn)生的購買數(shù)據(jù)在最后,客戶端的漏單順序和服務(wù)器的驗(yàn)證順序要保持一致。
五、蘋果充值常見的刷單手段和防范方法
1 重復(fù)使用receipt-data
這種問題發(fā)生的原因是雖然已經(jīng)用安全的方式檢查了receipt-data的有效性,但是沒有檢查receipt-data的唯一性。蘋果驗(yàn)單接口返回的數(shù)據(jù)格式如下:數(shù)據(jù)為json格式,其中status值為0表示該receipt有效,但是蘋果只負(fù)責(zé)真假,而不負(fù)責(zé)檢查是否已被使用過。同一個(gè)有效的receipt,無論多少次、相隔多少時(shí)間去蘋果接口驗(yàn)證,都會(huì)返回成功。如果只檢查了"status":0即發(fā)貨,則非法用戶可以先真實(shí)充值一筆,截取到receipt-data后,再多次使用到購買中騙過服務(wù)器端驗(yàn)證。防范的方法是在確定status值為0后,進(jìn)一步解析出數(shù)據(jù)中的transaction_id并存入數(shù)據(jù)庫。每次發(fā)貨前先檢查數(shù)據(jù)庫中是否已經(jīng)有本次的transaction_id存在,如果已存在則拒絕發(fā)貨。還有一種情況需要注意,有些游戲購買前先有一步創(chuàng)建訂單的行為,在服務(wù)器端記錄購買的商品、時(shí)間等,且發(fā)貨時(shí)是按照訂單記錄中的商品,那么需要比較蘋果返回信息中的product_id與訂單表中的記錄值是否一致。
這種問題發(fā)生的原因是雖然已經(jīng)用安全的方式檢查了receipt-data的有效性,但是沒有檢查receipt-data的唯一性。蘋果驗(yàn)單接口返回的數(shù)據(jù)格式如下:
數(shù)據(jù)為json格式,其中status值為0表示該receipt有效,但是蘋果只負(fù)責(zé)真假,而不負(fù)責(zé)檢查是否已被使用過。同一個(gè)有效的receipt,無論多少次、相隔多少時(shí)間去蘋果接口驗(yàn)證,都會(huì)返回成功。如果只檢查了"status":0即發(fā)貨,則非法用戶可以先真實(shí)充值一筆,截取到receipt-data后,再多次使用到購買中騙過服務(wù)器端驗(yàn)證。
防范的方法是在確定status值為0后,進(jìn)一步解析出數(shù)據(jù)中的transaction_id并存入數(shù)據(jù)庫。每次發(fā)貨前先檢查數(shù)據(jù)庫中是否已經(jīng)有本次的transaction_id存在,如果已存在則拒絕發(fā)貨。
還有一種情況需要注意,有些游戲購買前先有一步創(chuàng)建訂單的行為,在服務(wù)器端記錄購買的商品、時(shí)間等,且發(fā)貨時(shí)是按照訂單記錄中的商品,那么需要比較蘋果返回信息中的product_id與訂單表中的記錄值是否一致。
2 利用信用卡黑卡
這是最常見的刷單手段,是指用戶利用無效信用卡,在AppStore中進(jìn)行消費(fèi),由于信用卡已在銀行凍結(jié),因此銀行不會(huì)將款項(xiàng)結(jié)算給蘋果,蘋果自然也不會(huì)分成給開發(fā)者。
通常的形式是用戶去交易網(wǎng)站找代充,代充的商家用綁定了黑卡的AppleID給用戶的賬號(hào)充值,并收取遠(yuǎn)低于正常價(jià)格的金額。也有的代充商戶是召集大量的非游戲用戶接單,給指定的賬號(hào)充值后再申請(qǐng)退款,并給這些參與者一定返利來達(dá)到“共贏”。
對(duì)于這種情況,除了寄望于蘋果更嚴(yán)格的審核信用卡信息外,開發(fā)者還可以通過監(jiān)控和分析數(shù)據(jù)盡可能減小損失。對(duì)于最常見的代充形式,我們可以推測(cè):
a. 用戶充值時(shí)不在自己的常用設(shè)備上,而是由商戶在自有設(shè)備上操作
b. 商戶的充值設(shè)備可能為多個(gè)賬號(hào)充值
分析用戶的常用設(shè)備可以通過用戶日常的游戲記錄,如果只有在充值時(shí)會(huì)切換到不常用設(shè)備上,那么可以判定為可疑用戶。如果某些設(shè)備只在充值記錄中出現(xiàn),卻不屬于任何用戶的常用設(shè)備,那么使用這些設(shè)備充值的用戶也可以判定為可疑用戶。
對(duì)可疑用戶可以進(jìn)一步分析,確定后執(zhí)行扣除非法所得、封停賬號(hào)等。
3 利用外幣卡折扣賺取差價(jià)
這是一種需要天時(shí)的刷單手段。在一些新興市場(chǎng),如墨西哥、土耳其等,蘋果有專門的優(yōu)惠折扣,使用這些貨幣充值,折扣后的差額即刷單的獲利。還有一種情況是利用匯率的變化,如著名的南非幣事件。
防范這種手段也很簡單,客戶端獲取用戶支付使用的貨幣類型發(fā)給服務(wù)器驗(yàn)證,在服務(wù)器端建立貨幣白名單,只允許使用人民幣或穩(wěn)定的國家和地區(qū)的貨幣支付。
4 利用蘋果對(duì)小額消費(fèi)不做驗(yàn)證規(guī)則的"36技術(shù)”(小額消費(fèi)為40元以下的消費(fèi))
這是一種更有技術(shù)含量的手段,利用蘋果對(duì)信用卡的小額消費(fèi)不做驗(yàn)證的規(guī)則,并使用自動(dòng)注冊(cè)的虛擬信用卡完成綁卡。用戶發(fā)起購買后,蘋果不確認(rèn)扣款即返回給客戶端成功信息,而此后再進(jìn)行信用卡扣款時(shí),會(huì)出現(xiàn)扣不到錢的情況。 從開發(fā)者的角度來看,這筆訂單是真實(shí)有效的,receipt-data也能通過蘋果服務(wù)器的驗(yàn)證,但是最終蘋果不會(huì)對(duì)這些賬單分賬。
相比傳統(tǒng)的黑卡,這種方式實(shí)現(xiàn)了自動(dòng)化處理,刷單效率很高,對(duì)開發(fā)者造成的損失更大。特別是具有交易功能的游戲,刷單者大量充值,然后在游戲內(nèi)換成貨幣或道具低價(jià)售賣給普通玩家。
對(duì)于這種手段,目前開發(fā)者能做的就是監(jiān)控用戶的異常充值行為,對(duì)于頻繁小額充值的用戶予以限制。手游中,常見的小額商品就是6元和30元商品,也可以直接限制這些小額商品每用戶每日的購買次數(shù),來盡可能減少損失。
(PS:據(jù)調(diào)研資料整理顯示,目前行業(yè)沒有統(tǒng)一的限制標(biāo)準(zhǔn),如熱血江湖游戲?qū)τ谛☆~支付限制是每天6次,而騰訊代理的游戲龍之谷每日限制是3次,故對(duì)于小額次數(shù)限制規(guī)則應(yīng)根據(jù)公司項(xiàng)目情況做自我限制規(guī)定)