关于苹果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_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应用的版本号

				
时间: 2024-08-09 23:48:55

关于苹果purchase的验证的相关文章

Verify an App Store Transaction Receipt 【苹果服务端 验证一个应用程序商店交易收据有效性】

转自:http://blog.csdn.net/saindy5828/article/details/6414014 1. 从Transaction 的TransactionReceipt属性中得到接收的数据,并以base64编码: 2.创建JSON对象,字典格式,单键值对,键名为“receiptdata”,值为上一次编码的数据,效果: {"receipt-data":"base64编码之后的数据"} 3.发送HTTP POST请求,将数据发送到App Store 

【IAP支付之三】苹果IAP安全支付与防范 receipt收据验证

这里网上的朋友已经介绍的很详细了,具体的链接已经无法找到了. 这里主要说几点本人在开发中遇到的问题: 1.漏单必须要处理,玩家花RMB购买的东西却丢失了,是绝对不能容忍的.所谓的漏单就是玩家已经正常付费,却没有拿到该拿的道具. 解决:只要购买成功,便将购买记录(receipt等账单信息)保存下来,然后将账单信息传送给我们游戏服务器,游戏服务器获得账单后,和苹果服务器验证,账单有效的话,回馈给游戏服务器处理,游戏服务器处理后,返回给游戏客户端处理,处理完毕,将本地保存的购买记录删除. 2.漏单的检

iOS内购 服务端票据验证及漏单引发的思考.

因业务需要实现了APP内购处理,但在过程中出现了部分不可控的因素,导致部分用户反映有充值不成并漏单的情况. 仔细考虑了几个付费安全上的问题,凡是涉及到付费的问题都很敏感,任何一方出现损失都是不能接受的,所以在这里整理一些支付安全的要点分享一下. 支付方式 IAP是指In-App Purchase, 是一种付费方式,而并不是苹果专有的付费方式,在其它平台上也会有不同的实现,这里针对Apple IAP. 说到IAP安全问题,在苹果的IAP流程中有一个比较明显的逻辑漏洞,这个逻辑漏洞是建立在我们处理不

ios IAP 内购验证

参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购买,成功之后,Apple会返回以下四个数据给应用 四个验证数据 productIdentifier:cosmosbox.strikehero.gems60 state: Purchased receipt: ewoJInNpZ25hdHVyZSIgPSAiQXF1M3JiR1grbmJMeGVvZS

IOS内购验证

客户端在沙箱环境下购买成功之后,需要进行二次验证 参考自:http://www.himigame.com/iphone-cocos2d/550.html 当应用向Apple服务器请求购买成功之后,Apple会返回数据给应用,如下所示: 产品标识符: product Identifier[在itunes store应用内定义的产品ID,例如com.公司名.产品名.道具名(com.xxxx.video.vip)] 交易状态: state Purchased 购买成功 Restored 恢复购买 Fa

iOS: 实现苹果的内购

一.介绍: 在个人开发的app上架到AppStore后,苹果官方允许我们将自己的app在appstore上进行付费使用,也就是所谓的内购.其中,支付方式规定的必须是苹果的支付方式:应用内支付. 二.流程: 1.后台设置 (1)配置Developer.apple.com,为应用建立一个不带通配符的App ID (2)用该应用的App ID生成和安装相应的Provisioning Profile文件 2.配置iTunes Connect (1)用该App ID创建一个新的应用: (2)在该应用中,创

2015年最新苹果开发者账号注册流程详解

苹果开发者账号的注册过程比较复杂,和大家分享一下过程和细节,以免大家走了弯路. 1.登陆苹果开发者官网页面 https://developer.apple.com/programs/ios/ 2.点击“enroll now $99/year”按钮(如下图) 3.在弹出的介绍页面中点击按钮“continue”(如下图) 4.接下来的页面是让你选择用现有的苹果账号(Existing Apple ID)还是新建一个苹果账号(New Apple ID)来注册成为开发者.你根据自己需要选择.假如是已有账号

In-App Purchases验证

package com.demo.controller.web.app; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.security.cert.CertificateException; import java.se

苹果内购买笔记

苹果内购买包括4种类型:1.消耗性:  2.非消耗性:3.自动续订订阅:4.非续订订阅. 首先需要有一个itunesconnect上协议.税务和银行业务模块中有银行卡绑定同时遵守了各种苹果协议的开发帐号:(具体如何申请填写网上百度一堆) 然后代码前记得添加协议 <SKPaymentTransactionObserver,SKProductsRequestDelegate,SKRequestDelegate> //购买点击 -(void)payBtnClick { //购买 if ([SKPay