【支付】Cocos2d-x IOS內購(IAP支付)
【說明】
遊戲開發中,整合支付是一個重要的環節,AppStore稽核指南規定,App內虛擬物品必須使用IAP支付。這篇文章主要記錄我在整合IAP的過程,我參考了泰然網的一篇文章,對其進行了封裝和擴充套件,並對結構和使用流程進行了簡單的介紹,僅供自己學習使用。
關於iTunes Connect上的商品配置,可以參考泰然網的文章,這裡只對程式碼進行討論。
更新:加入內購恢復介面,一鍵恢復購買過的非消耗型商品。(蘋果規定費消耗型商品必須要有恢復購買)
【參考】
泰然網:http://www.tairan.com/archives/5515
完整程式碼: http://download.csdn.NET/detail/ldpjay/8949991
【封裝】
1. 結構介紹:
結構和核心程式碼還是參照泰然網的那篇文章,我主要是在其基礎上封裝做了一些封裝和強化,更加方便使用。
> IOSiAP:支付核心類,實現各種請求,直接呼叫API的介面。(在mm檔案中會實現一些API的回撥函式)
> IOSiAPDelegate:代理類(抽象類),方法會在API返回結果時呼叫,在IOSiAP_Birdge中實現,以達到將結果傳遞出去的目的。
> IOSiAP_Bridge:起到橋樑作用的中間類,主要功能是呼叫IOAiAP中的各種請求介面,並且IOSiAPDelegate中的結果會返回到此類中(通過代理)。
> GamePayment:單例類,純粹是為了方便使用,因為我把所有支付方式介面都統一到此類管理。(目前只有支付寶和IAP)
2. 支付流程:
如果完全按照我使用的流程說,會比較糾結,因為封裝層數太多容易混淆,這裡拋開單例那一層,直接從IOSiAP_Birdge這層開始。以下是一次正常支付的流程,都是從IOSiAP_Bridge開始請求直到其收到返回結果為止。
> 請求商品資訊:(主動)呼叫IOSiAP_Bridge的requestProducts方法,其會呼叫IOSiAP的requestProducts方法,呼叫API介面處理請求。
> 返回商品資訊:返回在iAPProductsRequestDelegate(.mm檔案中)的對應回撥函式,如果成功,進入requestDidFinish,如果失敗進入didFailWithEror,在這裡會分別呼叫IOSiAP_Bridge的onRequestProductsFinsih或者onRequestProductsError函式,即通過代理將結果傳遞到IOSiAP_Birdge中。
> 請求支付商品:(主動)呼叫IOSiAP_Birdge的requestPayment方法,其會呼叫IOSiAP的paymentWithProduct方法,呼叫API介面處理請求。
> 返回支付結果:方式與商品資訊返回一樣,但是會返回在iAPTransactionObserver(.mm檔案中)中的updatedTransactions中,注意,這裡會接收各種支付請求相關的事件,包括後面要說的回覆購買的事件。此處直接通過代理將引數傳到IOSiAP_Bridge中的onPaymentEvent進行分析處理。
到這裡,一次完整的請求支付並回撥就完成了,下面再說下回復購買的流程。
> 請求恢復購買:(主動)呼叫IOSiAP_Birdge的requestRestore方法,其會呼叫IOSiAP的restorePayment方法,呼叫API介面處理請求。
> 恢復購買結果:此時updateTransactions會受到已經購買的商品資訊(返回支付結果那裡),如果有多個就會返回多次,與支付結果一樣會呼叫IOSiAP_Birdge的onPaymentEvent處理。此時我們可以處理這些資訊,完成恢復操作。
> 恢復購買完成:當上一步資訊全部都返回完畢,在paymentQueueRestoreCompletedTransactionsFinsished會收到返回結果,如果上一步沒有內購,即沒有上一步的返回,會直接在restoreComletedTransactionsFailedWithError中返回。這兩個返回都會傳到IOSiAP_Birdge的onRestoreFinished中處理。
好了所有流程就這些了,看起來有點亂,不明白可以直接看程式碼,下面有完整版下載地址。
3. 核心程式碼:
這裡只貼出了最核心的部分,完整版見文章後面下載地址。
> IOSiAP
- class IOSiAP
- {
- public:
- IOSiAP();
- ~IOSiAP();
- void requestProducts(std::vector <std::string> &productIdentifiers); // 請求商品
- IOSProduct *iOSProductByIdentifier(std::string &identifier);
- void paymentWithProduct(IOSProduct *iosProduct, int quantity = 1); // 請求支付
- void restorePayment(); // 恢復購買
- IOSiAPDelegate *delegate;
- // === internal use for object-c class ===
- void *skProducts;// object-c SKProduct
- void *skTransactionObserver;// object-c TransactionObserver
- std::vector<IOSProduct *> iOSProducts;
- };
- class IOSiAPDelegate
- {
- public:
- virtual ~IOSiAPDelegate() {}
- // for request product
- virtual void onRequestProductsFinish(void) = 0;
- virtual void onRequestProductsError(int code) = 0;
- // for payment event (also for restore event)
- virtual void onPaymentEvent(std::string &identifier, IOSiAPPaymentEvent event, int quantity) = 0;
- // for restore finished
- virtual void onRestoreFinished(bool succeed) = 0;
- };
- @interface iAPProductsRequestDelegate : NSObject<SKProductsRequestDelegate>
- @property (nonatomic, assign) IOSiAP *iosiap;
- @end
- @implementation iAPProductsRequestDelegate
- - (void)productsRequest:(SKProductsRequest *)request
- didReceiveResponse:(SKProductsResponse *)response
- {
- ......
- }
- - (void)requestDidFinish:(SKRequest *)request
- {
- _iosiap->delegate->onRequestProductsFinish();
- [request.delegate release];
- [request release];
- }
- - (void)request:(SKRequest *)request didFailWithError:(NSError *)error
- {
- _iosiap->delegate->onRequestProductsError([error code]);
- }
- @end
- @interface iAPTransactionObserver : NSObject<SKPaymentTransactionObserver>
- @property (nonatomic, assign) IOSiAP *iosiap;
- @end
- @implementation iAPTransactionObserver
- - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
- {
- ......
- _iosiap->delegate->onPaymentEvent(identifier, event, transaction.payment.quantity);
- }
- - (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
- {
- _iosiap->delegate->onRestoreFinished(false);
- }
- - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
- {
- _iosiap->delegate->onRestoreFinished(true);
- }
- @end
- class IOSiAP_Bridge : public IOSiAPDelegate
- {
- public:
- // [請求]獲取商品資訊
- void requestProducts(std::string &identifier, iapProductCallback callback);
- // [請求]付款請求
- void requestPayment(int quantity, iapPaymentCallback callback);
- // [請求]恢復購買
- void requestRestore(iapRestoreCallback restoreCallback, iapRestoreFinishCallback finishCallback);
- public:
- IOSiAP_Bridge();
- ~IOSiAP_Bridge();
- // [回撥]請求商品資訊回撥
- virtual void onRequestProductsFinish(void);
- virtual void onRequestProductsError(int code);
- // [回撥]付款結果回撥(恢復流程也走這裡)
- virtual void onPaymentEvent(std::string &identifier, IOSiAPPaymentEvent event, int quantity);
- // [回撥]恢復購買完成回撥
- void onRestoreFinished(bool succeed);
- private:
- IOSiAP *iap; // IOSiAp例項
- std::string _identifier; // 商品編號(獲取請求)
- int _quantity; // 商品數量(購買請求)
- IOSProduct *_product; // 商品資訊(返回資訊)
- iapProductCallback _productCallback; // 外部回撥(商品資訊)
- iapPaymentCallback _paymentCallback; // 外部回撥(購買結果)
- iapRestoreCallback _restoreCallback; // 外部回撥(恢復購買);
- iapRestoreFinishCallback _restoreFinishCallback; // 外部回撥(恢復完成)
- };
- class GamePayment
- {
- public:
- static GamePayment *getInstance();
- protected:
- GamePayment();
- // IAP內購(IOS)
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- public:
- // 請求商品資訊
- void req_iap(std::string &identifier, iapProductCallback callback);
- // 購買請求
- void pay_iap(int quantity, iapPaymentCallback callback);
- // 恢復購買
- void restore_iap(iapRestoreCallback restoreCallback, iapRestoreFinishCallback finishCallback);
- private:
- IOSiAP_Bridge _iap;
- #endif
- }
相關文章
- iOS IAP內購 VS 支付寶iOS
- 【iOS】IAP內購整個流程iOS
- Flutter 接入iOS蘋果內購支付踩坑過程FlutteriOS蘋果
- iOS支付寶支付主要程式碼iOS
- iOS使用Stripe整合支付寶Alipay支付iOS
- 分析:線上購物與支付
- iOS各種支付大全iOS
- 蘋果內購IAP防掉單處理蘋果
- iOS IAP應用內購詳細步驟和問題總結指南iOS
- 內購支付踩過的坑以及自己的解決途徑
- iOS 模仿支付寶支付到賬推送,播報錢數iOS
- iOS不用官方SDK實現微信和支付寶支付XHPayKitiOS
- 對iOS端支付寶和微信支付程式碼進行整合iOS
- iOS 最新版本支付寶支付開發流程iOS
- 微信支付,支付寶支付,銀聯支付——三大支付總結
- 蘋果支付強勢崛起:移動支付即將迎來併購大戰蘋果
- 整合支付寶錢包支付 iOS SDK 的方法與經驗iOS
- iOS 微信支付(服務端下單)iOS服務端
- iOS 微信支付(客戶端下單)iOS客戶端
- PHP-Laravel支付寶支付和微信支付PHPLaravel
- 支付寶的快捷支付實現“支付”了
- 關於內購支付的流程和一些需要注意的坑
- XorPay 個人支付平臺【支援個人微信支付和支付寶支付介面】
- 支付寶線上支付介面
- iOS--支付寶環境整合iOS
- PHP語言之華為應用內購買IAP驗籤PHP
- java對接支付寶支付(手機網站支付)Java網站
- pay-spring-boot 開箱即用的Java支付模組,整合支付寶支付、微信支付SpringbootJava
- 微信的三種支付方式接入:APP支付、公眾號支付、掃碼支付APP
- 支付寶alipay移動支付
- Java接入支付寶支付教程Java
- Django呼叫支付寶支付介面Django
- vue-仿支付寶支付Vue
- 支付寶App支付全解析APP
- iOS10支付寶閃退怎麼辦 iOS10支付寶閃退解決方法iOS
- iOS WKWebView H5微信支付跳轉iOSWebViewH5
- iOS微信支付接入以及工具類封裝iOS封裝
- 乾貨系列:ios支付寶的整合iOS