'http://t2.1010jz.wang/', // 无感电签接口 'sw' => 'http://t1.1010jz.wang/', ]; /** * 正式API域名 * * @var array */ protected $devApi = [ // 登录接口 // 打款批次风控接口 // 支付时异步请求接口 // 打款批次支付结果接收接口 'sc' => 'https://sc.luyong.com/', // 无感电签接口 'sw' => 'https://sw.luyong.com/', ]; /** * 请求是否包含token * * @var boolean */ protected $token = false; /** * 不参与签名字段 * * @var array */ protected $notJoinSignFields = []; /** * 设置接口是sw * * @return void */ private function setSw() { $this->type = 'sw'; } /** * 设置接口是sc * * @return void */ private function setSc() { $this->type = 'sc'; } /** * @return void */ public function setTest() { $this->test = true; } /** * 不需要token * * @return void */ protected function setHasToken() { $this->token = true; } /** * 设置不参与签名字段 * * @param array $fields * @return void */ protected function setNotJoinSignFields(array $fields) { $this->notJoinSignFields = $fields; } /** * (一) 登录接口 * * @return void */ public function signIn() { $this->setSc(); $data = $this->sendRequest('/api/sign_in', [ 'email' => $this->email, 'pwd' => md5($this->pwd), ]); return $data['data']; } /** * (二) 打款批次风控接口 * * @param string $batchNo * @param array $userPayInfos * @return array */ public function riskCheck(string $batchNo, array $userPayInfos) { $this->setSc(); return $this->sendRequest('/api/alisafepay/riskCheck', [ 'token' => $this->getToken(), 'batchNo' => $batchNo, 'userPayInfos' => Json::encode($userPayInfos), ]); } /** * (三) 支付时异步请求接口 * * @param string $batchNo * @return array */ public function asyncTransferNotify(string $batchNo) { $this->setSc(); return $this->sendRequest('/api/alisafepay/asyncTransferNotify', [ 'token' => $this->getToken(), 'batchNo' => $batchNo, ]); } /** * (四) 打款批次支付结果接收接口失败 * * @param string $batchNo * @return array */ public function asyncTransferResultNotifyNo( string $bizOutNo, string $payStatus = 'false', string $message = '' ) { $this->setSc(); $this->setNotJoinSignFields(['message']); return $this->sendRequest('/api/alisafepay/asyncTransferResultNotify', [ 'token' => $this->getToken(), 'bizOutNo' => $bizOutNo, 'payStatus' => $payStatus, 'message' => $message, ], 'post'); } /** * (四) 打款批次支付结果接收接口成功 * * @param string $batchNo * @return array */ public function asyncTransferResultNotifyOk( string $bizOutNo, string $pay_fund_order_id, string $payStatus = 'true', string $message = '' ) { $this->setSc(); $this->setNotJoinSignFields(['message']); return $this->sendRequest('/api/alisafepay/asyncTransferResultNotify', [ 'token' => $this->getToken(), 'bizOutNo' => $bizOutNo, 'payStatus' => $payStatus, 'message' => $message, 'pay_fund_order_id' => $pay_fund_order_id ], 'post'); } /** * (五) 无感电签接口 * * @param string $name * @param string $phone * @param string $idCard * @param string|null $templateId * @param string|null $email * @param string|null $callbackUrl * @param string|null $extraMsg * @return array */ public function silentSign( string $name, string $phone, string $idCard, string $templateId = null, string $email = null, string $callbackUrl = null, string $extraMsg = null ) { $this->setSw(); return $this->sendRequest('/sign/silentSign', array_merge(compact( 'name', 'phone', 'idCard', 'templateId', 'email', 'callbackUrl', 'extraMsg', ), [ 'accountId' => $this->accountId, ]), 'get'); } /** * (二十一) 查询用户注册信息 * * @param string $idCard * @return array */ public function queryRegisterUser(string $idCard) { return $this->sendRequest('/signing/queryRegisterUser', compact('idCard'), 'get'); } /** * 手机号查询电签用户信息 * * @param string $phone * @return void */ public function querySignUserByPhone(string $phone) { $data = $this->querySignUser(compact('phone')); } /** * 身份证查询电签用户信息 * * @param string $idCard * @return array */ public function querySignUserByIdCard(string $idCard) { return $this->querySignUser(compact('idCard')); } /** * (六) 查询电签用户信息 * * @param array $data * @return void */ protected function querySignUser(array $data) { return $this->sendRequest('/signing/querySignUser', array_merge($data, [ 'accountId' => $this->accountId, ]), 'get'); } /** * (七) 批量导入签约用户接口 * * @param string $batchNum * @param array $signUsers [[idCard name phone]] * @return array */ public function importSignUser(string $batchNum, array $signUsers) { $this->setSc(); return $this->sendRequest('/api/settlement/batch/importSignUser', [ 'token' => $this->getToken(), 'batchNum' => $batchNum, 'signUsers' => Json::encode($signUsers) ], 'post'); } /** * 获取token * * @return string */ private function getToken() { $key = 'yl_token_' . $this->email; $redis = Yii::$app->redis; if (($cache = $redis->get($key)) == false) { $token = $this->signIn()['token']; $redis->setex($key, 3000, $token); return $token; } return $cache; } /** * @return string */ protected function getUri() { return $this->test ? $this->testApi[$this->type] : $this->devApi[$this->type]; } /** * 发送请求 * * @param string $api * @param array $data * @param string $method * @return array * @throws Exception */ protected function sendRequest(string $api, array $data = [], string $method = 'post') { // 客户端 $client = new Client([ 'base_uri' => $this->getUri(), 'verify' => false ]); try { $response = $client->send($this->getRequest($api, $data, $method)); } catch (ClientException $e) { throw new Exception($e->getMessage()); } $result = $this->getResponseData($response); // 记录 Yii::$app->custom->logs('当前接口: ' . $api); Yii::$app->custom->logs('传输参数: ' . Json::encode($data)); Yii::$app->custom->logs('返回结果: ' . Json::encode($result)); return $result; } /** * 获取请求返回内容 * * @param Response $response * @return array * @throws Exception */ protected function getResponseData(Response $response) { if ($response->getStatusCode() == 200) { $content = Json::decode($response->getBody()->getContents()); return $content; } throw new Exception('请求失败'); } /** * 获取请求类 * * @param string $api * @param array $data * @param string $method * @return Request */ protected function getRequest(string $api, array $data, string $method) { $method = strtoupper($method); if ($method == 'POST') { return new Request($method, $api, $this->getHeaders(), Json::encode($this->getBody($data))); } else if ($method == 'GET') { return new Request($method, $this->getUrlQuery($api, $this->getBody($data))); } } /** * 获取Query * * @param string $api * @param array $data * @return string */ protected function getUrlQuery(string $api, array $data) { return $api . '?' . $this->getSignStr($data); } /** * 请求体 * * @param array $array * @return array */ protected function getBody(array $data = []) { $data = array_filter($data, function($v) { // return $v !== null; return true; }); ksort($data); $string = $this->getSignStr($data, true); // echo $string . "\n"; $signature = $this->getSignature(strtoupper(md5($string))); // echo ($signature);die; $data['signature'] = $signature; return $data; } /** * 拼接字符串 * * @param array $data * @return string */ protected function getSignStr(array $data, bool $is_sign = false) { if ($is_sign) { foreach($this->notJoinSignFields as $field) { if (isset($data[$field])) unset($data[$field]); } } $pairs = []; foreach ($data as $k => $v) { $pairs[] = $k . '=' . $v; } return implode('&', $pairs); } /** * 请求头 * * @return array */ protected function getHeaders() { $headers['Content-Type'] = 'application/json'; return $headers; } /** * 回去签名字符串 * * @param string $signString * @return string */ public function getSignature($signString) { $privKeyId = openssl_pkey_get_private($this->getPrivateKey()); openssl_sign($signString, $signature, $privKeyId); if (PHP_MAJOR_VERSION < 8) { openssl_free_key($privKeyId); } return $this->base64UrlEncode($signature); } /** * @return string */ protected function base64UrlEncode($data) { $base64 = base64_encode($data); $base64Url = strtr($base64, '+/', '-_'); $base64Url = rtrim($base64Url, '='); return $base64Url; } /** * 私钥加头尾 * * @return string */ protected function getPrivateKey() { $begin = '-----BEGIN PRIVATE KEY-----'; $end = '-----END PRIVATE KEY-----'; if (stripos($this->privateKey, $begin) === false) { return $begin . "\n" . $this->privateKey . "\n" . $end; } return $this->privateKey; } }