1. 程式人生 > >ios 應用內支付(In-App Purchase,沙盒測試,後臺驗證)

ios 應用內支付(In-App Purchase,沙盒測試,後臺驗證)

1.蘋果iTunes Connect內購產品資訊錄入。

1)建立app內購買專案(Create New),選擇型別:

1.消耗型專案

對於消耗型 App 內購買專案,使用者每次下載時都必須進行購買。一次性服務通常屬於消耗型專案,例如釣魚App 中的魚餌。

2.非消耗型專案

對於非消耗型 App 內購買專案,使用者僅需要購買一次。不會過期或隨使用而減少的服務通常為非消耗型專案,例如遊戲App 的新跑道。

3.自動續訂訂閱

通過自動續訂訂閱,使用者可以購買指定時間期限內的更新和動態內容。除非使用者取消選擇,否則訂閱(例如雜誌訂閱等)會自動續訂。

4.免費訂閱

通過免費訂閱,開發者可以將免費訂閱內容放入

報刊雜誌。使用者註冊免費訂閱後,該訂閱內容將會出現在與該使用者Apple ID 關聯的所有裝置上。請注意,免費訂閱不會過期,並且僅在支援報刊雜誌功能的 App 中提供。

5.非續訂訂閱

非續訂訂閱允許有時限性的營銷服務。對於 App 內購買專案中的限時訪問內容,就需使用非續訂訂閱。例如,導航App 中語音導航功能的一週訂閱,或者年度訂閱已存檔的視訊或音訊的線上目錄。

一定要根據自己應用的情況選擇正確,不然會被App Store稽核團隊拒絕。應用內的虛擬幣要採用消耗型的,有固定時限的會員選擇自動續訂訂閱。也可以只選擇虛擬幣充值自己後臺購買的情況解決會員問題。

2)生成共享金鑰

共享金鑰是在您聯絡我們的伺服器獲取

App 內購買專案收據時使用的唯一程式碼。沒有共享金鑰,您將無法在沙箱技術模式下測試自動續訂 App 內購買專案。另外,共享金鑰不能在 App Store 使用。

注:無論與哪個 App 相關聯,您的所有自動續訂訂閱都將使用同一共享金鑰

此共享金鑰用於後臺伺服器驗證使用者購買專案的憑證,生成新密要伺服器也立即改變驗證金鑰。共享金鑰在驗證自動續訂訂閱型別專案的時候必須需要。

3)內購專案的狀態

A) Pending Developer Approval – Your in apppurchase has been created but has not been tested in a sandbox environment andapproved by you.

B) Approved By Developer – Your in apppurchase has been tested in a sandbox environment and has been approved by you.

C) Waiting For Review – You have submittedyour in app purchase to be reviewed by Apple.

D) In Review – Your in app purchase iscurrently being reviewed by Apple no edits can be made.

E) Developer Action Required – In app purchasedetail changes that you submitted have been rejected. You are required to takeaction to edit the detail information or cancel the request to change thedetail information before this in app purchase can be reviewed again.(內購專案詳情介面會提示那個地方出現了問題,稍微修改一下再次提交就行了)

F) Ready for Sale – Apple has approved your inapp purchase to go live on the App Store with its associated application. Thein app purchase must be cleared for sale in iTunes Connect to be Ready forSale.

G) Rejected – Apple has rejected your in apppurchase during the review process. If you have not already been contacted byApple with more information about your rejection, you may inquire through theContact Us section of iTunes Connect. A rejected in app purchase cannot bereinstated. You must create a new in app purchase if you still wish for it tobe sold.

H) Developer Removed from Sale – You havemarked your in app purchase as not cleared for sale in iTunes Connect.

2.app端程式程式碼編寫(程式碼僅供參考)

#pragma mark - 支付以單利的形式展開

+(PurchasesObject*)SharePurchases

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        if (_purchase == nil) {

            _purchase = [[super alloc]init];

            [[SKPaymentQueue defaultQueue]addTransactionObserver:_purchase];

        }

    });

    return _purchase;

}

+(id)allocWithZone:(struct _NSZone *)zone

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        if (_purchase == nil) {

            _purchase = [[super allocWithZone:zone]init];

        }

    });

    return _purchase;

}

+(id)alloc

{

    return _purchase;

}

#pragma mark -支付鑽石會員

_alter = [[UIAlertView alloc]initWithTitle:@"遊客模式購買僅限當前裝置使用所購買的許可權,推薦您登入購買" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"登陸購買(推薦)",@"遊客模式購買" ,nil];

//遊客購買很重要,會被AppStore稽核團隊拒絕。

#pragma mark -開始支付,根據錄入內購專案的產品id去AppStore請求產品資訊。

    if ([SKPaymentQueue canMakePayments]) {

        NSSet * set = [NSSet setWithArray:@[ProductID]];

        SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];

        request.delegate = self;

        [request start];

    }

    else

    {

        NSLog(@"無許可權購買");

    }

#pragma mark -SKProductsRequestDelegate 獲取appstroe產品資訊

- (void)productsRequest:(SKProductsRequest *)requestdidReceiveResponse:(SKProductsResponse *)response {

    self.mySelfView.userInteractionEnabled = NO;

    [AFTools showHUD:@"獲取產品資訊" atView:self.mySelfView];

    NSLog(@"-----------收到產品反饋資訊--------------");

    NSArray *myProduct = response.products;

    if (myProduct.count == 0) {

        [AFTools alertWithTitle:@"購買失敗" message:@"無法獲取產品資訊"];

        NSLog(@"無法獲取產品資訊,購買失敗。");

        return;

    }

    NSLog(@"產品products==%@",myProduct);

    NSLog(@"產品id==%@",response.invalidProductIdentifiers);

    NSLog(@"產品數量==========%lu",(unsigned long)myProduct.count);

    for(SKProduct *product in myProduct){

        //        SKMutablePayment

         NSLog(@"SKProduct描述資訊%@", [product description]);

        NSLog(@"產品標題 %@" , product.localizedTitle);

        NSLog(@"產品描述資訊: %@" , product.localizedDescription);

        NSLog(@"價格: %@" , product.price);

        NSLog(@"Product id: %@" , product.productIdentifier);

        SKMutablePayment *MpayMent = [SKMutablePayment paymentWithProduct:product];

        NSLog(@"===%@",MpayMent.requestData);

        if ([[SKPaymentQueue defaultQueue]respondsToSelector:@selector(addPayment:)]){

                  [[SKPaymentQueue defaultQueue] addPayment:MpayMent];

        }

        else

        {

        }

      }

}

#pragmamark-SKPaymentTransactionObserver支付結果

- (void)paymentQueue:(SKPaymentQueue *)queueupdatedTransactions:(NSArray *)transactions

{

    for (SKPaymentTransaction *transaction in transactions)

    {

        switch (transaction.transactionState)

        {

            case SKPaymentTransactionStatePurchased://交易完成

                NSLog(@"交易完成transactionIdentifier= %@", transaction.transactionIdentifier);

                [self completeTransaction:transaction];

                break;

            case SKPaymentTransactionStateFailed://交易失敗

                [self failedTransaction:transaction];

                NSLog(@"交易失敗");

                break;

            case SKPaymentTransactionStateRestored://已經購買過該商品

                [self restoreTransaction:transaction];

                NSLog(@"已買過商品");

                break;

            case SKPaymentTransactionStatePurchasing://商品新增進列表

                NSLog(@"商品新增進列表");

                break;

            default:

                break;

        }

    }

}

- (void)paymentQueue:(SKPaymentQueue *)queueremovedTransactions:(NSArray *)transactions

{

   NSLog(@"---------------移除-------------");

}

- (void)paymentQueue:(SKPaymentQueue *)queuerestoreCompletedTransactionsFailedWithError:(NSError *)error

{

    NSLog(@"---------------重複支付失敗-------------");

}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"-------------------支付完成--------------------");

    [self commitSeversSucceeWithTransaction:transaction];

}

-(void)restoreTransaction: (SKPaymentTransaction *)transaction

{

    NSLog(@"----------------重複支付-----------------");

    [self commitSeversSucceeWithTransaction:transaction];

}

- (void)commitSeversSucceeWithTransaction:(SKPaymentTransaction *)transaction

{

    NSString * productIdentifier = transaction.payment.productIdentifier;

NSString *transactionReceiptString= nil;

//系統IOS7.0以上獲取支付驗證憑證的方式應該改變,切驗證返回的資料結構也不一樣了。

    if(IOSSystemVersion>=7.0)

    {

        NSURLRequest*appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];

        NSError *error = nil;

        NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequestreturningResponse:nil error:&error];

        transactionReceiptString = [receiptDatabase64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

    }

    else

    {

        NSData * receiptData = transaction.transactionReceipt;

        transactionReceiptString = [receiptDatabase64EncodedString];

    }

        // 向自己的伺服器驗證購買憑證

   }

- (void)failedTransaction:(SKPaymentTransaction *)transaction {

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

最好在客戶端上鍵一個數據庫,跟蹤訂單的狀態,防止使用者訂單在某個環節出現問題時無法尋找到訂單進行二次處理。

去AppStore請求資料時有時候會出現錯誤,你可以iTunes connect裡的connect us去給他們寫郵件反饋問題。但是大部分時間你等等就能解決了,對就是什麼也不做等著。也許那一天他就好了。

3.後臺伺服器驗證

IOS 內支付有兩種模式:

1) 內建模式

2) 伺服器模式

內建模式的流程可以簡單的總結為以下幾步:

1) appapp store 獲取產品資訊

2) 使用者選擇需要購買的產品

3) app傳送支付請求到app store

4) app store 處理支付請求,並返回transaction資訊

5) app將購買的內容展示給使用者

伺服器模式的主要流程如下所示:

1) app從伺服器獲取產品標識列表

2) appapp store 獲取產品資訊

3) 使用者選擇需要購買的產品

4) app 傳送 支付請求到app store

5) app store 處理支付請求,返回transaction資訊

6) app transaction receipt 傳送到伺服器

7) 伺服器收到收據後傳送到app stroe驗證收據的有效性

8) app store 返回收據的驗證結果

9) 根據app store 返回的結果決定使用者是否購買成功

上述兩種模式的不同之處主要在於:交易的收據驗證,內建模式沒有專門去驗證交易收據,而伺服器模式會使用獨立的伺服器去驗證交易收據。內建模式簡單快捷,但容易被破解。伺服器模式流程相對複雜,但相對安全。

開發之初,蘋果方就很負責的告知:我們的伺服器不穩定。真正開發之後,發現蘋果方果然是很負責的,不僅是不穩定,而且足夠慢。app store server驗證一個收據需要3-6s時間。

1.使用者能否忍受3-6s的等待時間

2.如果app store server 宕機,如何確保成功付費的使用者能夠得到正常服務。

對於第一個問題,我們有理由相信使用者完全無法忍受,所以採用非同步驗證的方式,伺服器收到客戶端的請求後,就將請求放到MCQ中去處理。

對於第二個問題,由於蘋果人員很負責人的告知:我們的伺服器不穩定,所以不排除收據驗證超時的情況。對於驗證超時的收據,儲存到資料庫中並標記為驗證超時,定時任務每隔一定的時間去app store驗證,確保能夠獲取收據的驗證結果。

在開發過程中,需要測試應用是否能夠正常的進行支付,但是又不能進行實際的支付,因此需要使用蘋果提供的sandbox Store測試。Store Kit不能在iOS模擬器中使用,測試Store必須在真機上進行。

sandbox中驗證receipt

在生產環境中驗證receipt

在實際開發過程中,伺服器端通過issandbox欄位標識客戶端傳遞的收據是沙盒環境中的收據還是生產環境中的收據。在提交蘋果稽核前,沙盒測試均無問題。提交蘋果稽核後,被告知購買失敗,稽核未通過。通過查詢日誌發現,客戶端傳送的交易收據為沙盒收據,但是issandbox欄位卻標識為生產環境。

結論:蘋果稽核app時,仍然在沙盒環境下測試。但是客戶端同事在app提交蘋果稽核時,將issandbox欄位寫死,設定為生產環境。這樣就導致沙盒收據傳送到去驗證。

那麼如何自動的識別收據是否是sandbox receipt呢?

識別沙盒環境下收據的方法有兩種:

1.根據收據欄位 "environment" = "sandbox"

2.根據收據驗證介面返回的狀態碼

蘋果反饋的狀態碼;

21000App Store無法讀取你提供的JSON資料
21002
收據資料不符合格式
21003
收據無法被驗證
21004
你提供的共享金鑰和賬戶的共享金鑰不一致
21005
收據伺服器當前不可用
21006
收據是有效的,但訂閱服務已經過期。當收到這個資訊時,解碼後的收據資訊也包含在返回內容中
21007
收據資訊是測試用(sandbox),但卻被髮送到產品環境中驗證
21008
收據資訊是產品環境中使用,但卻被髮送到測試環境中驗證

先生產驗證後測試驗證,可以避免來回切換介面的麻煩。測試驗證只要用你自己申請的測試appid的時候才會用到,使用者不會擁有測試appid,所以不會走到測試驗證這一步。即使生產驗證出錯,應該也不回返回21007狀態嗎。測試驗證通過的使用者名稱,和充值金額最好用資料庫記錄下來,方便公司資金核對。

參考:


相關推薦

ios 應用支付In-App Purchase,測試後臺驗證

1.蘋果iTunes Connect內購產品資訊錄入。 1)建立app內購買專案(Create New),選擇型別: 1.消耗型專案 對於消耗型 App 內購買專案,使用者每次下載時都必須進行購買。一次性服務通常屬於消耗型專案,例如釣魚App 中的魚餌。 2.非消耗型

ios 應用支付In-App Purchase,測試後臺驗證

1.蘋果iTunes Connect內購產品資訊錄入。 1)建立app內購買專案(Create New),選擇型別: 1.消耗型專案 對於消耗型 App 內購買專案,使用者每次下載時都必須進行購買。一次性服務通常屬於消耗型專案,例如釣魚App 中的魚餌。 2.非消耗型專案

iOS應用建付費 In-App Purchase 詳細介紹(IAP詳解)

In App Purchase(程式內購買)為蘋果開發人員們打開了一個新的盈利渠道,如果您對此並不瞭解,下面這段 CocoaChina 會員“leon”翻譯的 In App Purchase 詳細介紹一定不能錯過。 一、In App Purchase概覽 Store

ios購(iap)關於問題“您已經購買了此程式購買In App Purchase專案但尚未下載"的解決方案

近日在專案內購中遇到“您已經購買了此程式內購買(In App Purchase)專案,但尚未下載”的問題,查閱google和百度各種文章,沒找到合適的解決方案,折騰一整天,終於解決,解決方案貼出來,供大家參考。也是為了驗證這個方案的正確性。歡迎拍磚! 首先說說出現這個問題的

iOS應用支付IAP服務端端校驗詳解

imageview sof 客戶端 標識 知識庫 ndb json replace undle IAP流程 IAP流程分為兩種: 一種是直接使用Apple的服務器進行購買和驗證, 另一種就是自己假設服務器進行驗證。由於國內網絡連接Apple服務器驗證非常慢,而且也為了防止黑

iOS應用支付IAP詳解

在iOS開發中如果涉及到虛擬物品的購買,就需要使用IAP服務,我們今天來看看如何實現。 在實現程式碼之前我們先做一些準備工作,一步步來看。 1、IAP流程 IAP流程分為兩種,一種是直接使用Apple的伺服器進行購買和驗證,另一種就是自己假設伺服

iOS應用支付

本文會給大家詳細介紹iOS內購,這是本人16年5月底的開發過程,希望對看完此篇文章的人有所幫助。  本文基於XcodeVersion 7.3 (7D175)版本,手機是iPhone 6,9.3系統。  部分地方直接摘自網路,基本上是我的邏輯,省時省心省力。 一. 建立測

IOS應用支付IAP從零開始詳解讓你少踩坑!

前言 什麼是IAP,即in-app-purchase 這幾天一直在搞ios的應用內購,查了很多部落格,發現幾乎沒有一篇部落格可以完整的概括出所有的點,為了防止大夥多次查閱資料,所以寫了這一篇部落格,希望大家能夠跟著我,從零開始,寫一個包含內購的應用出來 流程 一般有以下幾種

Google支付In-app Billing接入

應用內結算簡介 一、概述 使用應用內結算(In-app Billing)時,我們的應用通過相應的API來訪問In-app Billing服務。應用不直接與Google Play伺服器通訊,而是通過程序間通訊(IPC)向Google Play傳送結算請求並接收Google

IOS應用購的種類

Glossary IAP - In App Purchase, 應用內購。 內購種類 consumable - 可消費的,比如遊戲中的金幣,金幣可以購買遊戲道具或者裝備,這個金幣是可以消費的,用完之後可以再購買。 non-consumable - 不可消費的,一次購買,永久生效,比如去廣告,解鎖遊

iOS應用支付(IAP)的注意事項

來源:http://blog.csdn.net/xinruiios/article/details/9289573 IAP的全稱是In-App Purchase,應用內付費。這種業務模式允許使用者免費下載試用,對應用內提供的商品選擇消費,比如購買遊戲道具,購買遊戲等級

iOS應用支付(IAP)開發步驟

前兩天和服務端同事一起,完成了應用內付費(以下簡稱IAP, In app purchase)的開發工作。步驟繁多,在此把開發步驟列表整理如下。因為只是步驟列表,所以並不含詳細的說明教程,需要看教程的新手,可以看我附在最後的一些參考連結。 配置Developer.apple.com 為應用建立建立一個

iOS應用支付(IAP)開發中後期的那些坑

一,Product ID無效? 好了,經過前面的準備後,就到了真正和IAP聯通的步驟了。在輸入一個Product ID向伺服器發起request的時候,很有可能出現失敗的情況,在request屬性InvalidateIdentifier中,你會發現這個Product I

[iOS]應用支付(購)的個人開發過程及坑!

本文會給大家詳細介紹iOS內購,這是本人16年5月底的開發過程,希望對看完此篇文章的人有所幫助。 本文基於XcodeVersion 7.3 (7D175)版本,手機是iPhone 6,9.3系統。 部分地方直接摘自網路,基本上是我的邏輯,省時省心省力。 一

iOS 應用付費IAP開發步驟

參考文章連結: (1)http://mobile.51cto.com/iphone-389249.htm (2)http://blog.csdn.net/xiaominghimi/article/details/6937097 (3)http://zengwu3915.bl

iOS 蘋果In-App Purchase 踩過的坑

專案裡面要接蘋果支付,結果我研究了一個小時的apple pay,結果經理說是蘋果內購,當時就感覺被耍了!好了,那就說說In-App Purchase這個吧,前面所有的準備工作經理做完了,我只是碼程式碼,結果購買的回撥都執行,就是介面啥反應都沒有,不知道是前期的工

iOS開發--In-app Purchase驗證方法

IOS7開始:AppStore增加了驗證內購(In App Purchasement)的方法, 以確保此次支付是有效地. 下面是蘋果提供的驗證地址: 開發測試用: https://sandbox.itunes.apple.com/verifyReceipt 產品用: https://buy.itunes.a

In-App Purchase 被拒絕!IOS App上傳App Store 由於使用第三方支付而被拒絕的解決方案

Guideline 3.1.1 - In-App Purchase We noticed that your app contains a payment mechanism other than in-app purchase for digital content

iOS In-App Purchase 購之 問題總結

1、內購流程 1、在 AppStore 中建立相應的物品,建立內購沙盒測試賬號2、客戶端從後臺獲取相應的物品 ID (當然也可以再客戶端寫死,但後期擴充套件性就受限制了)3、依據相應的物品 ID 請求商品的相關資訊4、依據商品資訊建立訂單請求交易5、依據返回

iOS In-App Purchase 購之使用產品元資料

Working with Your Product’s Metadata 你可以改變除了產品ID和型別之外的產品的任何元資料。有些變化需要蘋果公司的審查。提交前的變化。如果你的程式內建購買產品從未被提交給蘋果稽核,您可以更改產品的詳細資訊。參考名稱。您可以隨時更改產品的名