关于苹果purchase的验证
用户在购买苹果的商品的过程如下:
- 1.应用发送请求到服务器,获取所有的Products ID列表
- 2.服务器返回Products ID列表
- 3.应用发送请求至App Store,获取Products的信息
- 4.App Store返回Product信息
- 5.应用使用这些信息,向用户显示一个Store界面
- 6.用户从Store中选择一项
- 7.应用向App Store发送payment请求
- 8.App Store处理该payment,并返回完成的transaction
- 9.应用从transaction中获取receipt数据,并将其发送给服务器
- 10.服务器记录receipt数据,并建立一个audit trail(审查跟踪)
- 11.服务器发送receipt数据到App Store,以验证是否合法的transaction
- 12.App Store解析receipt数据,并返回receipt,以及验证结果(是否合法)
- 13.服务器读取返回的receipt数据,并确定哪个用户已经完成购买
- 14.服务器交付已购买的内容至iOS应用
Purchase(购买)当用户准备好购买product时,应用请求App Store来完成支付。App Store会创建一个持久化的transaction,即使用户退出和重新启动应用,也会继续地处理该支付交易。App Store将未决交易列表同步给应用,并且在任何交易状态变化时,递送更新信息给应用。说到purchase我不得不提之前让我头疼的一个问题就是验证了:static public function getReceiptData($receipt, $isSandbox = false) { if ($isSandbox) { $endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt'; } else { $endpoint = 'https://buy.itunes.apple.com/verifyReceipt'; } error_log(date("Y-m-d h:i:s")." procAppstoreNotification request error data " . serialize($receipt) ."\r\n", 3 , 'appstore.log'); $postData = json_encode(array('receipt-data' => $receipt)); error_log(date("Y-m-d h:i:s")." procAppstoreNotification request error data " . serialize($postData) ."\r\n", 3 , 'appstore.log'); $ch = curl_init($endpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); //?芒?陆???禄露篓?陋录?拢卢虏禄录?禄谩卤篓SSL 麓铆?贸 curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); $response = curl_exec($ch); $errno = curl_errno($ch); $errmsg = curl_error($ch); curl_close($ch); //??露??卤潞貌鲁枚麓铆拢卢??鲁枚?矛鲁拢 if ($errno != 0) { throw new Exception($errmsg, $errno); } $data = json_decode($response); error_log(date("Y-m-d h:i:s")." procAppstoreNotification request error data " . serialize($data) ."\r\n", 3 , 'appstore.log'); //??露?路碌禄?碌??媒戮???路帽??露??贸 if (!is_object($data)) { throw new Exception('Invalid response data'); } //??露?鹿潞?貌?卤潞貌鲁?鹿娄 if (!isset($data->status) || $data->status != 0) { throw new Exception('Invalid receipt'); } error_log(date("Y-m-d h:i:s")." procAppstoreNotification request error data " . serialize($data) ."\r\n", 3 , 'appstore.log'); //路碌禄?虏煤?路碌????垄 return array( 'quantity' => $data->receipt->quantity, 'product_id' => $data->receipt->product_id, 'transaction_id' => $data->receipt->transaction_id, 'purchase_date' => $data->receipt->purchase_date, 'app_item_id' => $data->receipt->app_item_id, 'bid' => $data->receipt->bid, 'bvrs' => $data->receipt->bvrs );}之前是有部分账单验证未通过,后来查了下是在给苹果发验证数据的时候需要用base64进行编码的,后来我就改了$postData = json_encode(array('receipt-data' => base64_encode($receipt)));Store Receipt你发送给App Store的receipt数据编码了交易的信息。当App Store验证receipt时,会先解码receipt数据,并在响应中返回。receipt响应是一个JSON dictionary,包含了应用中SKPaymentTransaction对象的所有信息。因此服务器可以查询这些JSON域,来获取用户购买的详细信息。苹果推荐iOS应用只发送receipt数据给服务器,不发送交易数据给服务器,然后服务器再到App Store去验证receipt。App Store会验证receipt数据没有被篡改。服务器从App Store响应的receipt数据中获取交易信息,而不是由iOS应用直接发送交易信息给服务器,会更加安全。下表列出了你可以从响应receipt中获取的信息,许多键直接对应于SKPaymentTransaction类的属性。表中没有指定的键都被苹果保留,不得使用。
键 描述 quantity 购买的数量,对应于transaction.payment.quantity属性 product_id product ID标识,对应于transaction.payment.productIdentifier属性 transaction_id transaction ID标识,对应于transaction.transactionIdentifier属性 purchase_date 交易发生的日期和时间,对应于transaction.transactionDate属性 original_transaction_id 对于还原交易,这个值保存了原始交易ID original_purchase_date 对于还原交易,这个值保存了原始交易日期 app_item_id 字符串,App Store用来唯一地标识一个创建了支付交易的iOS应用。如果你的服务器支持多个iOS应用,你可以使用这个值来区分不同的应用。在sandbox中运行的应用没有app_item_id,因此这个键也不存在 version_external_identifier 唯一标识你的应用修订版本的任意数值。sandbox应用没有这个键 bid iOS应用的Bundle ID bvrs iOS应用的版本号
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。