iOS 內購

從開發iOS到如今,內購app也作過兩個了,如今好好記錄下這個流程。git

首先須要在所屬的app下建立物品,這個流程網上不少也不難。這邊就詳細說明了,可參考下面網址。 http://blog.csdn.net/shenjie12345678/article/details/40978977/github

咱們定義好一個或多個product 後 每一個product id對應着一個product。 咱們拿到一個或多個product id,數據處理後對appstore 發起購物請求,等待appstore處理後的響應(之間不少操做,都是appStore和用戶之間,客戶端沒法干預), 客戶端對購物成功的回執單進行校驗。 內購流程示意圖.png服務器

這個流程基本就是這樣,如上圖所示。網絡

理清整個流程後,咱們對內購就很是清晰了,要注意的就是細節了,對各類異常狀況的處理。各類case 見下列枚舉,基本和app的sdk保持一致app

typedef enum : NSUInteger {
    EPaymentTransactionStateNoPaymentPermission, //沒有Payment權限
    EPaymentTransactionStateAddPaymentFailed, //addPayment失敗
    EPaymentTransactionStatePurchasing,//正在購買
    EPaymentTransactionStatePurchased,//購買完成(銷燬交易)
    EPaymentTransactionStateFailed, //購買失敗(銷燬交易)
    EPaymentTransactionStateCancel,//用戶取消
    EPaymentTransactionStateRestored,//恢復購買(銷燬交易)
    EPaymentTransactionStateDeferred, //最終狀態未肯定
} EPaymentTransactionState;

內購有個重要的協議 SKPaymentTransactionObserver 須要特殊特殊處理,很少說廢話 直接附上代碼測試

#pragma mark - SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        EPaymentTransactionState state;
        switch (transaction.transactionState){
            case SKPaymentTransactionStatePurchasing:
            {
                // 鏈接appStore
                state = EPaymentTransactionStatePurchasing;
            }
                break;
            case SKPaymentTransactionStatePurchased:
            {
                state = EPaymentTransactionStatePurchased;
                //交易完成
                if (isServiceVerify) {
                    [self completeTransaction:transaction];
                }
                else
                {
                    //本地做校驗
                    [self verifyPurchase:transaction];
                }
            }
                break;
                
            case SKPaymentTransactionStateFailed:
            {
                //交易失敗
                if (transaction.error.code != SKErrorPaymentCancelled)
                {
                    state = EPaymentTransactionStateFailed;
                }else
                {
                    state = EPaymentTransactionStateCancel;
                }

                [self finshTransaction:transaction];
            }
                break;
                
            case SKPaymentTransactionStateRestored:
            {
                state = EPaymentTransactionStateRestored;
                //已經購買過該商品
        
                [self finshTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStateDeferred:
            {
                state = EPaymentTransactionStateDeferred;
            }
                break;
            default:
                break;
        }
        if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) {
            [self.delegate updatedTransactions:state];
        }

    }
}

補充一點 :一旦啓動了開始購買流程,必需要調用.net

    //結束交易
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

來結束購買流程,否者在下一次調用到 方法code

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

仍是會觸發繼續購買流程,這個特性能夠解決購買過程當中出現的各類異常場景,好比購買完成app crash(沒網絡了),在下一次啓動app時調用上面的方法能夠回覆購買。 具體類 放在gitHub下 https://github.com/weskhen/InAppPurchasingserver

蘋果反饋的狀態碼;blog

21000 App Store沒法讀取你提供的JSON數據

21002 收據數據不符合格式 (踩過坑,越獄機會出現)

21003 收據沒法被驗證

21004 你提供的共享密鑰和帳戶的共享密鑰不一致

21005 收據服務器當前不可用

21006 收據是有效的,但訂閱服務已通過期。當收到這個信息時,解碼後的收據信息也包含在返回內容中

21007 收據信息是測試用(sandbox),但卻被髮送到產品環境中驗證

21008 收據信息是產品環境中使用,但卻被髮送到測試環境中驗證

相關文章
相關標籤/搜索