前言:
最近在搞內(nèi)購蟆豫,也就研究了下,這里說說內(nèi)購我遇到的一些問題和receipt收據(jù)驗證的事
介紹:
什么時候用內(nèi)購懒闷?
個人理解十减,比如你的app里,存在一些支付永久有效的東西愤估,比如帮辟,支付的視頻,以后還是可以看玩焰,這種的就需要內(nèi)購來實現(xiàn)由驹。
內(nèi)購怎么實現(xiàn)?
先來看看這張圖昔园,內(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ù)是否有效:
- receipt的參數(shù)可以參考如下:
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1 - 發(fā)送驗證收據(jù)的網(wǎng)址
在sandbox中驗證receipt:
https://sandbox.itunes.apple.com/verifyReceipt
在生產(chǎn)環(huán)境中驗證receipt:
https://buy.itunes.apple.com/verifyReceipt
內(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(@"..未獲取到商品");
}
}];
總結(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了腾它。
祝大家好運~