IOS內購(IAP)的那些事

2022-07-29 12:36:09 字數 3851 閱讀 5963

最近看了內購相關的東西,發現坑還真是不少,這裡做個總結。

蘋果內購的主要流程:

獲取商品資訊 --> 建立交易 --> 把交易新增到佇列 --> 交易成功獲取憑證 --> 拿著憑證做二次驗證 --> 交易成功

通過產品id獲取商品資訊(skproduct)。

#import //把商品id資訊放入乙個集合中

nsset *sets = [nsset setwithobjects:@"phonicsphase1", nil];

//請求內購商品資訊,只返回你請求的產品(主要用於驗證商品的有效性)

skproductsrequest *productrequest = [[skproductsrequest alloc] initwithproductidentifiers:sets];

productrequest.delegate = self;

[productrequest start];

#pragma mark - 獲取商品id成功的**方法

- (void)productsrequest:(skproductsrequest *)request didreceiveresponse:(skproductsresponse *)response

拿到商品資訊,建立支付物件(skmutablepayment)。

- (void)startpaymentwithproduct:(skproduct *)product 

把當前交易新增到交易佇列中去(上面的addpayment:方法)。

//首先我們要在 viewdidload 方法中新增監聽物件 

[[skpaymentqueue defaultqueue] addtransactionobserver:self];

#pragma mark - 監聽的**方法

- (void)paymentqueue:(skpaymentqueue *)queue updatedtransactions:(nsarray *)transactions

break;

case skpaymenttransactionstatepurchased:

break;

case skpaymenttransactionstatefailed:

break;

case skpaymenttransactionstaterestored:

break;

case skpaymenttransactionstatedeferred:

break;

default:

break;

}}];

}

注意:

[[skpaymentqueue defaultqueue] finishtransaction:transation]如果不呼叫這個方法,那麼transation就永遠不會結束。也就是說每次進來都會重新呼叫updatedtransactions這個方法,就算你做過二次校驗都沒用

二次校驗只會校驗你的憑證是不是有效,不會關心你這個憑證是不是校驗過了,所以說,乙個憑證可以被校驗多次(這是刷單方法之一)

上面說過,如果不finishtransaction,每次進入這個介面都會呼叫監聽方法,但是注意了每次返回的 reciptdata都是不一樣,即使是同乙個訂單。也就是說,同乙個訂單也有可能有多個reciptdata,所以它並不能用來確定是哪個訂單。

我們從沙盒中取到憑證(recipt),傳送給我們自己後台進行二次驗證,驗證成功表示支付成功。

- (void)checkreceipt:(nsstring *)receipt  else 

} failure:^(id error) ];

}

,]}

}

status不為0的時候,是沒有其餘的json資料的。

21002 receipt-data 域的資料有問題

21003 receipt 無法通過驗證

21004 提供的 shared secret 不匹配你賬號中的 shared secret

21005 receipt 伺服器當前不可用

21006 receipt 合法, 但是訂閱已過期. 伺服器接收到這個狀態碼時, receipt 資料仍然會解碼並一起傳送

21007 receipt 是 sandbox receipt, 但卻傳送至生產系統的驗證服務

21008 receipt 是生產 receipt, 但卻傳送至 sandbox 環境的驗證服務

蘋果的iap缺陷還是很明顯的,但是沒辦法,誰讓蘋果一家獨大呢,我們也只能吐吐槽,想盡一切辦法防止掉單的發生。

掉單的原因是有多方面的,我們乙個個來說。

可以傳遞給後台未知訂單,但客戶投訴的時候,我們從未知訂單裡面找到符合條件的給恢復訂單資訊(這樣做顯然效率很低)

常用的做法是:

其實這個問題始終沒有乙個很好的解決方案,只能靠蘋果的優化了。

由於蘋果的伺服器在美帝,所以延遲的情況還是很嚴重的,這時候如果是請求超時,我們伺服器又沒有收到**,那麼就會產生掉單。比較坑的是,updatedtransactions:

注意:

掉單問題都是出現在支付完成之後,沒有通過二次校驗的時候。因為一旦我們得到了recipt,就說明蘋果已經扣款成功了。但是為什麼我們不能以這個作為支付成功的標準呢,請看下面的刷單系列。

針對上面第二種recipt存本地的方法,其實沒有必要,蘋果自己的補單措施基本上是夠用了。

刷單的**這篇部落格,我在這裡簡述一下,做個小結。

刷單主要有以下幾種方式:

破解iap

重複使用recipt-data

信用卡黑卡

外幣差價

以及蘋果對小額消費不做驗證規則的「36技術」

我們這裡只討論 1 和 2 ,因為下面三種跟我們開發者沒有關係,想要詳細了解的可以去開頭的部落格上了解一下。

1. 破解iap

2. 重複使用recipt-data

我們直到,recipt-data是支付成功返回給我們的校驗憑證,前面說過,蘋果校驗的時候只負責校驗recipt的有效性和真假,並不負責這個憑證是否被用過。如果我們在後台只判斷status == 0,而不去做其他判斷的話,非法使用者會儲存recipt-data,然後多次使用,因為每次都是校驗通過的。

我們也不能判斷recipt-data是否被使用,因為上面已經說過,同乙個訂單也會有多個recipt-data返回的。

防範的方法是在確定status值為0後,進一步解析出資料中的transaction_id並存入資料庫。每次發貨前先檢查資料庫中是否已經有本次的transaction_id存在,如果已存在則拒絕發貨。

到了這裡iap基本上已經結束了,這裡只是把iap的流程以及需要注意的點列出來,以上的方法只是作為總結,並不適用於所有狀況,我們在開發中還要具體問題具體分析。希望大家開發中都不會掉單

PHP實現蘋果 IOS 內購 IAP

反反覆覆經過多次重寫 內部需要 發現蘋果使用php來驗證蘋果內購資料是否正確並不是一件很難的事情。我把我的一些心得寫出來,以供以後有這方面需求的小夥伴參考,以php語言為例,誰讓php是最好的語言呢!首先要知道蘋果內購分沙箱環境和正式環境,兩者區別就是名字不同,請求是需要攜帶的引數是相同的。最重要的...

iOS應用內支付 IAP 的那些坑

猿題庫現在推出了公 行測和申論2個產品,均包括web,ios和android三個平台。這次我們嘗試做乙個收費的產品,所以在ios端整合了應用內支付 iap 功能。在開發過程中和上線後,我們遇到了iap中的一些坑,在此分享給各位。iap 審核相關的坑 iap開發的詳細步驟我寫在另一篇部落格中了。在此主...

ios 內購資料

如果您正在尋找乙份手把手教你實現iap的教程的話,這篇文章不是您的菜。關於iap的實現和步驟,可以參考下面的教程 和相應的 ray wenderlich的 一篇 並茂的 中文教程 直接使用大神們封好的store有關的庫,比如 mattt cargobay robotmedia rmstore 或者m...