123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- <?php
- namespace BsPaySdk\core;
- use BsPaySdk\config\MerConfig;
- class BsPayRequestV2 {
- # 请求头
- private $httpHeaders;
- # 网络应答码
- private $httpStateCode;
- # 请求数据
- private $reqDatas;
- # 应答数据
- private $rspDatas;
- # 请求报错
- private $error = null;
- public function curlRequest(MerConfig $merConfig, $url, $postFields = null, $file = null, $headers=null, $is_json=false) {
- // $postFields['needSign'] 是否需要添加签名, $postFields['needVerfySign'] 是否需要验证签名
- $needSign = isset($postFields['needSign']) ? $postFields['needSign'] : true;
- $needVerfySign = isset($postFields['needVerfySign']) ? $postFields['needVerfySign'] : true;
- unset($postFields['needSign'],$postFields['needVerfySign']);
- BsPay::writeLog("curl方法参数:". json_encode(func_get_args(), JSON_UNESCAPED_UNICODE));
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_FAILONERROR, false);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_HEADER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- if (is_array($postFields) && 0 < count($postFields)) {
- curl_setopt($ch, CURLOPT_POST, true);
- $body = $this->createBody($merConfig, $postFields, $file);
- if (!$needSign) {
- unset($body['sign']);
- }
- if ($is_json) {
- $json_data = json_encode($body);
- BsPay::writeLog("post-json请求参数:" . json_encode($body, JSON_UNESCAPED_UNICODE));
- array_push($headers, "Content-Length:" . strlen($json_data));
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
- } else {
- BsPay::writeLog("post-form请求参数:" . json_encode($body, JSON_UNESCAPED_UNICODE));
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- $this->reqDatas = $body;
- }
- # 拼装请求头
- $this->httpHeaders = $this->createHeaders($headers);
- BsPay::writeLog("curl请求头:". json_encode($this->httpHeaders, JSON_UNESCAPED_UNICODE));
- curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeaders);
- # 执行网络请求
- $resultString = curl_exec($ch);
- # 处理系统的报错
- if (curl_errno($ch)) {
- $this->error = curl_error($ch);
- BsPay::writeLog($this->error, "ERROR");
- # 这里报错直接就关闭本次会话return了
- curl_close($ch);
- return $this;
- }
- # http应答码
- $this->httpStateCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
- # 关闭本次会话
- curl_close($ch);
- $this->rspDatas = json_decode($resultString, true);
- BsPay::writeLog("curl返回参数:". $this->httpStateCode. " ". $resultString);
- $resp_sign = isset($this->rspDatas['sign']) ? $this->rspDatas['sign'] : '';
- # 不需要对应答数据验签的逻辑分支,斗拱存在一些不用验签的接口,例如:页面版的快捷支付、手机网页支等
- if (!$resp_sign || $this->httpStateCode == 401) {
- if ($needVerfySign) {
- $this->error = array(
- 'code' => 'RESP_SIGN_VERIFY_UNDO',
- 'msg' => '无法对应答数据进行验签',
- );
- }
- if (!$this->rspDatas) {
- # 无法解析出json格式的情况,就直接就把应答数据返回出去,针对返回数据为html页面的接口,例如:页面版的快捷支付等
- $this->rspDatas = $resultString;
- }
- return $this;
- }
- $resp_data = isset($this->rspDatas['data']) ? $this->rspDatas['data'] : '';
- // TODO response 应答错误 hardcode 待优化 --- Charles.huang 2021/09/09
- # 对返回数据验签失败的逻辑分支
- if (!BsPayTools::verifySign_sort($resp_sign, $resp_data, $merConfig->rsa_huifu_public_key)) {
- $this->error = array(
- 'code' => 'RESP_SIGN_VERIFY_FAILED',
- 'msg' => '接口结果返回签名验证失败',
- );
- return $this;
- }
- # 应答码异常情况
- if ($this->httpStateCode < 200 || $this->httpStateCode >= 400) {
- $this->error = array(
- 'code' => 'HTTP_REQUEST_FAILED',
- 'msg' => "请求失败: HTTP_STATE_CODE-".$this->httpStateCode,
- );
- return $this;
- }
- return $this;
- }
- private function createHeaders($header_data = array()){
- $headers = $header_data;
- if (empty($header_data)){
- $headers = array('Content-type: application/x-www-form-urlencoded');
- }
-
- array_push($headers, 'sdk_version:' . SDK_VERSION);
- array_push($headers, 'charset:UTF-8');
- return $headers;
- }
- private function createBody(MerConfig $merChantConfig, $post_data, $file = null){
- $body = array();
- $body['sys_id'] = $merChantConfig->sys_id;
- $body['product_id'] = $merChantConfig->product_id;
- ksort($post_data); // 根据key排序
- $body['data'] = $post_data;
- # 执行签名
- $sign = BsPayTools::sha_with_rsa_sign(
- json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), // 数据里有中文和斜杠都不转码
- $merChantConfig->rsa_merch_private_key);
- $body['sign'] = $sign;
- if(!empty($file)){
- $body['file'] = $file;
- $body['data'] = json_encode($post_data, JSON_UNESCAPED_UNICODE);
- }
- return $body;
- }
- /**
- * 本次请求的http头信息
- */
- public function getHttpHeaders()
- {
- return $this->httpHeaders;
- }
- /**
- * 本次请求应答的 http状态码
- */
- public function getHttpStateCode()
- {
- return $this->httpStateCode;
- }
- /**
- * 本次请求的数据
- */
- public function getReqDatas()
- {
- return $this->reqDatas;
- }
- /**
- * 本次请求的应答数据
- */
- public function getRspDatas()
- {
- return $this->rspDatas;
- }
- /**
- * 获取请求执行失败信息
- */
- public function getErrorInfo()
- {
- return $this->error;
- }
- /**
- * 请求是否成功执行
- */
- public function isError()
- {
- return $this->error != null;
- }
- }
|