內(nèi)購(gòu)的安全用法

最近一直在做app內(nèi)購(gòu)買(mǎi)的項(xiàng)目, 簡(jiǎn)單總結(jié)一下.
準(zhǔn)備工作這里就不再贅述了, 主要講一下, 注意事項(xiàng), 大家有時(shí)會(huì)忽略, 后期可能造成特別大的溝通成本.
有興趣的同學(xué)也可以參考:https://github.com/Balopy/PurchaseInApp

交易結(jié)束時(shí), 需要向 iTunes Store 驗(yàn)證票據(jù)信息. 分為兩種, 這里我定義了兩個(gè)宏:

沙盒測(cè)試環(huán)境驗(yàn)證
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式環(huán)境驗(yàn)證
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
  
  //系統(tǒng)IOS7.0以后,驗(yàn)證返回的數(shù)據(jù)
    //得到的憑證只能使用 base64解碼,規(guī)則這么定的
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
    
    if (!receipt) {
        
        if (self.failTransaction) {
            
            self.failTransaction (@"交易失敗");
        }
        return;
    }
   
    // Create the JSON object that describes the request
    NSString *receiptCode = [receipt base64EncodedStringWithOptions:0];
    NSError *error;
    NSDictionary *requestContents = @{
                                      @"receipt-data": receiptCode
                                      };
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error];

    // Create a POST request with the receipt data.
    NSURL *storeURL = [NSURL URLWithString:AppStore];
    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
    [storeRequest setHTTPMethod:@"POST"];
    [storeRequest setHTTPBody:requestData];
    
    // Make a connection to the iTunes Store on a background queue.
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (connectionError) {
            /* ... Handle error ... */
        } else {
            
            NSError *error;
            NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
           
            if (!jsonResponse) {//為空
               
                if (self.failTransaction) {
                    
                    self.failTransaction (@"驗(yàn)證失敗");
                }

            } else {
            
                [self checkPayForReciept:jsonResponse receipt:receiptCode];
            }
        }
    }];
    
    
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

通過(guò)返回的 jsonResponse 數(shù)據(jù)中的 status, 做判斷, 驗(yàn)證票據(jù)信息, 是否正確
可參考官方文檔
https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt

- (void) checkPayForReciept:(NSDictionary *)jsonResponse receipt:(NSString *)receipt {
    
    NSUInteger status = [[jsonResponse objectForKey:@"status"] integerValue];
    
    NSString *message = @"";
    switch (status) {
            
        case 0: {//驗(yàn)證成功
            NSString *temp = [NSString stringWithFormat:@"%@#",AppStore];
            
            message = [temp stringByAppendingString:receipt];
        } break;
            
        case 21007://使用的是沙盒測(cè)試賬號(hào), 但是線上環(huán)境
        {
            NSString *temp = [NSString stringWithFormat:@"%@#",SANDBOX];
            
            message = [temp stringByAppendingString:receipt];
        }
            break;
        case 21008://使用的是線上賬號(hào), 但是沙盒測(cè)試環(huán)境
        {
            
            NSString *temp = [NSString stringWithFormat:@"%@#",AppStore];
            
            message = [temp stringByAppendingString:receipt];
        }
            break;
            
        default:
            break;
    }
    
    if (self.purchaseBlock) {
        self.purchaseBlock (message);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容