Base.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <?php namespace Connect\Lib\Func;
  2. use Dever;
  3. class Base
  4. {
  5. protected $connect;
  6. protected $info;
  7. protected $domain;
  8. protected $param = array();
  9. # 设置基本信息
  10. protected function setting($type, $cate_id, $channel, $param = array())
  11. {
  12. $this->connect = Dever::db('info', 'connect')->find($channel['connect_id']);
  13. if (!$this->connect) {
  14. return false;
  15. }
  16. $this->connect['channel_id'] = $channel['id'];
  17. $this->connect['host'] = $channel['host'];
  18. $this->connect['appkey'] = $channel['appkey'];
  19. $this->connect['appsecret'] = $channel['appsecret'];
  20. $set = Dever::db('set', 'channel')->select(array('channel_id' => $channel['id']));
  21. $this->connect['set'] = array();
  22. if ($set) {
  23. foreach ($set as $k => $v) {
  24. $this->connect['set'][$v['key']] = $v['value'];
  25. }
  26. }
  27. $this->info = false;
  28. if ($cate_id) {
  29. $this->info = Dever::db($this->type, 'connect')->find(array('type' => $type, 'cate_id' => $cate_id, 'connect_id' => $this->connect['id']));
  30. }
  31. if (!$this->info) {
  32. $this->info = Dever::db($this->type, 'connect')->find(array('type' => $type, 'connect_id' => $this->connect['id']));
  33. if (!$this->info) {
  34. return false;
  35. }
  36. }
  37. $this->param = $param;
  38. return $this;
  39. }
  40. # 发起请求
  41. protected function curl($url = false)
  42. {
  43. if (!$url) {
  44. $url = $this->url();
  45. }
  46. $header = $body = array();
  47. $method = 'get';
  48. $json = false;
  49. if ($this->info['method'] == -1) {
  50. $this->info['method'] = $this->connect['method'];
  51. $this->info['post_method'] = $this->connect['post_method'];
  52. }
  53. if ($this->info['post_method'] == 2) {
  54. $method = 'file';
  55. } elseif ($this->info['method'] == 2) {
  56. $method = 'post';
  57. }
  58. if ($this->info['post_method'] == 3) {
  59. $json = true;
  60. }
  61. # 标准请求头
  62. $this->request($header, 'request_header', array('connect_id' => $this->connect['id']));
  63. # 标准请求体
  64. $this->request($body, 'request_body', array('connect_id' => $this->connect['id']));
  65. if (method_exists($this, 'requestHeader')) {
  66. $this->requestHeader($header);
  67. }
  68. if (method_exists($this, 'requestBody')) {
  69. $this->requestBody($body);
  70. }
  71. $this->sign($body);
  72. $response = Dever::curl($url, $body, $method, $json, $header)->result();
  73. $test = Dever::input('test');
  74. if ($test && $test == 1) {
  75. $result = array
  76. (
  77. 'url' => $url,
  78. 'header' => $header,
  79. 'method' => $method,
  80. 'json' => $json,
  81. 'body' => $body,
  82. 'response' => $response,
  83. );
  84. echo Dever::json_encode($result);die;
  85. }
  86. //$response = '{"code":1,"info":"ok","data":{"order":"Q202401037683854738260576","account":"15810090845","status":1}}';
  87. //$response = '{"status":0,"msg":"success","order_id":"24013117320741438be7f0b65a","product_id":20005,"price":104.1,"amount":100,"user_order":"C2024013193480488567061"}';
  88. //$response = '{"status":"0","msg":"success","balance":"100.0000","frozen_balance":"9.9800"}';
  89. $response = $this->response($response);
  90. $response['request'] = $body;
  91. return $response;
  92. }
  93. # 处理url
  94. protected function url()
  95. {
  96. if (strstr($this->info['uri'], 'http')) {
  97. $this->connect['host'] = '';
  98. }
  99. $uri = Dever::db('api_uri', 'connect')->select(array('api_id' => $this->info['id']));
  100. if ($uri) {
  101. $path = array();
  102. $param = array();
  103. foreach ($uri as $k => $v) {
  104. $v['value'] = $this->value(array(), $v['key'], $v['value']);
  105. if ($v['type'] == 1) {
  106. $path[] = $v['value'];
  107. } elseif ($v['type'] == 2) {
  108. $path[] = $v['key'] . '/' . $v['value'];
  109. } elseif ($v['type'] == 3) {
  110. $path[] = $v['key'] . '=' . $v['value'];
  111. } elseif ($v['type'] == 4) {
  112. $param[] = $v['value'];
  113. } elseif ($v['type'] == 5) {
  114. $param[] = $v['key'] . '=' . $v['value'];
  115. }
  116. }
  117. if ($path) {
  118. $this->info['uri'] .= implode('/', $path);
  119. }
  120. if ($param) {
  121. if (!strstr($this->info['uri'], '?')) {
  122. $this->info['uri'] .= '?';
  123. }
  124. $this->info['uri'] .= implode('&', $param);
  125. }
  126. }
  127. return $this->domain = $this->connect['host'] . $this->info['uri'];
  128. }
  129. # 获取请求参数
  130. protected function request(&$data, $table, $where)
  131. {
  132. $body = Dever::db($table, 'connect')->select($where);
  133. if ($body) {
  134. foreach ($body as $k => $v) {
  135. $value = $this->value($data, $v['key'], $v['default'], $v['type']);
  136. if ($value) {
  137. $data[$v['key']] = $value;
  138. }
  139. }
  140. }
  141. }
  142. # 数据响应格式处理
  143. protected function response($response)
  144. {
  145. if ($this->connect['response_type'] == 1) {
  146. $response = $this->filter($response);
  147. return array
  148. (
  149. 'status' => 1,
  150. 'msg' => 'ok',
  151. 'response' => false,
  152. 'request' => array(),
  153. 'data' => $response,
  154. );
  155. }
  156. if ($this->connect['response_type'] == 2) {
  157. $response = Dever::json_decode($response);
  158. } elseif ($this->connect['response_type'] == 3) {
  159. $response = (array) simplexml_load_string($response);
  160. } else {
  161. if (strstr($response, ',')) {
  162. $response = explode(',', $response);
  163. } elseif (strstr($response, ' ')) {
  164. $response = explode(' ', $response);
  165. } elseif (strstr($response, '|')) {
  166. $response = explode('|', $response);
  167. } else {
  168. $response = explode("\n", $response);
  169. }
  170. }
  171. $msg = '';
  172. $status = 2;
  173. if (isset($response[$this->connect['response_code']])) {
  174. $code = $response[$this->connect['response_code']];
  175. $code = Dever::db('response_code', 'connect')->find(array('connect_id' => $this->connect['id'], 'value' => $code));
  176. if ($code && $code['type'] == 1) {
  177. $status = 1;
  178. }
  179. }
  180. $msg = $response[$this->connect['response_msg']] ?? 'no';
  181. $data = '';
  182. if (strstr($this->connect['response_data'], ',')) {
  183. $temp = explode(',', $this->connect['response_data']);
  184. foreach ($temp as $k => $v) {
  185. if (isset($response[$v])) {
  186. $data = $response[$v];
  187. break;
  188. }
  189. }
  190. } elseif (strstr($this->connect['response_data'], '.')) {
  191. $temp = explode('.', $this->connect['response_data']);
  192. $data = isset($response[$temp[0]][$temp[1]]) ? $response[$temp[0]][$temp[1]] : (isset($response[$temp[0]]) ? $response[$temp[0]] : false);
  193. } else {
  194. $data = $response[$this->connect['response_data']] ?? $response;
  195. }
  196. if ($data) {
  197. if (method_exists($this, 'responseHandle')) {
  198. $this->responseHandle($data);
  199. }
  200. }
  201. return array
  202. (
  203. 'status' => $status,
  204. 'msg' => $msg,
  205. 'response' => $response,
  206. 'request' => array(),
  207. 'data' => $data,
  208. );
  209. }
  210. protected function sign(&$body)
  211. {
  212. if ($this->connect['sign_method'] == 1) {
  213. return;
  214. }
  215. if (!$this->connect['sign_name']) {
  216. $this->connect['sign_name'] = 'signature';
  217. }
  218. $sign = array();
  219. if ($this->info['sign_col']) {
  220. $col = explode('+', $this->info['sign_col']);
  221. foreach ($col as $k => $v) {
  222. $sign[$v] = $this->value($body, $v, $v, 1);
  223. }
  224. } elseif ($this->connect['sign_col']) {
  225. $col = explode('+', $this->connect['sign_col']);
  226. foreach ($col as $k => $v) {
  227. $sign[$v] = $this->value($body, $v, $v, 1);
  228. }
  229. } else {
  230. $sign = $body;
  231. }
  232. if ($this->connect['sign_appsecret'] && $this->connect['sign_appsecret_location'] == 1) {
  233. $sign[$this->connect['sign_appsecret']] = $this->connect['appsecret'];
  234. if (isset($sign['api_product'])) {
  235. $sign[$this->connect['sign_appsecret']] = sha1($this->connect['appkey'] . '|' . $this->connect['appsecret']);
  236. }
  237. }
  238. if ($this->connect['sign_sort'] == 2) {
  239. ksort($sign);
  240. }
  241. $string = '';
  242. foreach ($sign as $k => $v) {
  243. if ($this->connect['sign_empty'] == 2 && !$v) {
  244. continue;
  245. }
  246. if ($this->connect['sign_encode'] == 2 && strstr($v, 'http')) {
  247. $v = urlencode($v);
  248. if (isset($body[$k])) {
  249. $body[$k] = $v;
  250. }
  251. }
  252. if ($this->connect['sign_type'] == 1) {
  253. $string .= $v;
  254. } elseif ($this->connect['sign_type'] == 2) {
  255. $string .= $k . '=' . $v . '&';
  256. } elseif ($this->connect['sign_type'] == 3) {
  257. $string .= $k . $v;
  258. } elseif ($this->connect['sign_type'] == 4) {
  259. $string .= $k . $v . '&';
  260. }
  261. }
  262. $sign = rtrim($string, '&');
  263. if ($this->connect['sign_appsecret'] && $this->connect['sign_appsecret_location'] == 2) {
  264. if ($this->connect['sign_type'] == 1) {
  265. $sign .= $this->connect['appsecret'];
  266. } elseif ($this->connect['sign_type'] == 2) {
  267. $sign .= '&' . $this->connect['sign_appsecret'] . '=' . $this->connect['appsecret'];
  268. } elseif ($this->connect['sign_type'] == 3) {
  269. $sign .= $this->connect['sign_appsecret'] . $this->connect['appsecret'];
  270. } elseif ($this->connect['sign_type'] == 4) {
  271. $sign .= '&' . $this->connect['sign_appsecret'] . $this->connect['appsecret'];
  272. }
  273. }
  274. # 如果是ssl 这里需要处理一下,后续处理吧
  275. if ($this->connect['sign_method'] == 2) {
  276. $sign = md5($sign);
  277. } elseif ($this->connect['sign_method'] == 3) {
  278. $sign = hash("sha256", $sign);
  279. } elseif ($this->connect['sign_method'] == 4) {
  280. $sign = sha1($sign);
  281. }
  282. if ($this->connect['sign_after'] == 2) {
  283. $sign = strtoupper($sign);
  284. } elseif ($this->connect['sign_after'] == 2) {
  285. $sign = strtolower($sign);
  286. }
  287. $body[$this->connect['sign_name']] = $sign;
  288. return $sign;
  289. }
  290. protected function value($data, $key, $value, $type = 1)
  291. {
  292. $value = trim($value);
  293. if ($this->param && isset($this->param[$value])) {
  294. $value = $this->param[$value];
  295. } elseif ($data && isset($data[$value])) {
  296. $value = $data[$value];
  297. } elseif (isset($this->connect['set'][$value]) && $this->connect['set'][$value]) {
  298. $value = $this->connect['set'][$value];
  299. } elseif (isset($this->connect[$value]) && $this->connect[$value]) {
  300. $value = $this->connect[$value];
  301. } elseif ($value == 'notify') {
  302. $value = $this->createNotify($this->param['order_id'] ?? '');
  303. } elseif ($value == 'api_request') {
  304. $value = $data;
  305. } elseif ($value == 'timestamp') {
  306. $value = \Dever\Helper\Secure::timestamp();
  307. } elseif ($value == 'nonce') {
  308. $value = \Dever\Helper\Secure::nonce();
  309. } elseif ($value == 'token') {
  310. $value = $this->token(1, 'token');
  311. } elseif ($value == 'ticket') {
  312. $value = $this->token(2, 'ticket');
  313. } elseif ($a = strstr($value, '{') || strstr($value, '(')) {
  314. if ($a) {
  315. $func = function ($r) use($data) {
  316. return $this->value($data, $r[1], $r[1]);
  317. };
  318. $value = preg_replace_callback('/{(.*?)}/', $func, $value);
  319. }
  320. $value = '$value = '.$value.';';
  321. eval($value);
  322. }
  323. if (!$value) {
  324. $key = trim($key);
  325. return Dever::input($key);
  326. }
  327. if ($type == 1 || $type == 100) {
  328. $value = (string) $value;
  329. } elseif ($type == 2 || $type == 200) {
  330. $value = (float) $value;
  331. } elseif ($type == 3 && is_array($value)) {
  332. $value = Dever::json_encode($value);
  333. } elseif ($type == 4) {
  334. $value = $this->encrypt($value);
  335. } elseif ($type == 300 && is_array($value)) {
  336. $value = Dever::json_decode($value);
  337. } elseif ($type == 400) {
  338. $value = $this->decrypt($value);
  339. }
  340. return $value;
  341. }
  342. protected function service($data)
  343. {
  344. # 转换处理
  345. $convert = Dever::db('convert', 'connect')->select(array('connect_id' => $this->connect['id']));
  346. $param = array();
  347. if ($convert) {
  348. if (isset($data[0])) {
  349. foreach ($data as $k1 => $v1) {
  350. foreach ($convert as $k => $v) {
  351. if (isset($data[$k1][$v['before']])) {
  352. $param[$k1][$v['after']] = $data[$k1][$v['before']];
  353. }
  354. }
  355. }
  356. } else {
  357. foreach ($convert as $k => $v) {
  358. if (isset($data[$v['before']])) {
  359. $param[$v['after']] = $data[$v['before']];
  360. }
  361. }
  362. }
  363. } else {
  364. $param = $data;
  365. }
  366. # 具体业务处理,这里先不做
  367. //Dever::load('channel/lib/service')->act($this->channel['id'], $this->info['service_id'], $this->type, $this->info['id'], $param);
  368. return $param;
  369. }
  370. protected function token($id = 1, $type = 'token')
  371. {
  372. return '';
  373. $db = Dever::db($type, 'connect');
  374. $data['connect_id'] = $connect['id'];
  375. $data['api_id'] = $api['id'];
  376. $info = $db->find($data);
  377. if ($info && time() - $info['mdate'] >= $info['expires']) {
  378. } elseif ($info) {
  379. return $info['value'];
  380. }
  381. $result = $this->init()->curl();
  382. if (isset($result[$type])) {
  383. $data['value'] = $result[$type];
  384. $data['expires'] = '7200';
  385. if (isset($result['expires'])) {
  386. $data['expires'] = $result['expires'];
  387. }
  388. if ($info) {
  389. $data['where_id'] = $info['id'];
  390. $db->update($data);
  391. } else {
  392. $db->insert($data);
  393. }
  394. return $result[$type];
  395. }
  396. return '';
  397. }
  398. protected function encrypt($value)
  399. {
  400. if ($this->connect['ssl_method'] && $this->connect['ssl_key']) {
  401. $value = openssl_encrypt($value, $this->connect['ssl_method'], $this->connect['ssl_key'], $this->connect['ssl_option'], $this->connect['ssl_iv']);
  402. if ($this->connect['ssl_after'] == 2) {
  403. $value = base64_encode($value);
  404. }
  405. }
  406. return $value;
  407. }
  408. protected function decrypt($value)
  409. {
  410. if ($this->connect['ssl_method'] && $this->connect['ssl_key']) {
  411. if (is_array($value)) {
  412. $value = Dever::json_encode($value);
  413. }
  414. $value = openssl_decrypt($value, $this->connect['ssl_method'], $this->connect['ssl_key'], $this->connect['ssl_option'], $this->connect['ssl_iv']);
  415. if ($this->connect['ssl_after'] == 2) {
  416. $value = base64_decode($value);
  417. }
  418. }
  419. return $value;
  420. }
  421. protected function public_encrypt()
  422. {
  423. $publicKey = "-----BEGIN PUBLIC KEY-----\n" .
  424. chunk_split($this->nowpayPublickey, 64, "\n") .
  425. "-----END PUBLIC KEY-----\n";
  426. $output = '';
  427. openssl_public_encrypt($this->encryptKey, $output, $publicKey);
  428. return base64_encode($output);
  429. }
  430. protected function protected_decrypt($str)
  431. {
  432. $priKey = "-----BEGIN RSA protected KEY-----\n" .
  433. chunk_split($this->protectedKey, 64, "\n") .
  434. "-----END RSA protected KEY-----\n";
  435. $output = '';
  436. openssl_protected_decrypt(base64_decode($str), $output, $priKey);
  437. return $output;
  438. }
  439. protected function filter($data)
  440. {
  441. return preg_replace("/<!--[^\!\[]*?(?<!\/\/)-->/","",$data);
  442. }
  443. }