ios内购php验证码,PHP (Laravel) 实现 iOS 内购服务端验证

/**

* @Author woann

* @param Request $request

* @return \Illuminate\Http\JsonResponse

* @des ios内购支付回调

*/

public function iosNotify(Request $request)

{

$this->validate(

$request,

[

'order_id' => 'required|digits_between:1,9|integer',

'apple_receipt' => 'required|min:20',

]

);

//苹果内购的验证收据

$receipt_data = $request->input('apple_receipt');

$order_id = $request->input('order_id');

$order = LevelOrder::find($order_id);

if (!$order || $order->state != 0) {

return returnApi(500,'订单状态异常');

}

$ios_sandBox = env('IOS_SANDBOX',true);//判断生产环境,开发环境

if(empty($receipt_data)){

return json(500, '参数不正确');

}

// 获取校验结果

$result=$this->validate_apple_pay($receipt_data,$ios_sandBox);

if (!$result || !is_array($result) || !isset($result['status'])) {

return returnApi(500,'获取数据失败,请重试');

}

//如果校验失败

if ($result['status'] != 0) {

return returnApi(500,'miss [apple_receipt]');

}

if ($result['status'] == 0) {

$transaction_ids = [];//用来收集需要关闭的transaction_id

//遍历未结束交易的列表(in_app)

foreach ($result['receipt']['in_app'] as $v){

$transaction_ids[] = $v['transaction_id'];//不管当前交易是否已经处理过,都要返回给客户端结束交易

$is_exist = DB::table('ios_transaction_id')->where('transaction_id', $v['transaction_id'])->first();

if ($is_exist) {

//如果已经处理过该订单 直接跳过

continue;

}

//否则在此处理业务逻辑

//...

//然后记录下此transaction_id标记为已处理过

DB::table('ios_transaction_id')->insert(['transaction_id' => $v['transaction_id']]);

}

//返回给客户端需要结束交易的transaction_id列表

return returnApi(200,'SUCCESS',['transaction_ids' => $transaction_ids]);

}

}

/**

* 验证AppStore内付

* @param string $receipt_data 付款后凭证

* @return array 验证是否成功

*/

protected function validate_apple_pay($receipt_data,$ios_sandBox)

{

/**

* 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环境的验证服务

*/

$POSTFIELDS = '{"receipt-data":"'. $receipt_data .'"}';

if($ios_sandBox){

// 请求验证

$data = httpRequest('https://sandbox.itunes.apple.com/verifyReceipt', $POSTFIELDS);

}else{

// 请求验证

$data = httpRequest('https://buy.itunes.apple.com/verifyReceipt', $POSTFIELDS);

}

return $data;

}

protected function httpRequest($url, $postData = array(), $json = true)

{

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

if ($postData) {

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

}

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);

$info = curl_getinfo($ch);

$data = curl_exec($ch);

curl_close($ch);

if ($json) {

return json_decode($data, true);

} else {

return $data;

}

}