支付流程:
1,把訂單信息,價(jià)格,名稱,時(shí)間,訂單號(hào)等等傳給后臺(tái),生成一個(gè)未完成的訂單
2,判斷手機(jī)有沒(méi)有開(kāi)啟內(nèi)購(gòu)權(quán)限.
[SKPaymentQueuecanMakePayments]
3,去蘋果服務(wù)器請(qǐng)求商品信息.
//proTd為內(nèi)購(gòu)商品ID
NSArray*product = [[NSArrayalloc]initWithObjects:proId,nil];
???NSSet*nsset = [NSSetsetWithArray:product];
???SKProductsRequest*request = [[SKProductsRequestalloc]initWithProductIdentifiers:nsset];
??? request.delegate=self;
??? [requeststart];
4,組裝購(gòu)買請(qǐng)求放入購(gòu)買隊(duì)列
-(void)productsRequest:(SKProductsRequest*)requestdidReceiveResponse:(SKProductsResponse*)response
回調(diào)內(nèi)收到商品信息,然后組裝成SKPayment,放入SKPaymentQueue
SKPayment*payment = [SKPaymentpaymentWithProduct:p];
[[SKPaymentQueuedefaultQueue]addPayment:payment];
5,監(jiān)聽(tīng)請(qǐng)求回調(diào).
-(void)paymentQueue:(SKPaymentQueue*)queueupdatedTransactions:(NSArray<SKPaymentTransaction*> *)transactions;
SKPaymentTransactionStatePurchased狀態(tài)為成功狀態(tài)
6,成功回調(diào)里向自己的服務(wù)器發(fā)起驗(yàn)證.
這一步至少需要傳入三個(gè)參數(shù):
1,receiptData
?NSURL*receiptUrl = [[NSBundlemainBundle]appStoreReceiptURL];
?NSData*receiptData = [NSDatadataWithContentsOfURL:receiptUrl];
NSString? *receiptDataString = [receiptDatabase64EncodedStringWithOptions:0];
可能會(huì)是空值,可以手動(dòng)刷新后再取
SKReceiptRefreshRequest*receiptRefreshRequest= [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
receiptRefreshRequest.delegate=self;
[receiptRefreshRequest start];
然后return;重新進(jìn)入代理方法,重新去沙盒中獲取receiptData
2,transactionIdentifier
NSString*transactionIdentifier = transaction.transactionIdentifier;
3,productIdentifier
NSString*productIdentifier = transaction.payment.productIdentifier;
這三個(gè)值足矣驗(yàn)明正身
另外還需要一些其他的訂單信息,價(jià)格,名稱,時(shí)間,訂單號(hào)等等,但是不是訂單驗(yàn)證所需要的必要元素
6,驗(yàn)證成功的回調(diào)里刷新本地權(quán)限,并且把本次購(gòu)買的請(qǐng)求從購(gòu)買隊(duì)列中移除.
[[SKPaymentQueuedefaultQueue]finishTransaction:transaction];
防丟單處理:
在appdelegate里監(jiān)聽(tīng)paymentQueue
會(huì)重復(fù)-(void)paymentQueue:(SKPaymentQueue*)queueupdatedTransactions:(NSArray<SKPaymentTransaction*> *)transactions 里的流程
如何去后臺(tái)尋找相對(duì)應(yīng)的未完成訂單?
假設(shè)一種最極端的情況,APP在向蘋果服務(wù)器發(fā)送完購(gòu)買請(qǐng)求后馬上斷網(wǎng),APP被立即刪除,此時(shí)即使重裝APP后,paymentQueue里的數(shù)據(jù)依然無(wú)法與后臺(tái)服務(wù)器的訂單數(shù)據(jù)映射起來(lái),怎么辦呢?
我的方案:
在第4部,拼裝SKPayment,的時(shí)候,改用系統(tǒng)提供的SKMutablePayment,里面有幾個(gè)可以自定義的字段,applicationUsername
requestData
這些都是可選字段,可填可不填
可以利用requestData這個(gè)字段填入我們自己服務(wù)器生成的訂單號(hào),例如:12345678
那么在下次一的appdelegate里監(jiān)聽(tīng)paymentQueue的數(shù)據(jù)時(shí)候,蘋果后臺(tái)就能在requestData返回給我們自己傳入的12345678
拿到這個(gè)字段后我們就可以去我們的后臺(tái)去尋找相應(yīng)的訂單,后臺(tái)receiptData,ransactionIdentifier,productIdentifier校驗(yàn)無(wú)誤后直接處理12345678訂單號(hào)的訂單狀態(tài).
完美的的閉環(huán),丟單,刷單的情況是絕對(duì)不會(huì)出現(xiàn)了.
paymentQueue是一個(gè)基于appID的遠(yuǎn)程隊(duì)列,只要你沒(méi)有手動(dòng)移除隊(duì)列里的購(gòu)買請(qǐng)求,即使你的app重啟,刪除重裝,只要手機(jī)登錄的還是你原來(lái)的appID,在APP啟動(dòng)的時(shí)候仍然可以同步下來(lái)你上一次沒(méi)有完成的購(gòu)買請(qǐng)求.
監(jiān)聽(tīng)paymentQueue可以解決那些丟單情況?
1,內(nèi)購(gòu)?fù)瓿苫卣{(diào),當(dāng)你向自己的服務(wù)器發(fā)起驗(yàn)證的時(shí)候,斷網(wǎng),app崩潰,app被刪除,總之a(chǎn)pp內(nèi)有收到自己服務(wù)器驗(yàn)證的成功回調(diào),造成本次購(gòu)買請(qǐng)求沒(méi)有從paymentQueue移除,那么它仍然存在于paymentQueue內(nèi),下次重新安裝啟動(dòng)app的時(shí)候,可以監(jiān)聽(tīng)到paymentQueue里沒(méi)有處理完的購(gòu)買,可以繼續(xù)執(zhí)行剩下來(lái)步驟.
2,app向蘋果服務(wù)器發(fā)起購(gòu)買后,斷網(wǎng),app崩潰,app被刪除,導(dǎo)致app端根本就沒(méi)有手到蘋果內(nèi)購(gòu)的回調(diào),接下來(lái)的步驟全部中斷,沒(méi)關(guān)系,只要購(gòu)買請(qǐng)求沒(méi)有從paymentQueue中手動(dòng)移除,下次重新安裝啟動(dòng)app的時(shí)候都能重新監(jiān)聽(tīng)到結(jié)果.
監(jiān)聽(tīng)paymentQueue不能處理那些丟單情況?
沒(méi)有.