Base.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <?php
  2. namespace Yurun\PaySDK;
  3. use Yurun\PaySDK\Lib\XML;
  4. use Yurun\Util\HttpRequest;
  5. /**
  6. * SDK类基类.
  7. */
  8. abstract class Base
  9. {
  10. /**
  11. * HttpRequest.
  12. *
  13. * @var \Yurun\Util\HttpRequest
  14. */
  15. public $http;
  16. /**
  17. * 接口请求的返回结果.
  18. *
  19. * @var \Yurun\Util\YurunHttp\Http\Response
  20. */
  21. public $response;
  22. /**
  23. * 请求数据.
  24. *
  25. * @var array
  26. */
  27. public $requestData;
  28. /**
  29. * 公共参数.
  30. *
  31. * @var mixed
  32. */
  33. public $publicParams;
  34. /**
  35. * 最后请求的url地址
  36. *
  37. * @var string
  38. */
  39. public $url;
  40. /**
  41. * 最后请求的结果.
  42. *
  43. * @var mixed
  44. */
  45. public $result;
  46. /**
  47. * swoole 请求类,或支持 PSR-7 标准的对象
  48. *
  49. * @var \Swoole\Http\Request|\Psr\Http\Message\ServerRequestInterface
  50. */
  51. public $swooleRequest;
  52. /**
  53. * swoole 响应类,或支持 PSR-7 标准的对象
  54. *
  55. * @var \Swoole\Http\Response|\Psr\Http\Message\ResponseInterface
  56. */
  57. public $swooleResponse;
  58. public function __construct($publicParams)
  59. {
  60. $this->publicParams = $publicParams;
  61. $this->http = new HttpRequest();
  62. }
  63. /**
  64. * 调用执行接口.
  65. *
  66. * @param RequestBase $params
  67. * @param string $method
  68. *
  69. * @return mixed
  70. */
  71. public function execute($params, $format = 'JSON')
  72. {
  73. if ($params->__onExecute($this, $format))
  74. {
  75. return $this->result;
  76. }
  77. $this->prepareExecute($params, $url, $data);
  78. $this->url = $url;
  79. $this->response = $this->http->send($url, $this->requestData, $params->_method, $params->_contentType);
  80. if (!$this->response->success)
  81. {
  82. throw new \RuntimeException(sprintf('Request error: [%s] %s', $this->response->errno(), $this->response->error()));
  83. }
  84. switch ($format)
  85. {
  86. case 'JSON':
  87. $this->result = $this->response->json(true);
  88. break;
  89. case 'XML':
  90. $this->result = XML::fromString($this->response->body());
  91. break;
  92. default:
  93. $this->result = $this->response->body();
  94. }
  95. if (!$this->checkResult($this->result))
  96. {
  97. throw new \Exception(sprintf('Error: [%s] %s', $this->getErrorCode($this->result), $this->getError($this->result)));
  98. }
  99. if ($params->_isSyncVerify && !$this->verifySync($params, $this->result, $this->response))
  100. {
  101. throw new \Exception('同步返回数据验证失败');
  102. }
  103. else
  104. {
  105. return $this->result;
  106. }
  107. }
  108. /**
  109. * 调用执行接口,将结果保存至文件.
  110. *
  111. * @param mixed $params
  112. * @param string $saveFilename
  113. *
  114. * @return void
  115. */
  116. public function executeDownload($params, $saveFilename)
  117. {
  118. $this->prepareExecute($params, $url, $data);
  119. $this->url = $url;
  120. $this->http->saveFile($saveFilename)->send($url, $this->requestData, $params->_method);
  121. }
  122. /**
  123. * 签名.
  124. *
  125. * @param array $data
  126. *
  127. * @return string
  128. */
  129. abstract public function sign($data);
  130. /**
  131. * 处理执行接口的数据.
  132. *
  133. * @param $params
  134. * @param &$data 数据数组
  135. * @param &$requestData 请求用的数据,格式化后的
  136. * @param &$url 请求地址
  137. *
  138. * @return array
  139. */
  140. abstract public function __parseExecuteData($params, &$data, &$requestData, &$url);
  141. /**
  142. * 验证回调通知是否合法.
  143. *
  144. * @param $data
  145. *
  146. * @return bool
  147. */
  148. abstract public function verifyCallback($data);
  149. /**
  150. * 验证同步返回内容.
  151. *
  152. * @param mixed $params
  153. * @param array $data
  154. * @param \Yurun\Util\YurunHttp\Http\Response|null $response
  155. *
  156. * @return bool
  157. */
  158. abstract public function verifySync($params, $data, $response = null);
  159. /**
  160. * 检查是否执行成功
  161. *
  162. * @param array $result
  163. *
  164. * @return bool
  165. */
  166. abstract protected function __checkResult($result);
  167. /**
  168. * 获取错误信息.
  169. *
  170. * @param array $result
  171. *
  172. * @return string
  173. */
  174. abstract protected function __getError($result);
  175. /**
  176. * 获取错误代码
  177. *
  178. * @param array $result
  179. *
  180. * @return string
  181. */
  182. abstract protected function __getErrorCode($result);
  183. /**
  184. * 检查是否执行成功
  185. *
  186. * @param array $result
  187. *
  188. * @return bool
  189. */
  190. public function checkResult($result = null)
  191. {
  192. return $this->__checkResult(null === $result ? $this->result : $result);
  193. }
  194. /**
  195. * 获取错误信息.
  196. *
  197. * @param array $result
  198. *
  199. * @return string
  200. */
  201. public function getError($result = null)
  202. {
  203. return $this->__getError(null === $result ? $this->result : $result);
  204. }
  205. /**
  206. * 获取错误代码
  207. *
  208. * @param array $result
  209. *
  210. * @return string
  211. */
  212. public function getErrorCode($result = null)
  213. {
  214. return $this->__getErrorCode(null === $result ? $this->result : $result);
  215. }
  216. /**
  217. * 使用跳转的方式处理.
  218. *
  219. * @param array $params
  220. *
  221. * @return void
  222. */
  223. public function redirectExecute($params)
  224. {
  225. $this->__parseExecuteData($params, $data, $requestData, $url);
  226. if (false === strpos($url, '?'))
  227. {
  228. $url .= '?';
  229. }
  230. else
  231. {
  232. $url .= '&';
  233. }
  234. $this->requestData = $data;
  235. $url .= http_build_query($data, '', '&');
  236. if (null === $this->swooleResponse)
  237. {
  238. header('HTTP/1.1 302 Temporarily Moved');
  239. header('Status: 302 Temporarily Moved');
  240. header('Location: ' . $url);
  241. exit;
  242. }
  243. elseif ($this->swooleResponse instanceof \Swoole\Http\Response)
  244. {
  245. $this->swooleResponse->redirect($url, 302);
  246. }
  247. elseif ($this->swooleResponse instanceof \Psr\Http\Message\ResponseInterface)
  248. {
  249. $this->swooleResponse = $this->swooleResponse->withStatus(302)->withHeader('Location', $url);
  250. }
  251. }
  252. /**
  253. * 准备处理数据.
  254. *
  255. * @param $params
  256. * @param string $url
  257. * @param array $data
  258. *
  259. * @return void
  260. */
  261. public function prepareExecute($params, &$url = null, &$data = null)
  262. {
  263. $this->__parseExecuteData($params, $data, $requestData, $url);
  264. $this->requestData = $requestData;
  265. if ('GET' === $params->_method)
  266. {
  267. if (false === strpos($url, '?'))
  268. {
  269. $url .= '?';
  270. }
  271. else
  272. {
  273. $url .= '&';
  274. }
  275. $url .= http_build_query($data, '', '&');
  276. }
  277. }
  278. /**
  279. * 处理异步通知.
  280. *
  281. * @param \Yurun\PaySDK\NotifyBase $notifyHandler
  282. *
  283. * @return void
  284. */
  285. public function notify($notifyHandler)
  286. {
  287. $notifyHandler->sdk = $this;
  288. $notifyHandler->exec();
  289. }
  290. }