Service.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. namespace addons\epay\library;
  3. use Exception;
  4. use think\Log;
  5. use think\Response;
  6. use think\Session;
  7. use Yansongda\Pay\Pay;
  8. /**
  9. * 订单服务类
  10. *
  11. * @package addons\epay\library
  12. */
  13. class Service
  14. {
  15. public static function submitOrder($amount, $orderid = null, $type = null, $title = null, $notifyurl = null, $returnurl = null, $method = null)
  16. {
  17. if (!is_array($amount)) {
  18. $params = [
  19. 'amount' => $amount,
  20. 'orderid' => $orderid,
  21. 'type' => $type,
  22. 'title' => $title,
  23. 'notifyurl' => $notifyurl,
  24. 'returnurl' => $returnurl,
  25. 'method' => $method,
  26. ];
  27. } else {
  28. $params = $amount;
  29. }
  30. $type = isset($params['type']) && in_array($params['type'], ['alipay', 'wechat']) ? $params['type'] : 'wechat';
  31. $method = isset($params['method']) ? $params['method'] : 'web';
  32. $orderid = isset($params['orderid']) ? $params['orderid'] : date("YmdHis") . mt_rand(100000, 999999);
  33. $amount = isset($params['amount']) ? $params['amount'] : 1;
  34. $title = isset($params['title']) ? $params['title'] : "支付";
  35. $auth_code = isset($params['auth_code']) ? $params['auth_code'] : '';
  36. $openid = isset($params['openid']) ? $params['openid'] : '';
  37. $request = request();
  38. $notifyurl = isset($params['notifyurl']) ? $params['notifyurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'notify';
  39. $returnurl = isset($params['returnurl']) ? $params['returnurl'] : $request->root(true) . '/addons/epay/index/' . $type . 'return/out_trade_no/' . $orderid;
  40. $html = '';
  41. $config = Service::getConfig($type);
  42. $config[$type]['notify_url'] = $notifyurl;
  43. $config[$type]['return_url'] = $returnurl;
  44. if ($type == 'alipay') {
  45. //创建支付对象
  46. $pay = new Pay($config);
  47. //支付宝支付,请根据你的需求,仅选择你所需要的即可
  48. $params = [
  49. 'out_trade_no' => $orderid,//你的订单号
  50. 'total_amount' => $amount,//单位元
  51. 'subject' => $title,
  52. ];
  53. //如果是移动端自动切换为wap
  54. $method = $request->isMobile() ? 'wap' : $method;
  55. switch ($method) {
  56. case 'web':
  57. //电脑支付,跳转
  58. $html = $pay->driver($type)->gateway('web')->pay($params);
  59. Response::create($html)->send();
  60. break;
  61. case 'wap':
  62. //手机网页支付,跳转
  63. $html = $pay->driver($type)->gateway('wap')->pay($params);
  64. Response::create($html)->send();
  65. break;
  66. case 'app':
  67. //APP支付,直接返回字符串
  68. $html = $pay->driver($type)->gateway('app')->pay($params);
  69. break;
  70. case 'scan':
  71. //扫码支付,直接返回字符串
  72. $html = $pay->driver($type)->gateway('scan')->pay($params);
  73. break;
  74. case 'pos':
  75. //刷卡支付,直接返回字符串
  76. //刷卡支付必须要有auth_code
  77. $params['auth_code'] = $auth_code;
  78. $html = $pay->driver($type)->gateway('pos')->pay($params);
  79. break;
  80. default:
  81. //其它支付类型请参考:https://docs.pay.yansongda.cn/alipay
  82. }
  83. } else {
  84. //如果是PC支付,判断当前环境,进行跳转
  85. if ($method == 'web') {
  86. if ((strpos($request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false)) {
  87. Session::delete("openid");
  88. Session::set("wechatorderdata", $params);
  89. $url = addon_url('epay/api/wechat', [], true, true);
  90. header("location:{$url}");
  91. exit;
  92. } elseif ($request->isMobile()) {
  93. $method = 'wap';
  94. }
  95. }
  96. //创建支付对象
  97. $pay = new Pay($config);
  98. $params = [
  99. 'out_trade_no' => $orderid,//你的订单号
  100. 'body' => $title,
  101. 'total_fee' => $amount * 100, //单位分
  102. ];
  103. switch ($method) {
  104. case 'web':
  105. //电脑支付,跳转到自定义展示页面(FastAdmin独有)
  106. $html = $pay->driver($type)->gateway('web')->pay($params);
  107. Response::create($html)->send();
  108. break;
  109. case 'mp':
  110. //公众号支付
  111. //公众号支付必须有openid
  112. $params['openid'] = $openid;
  113. $html = $pay->driver($type)->gateway('mp')->pay($params);
  114. break;
  115. case 'wap':
  116. //手机网页支付,跳转
  117. $params['spbill_create_ip'] = $request->ip(0, false);
  118. $html = $pay->driver($type)->gateway('wap')->pay($params);
  119. header("location:{$html}");
  120. exit;
  121. break;
  122. case 'app':
  123. //APP支付,直接返回字符串
  124. $html = $pay->driver($type)->gateway('app')->pay($params);
  125. break;
  126. case 'scan':
  127. //扫码支付,直接返回字符串
  128. $html = $pay->driver($type)->gateway('scan')->pay($params);
  129. break;
  130. case 'pos':
  131. //刷卡支付,直接返回字符串
  132. //刷卡支付必须要有auth_code
  133. $params['auth_code'] = $auth_code;
  134. $html = $pay->driver($type)->gateway('pos')->pay($params);
  135. break;
  136. case 'miniapp':
  137. //小程序支付,直接返回字符串
  138. //小程序支付必须要有openid
  139. $params['openid'] = $openid;
  140. $html = $pay->driver($type)->gateway('miniapp')->pay($params);
  141. break;
  142. default:
  143. }
  144. }
  145. //返回字符串
  146. $html = is_array($html) ? json_encode($html) : $html;
  147. return $html;
  148. }
  149. /**
  150. * 创建支付对象
  151. * @param string $type 支付类型
  152. * @param array $config 配置信息
  153. * @return bool
  154. */
  155. public static function createPay($type, $config = [])
  156. {
  157. $type = strtolower($type);
  158. if (!in_array($type, ['wechat', 'alipay'])) {
  159. return false;
  160. }
  161. $config = self::getConfig($type);
  162. $config = array_merge($config[$type], $config);
  163. $pay = new Pay($config);
  164. return $pay;
  165. }
  166. /**
  167. * 验证回调是否成功
  168. * @param string $type 支付类型
  169. * @param array $config 配置信息
  170. * @return bool|Pay
  171. */
  172. public static function checkNotify($type, $config = [])
  173. {
  174. $type = strtolower($type);
  175. if (!in_array($type, ['wechat', 'alipay'])) {
  176. return false;
  177. }
  178. try {
  179. $pay = new Pay(self::getConfig($type));
  180. $data = $type == 'wechat' ? file_get_contents("php://input") : request()->post('', null, 'trim');
  181. $data = $pay->driver($type)->gateway()->verify($data);
  182. if ($type == 'alipay') {
  183. if (in_array($data['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
  184. return $pay;
  185. }
  186. } else {
  187. return $pay;
  188. }
  189. } catch (Exception $e) {
  190. return false;
  191. }
  192. return false;
  193. }
  194. /**
  195. * 验证返回是否成功
  196. * @param string $type 支付类型
  197. * @param array $config 配置信息
  198. * @return bool|Pay
  199. */
  200. public static function checkReturn($type, $config = [])
  201. {
  202. $type = strtolower($type);
  203. if (!in_array($type, ['wechat', 'alipay'])) {
  204. return false;
  205. }
  206. //微信无需验证
  207. if ($type == 'wechat') {
  208. return true;
  209. }
  210. try {
  211. $pay = new Pay(self::getConfig($type));
  212. $data = $type == 'wechat' ? file_get_contents("php://input") : request()->get('', null, 'trim');
  213. $data = $pay->driver($type)->gateway()->verify($data);
  214. if ($data) {
  215. return $pay;
  216. }
  217. } catch (Exception $e) {
  218. return false;
  219. }
  220. return false;
  221. }
  222. /**
  223. * 获取配置
  224. * @param string $type 支付类型
  225. * @return array|mixed
  226. */
  227. public static function getConfig($type = 'wechat')
  228. {
  229. $config = get_addon_config('epay');
  230. $config = isset($config[$type]) ? $config[$type] : $config['wechat'];
  231. if ($config['log']) {
  232. $config['log'] = [
  233. 'file' => LOG_PATH . '/epaylogs/' . $type . '-' . date("Y-m-d") . '.log',
  234. 'level' => 'debug'
  235. ];
  236. }
  237. if (isset($config['cert_client']) && substr($config['cert_client'], 0, 6) == '/epay/') {
  238. $config['cert_client'] = ADDON_PATH . $config['cert_client'];
  239. }
  240. if (isset($config['cert_key']) && substr($config['cert_key'], 0, 6) == '/epay/') {
  241. $config['cert_key'] = ADDON_PATH . $config['cert_key'];
  242. }
  243. $config['notify_url'] = empty($config['notify_url']) ? addon_url('epay/api/notifyx', [], false) . '/type/' . $type : $config['notify_url'];
  244. $config['notify_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['notify_url']) ? request()->root(true) . $config['notify_url'] : $config['notify_url'];
  245. $config['return_url'] = empty($config['return_url']) ? addon_url('epay/api/returnx', [], false) . '/type/' . $type : $config['return_url'];
  246. $config['return_url'] = !preg_match("/^(http:\/\/|https:\/\/)/i", $config['return_url']) ? request()->root(true) . $config['return_url'] : $config['return_url'];
  247. return [$type => $config];
  248. }
  249. }