美文网首页
苹果内购-后端php验证

苹果内购-后端php验证

作者: Gneeux | 来源:发表于2017-07-16 19:48 被阅读2080次

    公司项目支付加入了苹果内购,所以就涉及到需要去苹果服务器那边验证订单不是正确的。我这边是使用PHP写的服务器验证。
    有人问为什么要用PHP吗?(假装你们有问,因为PHP是世界上最好的语言!!!!)
    作好小板凳!知识点来了!!!!


    思路:
    1.判断status
    2.检查receipt里面的bundle_id是否在允许列表
    3.检查in_app,是否包含数据
    4.判断返回数据的中产品ID是不是在合法的产品ID
    5.判断该订单的时间,如果时间太久肯定不是不对的

    /**
     * 苹果内购服务器验证
     * @return string
     */
    public function CheckApplePay ()
    {
        // 苹果内购的验证收据,由客户端传过来
        $apple_receipt = I("post.apple_receipt", "");
        $password = I("post.password", "");
        if (empty($password)) {
            $jsonData = array("receipt-data"=>$apple_receipt);
            unset($password);
        }else{
            $jsonData = array("receipt-data"=>$apple_receipt, "password" =>$password);
        }
        $jsonData1 = json_encode($jsonData);
        $response = $this->http_post_data($jsonData1, ApplePayURLStatus);
        if($response->status==21007) {
            $response = $this->http_post_data($jsonData1, false);
        }else if ($response->status==21008) {
            $response = $this->http_post_data($jsonData1, true);
        }
        if($response->status == 0){
            // 允许名单数组
            $bundlelist=[];
            $bundleid= $response->receipt->bundle_id;
            if($bundleid && in_array($bundleid,$bundlelist)) {
                $in_app = $response->receipt->in_app;
                if($in_app && !empty($in_app)){
                    // 取出第一个支付时间
                    $firsttime = $in_app[0]->purchase_date;
                    foreach($in_app as $k=>$v){
                       if($firsttime < $v->purchase_date){
                           $firsttime = $v->purchase_date;
                       }
                    }
                    foreach($in_app as $key=>$value){
                        if($value->purchase_date == $firsttime){
                            $arr = $value;
                        }
                    }
                    // 产品的ID
                    $product_id = $arr->product_id;
                    // 原始购买时间毫秒
                    $purchase_date_pst = $arr->original_purchase_date_ms;
                    // 到期时间毫秒
                    $expires_date_formatted = $arr->expires_date_ms;
                    // 支付时间毫秒
                    $purchase_date_ms = $arr->purchase_date_ms;
                    if(empty($expires_date_formatted)){
                        $expires_date_formatted = 0;
                    }
                    if($product_id && !empty($product_id)){
                         // 产品ID数组
                        $productids = [];
                        if(in_array($product_id, $productids)){
                            // 自动订阅类型
                            $product_id_arr = [];
                            if(in_array($product_id, $product_id_arr)){
                                $purchase_date = strtotime(DateUtility::GetBeiJingTime($purchase_date_ms));
                                $difftime = time() - $purchase_date;
                                if($difftime > 10*60){
                                    return self::run(4,"支付时间过期");
                                }else{
                                    // 把自动订阅型的记录到数据库,方便检测订阅是否到期和继续订阅的操作
                                }
                            }else{
                                  // 记录到数据库
                            }
                             // 写确认订单的业务逻辑
                            return self::run(0, "支付成功");
                        } else{
                            return self::run(6, "非法product_id");
                        }
                    }else{
                        return self::run(3, "produce_id不存在伪造充值");
                    }
                }else{
                   return self::run(2, "伪造充值");
                }
            }else{
                return self::run(1, "凭据bundleid不在白名单之内");
            }
        }else{
            $code = $response->status;
            $messagearr[21000] = "App Store无法读取你提供的JSON数据";
            $messagearr[21002] = "收据数据不符合格式";
            $messagearr[21003] = "收据无法被验证";
            $messagearr[21004] = "你提供的共享密钥和账户的共享密钥不一致";
            $messagearr[21005] = "收据服务器当前不可用";
            $messagearr[21006] = "收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中";
            $messagearr[21007] = "收据信息是测试用(sandbox),但却被发送到产品环境中验证";
            $messagearr[21008] = "收据信息是产品环境中使用,但却被发送到测试环境中验证";
            return self::run($code, $messagearr[$code]);
        }
    }
    
    /**
     * curl请求苹果app_store验证地址
     * @param $data_string      验证字符串
     * @param $istest           是否是测试地址 true正式地址 false测试地址
     * @return mixed
     */
    private function http_post_data($data_string, $istest) {
        if ($istest) {
            // 正式验证地址
            $url = 'https://buy.itunes.apple.com/verifyReceipt';
        } else {
            // 测试验证地址
            $url = 'https://sandbox.itunes.apple.com/verifyReceipt';
        }
        $curl_handle=curl_init();
        curl_setopt($curl_handle,CURLOPT_URL, $url);
        curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_handle,CURLOPT_HEADER, 0);
        curl_setopt($curl_handle,CURLOPT_POST, true);
        curl_setopt($curl_handle,CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($curl_handle,CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl_handle,CURLOPT_SSL_VERIFYPEER, 0);
        $response_json =curl_exec($curl_handle);
        $response =json_decode($response_json);
        curl_close($curl_handle);
        return $response;
    }
    

    相关文章

      网友评论

          本文标题:苹果内购-后端php验证

          本文链接:https://www.haomeiwen.com/subject/sbhxkxtx.html