IOS应用内支付返回新旧Receipt适配的方法

ios7.0后ios支付成功返回的票据Receipt的获取方式有了新的方式,

原来的SKPaymentTransaction中的transactionReceipt属性获取票据的方式已经过期,虽然还能使用,但是苹果官方建议使用新的

新版的获取Receipt的方式是通过新接口如下

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];

当然,低于ios7.0的还是需要使用老版本接口,对两种版本进行适配的代码如下:

NSData*receipt= nil;
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){
//ios after 7.0
  NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
  receipt = [NSData dataWithContentsOfURL:receiptURL];
  NSString *receiptURLStr = [receiptURL absoluteString];
  NSRange rangeSandbox = [receiptURLStr rangeOfString:@"sandbox"];
  if (rangeSandbox.location != NSNotFound){
    record[kIAPEnvironment] = [NSNumber numberWithInt:1];
  }
}else{
//ios 3.0~7.0
  receipt = transaction.transactionReceipt;
  NSDictionary *dict = [NSDictionary dictionaryWithContentsOfData:receipt];
  if (dict){
    NSString *env = [dict objectForKey:@"environment"];
    if ([env isEqualToString:@"Sandbox"]) {
      record[kIAPEnvironment] = [NSNumber numberWithInt:1];
    }
 }
}

判断是否是沙盒支付,新版本可以直接判断receiptURL中是否存在“sandbox“

老版本receipt可以解析NSData 查看environment是否为Sandbox来判断

+ (NSDictionary *)dictionaryWithContentsOfData: (NSData *)data{
  CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (__bridge CFDataRef)data,
  kCFPropertyListImmutable, NULL);
  if(plist == nil) return nil;
  if ([(__bridge id)plist isKindOfClass:[NSDictionary class]]){
  return (__bridge NSDictionary *)plist;
  }else{
  CFRelease(plist);
  return nil;
  }
}

客户端receipt验证方式:

NSError *error;
NSDictionary *requestContents = @{
@"receipt-data": [receipt base64EncodedString]
};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:&error];
if (!requestData) {
  return;
}
// Create a POST request with the receipt data.
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];
  if (!jsonResponse) { /* ... Handle error ...*/ }
  /* ... Send a response back to the device ... */
  }
}];

老版本返回格式:

{
bid = "com.coodezhang.test";
bvrs = "1.0";
"item_id" = 892617314;
"original_purchase_date" = "2017-12-14 07:43:14 Etc/GMT";
"original_purchase_date_ms" = 1626147394550;
"original_purchase_date_pst" = "2017-12-14 12:43:14 America/Los_Angeles";
"original_transaction_id" = 1000001127239959;
"product_id" = "com.coodezhang.test_coins99M_Tier1";
"purchase_date" = "2017-12-14 07:43:14 Etc/GMT";
"purchase_date_ms" = 1626147394550;
"purchase_date_pst" = "2017-12-14 12:43:14 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000001127239959;
"unique_identifier" = 0000b0124819;
"unique_vendor_identifier" = "ASDGF2DB-DSAD-5A21-9611-642A4B9CASDE7";
};
status = 0;
}

新版本返回格式官方文档:官方文档

新版本返回格式:

{
environment = Sandbox;
receipt =   {
"adam_id" = 0;
"app_item_id" = 0;
"application_version" = 1;
"bundle_id" = "com.coodezhang.test";
"download_id" = 0;
"in_app" =     (
{
"is_trial_period" = false;
"original_purchase_date" = "2017-12-14 07:18:56 Etc/GMT";
"original_purchase_date_ms" = 1513235936000;
"original_purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
"original_transaction_id" = 1000000359369424;
"product_id" = "com.coodezhang.test_coins99M_Tier1";
"purchase_date" = "2017-12-14 07:18:56 Etc/GMT";
"purchase_date_ms" = 1513235936000;
"purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
quantity = 1;
"transaction_id" = 1000000359369424;
}
...... 可能存在多条
);
"original_application_version" = "1.0";
"original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
"original_purchase_date_ms" = 1375340400000;
"original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
"receipt_creation_date" = "2017-12-14 07:18:56 Etc/GMT";
"receipt_creation_date_ms" = 1513235936000;
"receipt_creation_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles";
"receipt_type" = ProductionSandbox;
"request_date" = "2017-12-14 07:19:23 Etc/GMT";
"request_date_ms" = 1513235963829;
"request_date_pst" = "2017-12-13 23:19:23 America/Los_Angeles";
"version_external_identifier" = 0;
};
status = 0;
}

值得注意的是,新版中数据结构中的in_app字段,可能包含多个transaction的receipt。当完成transaction后,还没有成功调用读取过receipt的接口,那下一次读取recept时会把所有的都读取出来,从而出现多条数据。

一般开发商app支付都有自己的支付系统,可能每次下单之前都会创建自己的订单号,需要与ios支付后返回的receipt一一对应,这种情况下如何处理还需要注意。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS 9.0后微信支付回调处理实例

    如果是iOS 9.0之前,处理微信回调时,首先在APPDelegate中写如下的代码: //iOS 9.0 之前的处理方法不保证正确,如有错误还望指正 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if ([url.host isEqualToStrin

  • 解决iOS调起微信支付显示系统繁忙问题

    最新刚到新公司接手一个项目,当微信支付时可以跳转到微信界面,但会弹出对话框显示 '系统繁忙',点击确定就留在微信,不返回APP,然后就各种调试,微信的DEMO和接入文档都看穿了,都还没能解决问题,网上也是找了各种答案,什么降低微信支付SDK版本,还有检查传过去的参数,也反复检查了参数,确实没发现问题,也没能解决我的问题,安卓那边可以微信支付,iOS这边不行,参数都是由服务器返回的一样的参数,所以也解决参数不会有问题,然后无意中看到了网上一个哥们的问题说和友盟分享SDK冲突了,刚好这个工程也集成了

  • 微信支付终于成功了(安卓、iOS)在此分享

    经过了几天的痛苦煎熬,终于把微信支付调通,整个调试过程很痛苦,痛苦的主要来源是微信支付的调试真的是,以前调试公众号支付也是一波三折啊.好吧,开始!首先说明,我这里主要没有使用getToken,getOrder方法,我的所有参数全部是在后端生成传递给前端的,看了一下前面朋友分享的源代码,还用到了jquery,md5,sha对于新手来说简直是天文啊,而且jquery在apicloud中效率不好,所以放弃了研究那个代码,另外官方也说了,最好签名等参数全部服务器端生成,微信也是这么说的. 注意:微信本身

  • iOS仿支付宝芝麻信用分数仪表盘动画效果

    先看看效果图: 仪表盘动画效果.jpg 1.圆环上绿点的旋转 2.分数值及提示语的变化 3.背景色的变化 直接上主要代码: 1.自定义ZLDashboardView仪表盘文件: .h 文件: /** * 根据跃动数字 * * 确定百分比 * 现在的跳动数字-->背景颜色变化 * */ #import <UIKit/UIKit.h> @interface ZLDashboardView : UIView @property (nonatomic, strong) UIImage *bgIm

  • iOS实现类似微信和支付宝的密码输入框(UIKeyInput协议)

    目前在项目中需要实现发红包的功能,自己就写了一个密码输入框的控件,主要用到了UIKeyInput协议和CoreGraphics框架,效果类似微信支付,感觉还行就把我的思路和制作过程写下来给大家分享一下. 让你的自定义View具备输入的功能(UIKeyInput协议) 通过UIKeyInput协议可以为响应者提供简单的键盘输入的功能,让需要键盘的responder成为第一响应者就行了.UIKeyInput协议必须实现的有三个方法,分别是以下方法: #pragma mark - UIKeyInput

  • 支付宝支付开发IOS图文教程案例

    前言:继上次<微信支付开发IOS图文教程案例>以来,一直没有太多时间,更新总结详细支付这样的长篇大论,很抱歉.今天,推出支付宝支付的详细流程. 1.开始下载和查看支付宝支付的Demo. 我们直接进入支付宝的支付平台参考来进行集成支付宝支付: https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.jIUkAQ&treeId=59&articleId=103675&docType=1 集成过程基本

  • 微信支付开发IOS图文教程案例

    前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要知道的,打开下面链接: https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=3_1 然后可以看到下面的页面,这个就是微信支付商户平台的开发文档,很多东西是可以查阅和了解的,在开发使用微信SDK支付功能的时候,遇到了问题也可以到这找找相关须知信

  • IOS客户端接入微信支付

    实际上,从代码的角度,调起支付APP就是把一些关键的参数通过一定方式打包成为一个订单,然后发送到支付平台的服务器.所以,只要搞清楚了参数设置,搞清楚了每个支付平台的SDK里面一些关键API的使用,基本上就可以很简单的支持支付. 今天记录一下客户端里面,如何支持微信支付.首先.我们要仔细阅读一下微信SDK的开发文档,了解一下整个支付的大概流程. 然后根据提示,把相应的SDK下载下来,所谓的SDK,也就是一个链接库和两个头文件,很简单. 下载完毕,需要把SDK导入到工程里面,并且配置一下工程.因为开

  • iOS集成微信支付开发

    本文实例为大家分享了iOS集成微信支付开发代码,供大家参考,具体内容如下 首先需要理清楚流程: 1.用户使用APP客户端,选择商品下单. 2.商户客户端(就是你做的APP)将用户的商品数据传给商户服务器,请求生成支付订单. 3.商户后台调用统一下单API向微信的服务器发送请求,微信服务器生成预付单,并生成一个prepay_id返回给商户后台. 4.商户后台将这个prepay_id返回给商户客户端. 5.用户点击确认支付,这时候商户客户端调用SDK打开微信客户端,进行微信支付. 6.微信客户端向微

  • iOS开发支付宝支付成功返回字符串的处理操作

    { memo=""; result="partner=\"311811\"&seller_id=\"nse@gmail.com\"&out_trade_no=\"S005372\"&subject=\"\U522b\U5885\U8ba2\U5355\"&body=\"\U5885\"&total_fee=\"0.1\"

随机推荐