SDK接入(3)之iOS內支付(In-App Purchase)接入

来源:http://www.cnblogs.com/alphagl/archive/2016/11/07/6035546.html
-Advertisement-
Play Games

"SDK接入(3)之iOS內支付(In App Purchase)接入" 繼整理了Android平臺的SDK接入過程。再來分享下iOS平臺的內支付(In App Purchase)接入,作為筆者在游戲開發中實際遇到的,覺得有必要分享下,同時也當作是對工作的總結,就放在該SDK接入系列文章中了。 作者 ...


SDK接入(3)之iOS內支付(In-App Purchase)接入

繼整理了Android平臺的SDK接入過程。再來分享下iOS平臺的內支付(In-App Purchase)接入,作為筆者在游戲開發中實際遇到的,覺得有必要分享下,同時也當作是對工作的總結,就放在該SDK接入系列文章中了。

作者:AlphaGL。版權所有,歡迎保留原文鏈接進行轉載 :)

作為SDK接入系列,同時也是Android平臺的SDK接入有:
SDK接入(2)之Android Google Play內支付(in-app Billing)接入
SDK接入(1)之Android Facebook SDK接入

這裡提一點,SDK的接入,官方文檔肯定最詳細,最準確,而且有時效性,接入流程變化,API修改更新,肯定最終都以官方的為準。那麼,蘋果官方內支付(IAP)接入文檔地址為:

In-App Purchase Programming Guide

iOS內支付流程

1.商品種類

在瞭解蘋果IAP內支付之前,有必要先瞭解下蘋果的商品種類。在蘋果In-App Purchase Programming Guide文檔上寫明瞭,商品種類分為如下幾種。接過GooglePlay支付的會發現,這點還是很相似的。
(1)消耗類商品
每次使用都須從新購買。
(2)非消耗類商品
購買一次即可。系統會自己購買狀態,且會同步所有用戶設備都一直保持可用狀態。
(3)自動再生訂閱
例如:一本書的章節內容。
(4)非自動再生訂閱
例如:一個航班表。
(5)免費訂閱
例如:報刊雜誌等。

消耗類與非消耗類商品的區別:
原文:http://www.cnblogs.com/alphagl/

訂閱類商品的區別:
原文:http://www.cnblogs.com/alphagl/

2.支付流程

對於IAP整個下單到支付過程,下圖很形象的說明瞭該步驟:
原文:http://www.cnblogs.com/alphagl/

(1) 應用向伺服器發送請求,獲得一份產品列表。

(2) 伺服器返回包含商品標識符的列表。

(3) 應用向App Store發送請求,得到商品的信息。

(4) App Store返回商品信息。

(5) 應用把返回的商品信息顯示在UI界面上。

(6) 用戶選擇某個商品。

(7) 應用向App Store發送支付請求。

(8) App Store處理支付請求並返回交易完成信息。

(9) 應用從信息中獲得數據,併發送至伺服器。

(10) 伺服器紀錄數據,併進行校驗。

(11) 伺服器將數據發給App Store來驗證該交易的有效性。

(12) App Store對收到的數據進行解析,返回該數據和說明其是否有效的標識。

(13) 伺服器讀取返回的數據,確定用戶購買的內容。

(14) 伺服器將購買的內容傳遞給程式。

3.配置商品

(1)打開iTunes Connect後臺
用開發者帳號,登錄iTunes Connect,企業級用戶需用主開發者帳號。

(2)配置iTunes Connect
在iTunes Connect後臺添加應用,並配置App內購買項目,由於我們游戲中的鑽石、金幣等都屬於消耗型商品,因此,直接選的這個。需註意下配置的Bundle id須和項目plist中的Bundle id一致。並添加沙箱測試帳號。

註意:商品Id不可重覆,如果刪除某個商品,以後這個商品的ID也不可用,即使它已經被刪除了;另外類型也不能改,選錯了只能重新增加一個商品。

iOS內支付接入

1. 項目工程引入StoreKit.framework
2. 這裡推薦一個叫IAPHelper的開源封裝,有效的封裝支付流程,進一步簡化了接入的效率。所以,下麵也是基於該項目進行的接入。IAPHelper可自行Github搜索。

(1)InAppRageIAPHelper.m。在init中初始化商品id列表。

// 原文:http://www.cnblogs.com/alphagl/
#import "InAppRageIAPHelper.h"
#import "InAppRageIAPHelper.h"

@implementation InAppRageIAPHelper
@synthesize orderInfo = _orderInfo;

static InAppRageIAPHelper * _sharedHelper;

+ (InAppRageIAPHelper *) sharedHelper {
    if (_sharedHelper != nil) {
        return _sharedHelper;
    }

    _sharedHelper = [[InAppRageIAPHelper alloc] init];
    return _sharedHelper;
}

- (void)dealloc
{
    [_orderInfo release];
    _orderInfo = nil;
    [super dealloc];
}

- (id)init {
    NSSet *productIdentifiers = [NSSet setWithObjects:
                                 @"com.game.test.10001",
                                 @"com.game.test.10002",
                                 @"com.game.test.10003",
                                 @"com.game.test.10004",
                                 @"com.game.test.10005",
                                 nil];
    
    if ((self = [super initWithProductIdentifiers:productIdentifiers])) {                
        
    }
    
    return self;
}

@end

(2)註冊本地通知。一般在應用啟動時,添加如下代碼:(productsLoaded、productPurchased、productPurchaseFailed分別對應支付過程中三種載入中,支付完成,支付失敗狀態回調,可根據實際情況作對應的處理)

    // 原文:http://www.cnblogs.com/alphagl/
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(productsLoaded:) name:kProductsLoadedNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(productPurchased:) name:kProductPurchasedNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object:nil];
    [[InAppRageIAPHelper sharedHelper]requestProducts];

(3)發起支付。

    // 原文:http://www.cnblogs.com/alphagl/
    if ([SKPaymentQueue canMakePayments]) {
        [[InAppRageIAPHelper sharedHelper]buyProductIdentifier:[self getItemId] game_order:[self getOrderId]];
    } else {
        // 不允許程式內付費購買
        
    }

(4)支付成功的回調。這裡將AppStore返回的數據,進行Base64加密,然後再發送給游戲伺服器進行校驗。同時,本地也會存儲返回的票據receipt,防止在發送給伺服器過程中請求失敗,造成的充值成功但不到賬的漏單現象。

// 原文:http://www.cnblogs.com/alphagl/
-(NSData*)receiptWithTransation:(SKPaymentTransaction*) transcation {
    NSData *receipt = nil;
    if ([[NSBundle mainBundle]respondsToSelector:@selector(appStoreReceiptURL)]) {
        NSURL *receiptUrl = [[NSBundle mainBundle]appStoreReceiptURL];
        receipt = [NSData dataWithContentsOfURL:receiptUrl];
    } else {
        if ([transcation respondsToSelector:@selector(transactionReceipt)]) {
            receipt = [transcation transactionReceipt];
        }
    }
    
    return receipt;
}

-(void)productPurchased:(NSNotification*) notification {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    SKPaymentTransaction *transaction = (SKPaymentTransaction*)notification.object;
    
    NSData *receipt = [self receiptWithTransation:transaction];
    NSString *base64Receipt = [receipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    [[InAppRageIAPHelper sharedHelper].orderInfo setObject:[NSString stringWithFormat:@"%@", base64Receipt] forKey:@"originReceipt"];
    
    NSString *m_params = [self makeHttpParams:base64Receipt];
    if (m_params != nil) {
        [self saveReceipt:m_params];
        [self postGameServer:[self getPayUrl] params:m_params];
    }
}

(5)漏單檢測。下次,啟動時,會進行漏單檢測。若存在本地票據receipt,就向游戲伺服器發起請求。直到游戲伺服器返回成功,再刪除本地的票據receipt。

    // 原文:http://www.cnblogs.com/alphagl/
    NSUserDefaults *userDefalut = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *receiptDict = [NSMutableDictionary dictionaryWithDictionary:[userDefalut objectForKey:@"receipts"]];
    NSEnumerator *enumerator = [receiptDict objectEnumerator];
    for (NSObject *obj in enumerator) {
        [self postGameServer:[self getPayUrl] params:[NSString stringWithFormat:@"orderdata=%@",obj]];
    }

(6)由於,我們的校驗是放在伺服器進行的,所以,這裡就不進行過多的介紹了。簡單說下,App Store正式環境校驗地址是https://buy.itunes.apple.com/verifyReceipt ,測試環境校驗地址是:https://sandbox.itunes.apple.com/verifyReceipt

iOS支付安全問題

對於某些越獄設備來說,如果校驗流程有漏洞的話,使用某些神器,就能繞過Appstore的付費流程,偽造訂單,達到免支付體驗各種付費功能。
其中列舉如下神器:
(1)ap cracker:越獄軟體可以截獲付費請求,並直接返回付費成功。
(2)iap free: 截獲付費請求的同時,還能截獲客戶端發起的驗證請求 ,返回驗證成功的數據 ,返回的數據和官方的數據並不是完全一樣,可以識別出來是否作弊,但是不保證永久有效。

因此,首先在支付成功之後,要將支付成功返回的票據發送給伺服器,在伺服器端作驗證,根據伺服器的驗證結果來做相應的處理。其次,本地對應偽造的票據進行過濾。

技術交流QQ群:528655025
作者:AlphaGL
出處:http://www.cnblogs.com/alphagl/
版權所有,歡迎保留原文鏈接進行轉載 :)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 感覺一個人玩lol也沒意思了,玩會手機,看到這個下拉刷新功能就寫了這個demo! 這個demo寫的比較隨意,咱不能當做插件使用,基本思想是沒問題的,要用就自己封裝吧! 直接上代碼分析下吧! 佈局: 就2行,只為實現功能,足矣! js也不複雜,先定義2個變數,貫穿整個demo,進了不要全局變數,當然, ...
  • 前言 在一個應用中,通常會有很多圖片,眾所周知,載入圖片需要時間,在圖片沒有載入出來之前,頁面會是空白,為了提升用戶體驗,應用的開發人員使出渾身解數,其中最為常見的就是在圖片沒有載入完成之前,有一個載入動畫。這裡用到的技術主要是圖片預載入。圖片預載入的原理並不難,當給一個Image對象設置src屬性 ...
  • CSS hack的原理 由於不同的瀏覽器和瀏覽器各版本對CSS的支持及解析結果不一樣,以及CSS優先順序對瀏覽器展現效果的影響,我們可以據此針對不同的瀏覽器情景來應用不同的CSS。 CSS hack分類 CSS Hack大致有3種表現形式,CSS屬性首碼法、選擇器首碼法以及IE條件註釋法(即HTML頭 ...
  • JavaScript 是允許給基本類型擴充功能的。例如,可以通過對Object.prototype增加方法,可以讓該方法對所有的對象都可用。 這樣的方式對函數,數組,字元串,數字,正則表達式和布爾值同樣適用。 例如,可以通過對Function.prototype 增加方法對所有的函數可用: 通過給F ...
  • 增 push 在數組的末尾添加一個或多個元素,並返回新的長度。 array.push(1,2,3.........) unshift 在數組的開頭添加一個或多個元素,並返回新的長度。 array.unshift(1,2,3......) splice 在制定位置添加一個活多個元素,splice(st ...
  • jquery方法 siblings 用於選取每個匹配元素的所有同輩元素(不包括自己),並以jQuery對象的形式返回。 index 返回指定元素相對於其他指定元素的 index 位置,如果未找到元素,index() 將返回 -1 用法實例 siblings 除第三個之外,給每個li標簽添加背景色 ...
  • 在實際工作中,經常遇到客戶需要用代碼設置系統時間的需求,但是Android非系統應用是無法設置系統時間的。於是,我設計了一個使用系統簽名的時間設置服務,客戶通過bind調用服務里的方法就能達到設置時間的目的。 這裡用到的技術有: 1、Signapk簽名 2、AIDL 3、bind service 將 ...
  • 錯誤日誌圖 被這弱智的錯誤吭了半個小時,項目本來好好的,然後因為改版加了很多東西,所以就超限了,一開始總是報下麵那圖的錯,搞的我總以為是retrofit的錯,但是好好的框架而且沒改過,怎麼可能會出錯呢,然後就總是猜測或者是編譯器的吭,運行的是上次的代碼,可是試了好多次還是如此,最後我卸載app在重裝 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...