IAP实现之一掉单优化处理 — cocos2dx

11 篇文章 0 订阅
6 篇文章 0 订阅


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!");
        
    }
}

2.删除缓存
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值