苹果内购-后端php验证

2017-07-16  本文已影响2080人  Gneeux

公司项目支付加入了苹果内购,所以就涉及到需要去苹果服务器那边验证订单不是正确的。我这边是使用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;
}
上一篇下一篇

猜你喜欢

热点阅读