iOS內(nèi)購Iap-In-App Purchases那些事

前言:

最近在搞內(nèi)購蟆豫,也就研究了下,這里說說內(nèi)購我遇到的一些問題和receipt收據(jù)驗證的事

介紹:

什么時候用內(nèi)購懒闷?

個人理解十减,比如你的app里,存在一些支付永久有效的東西愤估,比如帮辟,支付的視頻,以后還是可以看玩焰,這種的就需要內(nèi)購來實現(xiàn)由驹。

內(nèi)購怎么實現(xiàn)?

Snip20161219_3.png

先來看看這張圖昔园,內(nèi)購過程大致分為幾部分:
你在app Developer上面填寫好內(nèi)購的商品蔓榄,記錄下商品的ID

1并炮、客戶端向蘋果發(fā)起請求,獲取內(nèi)購的全部商品
2甥郑、客戶端獲取全部商品成功逃魄,根據(jù)你選擇的產(chǎn)品id去蘋果服務(wù)器發(fā)起支付請求,支付成功后壹若,蘋果返回給你一個receipt收據(jù)嗅钻,收據(jù)包含你這次交易的全部信息,產(chǎn)品id店展,交易號养篓,時間等。
3赂蕴、你拿到receipt收據(jù)之后柳弄,需要發(fā)送到你的app的服務(wù)器做校驗,這里我的做法是:蘋果返回的收據(jù)概说,產(chǎn)品id碧注,和金額,一同扔給app服務(wù)器
4糖赔、app服務(wù)器拿到收據(jù)之后萍丐,做base64加密(蘋果要求加密),再發(fā)送給蘋果服務(wù)器做收據(jù)的校驗放典,蘋果驗證成功之后會返回收據(jù)的json形式逝变,服務(wù)器拿到,然后取出里面的產(chǎn)品id等奋构,跟你app客戶端最開始發(fā)送到服務(wù)器的產(chǎn)品id等做次對比
5壳影、對比成功后,服務(wù)器返回app客戶端所購買的商品數(shù)量

  • 我總結(jié)弥臼,蘋果的內(nèi)購宴咧,就是蘋果先扣費再說,購買的商品返回以及驗證等径缅,app客戶端和app服務(wù)器自己去處理掺栅。

那么問題來了...

app內(nèi)購扣費成功了,但是購買的商品(比如鉆石)沒收到

  • 這種情況纳猪,就是因為app內(nèi)購扣費氧卧,確實成功了~ 你app客戶端也收到蘋果返回的收據(jù)了,但是你在向你app服務(wù)器發(fā)送收據(jù)的過程中兆旬,或者假抄,app服務(wù)器發(fā)送收據(jù)到蘋果服務(wù)器做收據(jù)驗證的過程中,不幸發(fā)送失敗了...so,錢扣了宿饱,貨沒了熏瞄。
  • 對于處理:要么重發(fā),要么等用戶投訴... 反正對于你公司來說谬以,鉆石這種就是一些虛擬貨幣强饮,發(fā)個雙倍給用戶做補償~

不做驗證,或者客戶端做收據(jù)驗證

不做驗證這種为黎,風險就不多說了邮丰。
說說客戶端做驗證,上面的3-4兩個步驟铭乾,可以這樣:

1剪廉、扣費成功后,蘋果返回的收據(jù)炕檩,你客戶端做base64加密斗蒋,然后發(fā)送到蘋果服務(wù)器做驗證,驗證其實就是將加密的base64收據(jù)發(fā)送到一個網(wǎng)址笛质。
2泉沾、等蘋果驗證成功后,返回給你的json妇押,你取出產(chǎn)品id等跷究,做個簡單的比較,就算支付成功
3敲霍、然后你再發(fā)個請求到你的app服務(wù)器俊马,說交易成功啦,快給我返回鉆石色冀,就OK了潭袱。

  • 對于這種客戶端校驗柱嫌,我也是百度了下锋恬,說是越獄手機,被黑了编丘,這種客戶端的驗證就廢了与学。so,收據(jù)的校驗還是扔給你的服務(wù)器去做吧嘉抓,萬一你客戶端出了問題索守,誰來承擔呢,是吧抑片?坑~

蘋果返回的收據(jù)json卵佛,有個code,作為你app服務(wù)器判斷蘋果驗證的收據(jù)是否有效:

Snip20161219_5.png

內(nèi)購代碼:

我使用的是IAPHelper
導入頭文件 #import "IAPShare.h"

- (void)viewDidLoad {
[super viewDidLoad];

if(![IAPShare sharedHelper].iap) {
   // ProductID_diamond1 我這里是宏,產(chǎn)品id一般為你工程的 Bundle ID+數(shù)字
  // 我這里是6個內(nèi)購的商品
    NSSet* dataSet = [[NSSet alloc] initWithObjects:
                                                  ProductID_diamond1,
                                                  ProductID_diamond2,
                                                  ProductID_diamond3,
                                                  ProductID_diamond4,
                                                  ProductID_diamond5,
                                                  ProductID_diamond6,
                                                  nil];
    
    [IAPShare sharedHelper].iap = [[IAPHelper alloc] initWithProductIdentifiers:dataSet];
 }

//yes為生產(chǎn)環(huán)境  no為沙盒測試模式   
// 客戶端做收據(jù)校驗有用  服務(wù)器做收據(jù)校驗忽略...
// [IAPShare sharedHelper].iap.production = NO;
 }

在你支付的按鈕方法里:

// 請求商品信息
[[IAPShare sharedHelper].iap requestProductsWithCompletion:^(SKProductsRequest* request,SKProductsResponse* response)
 {
     if(response.products.count > 0 ) {
          //取出第一件商品id 
         SKProduct *product = response.products[0];
         
         [[IAPShare sharedHelper].iap buyProduct:product
                                    onCompletion:^(SKPaymentTransaction* trans){
                                        if(trans.error)
                                        {
                                        }
                                        else if(trans.transactionState == SKPaymentTransactionStatePurchased) {
                                            NSLog(@"購買成功");
                                         // 這個 receipt 就是內(nèi)購成功 蘋果返回的收據(jù)
                                            NSData *receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
                                            
                                          /******這里我將receipt base64加密截汪,把加密的收據(jù) 和 產(chǎn)品id疾牲,一起發(fā)送到app服務(wù)器********/
                                            NSString *receiptBase64 = [NSString base64StringFromData:receipt length:[receipt length]];
                                       
                                            [self sendCheckReceiptWithBase64:receiptBase64 productID:product.productIdentifier];
                                          /*******上面的sendCheckReceipt請求成功了,會返回用戶購買的鉆石數(shù)量*******/
                                            
                                            //客戶端做收據(jù)驗證 (不建議)                                        
                                            //  [[IAPShare sharedHelper].iap checkReceipt:receipt onCompletion:^(NSString *response, NSError *error) {                                               
                                            //   NSLog(@"購買驗證---%@",response);
                                            //  }];
                                            
                                        
                                        }
                                        else if(trans.transactionState == SKPaymentTransactionStateFailed) {
                                            if (trans.error.code == SKErrorPaymentCancelled) {
                                            }else if (trans.error.code == SKErrorClientInvalid) {
                                            }else if (trans.error.code == SKErrorPaymentInvalid) {
                                            }else if (trans.error.code == SKErrorPaymentNotAllowed) {
                                            }else if (trans.error.code == SKErrorStoreProductNotAvailable) {
                                            }else{
                                            }
                                        }
                                    }];
     }else{
         //  ..未獲取到商品
         NSLog(@"..未獲取到商品");
     }
 }];
Snip20161219_7.png
Snip20161219_6.png

總結(jié):

  • app內(nèi)購到這里就差不多了衙解,大家可以使用沙盒進行測試阳柔,測試之前記得退出自己的app store賬號。
  • 等你的app上線了蚓峦,記得讓你app服務(wù)器的哥們舌剂,把內(nèi)購校驗的網(wǎng)址切換下,換成收據(jù)發(fā)送到生產(chǎn)環(huán)境暑椰。
  • app剛過審核霍转,內(nèi)購商品需要你的app過了審核之后,再上到蘋果的內(nèi)購服務(wù)器一汽,可能不會同時和你的app審核通過同步谴忧。

最后....為什么沙盒測試,很規(guī)律的成功一次角虫,失敗一次沾谓,但是大金額的支付就不存在這問題。我百度了戳鹅,很多人也在問均驶,蘋果技術(shù)支持我也打了,也是讓我自查原因枫虏,哎妇穴,搞得我好焦灼,算了隶债,app上線了能用就OK了腾它。

祝大家好運~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市死讹,隨后出現(xiàn)的幾起案子瞒滴,更是在濱河造成了極大的恐慌,老刑警劉巖赞警,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妓忍,死亡現(xiàn)場離奇詭異,居然都是意外死亡愧旦,警方通過查閱死者的電腦和手機世剖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笤虫,“玉大人旁瘫,你說我怎么就攤上這事祖凫。” “怎么了酬凳?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵蝙场,是天一觀的道長。 經(jīng)常有香客問我粱年,道長售滤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任台诗,我火速辦了婚禮完箩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拉队。我一直安慰自己弊知,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布粱快。 她就那樣靜靜地躺著秩彤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪事哭。 梳的紋絲不亂的頭發(fā)上漫雷,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音鳍咱,去河邊找鬼降盹。 笑死,一個胖子當著我的面吹牛谤辜,可吹牛的內(nèi)容都是我干的蓄坏。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼丑念,長吁一口氣:“原來是場噩夢啊……” “哼涡戳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脯倚,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤渔彰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挠将,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胳岂,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡编整,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年舔稀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掌测。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡内贮,死狀恐怖产园,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夜郁,我是刑警寧澤什燕,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站竞端,受9級特大地震影響屎即,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜事富,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一技俐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧统台,春花似錦雕擂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贵扰,卻和暖如春仇穗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戚绕。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工仪缸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人列肢。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓恰画,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瓷马。 傳聞我的和親對象是個殘疾皇子拴还,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容