话不多说,直接上代码
/***
* 初始化人脸认证
*/
public function face_initialize(){
$cert_name=$this->request->request('cert_name');//姓名
$cert_no=$this->request->request('cert_no');//证件号码
$certify_id='';
$params=[
'outer_order_no'=>order_sn('22'),
'biz_code'=>'FACE',
'identity_param'=>[
'identity_type'=>'CERT_INFO',
'cert_type'=>'IDENTITY_CARD',
'cert_name'=>$cert_name,
'cert_no'=>$cert_no,
],
'merchant_config'=>[
'return_url'=>'......'//支付宝认证成功后跳转回来的路径
]
];
$method='alipay.user.certify.open.initialize';
$rest=$this->send_alipay($method,json_encode($params,true));
if($rest['code']!=10000) $this->error($rest['sub_msg']);
$certify_id=$rest['certify_id'];
//请求开始认证接口
$params=[
'certify_id'=>$certify_id
];
$method='alipay.user.certify.open.certify';
//$res 是字符串,返回给前端调用打开支付宝开始实名认证,此处请求方式存在变化,特别注意
$res=$this->send_alipay($method,json_encode($params,320));
//返回接口调用成功
$this->success('success',['list'=>$res]);
}
/***
* 检查实名认证是否成功
*/
public function check_authentication(){
$user_id=$this->user['id'];
$info=Db::name('user_identity_authentication')
->where(['user_id'=>$user_id])
->find();
if(empty($info)) $this->error('请先开始认证');
$method='alipay.user.certify.open.query';
$params=[
'certify_id'=>$info['certify_id']
];
$rest=$this->send_alipay($method,json_encode($params,320));
if($rest['code']!=10000) $this->error($rest['sub_msg']);
$passed=is_array($rest['passed'])?(in_array('T',$rest['passed'])?true:false):($rest['passed']=='T'?true:false);
if($passed) {
//改变认证状态
Db::name('user_identity_authentication')
->where(['user_id'=>$user_id])
->update(['is_success'=>1]);
$this->success('success');
}
$this->error($rest['sub_msg']);
}
/***
* 请求支付宝接口
* @param string $method
* @param string $content
* @param string $notify_url
* @param bool $is_cert
* @param bool $is_dev
*/
public function send_alipay($method='',$content='',$notify_url='/admin/notify',$is_cert=true,$is_dev=false){
$http_type= ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
$notify_url = $http_type . $_SERVER['HTTP_HOST'].$notify_url;
if($is_cert) return $this->cert_client($method ,$content ,$notify_url ,$is_dev );
else return $this->client($method ,$content ,$notify_url ,$is_dev );
}
/***
* 证书公钥模式
* @param string $method
* @param string $content
* @param string $notify_url
* @param bool $is_dev
* @return \SimpleXMLElement|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function cert_client($method='',$content='',$notify_url='/admin/notify',$is_dev=false){
$set=Db::name('set')->where(['key'=>'payment'])->find();
if(empty($set)) return '支付参数未配置';
$set=collection($set)->toArray();
$set=json_decode($set['value'],true)['ali_pay'];
$aop= new \alipay\aop\AopCertClient();
$dev_url='https://openapi.alipaydev.com/gateway.do';
$url='https://openapi.alipay.com/gateway.do';
$alipayCertPath=ROOT_PATH.'/alipayCertPublicKey_RSA2.crt';//支付宝公钥证书路径
$rootCertPath=ROOT_PATH.'/cert/alipayRootCert.crt';//支付宝根证书路径
$appCertPath=ROOT_PATH.'/cert/appCertPublicKey.crt';//应用证书路径
$aop->gatewayUrl=$is_dev?$dev_url:$url;
$aop->appId=$set['appid'];
$aop->rsaPrivateKey=$set['privateKey'];
$aop->alipayrsaPublicKey=$aop->getPublicKey($alipayCertPath);
$aop->appCertSN = $aop->getCertSN($appCertPath);
$aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);
$aop->signType = 'RSA2';
$request = new \alipay\request\AlipayRequest();
$request->setBizContent($content);
$request->setNotifyUrl($notify_url);
$request->setApiMethodName($method);
if($method=='alipay.fund.auth.order.app.freeze' || $method=='alipay.trade.app.pay'){
return $aop->sdkExecute ($request);
}elseif ($method=='alipay.user.certify.open.certify'){//特别强调注意,开始实名认证接口请求方式使用该方式,第二个参数“GET”十分重要,将该字符串给到前端,前端调用打开支付宝开始实名认证
return $aop->pageExecute ($request,'GET');
}else{
$result = $aop->execute($request);
}
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
if(!is_object($result)) return $result;
$resultCode = $result->$responseNode->code;
if (!empty($resultCode) && $resultCode == 10000) {
return is_object($result)?collection($result->$responseNode)->toArray():$result->$responseNode;
} else {
return is_object($result)?collection($result->$responseNode)->toArray():$result->$responseNode->code;
}
}
/***
* 普通公钥模式
* @param string $method
* @param string $content
* @param string $notify_url
* @param bool $is_dev
* @return \SimpleXMLElement|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function client($method='',$content='',$notify_url='/admin/notify',$is_dev=false){
$set=Db::name('set')->where(['key'=>'payment'])->find();
if(empty($set)) return '支付参数未配置';
$set=collection($set)->toArray();
$set=json_decode($set['value'],true)['ali_pay'];
$aop= new \alipay\aop\AopClient();
$dev_url='https://openapi.alipaydev.com/gateway.do';
$url='https://openapi.alipay.com/gateway.do';
$aop->gatewayUrl=$is_dev?$dev_url:$url;
$aop->appId=$set['appid'];
$aop->rsaPrivateKey=$set['privateKey'];
$aop->alipayrsaPublicKey=$set['publicKey'];
$aop->signType = 'RSA2';
$request = new \alipay\request\AlipayRequest();
$request->setBizContent($content);
$request->setNotifyUrl($notify_url);
$request->setApiMethodName($method);
if($method=='alipay.fund.auth.order.app.freeze' || $method=='alipay.user.certify.open.certify'){
//特别强调注意,开始实名认证接口请求方式使用该方式,第二个参数“GET”十分重要,将该字符串给到前端,前端调用打开支付宝开始实名认证
$result = $aop->pageExecute ($request,"GET");
return $result;
}else{
$result = $aop->execute ($request);
}
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if (!empty($resultCode) && $resultCode == 10000) {
return json_decode($result->$responseNode,true);
} else {
return $result->$responseNode->code;
}
}