iOS开发--In-app Purchase内购验证方法
来源:互联网 发布:强制刷机软件 编辑:程序博客网 时间:2024/04/27 16:11
IOS7开始:AppStore增加了验证内购(In App Purchasement)的方法, 以确保此次支付是有效地.
下面是苹果提供的验证地址:
开发测试用:
https://sandbox.itunes.apple.com/verifyReceipt
产品用:
https://buy.itunes.apple.com/verifyReceipt
当购买成功时,会得到苹果返回的一个收据(receipt),苹果推荐的方法是将收据发给开发者的server,由server像上述地址post http消息,进行验证,苹果将结果返回.用来判断到底是真正的购买还是虚假的购买.
当然,我们也可以在客户端来验证,代码如下:
#define ITMS_SANDBOX_VERIFY_RECEIPT_URL @"https://sandbox.itunes.apple.com/verifyReceipt"#pragma mark - VerifyFinishedTransaction-(void)verifyFinishedTransaction:(SKPaymentTransaction *)transaction{ if(transaction.transactionState == SKPaymentTransactionStatePurchased){ NSData *transactionReceipt = transaction.transactionReceipt; //将transactionIdentifer和加密后的transactionReceipt数据发送给server端// NSString* receipent = [NSString stringWithFormat:@"%s", transactionReceipt.bytes];//用来POST给server NSDictionary *requestContents = @{ @"receipt-data": [self encode:(uint8_t *)transactionReceipt.bytes length:transactionReceipt.length]}; NSLog(@"receipent = %@", requestContents); // 在app上做验证, 仅用于测试 NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:ITMS_SANDBOX_VERIFY_RECEIPT_URL]]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:requestData]; NSError* err; NSURLResponse *theResponse = nil; NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&err]; NSError *jsonParsingError = nil; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonParsingError]; NSLog(@"requestDict: %@", dict); }}//Base64加密- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length { static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData *data = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t *output = (uint8_t *)data.mutableBytes; for (NSInteger i = 0; i < length; i += 3) { NSInteger value = 0; for (NSInteger j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { value |= (0xFF & input[j]); } } NSInteger index = (i / 3) * 4; output[index + 0] = table[(value >> 18) & 0x3F]; output[index + 1] = table[(value >> 12) & 0x3F]; output[index + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; output[index + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; } return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];}
正确地返回数据应该是:
{
receipt = {
bid = APPBundleID
bvrs = AppVersion
"item_id" = 1011063440;
"original_purchase_date" = "2015-06-25 02:40:46 Etc/GMT";
"original_purchase_date_ms" = 1435200046685;
"original_purchase_date_pst" = "2015-06-24 19:40:46 America/Los_Angeles";
"original_transaction_id" = 1000000160740781;
"product_id" = ProductID
"purchase_date" = "2015-06-25 02:40:46 Etc/GMT";
"purchase_date_ms" = 1435200046685;
"purchase_date_pst" = "2015-06-24 19:40:46 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000160740781;
"unique_identifier" = bea76003f25d87d1572ac452f600ef2575af0c7f;
"unique_vendor_identifier" = "7C4CE200-847F-4F5C-BE32-04FAEE6C64E7";
};
status = 0;
}
其中: status=0,表示支付有效.
下面是其他的一些状态码:
Status Code
Description
21000
The App Store could not read the JSON object you provided.
21002
The data in the receipt-data property was malformed or missing.
21003
The receipt could not be authenticated.
21004
The shared secret you provided does not match the shared secret on file for your account.
Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21005
The receipt server is not currently available.
21006
This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.
Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21007
This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
21008
This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.
- iOS开发--In-app Purchase内购验证方法
- iOS开发 app内购In-App Purchase(一)
- iOS开发 app内购In-App Purchase(二)
- iOS内购In-App Purchase
- in-app Purchase (iOS内购)
- iOS 开发 初级:应用内购买 In-App Purchase
- iOS 开发 初级:应用内购买 In-App Purchase
- IOS 应用内购买(In-App Purchase)之开发
- ios In-App Purchase 内购验证购买是沙盒环境还是真实环境
- iOS In-App Purchase 内购之 验证订单是沙盒环境还是真实环境
- C# [IPA]IOS In App Purchase(内购)验证(asp.net 版本)
- iOS开发内购教程In App Purchase 需要了解的
- iOS In-App Purchase 内购之简介
- iOS In-App Purchase 内购之问题总结
- iOS In-App Purchase 内购之 问题总结
- iOS In-App Purchase 内购之问题总结
- ios 应用内购买 In-App Purchase
- ios 应用内支付(In-App Purchase,沙盒测试,后台验证)
- IOS利用app groups实现app间数据共享
- c++单链表里查找最小值和次小值函数
- nginx搭建pathinfo模式支持
- 命令行启动mysql时“服务名无效”
- 把自己的jsp或html模板添加到myeclipse中
- iOS开发--In-app Purchase内购验证方法
- oracle sql
- Jenkins -- #of executor 的意思
- leetcode-163Sum Closest
- CocoaPods安装和使用
- JNI内存泄露JNI ERROR (app bug): local reference table overflow (max=512)
- TCP和UDP
- Hibernate JPA 悲观锁,乐观锁
- Eclipse上的Android工程显示出错,但是其实没有异常解决