ios 内购 服务器二次验证元宝处理

以前都是在本地处理内购  也没有做验证。这次手机网游 为了避免作弊 网络游戏都是在服务器端实现元宝的加减。

ios 内购 服务器二次验证元宝处理 - MOMO教程以前都是在本地处理内购  也没有做验证。这次手机网游 为了避免作弊 网络游戏都是在服务器端实现元宝的加减。内购代码 还是以前写的 直接用了 。这次主要做了服务器二次验证。https://www.momojc.cn/post_929.html

内购代码 还是以前写的 直接用了 。这次主要做了服务器二次验证。

NSString *roleId = [[NSString alloc] initWithUTF8String:name];
[[PlatformHandler sharedHandler]doBuyByRoleId:roleId money:money];
//内部函数
-(void)doBuyByRoleId:(NSString *)paramRoleId money:(int)money
{
 NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
    //是否越狱
    if ([[UIApplication sharedApplication] canOpenURL:url])
    {
        NSString *sMes = NSLocalizedString(@"SHOP_ERROR_STOREBUY_INFO", nil);
        UIAlertView *alertV = [[UIAlertView alloc]initWithTitle:nil message:sMes delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertV show];
        [alertV release];
        return;
    }
    CGSize mWinSize=  [UIScreen mainScreen].bounds.size;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0)
    {
        std::swap(mWinSize.width, mWinSize.height);
    }
    LoadingView *lv = [[LoadingView alloc] initWithFrame:CGRectMake(0, 0, mWinSize.width, mWinSize.height)];
    lv.tag = TAG_VIEW_LOADING;
    [[EAGLView sharedEGLView] addSubview:lv];
    [lv release];
    
    if ([SKPaymentQueue canMakePayments])
    {
        NSLog(@"addObserver:receiveAppStoreInfo");
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveAppStoreInfo:) name:NOTIFICATION_APPSTORE_BUY_FOLDER object:nil];
        [[CBiOSStoreManager sharedInstance] initialStore];
        [[CBiOSStoreManager sharedInstance] buy:[NSString stringWithFormat:@"%@%d",BUY_ID,index] paramRoleId:paramRoleId];
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"STR_BUY_ERROR", nil) message:NSLocalizedString(@"STR_BUY_ERROR_INFO", nil) delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
        if([[EAGLView sharedEGLView] viewWithTag:TAG_VIEW_LOADING])
            [[[EAGLView sharedEGLView] viewWithTag:TAG_VIEW_LOADING] removeFromSuperview];
    }
}
//购买成功函数回调
-(void)receiveAppStoreInfo:(id)sender
{
    NSLog(@"receive info");
    if([[EAGLView sharedEGLView] viewWithTag:TAG_VIEW_LOADING])
    {
        [[[EAGLView sharedEGLView] viewWithTag:TAG_VIEW_LOADING] removeFromSuperview];
    }
    
    NSNotification *notification = (NSNotification *)sender;
    NSString *action = [notification object];
    if ([action isEqualToString:MSG_ACTION_FINISH])
    {
        NSLog(@"------------MSG_ACTION_FINISH==============购买成功");
    }
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIFICATION_APPSTORE_BUY_FOLDER object:nil];
}
/*
 *  CBiOSStoreManager.mm
 *  CloudBox Cross-Platform Framework Project
 *
 *  Created by xxhh on 2012/10/30.
 *
 */

#import "CBiOSStoreManager.h"
#define SERVER_DOMAIN @"http://192.168.0.177"
#define TEST_SANDBOX  1
@implementation CBiOSStoreManager

//自身实例
static CBiOSStoreManager* _sharedInstance = nil;

//付费单例获取
+(CBiOSStoreManager*)sharedInstance
{
    @synchronized([CBiOSStoreManager class])
    {
        if (!_sharedInstance)
            [[self alloc] init];
        
        return _sharedInstance;
    }
    return nil;
}

//
+(id)alloc
{
    @synchronized([CBiOSStoreManager class])
    {
        NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of a singleton.\n");
        _sharedInstance = [super alloc];
        return _sharedInstance;
    }
    return nil;
}

-(id)init {
    self = [super init];
    if (self != nil) {
    }
    return self;
}

-(void)initialStore
{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
-(void)releaseStore
{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

-(void)buy:(NSString*)buyProductIDTag paramRoleId:(NSString *)paramRoleId
{
    _paramRoleId=paramRoleId;
    [self requestProductData:buyProductIDTag];
}

//查找付费列表。
-(bool)CanMakePay
{
    NSLog(@"----------CanMakePay--------------\n");
    return [SKPaymentQueue canMakePayments];
}

-(void)requestProductData:(NSString*)buyProductIDTag
{
    NSLog(@"----------Request--------------\n");
    _buyProductIDTag = [buyProductIDTag retain];
    NSArray *product = [[NSArray alloc] initWithObjects:buyProductIDTag,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(@"----------didReceiveResponse--------------\n");
    SKPayment *payment = nil;
    if (response == NULL || response.products == NULL || response.products.count == 0) {
        [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_APPSTORE_BUY_FOLDER object:MSG_ACTION_ERROR];
        [request autorelease];
        return;
    }
    payment = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
    [request autorelease];
    
}
- (void)requestProUpgradeProductData:(NSString*)buyProductIDTag
{
    NSLog(@"----------requestProUpgradeProductData--------------\n");
    NSSet *productIdentifiers = [NSSet setWithObject:buyProductIDTag];
    SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];
    
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"----------Request Failed--------------\n");
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_APPSTORE_BUY_FOLDER object:MSG_ACTION_ERROR];
    
}

-(void) requestDidFinish:(SKRequest *)request
{
    NSLog(@"----------Request finished--------------\n");
    
}

-(void) purchasedTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@"-----Purchased Transaction----\n");
    NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
    [self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
    [transactions release];
}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    NSLog(@"----------updatedTransactions--------------\n");
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"-----Transaction--购买完成-----\n");
                [self completeTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:{
                [self failedTransaction:transaction];
                NSLog(@"-----Transaction Failed--购买失败-----\n");
                break;
            }
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                NSLog(@"----- Already buy this product---已经购买-----\n");
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"-----Transcation puchasing---正在购买-----\n");
                break;
            default:
                break;
        }
    }
}

- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
    // 验证购买凭据
    [self verifyReceipt:transaction];
    NSString *sBuyID = transaction.payment.productIdentifier;
    NSLog(@"completeTransaction: BuyID: %@", sBuyID);
    
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_APPSTORE_BUY_FOLDER object:MSG_ACTION_FINISH];
    // 将交易从交易队列中删除
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

#pragma mark 本地验证购买凭据
- (void)verifyPruchase:(SKPaymentTransaction *)transaction
{
    //  transaction.transactionReceipt
    
    // 验证凭据,获取到苹果返回的交易凭据
    // appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
    //    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    // 从沙盒中获取到购买凭据
    //    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    
    // 发送网络POST请求,对购买凭据进行验证
    //    NSURL *url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
    // 国内访问苹果服务器比较慢,timeoutInterval需要长一点
    //    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
    
    //    request.HTTPMethod = @"POST";
    
    // 在网络中传输数据,大多情况下是传输的字符串而不是二进制数据
    // 传输的是BASE64编码的字符串
    /**
     BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性
     BASE64是可以编码和解码的
     */
    
    //  NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    //    NSString *encodeStr = [transaction.transactionReceipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    
    //    NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
    //    NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
    
    //    request.HTTPBody = payloadData;
    
    // 提交验证请求,并获得官方的验证JSON结果
    //    NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
    // 官方验证结果为空
    //    if (result == nil) {
    //        NSLog(@"验证失败");
    //    }
    
    //    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
    
    //    NSLog(@"%@", dict);
    
    //    if (dict != nil) {
    // 比对字典中以下信息基本上可以保证数据安全
    // bundle_id&application_version&product_id&transaction_id
    //        NSLog(@"验证成功");
    //    }
    
}
#pragma mark 服务器验证购买凭据
- (void) verifyReceipt:(SKPaymentTransaction *)transaction
{
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/verify.php", SERVER_DOMAIN]];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];
    request.HTTPMethod = @"POST";
    
    NSString *encodeStr = [transaction.transactionReceipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    
    int isSandBox =0;
#ifdef TEST_SANDBOX
    isSandBox=1;
#endif
    NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\",\"sandbox\":%d,\"paramRoleId\":\"%@\"}", encodeStr,isSandBox,_paramRoleId];
    //把bodyString转换为NSData数据
    NSData *bodyData = [payload dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];//把bodyString转换为NSData数据
    [request setHTTPBody:bodyData];
    
    // 提交验证请求,并获得官方的验证JSON结果
    NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
    // 官方验证结果为空
    if (result == nil) {
        NSLog(@"验证失败");
    }
    else
    {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
        if (dict != nil && [[dict objectForKey:@"status"]integerValue] ==1 && [[dict objectForKey:@"success"]integerValue] ==1) {
            // 比对字典中以下信息基本上可以保证数据安全
            NSLog(@"验证成功");
        }else
        {
            NSLog(@"验证失败");
        }
    }
}

-(void)recordTransaction:(NSString *)product
{
    NSLog(@"-----Record transcation--------\n");
    
}

-(void)provideContent:(NSString *)product
{
    NSLog(@"-----Download product content--------\n");
}

- (void) failedTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@"-----failedTransaction--------\n");
    NSNotification *notification= [NSNotification notificationWithName:NOTIFICATION_APPSTORE_BUY_FOLDER object:MSG_ACTION_ERROR];
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    if (center == nil  && notification == nil) {
        NSLog(@"null");
    }
    [center postNotification:notification];
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_APPSTORE_BUY_FOLDER object:MSG_ACTION_ERROR];
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        if(transaction.error.code == SKErrorUnknown)
        {
            NSLog(@"Unknown Error (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
                                                                    message: @"There was an error purchasing this item please try again."
                                                                  delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
        
        if(transaction.error.code == SKErrorClientInvalid)
        {
            NSLog(@"Client invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
                                                                    message: @"There was an error purchasing this item please try again."
                                                                  delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
        
        if(transaction.error.code == SKErrorPaymentInvalid)
        {
            NSLog(@"Payment invalid (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
                                                                    message: @"There was an error purchasing this item please try again."
                                                                  delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
        
        if(transaction.error.code == SKErrorPaymentNotAllowed)
        {
            NSLog(@"Payment not allowed (%d), product: %@", (int)transaction.error.code, transaction.payment.productIdentifier);
            UIAlertView *failureAlert = [[UIAlertView alloc] initWithTitle :@"In-App-Purchase Error:"
                                                                    message: @"There was an error purchasing this item please try again."
                                                                  delegate : self cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [failureAlert show];
            [failureAlert release];
        }
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction
{
    NSLog(@"-----paymentQueueRestoreCompletedTransactionsFinished-------\n");
    
}

- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
    NSLog(@"-----Restore transaction--------\n");
}

-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
    NSLog(@"-------Payment Queue----\n");
}


-(void)dealloc
{
    [super dealloc];
}

@end

/*
 *  CBiOSStoreManager.h
 *  CloudBox Cross-Platform Framework Project
 *
 *  Created by xxhh on 2012/10/30.
 *
 */

#import 
#import 

#define NOTIFICATION_APPSTORE_BUY_FOLDER @"buy_folder"
#define MSG_ACTION_ERROR    @"msg_action_error"
#define MSG_ACTION_FINISH   @"msg_action_finish"
#define MSG_ACTION_RESTORE  @"msg_action_restore"


@interface CBiOSStoreManager : NSObject
{
    int buyType;
    NSString* _buyProductIDTag;
    NSString* _paramRoleId;
}

+ (CBiOSStoreManager*) sharedInstance;

- (void) buy:(NSString*)buyProductIDTag paramRoleId:(NSString *)paramRoleId;
- (bool) CanMakePay;
- (void) initialStore;
- (void) releaseStore;
- (void) requestProductData:(NSString*)buyProductIDTag;
- (void) provideContent:(NSString *)product;
- (void) recordTransaction:(NSString *)product;

- (void) requestProUpgradeProductData:(NSString*)buyProductIDTag;

- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
- (void) purchasedTransaction: (SKPaymentTransaction *)transaction;

- (void) completeTransaction: (SKPaymentTransaction *)transaction;
- (void) failedTransaction: (SKPaymentTransaction *)transaction;
- (void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;
- (void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;

- (void) restoreTransaction: (SKPaymentTransaction *)transaction;

@end
//
//  LoadingView.m
//  pDownloader
//
//  Created by xxhh on 10/5/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "LoadingView.h"
#import 

@implementation LoadingView


- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame]))
    {
        // Initialization code
		self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.0];
		UIActivityIndicatorView *loadingview  = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0 , 0, 36, 36)];
        loadingview.center=CGPointMake(frame.size.width/2, frame.size.height/2-20);
		[loadingview startAnimating];
        UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"bg_black.png"]];
        image.frame = CGRectMake(0, 0, 210, 150);
        image.center=CGPointMake(frame.size.width/2, frame.size.height/2);
        [self addSubview:image];
        
        UILabel *labLoading = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 210, 200)];
        labLoading.center=CGPointMake(frame.size.width/2, frame.size.height/2+20);
        labLoading.textAlignment = UITextAlignmentCenter;
        [labLoading setText:@"Loading..."];
        [labLoading setBackgroundColor:[UIColor clearColor]];
        [labLoading setTextColor:[UIColor whiteColor]];
        [self addSubview:labLoading];
        [self addSubview:loadingview];
		UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        [self addSubview:btn];
        
        [btn release];
        [labLoading release];
		[loadingview release];
        [image release];
    }
    return self;
}


- (void)drawRect:(CGRect)rect {
    // Drawing code
}


- (void)dealloc {
    [super dealloc];
}


@end
//
//  LoadingView.h
//  pDownloader
//
//  Created by leefj on 10/5/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import 

#define TAG_VIEW_LOADING        1234


@interface LoadingView : UIView {

}

@end

php 时间函数衔接
服务器端代码

 $receipt)   
        );   
    
        $ch = curl_init($endpoint);   
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
        curl_setopt($ch, CURLOPT_POST, true);   
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);   
    
        $response = curl_exec($ch);   
        $errno    = curl_errno($ch);   
        $errmsg   = curl_error($ch);   
        curl_close($ch);   
    
        if ($errno != 0) {   
            throw new Exception($errmsg, $errno);   
        }   
    
        $data = json_decode($response);   
    
        if (!is_object($data)) {   
            throw new Exception('Invalid response data');   
        }   
    
        if (!isset($data->status) || $data->status != 0) {   
            throw new Exception('Invalid receipt');   
        }   
    
        return array(   
            'quantity'       =>  $data->receipt->quantity,   
            'product_id'     =>  $data->receipt->product_id,   //产品id
            'transaction_id' =>  $data->receipt->transaction_id,   
            'purchase_date'  =>  $data->receipt->purchase_date,   
            'app_item_id'    =>  $data->receipt->app_item_id,   
            'bid'            =>  $data->receipt->bid,   
            'bvrs'           =>  $data->receipt->bvrs   
        );   
    }


    $content=file_get_contents("php://input");
    $data = json_decode($content,true);  
    $receipt = $data["receipt-data"];   
    $isSandbox = (bool) $data["sandbox"]; 
    $paramRoleId  = $data["paramRoleId"];
    $hostIp  = $data["hostIp"];  

    try {   
        $info = getReceiptData($receipt, $isSandbox);
        $infoJson=json_encode($info);
        //进行相关充值处理
        // 日志记录
        $fh = fopen("lshudong.txt", "a+"); 
        fwrite($fh, "userId:".$paramRoleId."==hostIp:".$hostIp."==时间:".date("Y-m-d H:i:s") ." ==验证成功\n\r");
        fclose($fh);
        // 发送回传消息
        echo json_encode(array(   
            'status'       =>  1,   
            'success'     =>  1,   
        ));
     }   
     catch (Exception $ex) {   
        echo $ex;
        //日志记录
        $fh = fopen("lshudong.txt", "a+"); 
        fwrite($fh, "userId:".$paramRoleId."hostIp:".$hostIp."时间:".date("Y-m-d H:i:s") ." 验证失败\n\r");
        fclose($fh);
        //发送回传消息
        echo  json_encode(array(   
            'status'       =>  1,   
            'success'     =>  0,   
        ));
     } 
?>  
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值