苹果支付服务器二次验证

苹果客户端支付后,服务器端对数据进行二次验证,防止破解和篡改

class PayController extends Controller{
        private $product = [
            'price_1'  => 10,
            'price_2'  => 30,
            'price_3'  => 88,
            'price_4'  => 188,
            'price_5'  => 388,
            'price_6'  => 688,
        ];

         * 服务器二次验证代码
         * 21000 App Store不能读取你提供的JSON对象
         * 21002 receipt-data域的数据有问题
         * 21003 receipt无法通过验证
         * 21004 提供的shared secret不匹配你账号中的shared secret
         * 21005 receipt服务器当前不可用
         * 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
         * 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
         * 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务

        public function iapVerify(){
            if(IS_POST){
                $receipt = $_POST['receipt'];//苹果发来的数据,base64的大字符串,一会发送给苹果进行二次验证,验证后会给你可读的json数据
                $orderid = $_POST['transactionId'];//苹果的订单号,拿来用即可,不会重复,类似'1000000123465272',
                //创建订单,使用苹果给的订单号
                $record = M('Recharge_log')->where("trade_no='%s'", $orderid)->find();
                if(empty($record)){
                    $data = array(
                        'uid'           => $this->uid,
                        'trade_no'      => $orderid,
                        'money'         => 0,
                        'recharge_time' => time(),
                        'pay_type'      => 'iap',
                    );
                    M('Recharge_log')->add($data);
                }
                $isSandbox = true;//沙箱是测试环境,正式环境改为false
                $info = $this->getReceiptData($receipt, $isSandbox);//去苹果进行二次验证,防止收到的是伪造的数据
                if(is_array($info) && $info['errNo'] == 0){//没有错误就进行业务逻辑的处理,订单设置成已支付,给用户加钱
                    $this->answer['status'] = 0;
                    $this->answer['msg']    = '支付成功';
                    if($record['trade_status'] !== 'TRADE_FINISHED'){
                        $data['money']          = $this->product[$info['product_id']];//这个价格列表是你提交给苹果的,你参照本class的属性获得具体多少钱,苹果不会直接给你具体多少钱
                        $data['trade_status']   = 'TRADE_FINISHED';
                        $data['finish_time']    = time();
                        M('Recharge_log')->where("trade_no='%s'", $orderid)->save($data);
                        M('Users')->where('uid=' . $this->uid)->setInc('money', $this->product[$info['product_id']]);
                    }else{
                        $this->answer['msg']    = '订单已支付';
                    }
                }else{
                    $this->answer['status'] = 0;
                    $this->answer['msg']    = $info['errMsg'];
                    $this->answer['data']   = array(
                        'errCode' => $info['errNo']
                    );
                }
            }
            $this->response($this->answer);
        }

        //去苹果服务器二次验证代码
        protected function getReceiptData($receipt, $isSandbox = false) {
            if ($isSandbox) {
                $endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';//沙箱地址
            } else {
                $endpoint = 'https://buy.itunes.apple.com/verifyReceipt';//真实运营地址
            }
            $postData = json_encode(
                array('receipt-data' => $receipt)
            );
            $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) {//curl请求有错误
                return [
                    'errNo' => 1,
                    'errMsg' => '请求超时,请稍后重试',
                ];
            }else{
                $data = json_decode($response, true);
                if (!is_array($data)) {
                    return [
                        'errNo' => 2,
                        'errMsg' => '苹果返回数据有误,请稍后重试',
                    ];
                }
                //判断购买时候成功
                if (!isset($data['status']) || $data['status'] != 0) {
                    return [
                        'errNo' => 3,
                        'errMsg' => '购买失败',
                    ];
                }
                //返回产品的信息
                $order = $data['receipt']['in_app'][0];
                $order['errNo'] = 0;
                return $order;
            }
        }

        返回数据参照样例
        array (
          'status' => 0,
          'environment' => 'Sandbox',
          'receipt' => 
          array (
            'receipt_type' => 'ProductionSandbox',
            'adam_id' => 0,
            'app_item_id' => 0,
            'bundle_id' => 'com.abcde.www',
            'application_version' => '0.0.9',
            'download_id' => 0,
            'version_external_identifier' => 0,
            'receipt_creation_date' => '2016-07-13 18:22:19 Etc/GMT',
            'receipt_creation_date_ms' => '1468434139000',
            'receipt_creation_date_pst' => '2016-07-13 11:22:19 America/Los_Angeles',
            'request_date' => '2016-07-13 18:22:22 Etc/GMT',
            'request_date_ms' => '1468434142143',
            'request_date_pst' => '2016-07-13 11:22:22 America/Los_Angeles',
            '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',
            'original_application_version' => '1.0',
            'in_app' => 
            array (
              0 => 
              array (
                'quantity' => '1',
                'product_id' => 'price_1',//去看$this->product里对应的价格,就是你的充值额
                'transaction_id' => '1000000223463280',
                'original_transaction_id' => '1000000223463280',
                'purchase_date' => '2016-07-13 18:22:19 Etc/GMT',
                'purchase_date_ms' => '1468434139000',
                'purchase_date_pst' => '2016-07-13 11:22:19 America/Los_Angeles',
                'original_purchase_date' => '2016-07-13 18:22:19 Etc/GMT',
                'original_purchase_date_ms' => '1468434139000',
                'original_purchase_date_pst' => '2016-07-13 11:22:19 America/Los_Angeles',
                'is_trial_period' => 'false',
              ),
            ),
          ),
        )
}
联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2024

备案号:京ICP备15003423号-3