IOS应用内支付返回新旧Receipt适配的方法
程序员文章站
2023-12-17 10:41:22
ios7.0后ios支付成功返回的票据receipt的获取方式有了新的方式,
原来的skpaymenttransaction中的transactionreceipt属性获...
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一一对应,这种情况下如何处理还需要注意。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。