IAP实现之一内建模式 — cocos2dx
来源:互联网 发布:杜克大学 知乎 编辑:程序博客网 时间:2024/06/03 22:32
cocos2dx中的IAP实现:一
A.苹果内购IAP两种模式流程:
1.内置模式:
app从app store 获取产品信息
用户选择需要购买的产品
app发送支付请求到app store
app store 处理支付请求,并返回transaction信息
app将购买的内容展示给用户
app从app store 获取产品信息
用户选择需要购买的产品
app发送支付请求到app store
app store 处理支付请求,并返回transaction信息
app将购买的内容展示给用户
2.服务器模式的流程:
app从服务器获取产品标识列表
app从app store 获取产品信息
用户选择需要购买的产品
app 发送 支付请求到app store
app store 处理支付请求,返回transaction信息
app 将transaction receipt 发送到服务器
服务器收到收据后发送到app stroe验证收据的有效性
app store 返回收据的验证结果
根据app store 返回的结果决定用户是否购买成功
上述两种模式的不同之处主要在于:交易的收据验证,内建模式没有专门去验证交易收据,而服务器模式会使用独立的服务器去验证交易收据。内建模式简单快捷,但容易被破解。服务器模式流程相对复杂,但相对安全。
B.内置模式代码实现:添加StoreKit.framework
PaymentController.h文件:
/** PaymentController.h** Created by chiu on 15-06-16.* Copyright (c) 2015年 Idlehands. All rights reserved.*/#import <UIKit/UIKit.h>#import <StoreKit/StoreKit.h>@interface PaymentController : NSObject<SKPaymentTransactionObserver,SKProductsRequestDelegate>@property NSString *productID;- (void)initProductId:(NSString*) productIdStr;- (void)purchaseFunc;@end
PaymentController.mm文件:
/* author: chiu project: BYGame date: 2016/08/22 */#import "PaymentController.h"#import "CCHelp.h"@interface PaymentController ()@end@implementation PaymentControllerstatic bool hasAddObersver = NO;- (id)initWithPayConstructor:(NSString *) productIdStr{ self = [super init]; if (self) { // Custom initialization [self initProductId:productIdStr]; if (!hasAddObersver) { hasAddObersver = YES; // 监听购买结果 [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; } } return self;}- (void)initProductId:(NSString*) productIdStr{ self.productID = productIdStr;}- (void)purchaseFunc{ NSString *product = self.productID; if([SKPaymentQueue canMakePayments]){ [self requestProductData:product]; NSLog(@"允许程序内付费"); }else{ NSLog(@"不允许程序内付费"); }}//请求商品- (void)requestProductData:(NSString *)type{ NSLog(@"-------------请求对应的产品信息----------------"); NSArray *product = [[NSArray alloc] initWithObjects:type, nil]; NSSet *nsset = [NSSet setWithArray:product]; SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset]; request.delegate = self; [request start]; [product release];}//收到产品返回信息- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSLog(@"--------------收到产品反馈消息---------------------"); NSArray *product = response.products; if([product count] == 0){ NSLog(@"--------------没有商品------------------"); return; } NSLog(@"productID:%@", response.invalidProductIdentifiers); NSLog(@"产品付费数量:%d",[product count]); SKProduct *payInfoPorduct = nil; for (SKProduct *pro in product) { NSLog(@"%@", [pro description]); NSLog(@"%@", [pro localizedTitle]); NSLog(@"%@", [pro localizedDescription]); NSLog(@"%@", [pro price]); NSLog(@"%@", [pro productIdentifier]); if([pro.productIdentifier isEqualToString:self.productID]){ payInfoPorduct = pro; } } if(!payInfoPorduct) { return; } NSLog(@"发送购买请求"); if (floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_5_0) { NSLog(@"pay_it less 5.0"); SKPayment* payment = [SKPayment paymentWithProductIdentifier:self.productID]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } else { NSLog(@"pay_it 5.0+"); SKMutablePayment* payment = [SKMutablePayment paymentWithProduct:payInfoPorduct]; payment.quantity = [product count]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } [request autorelease];}- (void)requestProUpgradeProductData{ NSLog(@"------请求升级数据---------"); NSSet *productIdentifiers = [NSSet setWithObject:@"com.productid"]; SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; productsRequest.delegate = self; [productsRequest start]; }//请求失败- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{ NSLog(@"------------------错误-----------------:%@", error); UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription] delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil]; [alerView show]; [alerView release];}- (void)requestDidFinish:(SKRequest *)request{ NSLog(@"------------反馈信息结束-----------------");}-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{ NSLog(@"-----PurchasedTransaction----"); NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil]; [self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions]; [transactions release];}//监听购买结果- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{ for(SKPaymentTransaction *tran in transaction){ switch (tran.transactionState) { case SKPaymentTransactionStatePurchased: { NSLog(@"交易完成"); [self completeTransaction:tran]; CCHelp* cppHelper = GetCCHelp(); cppHelper->purchaseResult(1,1); [[SKPaymentQueue defaultQueue] finishTransaction:tran]; } break; case SKPaymentTransactionStatePurchasing: { NSLog(@"商品添加进列表"); } break; case SKPaymentTransactionStateRestored: { NSLog(@"已经购买过商品"); [self restoreTransaction:tran]; [[SKPaymentQueue defaultQueue] finishTransaction:tran]; } break; case SKPaymentTransactionStateFailed: { NSLog(@"交易失败"); [self failedTransaction:tran]; CCHelp* cppHelper = GetCCHelp(); cppHelper->purchaseResult(1,-1); [[SKPaymentQueue defaultQueue] finishTransaction:tran]; } break; default: { CCHelp* cppHelper = GetCCHelp(); cppHelper->purchaseResult(1,-1); [[SKPaymentQueue defaultQueue] finishTransaction:tran]; } break; } }}//交易结束- (void)completeTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"交易结束"); // Remove the transaction from the payment queue. [[SKPaymentQueue defaultQueue] finishTransaction:transaction];}- (void) failedTransaction: (SKPaymentTransaction *)transaction{ if (transaction.error.code != SKErrorPaymentCancelled) { } switch (transaction.error.code) { case SKErrorUnknown: NSLog(@"SKErrorUnknown"); break; case SKErrorClientInvalid: NSLog(@"SKErrorClientInvalid"); break; case SKErrorPaymentCancelled: NSLog(@"SKErrorPaymentCancelled"); break; case SKErrorPaymentInvalid: NSLog(@"SKErrorPaymentInvalid"); break; case SKErrorPaymentNotAllowed: NSLog(@"SKErrorPaymentNotAllowed"); break; case SKErrorStoreProductNotAvailable: NSLog(@"SKErrorStoreProductNotAvailable"); break; default: break; } [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; }- (void) restoreTransaction: (SKPaymentTransaction *)transaction{ }#pragma mark connection delegate- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ }- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ switch([(NSHTTPURLResponse *)response statusCode]) { case 200: case 206: break; case 304: break; case 400: break; case 404: break; case 416: break; case 403: break; case 401: case 500: break; default: break; }}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"test");}- (void)dealloc{ [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; [super dealloc];}@end
调用例子:
/* Ios IAP entrance */ int payPrice = pNotify->GetSubType(); std::string productIdStr; switch (payPrice) { case 1024: productIdStr = "ttz_yk"; break; case 1025: productIdStr = "ttz_6"; break; default: break; } NSLog(@"----------当前商品ID: %s", productIdStr.c_str()); NSString* ocProductIdStr = [NSString stringWithFormat:@"%s", productIdStr.c_str()]; PaymentController* pPayController = [[PaymentController alloc] initWithPayConstructor:ocProductIdStr]; [pPayController purchaseFunc];
PS:内置模式并没有做订单凭证后台验证,整个流程看起来都非常简单,所以是很不安全的方式,容易被破解内购产品刷单,下篇blog处理服务器模式
阅读全文
1 0
- IAP实现之一内建模式 — cocos2dx
- IAP实现之一服务器模式 — cocos2dx
- IAP实现之一掉单优化处理 — cocos2dx
- Cocos2dx使用ios内支付IAP详细流程-白白
- Cocos2dx使用ios内支付IAP详细流程
- 堵你妹研究之一 iap应用内购买分析
- IAP应用内付费怎么实现?
- IOS应用内付费(IAP)代码实现
- IOS应用内付费(IAP)代码实现
- IOS应用内付费(IAP)代码实现
- iOS 内购IAP(In-App Purchases)代码实现(上)
- iOS 内购IAP(In-App Purchases)代码实现(下)
- IAP 实现
- unity3d内嵌IAP
- IAP 程序内购
- IAP-应用内购买
- ios iap 内购
- IAP 程序内购
- 实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定。
- dhcp服务器的配置
- ExtJs的列模式column详解
- [2017.11.25]verlauf
- TensorFlow学习笔记-ExponentialMovingAverage
- IAP实现之一内建模式 — cocos2dx
- sublime配置PHP环境
- caffe安装配置
- 深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制
- Play2 for Java(一:简介)
- 蓝桥杯-算法训练 出现次数最多的整数
- linux中数据库的操作命令
- 【深度学习笔记】(二)Hello, Tensorflow!
- 树莓派3安装raspbian stretch,tensorflow1.1和opencv3.3