我们在内购开发中,购买成功后。要把这次交易的凭证发送给服务器。让服务器去验证这次交易是否真实。
拿到凭证的代码:
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 ... */
}
}];
网友评论