苹果客户端支付后,服务器端对数据进行二次验证接口开发

最近项目中用到了苹果支付,当客户段进行支付后,服务端要进行二次验证,防止篡改。这时IOS只需要把支付凭证传递给服务端,服务端进行验证。如果验证通过,将支付记录保存之数据库,给用户返回支付成功的消息即可。

首先,通过curl发送请求,获取苹果端的响应。代码如下:

//去苹果服务器二次验证代码
 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);
    curl_close($ch); 
    if ($errno != 0) {//curl请求有错误
         $order['errNo'] = 1;
        return $order;
    }else{
        $data = json_decode($response, true);
        if (!is_array($data)) {
            $order['errNo'] = 2;
            return $order;
        }
        //判断购买时候成功
        if (!isset($data['status']) || $data['status'] != 0) {
           $order['errNo'] = 3;
             return $order;
        }
        //返回产品的信息
        $order = $data['receipt']['in_app'][0];
        $order['errNo'] = 0;
        return $order;
    }          
}
$endpoint代表请求地址,沙箱模式和正式运营时的地址是不一样的,是否是沙箱模式在配置文件里面定义下就行了。次函数主要返回的苹果验证的结果。errNo位1时:请求超时。errNo位2时:苹果返回数据有误。errNo位3时:购买失败。errNo位0时:支付成功。

接下来就是接口的编写了,具体代码如下:

ApiError('001', '用户ID不能为空');
if ($receipt == '') $api->ApiError('002', '充值凭证不能为空');
if ($vcode == '') $api->ApiError('004', '校验码不能为空');
if ($source == '') $api->ApiError('005', '来源不能为空');

$vcode_raw = md5(md5($userid)  . md5($source));
if ($vcode_raw != $vcode) {
    $api->ApiError('006', '校验码不正确');
}

if (!in_array($source, array_keys($Array_API_Source)))
    $api->ApiError('007', '来源错误');
//设置API来源
$api->setsource($source);


$userInfo = User::getInfoById($userid);
if (!$userInfo)
    $api->ApiError('008', '用户不存在');
$chargeInfo=Chargelog::getInfoByReceipt($userid,$receipt);
if (!empty($chargeInfo))
    $api->ApiError('009', '该凭证已经充值');
 $isSandbox = true;//沙箱是测试环境,正式环境改为false
 $info =getReceiptData($receipt, $isSandbox);//去苹果进行二次验证,防止收到的是伪造的数据
 if(is_array($info) && $info['errNo'] == 0){//没有错误就进行业务逻辑的处理,订单设置成已支付,给用户加钱
 	 $priceArr=split(".", $info['product_id']);
 	 //$money=0;
 	  // $api->ApiError('010', $info['product_id']);
 	 if($info['product_id']=="cn.shushubuyue.product6")
 	 	$money=6;
 	 elseif ($info['product_id']=="cn.shushubuyue.product30")
 	 	$money=30;
 	  elseif ($info['product_id']=="cn.shushubuyue.product98")
 	 	$money=98;
 	$rs=Chargelog::add($userid, $money, $receipt,1);
 	if($rs>0){
 		User::chargeMoney($userid,$money);
 		echo json_encode_cn(array('status' => 'ok'));
 		 $api->apicount();
 	}else{
 		 $api->ApiError('010', '操作失败');
 	}
 }else{
 	if($info['errNo'] == 1)
 	 	$api->ApiError('011',  '请求超时,请稍后重试');
 	if($info['errNo'] == 2)
 	 	$api->ApiError('012',  '苹果返回数据有误,请稍后重试');
 	if($info['errNo'] == 3)
 	 	$api->ApiError('013',  '购买失败');
 }


?>
代码中有好多公司自己封装的函数在这里就不贴出来了。其中:strCheck主要用于参数检查。ApiError 主要是用于接口调用的统计。到此,苹果支付接口就开发完毕了。


你可能感兴趣的:(PHP)