关于苹果purchase的验证

用户在购买苹果的商品的过程如下:
  1. 1.应用发送请求到服务器,获取所有的Products ID列表
  2. 2.服务器返回Products ID列表
  3. 3.应用发送请求至App Store,获取Products的信息
  4. 4.App Store返回Product信息
  5. 5.应用使用这些信息,向用户显示一个Store界面
  6. 6.用户从Store中选择一项
  7. 7.应用向App Store发送payment请求
  8. 8.App Store处理该payment,并返回完成的transaction
  9. 9.应用从transaction中获取receipt数据,并将其发送给服务器
  10. 10.服务器记录receipt数据,并建立一个audit trail(审查跟踪)
  11. 11.服务器发送receipt数据到App Store,以验证是否合法的transaction
  12. 12.App Store解析receipt数据,并返回receipt,以及验证结果(是否合法)
  13. 13.服务器读取返回的receipt数据,并确定哪个用户已经完成购买
  14. 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_idproduct ID标识,对应于transaction.payment.productIdentifier属性
transaction_idtransaction 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应用没有这个键
bidiOS应用的Bundle ID
bvrsiOS应用的版本号


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。