一.內購沙盒測試賬號在支付成功后,再次購買相同 ID 的物品,會提示如下內容的彈窗。您以購買過此APP內購項目,此項目將免費恢復
您以購買過此APP內購項目,此項目將免費恢復.PNG
原因:
當使用內購購買過商品后沒有把這個交易事件關,所以當我們再次去購買商品后就會調用以前已經購買成功的交易事件去購買因為已經購買過,才會有這個提示
解決方法:
1.當我們使用[[SKPaymentQueue defaultQueue] addPayment:payment];這個方法進行支付請求后,因為我們已經把支付所需要的信息都添加到蘋果的支付隊列,蘋果會自動完成后續的購買請求。
在用戶購買成功或者點擊取消購買的后會回調- (void)paymentQueue:(SKPaymentQueue )queue updatedTransactions:(NSArray )transaction;方法返回響應的結果信息,在該方法內除了得到響應的支付信息編寫自身的業務的代碼外還要記得調用[[SKPaymentQueue defaultQueue] finishTransaction:transaction];方法通知蘋果的支付隊列該交易已經完成,否者就會調用已經購買成功的支付隊列,就會出現您以購買過此APP內購項目,此項目將免費恢復這句提示。
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
NSLog(@"調用了幾次這個方法?");
SKPaymentTransaction *transaction = transactions.lastObject;
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];//記得關閉交易事件
NSLog(@"購買完成,向自己的服務器驗證 ---- %@", transaction.payment.applicationUsername);
NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
NSString *receipt = [data base64EncodedStringWithOptions:0];
// [self buySuccessWithReceipt:receipt transaction:transaction];
}
break;
case SKPaymentTransactionStateFailed: {
NSLog(@"交易失敗");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStateRestored: {
NSLog(@"已經購買過該商品");
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
break;
case SKPaymentTransactionStatePurchasing: {
NSLog(@"商品添加進列表");
}
break;
default: {
NSLog(@"這是什么情況啊?");
}
break;
}
}
2.在買次購買之前檢測是否有未完成的交易如果有就關閉。
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
if (transactions.count > 0) {
//檢測是否有未完成的交易
SKPaymentTransaction* transaction = [transactions firstObject];
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
return;
}
}
二.內購 元數據丟失
一般情況下是需要填的選項沒有填寫完整,還有要填寫完整不然審核內購項目可能會不通過。
三.iOS 內購 您已經購買了此項目,您想免費再獲取一次嗎
這個是內購選擇類型不匹配原因導致。
非消耗型就是消耗一次后在該appid下都能使用。
消耗型比如一些直播平臺的貨幣 使用完以后可以在充值。
我有這個問題是 最開始我們的項目是購買完產品以后可以永久使用,后來修改成充值余額購買,但是我沒有去修改類型才導致的這個錯誤,
四.測試時記得把App Store上的賬號注銷,不然會出現購買失敗,注銷賬號后,在進行內購時登錄沙盒測試賬號。
五.In-App Purchase二次驗證
IOS在沙箱環境下購買成功之后,向蘋果進行二次驗證,確認用戶是否購買成功。
當應用向Apple服務器請求購買,成功之后,Apple會返回以下四個數據給應用
- 產品標識符: product Identifier[在itunes store應用內定義的產品ID,例如com.公司名.產品名.道具名(com.xxxx.317hu.66)]
- 交易狀態: state
- Receipt:很長的一段字符串,大概49行,作為二次驗證的重要依據
- 交易標識符: transaction Identifier 我們需要把Receipt發送給蘋果的蘋果的服務器驗證,用戶的購買信息是否真實
交易狀態 | 解釋 |
---|---|
Purchased | 購買成功 |
Restored | 恢復購買 |
Failed | 失敗 |
Deferred | 等待確認,兒童模式需要詢問家長同意 |
蘋果返回狀態碼 狀態碼
狀態 | 描述 |
---|---|
21000 | App Store不能讀取你提供的JSON對象 |
21002 | receipt-data域的數據有問題 |
21003 | receipt無法通過驗證 |
21004 | 提供的shared secret不匹配你賬號中的shared secret |
21005 | receipt服務器當前不可用 |
21006 | receipt合法,但是訂閱已過期。服務器接收到這個狀態碼時,receipt數據仍然會解碼并一起發送 |
21007 | receipt是Sandbox receipt,但卻發送至生產系統的驗證服務 |
21008 | receipt是生產receipt,但卻發送至Sandbox環境的驗證服務 |