内购开发中,发送receipt(凭证)+号变空格的解决办法

我们在内购开发中,购买成功后。要把这次交易的凭证发送给服务器。让服务器去验证这次交易是否真实。
拿到凭证的代码:

NSURL* receiptURL = [[NSBundle mainBundle]appStoreReceiptURL];
//这里直接转成base64是因为要发生给服务器。
NSString* receipt = [[NSData dataWithContentsOfURL:receiptURL]base64EncodedStringWithOptions:0];

但是发生过去后,发送一直凭证错误。导致浪费了,三个小时时间在找问题上。后来,对比发送前和发送后的凭证。发现!+变成了“ ”(空格)
研究后,这个特殊字符发送过去后,会发生改变。查资料后,解决办法如下:

NSURL* receiptURL = [[NSBundle mainBundle]appStoreReceiptURL];
    
NSString* receipt = [[NSData dataWithContentsOfURL:receiptURL]base64EncodedStringWithOptions:0];
receipt = [receipt stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"#%<>[\\]^`{|}\"]+"].invertedSet];

加一行代码就OK!

实际开发中,我们还可以自己去官网上先验证一下凭证,然后再发生给服务器:

这里有个有趣现象,就是不加上面那段代码,发送给苹果也是正常的,估计苹果那里做了处理。把空格替换为+号了。
NSURL* receiptURL = [[NSBundle mainBundle]appStoreReceiptURL];
//这里直接转成base64是因为要发生给服务器。
NSString* receipt = [[NSData dataWithContentsOfURL:receiptURL]base64EncodedStringWithOptions:0];

~~~//======这里有个有趣现象,就是不加上面那段代码,发送给苹果也是正常的,估计苹果那里做了处理。把空格替换为+号了。======


          .....................................
              .....................................
NSError *error;
    NSDictionary *requestContents = @{
                                      @"receipt-data": receipt
                                      };
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                          options:0
                                                            error:&error];
    
    if (!requestData) { /* ... Handle error ... */ }
    
    // Create a POST request with the receipt data.
    //正式环境请替换下面的地址为https://buy.itunes.apple.com/verifyReceipt
    NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
    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];
                                   [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
                                   if (!jsonResponse) { /* ... Handle error ...*/ }
                                   /* ... Send a response back to the device ... */
                               }
                           }];

你可能感兴趣的:(内购开发中,发送receipt(凭证)+号变空格的解决办法)