IAP实现之一掉单优化处理 — cocos2dx
来源:互联网 发布:无忧推广软件骗局 编辑:程序博客网 时间:2024/06/09 15:10
IAP实现之一掉单优化处理 — cocos2dx
前两片文章分别介绍了苹果内购的两种验证方式处理,那么在内购的过程中,会不可避免的出现些掉单情况,比如网络不好,程序闪退,或者使用外挂恶意刷单等种种突发原因,导致玩家支付成功却未能实现后台验证加货币的情况,以下介绍的方案只是优化中的一种。
1.在收到内购支付成功回调函数中,发送receipt-data至服务器的同时,将订单号和receipt-data缓存到本地。
2.服务器验证完毕后返回给客户端回调函数处理删除缓存中该订单号和recepit-data。
3.同时,根据实际情况(比如像在打开商城界面的时候,刷新),在程序某个地方调用遍历缓存数据,重新发起这些缓存数据至服务器验证。
具体流程代码实现:
1.缓存iapUnhandledOrderAddData
- (void)iapDealReceiptFun:(SKPaymentTransaction *)transaction{ NSData *receipt; // [[UIDevice currentDevice].systemVersion floatValue] < 6.0 if ([[UIDevice currentDevice].systemVersion floatValue] < 6.9f) { NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle] appStoreReceiptURL]];//苹果推荐 NSError *error = nil; receipt = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:&error]; } else { receipt = transaction.transactionReceipt; } if (!receipt) { /* No local receipt -- handle the error. */ } //因为此处可能会多次调用原因不明所以加判断只调用一次 else if (receipt && self.startContentService) { /** 服务器要做的事情: 接收ios端发过来的购买凭证。 判断凭证是否已经存在或验证过,然后存储该凭证。 将该凭证发送到苹果的服务器验证,并将验证结果返回给客户端。 如果需要,修改用户相应的会员权限 */ NSString *recepitNStr = [receipt base64EncodedStringWithOptions:0]; CCHelp* cppHelper = GetCCHelp(); cppHelper->iapUnhandledOrderAddData(PayInstance::GetPayInstance()->getCurOrderIdStr().c_str(), [recepitNStr UTF8String]); cppHelper->purchaseRecepit(PayInstance::GetPayInstance()->getCurOrderIdStr().c_str(),[recepitNStr UTF8String]); }}
void CCHelp::iapUnhandledOrderAddData(const char* orderStr,const char* recepitDataStr){ std::string writeFilePath = FileUtils::getInstance()->getWritablePath(); std::string m_IapCacheStr = writeFilePath + "iapLostcache.plist"; ValueMap m_CacheMap; if(FileUtils::getInstance()->isFileExist(m_IapCacheStr)){ m_CacheMap = FileUtils::getInstance()->getValueMapFromFile(m_IapCacheStr); } else{ //创建缓存文件并存入测试数据 //创建目录 //FileUtils::getInstance()->createDirectory(m_IapCacheStr); Value firstValue = Value("recepitdata_1"); m_CacheMap.insert(std::make_pair("orderstr_1",firstValue)); m_CacheMap.insert(std::make_pair("orderstr_2",Value(""))); //初次写入 创建文件 FileUtils::getInstance()->writeToFile(m_CacheMap,m_IapCacheStr); } ValueMap::iterator iter; for(iter = m_CacheMap.begin() ; iter != m_CacheMap.end() ; ++iter) { std::string orderCurStr = iter->first; if(YYCompareStr(orderStr, orderCurStr.c_str())){ return; } } Value curValue = Value(recepitDataStr); m_CacheMap.insert(std::make_pair(orderStr,curValue)); bool writeResult = FileUtils::getInstance()->writeToFile(m_CacheMap,m_IapCacheStr); if(writeResult){ CCLOG("write success!"); } else{ CCLOG("write error!"); }}
void CCHelp::iapUnhandledOrderDeleteData(const char* orderStr){ std::string writeFilePath = FileUtils::getInstance()->getWritablePath(); std::string m_IapCacheStr = writeFilePath + "iapLostcache.plist"; ValueMap m_CacheMap; if(FileUtils::getInstance()->isFileExist(m_IapCacheStr)){ m_CacheMap = FileUtils::getInstance()->getValueMapFromFile(m_IapCacheStr); ValueMap::iterator iter; for(iter = m_CacheMap.begin() ; iter != m_CacheMap.end() ;) { std::string orderCurStr = iter->first; if(YYCompareStr(orderStr, orderCurStr.c_str())){ //缓存中找到订单号 iter = m_CacheMap.erase(iter); CCLOG("erase success!"); //写入plist问价 FileUtils::getInstance()->writeToFile(m_CacheMap,m_IapCacheStr); return; } else{ ++iter; } } } else{ CCLOG("no orderstr erase!"); return; }}
3.遍历缓存验证receipt-data
void CCHelp::iapUnhandledOrderRecovery(){ std::string writeFilePath = FileUtils::getInstance()->getWritablePath(); std::string m_IapCacheStr = writeFilePath + "iapLostcache.plist"; ValueMap m_CacheMap; if(FileUtils::getInstance()->isFileExist(m_IapCacheStr)){ m_CacheMap = FileUtils::getInstance()->getValueMapFromFile(m_IapCacheStr); ValueMap::iterator iter; for(iter = m_CacheMap.begin() ; iter != m_CacheMap.end() ; ++iter) { std::string orderCurStr = iter->first; std::string recepitdataCurStr = m_CacheMap.at(orderCurStr.c_str()).asString(); if(!YYCompareStr(recepitdataCurStr.c_str(), "") && !YYCompareStr(orderCurStr.c_str(),"orderstr_1")){ purchaseRecepit(orderCurStr.c_str(),recepitdataCurStr.c_str()); } } } else{ CCLOG("no plist data recovery!"); return; }}
流程结束,如有新优化内容,后续补充。
阅读全文
0 0
- IAP实现之一掉单优化处理 — cocos2dx
- IAP实现之一服务器模式 — cocos2dx
- IAP实现之一内建模式 — cocos2dx
- 处理ipv6和内购(IAP)及掉单问题的正确姿势
- 处理ipv6和内购(IAP)及掉单问题的正确姿势
- 【Cocos2d-x 012】 cocos2dx内存优化(之一)
- IAP 实现
- [cocos2dx 3.0 + iap]中文文档
- Cocos2dx-lua实现单例设计模式
- cocos2dx radiogrouop单选按钮的实现
- 苹果IAP开发中的那些坑和掉单问题
- 正确处理ipv6和内购(IAP)及掉单问题
- STM32存储器 — <3> STM32实现IAP(上位机和IAP程序设计)
- STM32的IAP实现
- STM32 IAP实现流程
- cocos2dx-3.3 lua实现一个单选按钮
- cocos2dx-3.x android ant配置实现单工程管理
- 简单使用Cocos2dx-lua 实现单例模式
- 博凌科技携手中企动力用互联网思维卖乐器
- 众数问题
- Android Volley完全解析之加载网络图片
- eclipse优化和快捷键
- Python中使用Beautiful Soup库的超详细教程
- IAP实现之一掉单优化处理 — cocos2dx
- 设计模式<二>单例模式
- 如何从MySQL全备文件中恢复单个库或者单个表
- java--多线程--CAS
- 一个软件开发者的历史 1996年9月
- JSTL拼接table并且每行两条数据
- sqlserver查询数据库中有多少个表
- android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl
- Linux下开发调试中大型C语言代码-如何提高效率