No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PayApi.php 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /**
  3. * 易优CMS
  4. * ============================================================================
  5. * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
  6. * 网站地址: http://www.eyoucms.com
  7. * ----------------------------------------------------------------------------
  8. * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
  9. * ============================================================================
  10. * Author: 陈风任 <491085389@qq.com>
  11. * Date: 2020-05-22
  12. */
  13. namespace app\admin\model;
  14. use think\Model;
  15. use think\Config;
  16. use think\Db;
  17. /**
  18. * 支付接口模型
  19. */
  20. class PayApi extends Model
  21. {
  22. private $key = ''; // key密钥
  23. //初始化
  24. protected function initialize()
  25. {
  26. // 需要调用`Model`的`initialize`方法
  27. parent::initialize();
  28. }
  29. /*
  30. * 验证微信支付配置信息是否正确
  31. */
  32. public function VerifyWeChatConfig($wechat = [])
  33. {
  34. if (empty($wechat)) return false;
  35. $this->key = $wechat['key'];
  36. // 支付备注
  37. $body = "验证支付";
  38. if (1 == config('global.opencodetype')) {
  39. $web_name = tpCache('web.web_name');
  40. $web_name = !empty($web_name) ? "[{$web_name}]" : "";
  41. $body = $web_name.$body;
  42. }
  43. // 支付数据
  44. $out_trade_no = getTime();
  45. $data['out_trade_no'] = $out_trade_no;
  46. $data['total_fee'] = '1';
  47. $data['spbill_create_ip'] = $this->get_client_ip();
  48. $data['attach'] = '微信扫码支付';
  49. $data['body'] = $body."订单号:{$out_trade_no}";
  50. $data['appid'] = $wechat['appid'];
  51. $data['mch_id'] = $wechat['mchid'];
  52. $data['nonce_str'] = getTime();
  53. $data['trade_type'] = "NATIVE";
  54. $data['notify_url'] = url('user/Pay/pay_deal_with');
  55. // 签名加密
  56. $sign = $this->getParam($data);
  57. // 转化XML格式
  58. $dataXML = "<xml>
  59. <appid>".$data['appid']."</appid>
  60. <attach>".$data['attach']."</attach>
  61. <body>".$data['body']."</body>
  62. <mch_id>".$data['mch_id']."</mch_id>
  63. <nonce_str>".$data['nonce_str']."</nonce_str>
  64. <notify_url>".$data['notify_url']."</notify_url>
  65. <out_trade_no>".$data['out_trade_no']."</out_trade_no>
  66. <spbill_create_ip>".$data['spbill_create_ip']."</spbill_create_ip>
  67. <total_fee>".$data['total_fee']."</total_fee>
  68. <trade_type>".$data['trade_type']."</trade_type>
  69. <sign>".$sign."</sign>
  70. </xml>";
  71. // 调用接口
  72. $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  73. $result = $this->https_post($url, $dataXML);
  74. // 转换回数组格式
  75. $result = $this->xmlToArray($result);
  76. // 返回结果
  77. if($result['return_code'] == 'SUCCESS' && $result['return_msg'] == 'OK') {
  78. return $result['code_url'];
  79. } else {
  80. if ('签名错误' == $result['return_msg']) {
  81. $result['return_msg'] = '微信KEY值错误!';
  82. } else if (stristr($result['return_msg'], 'mch_id')) {
  83. $result['return_msg'] = '微信商户号错误!';
  84. } else if (stristr($result['return_msg'], 'appid')) {
  85. $result['return_msg'] = '微信AppId错误!';
  86. }
  87. return $result;
  88. }
  89. }
  90. // 获取客户端IP
  91. private function get_client_ip() {
  92. if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
  93. $ip = getenv('HTTP_CLIENT_IP');
  94. } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
  95. $ip = getenv('HTTP_X_FORWARDED_FOR');
  96. } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
  97. $ip = getenv('REMOTE_ADDR');
  98. } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
  99. $ip = $_SERVER['REMOTE_ADDR'];
  100. }
  101. return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
  102. }
  103. // 对参数排序,生成MD5加密签名
  104. private function getParam($paramArray, $isencode=false)
  105. {
  106. $paramStr = '';
  107. ksort($paramArray);
  108. $i = 0;
  109. foreach ($paramArray as $key => $value)
  110. {
  111. if ($key == 'Signature'){
  112. continue;
  113. }
  114. if ($i == 0){
  115. $paramStr .= '';
  116. }else{
  117. $paramStr .= '&';
  118. }
  119. $paramStr .= $key . '=' . ($isencode ? urlencode($value) : $value);
  120. ++$i;
  121. }
  122. $stringSignTemp=$paramStr."&key=".$this->key;
  123. $sign=strtoupper(md5($stringSignTemp));
  124. return $sign;
  125. }
  126. // POST提交数据
  127. private function https_post($url,$data)
  128. {
  129. $ch = curl_init ();
  130. curl_setopt ( $ch, CURLOPT_URL, $url );
  131. curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
  132. curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
  133. curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
  134. // curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
  135. curl_setopt ( $ch, CURLOPT_AUTOREFERER, 1 );
  136. curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
  137. curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
  138. $result = curl_exec($ch);
  139. if (curl_errno($ch)) {
  140. return 'Errno: '.curl_error($ch);
  141. }
  142. curl_close($ch);
  143. return $result;
  144. }
  145. // XML转array
  146. private function xmlToArray($xml)
  147. {
  148. libxml_disable_entity_loader(true);
  149. $xmlstring = (array)simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
  150. $val = json_decode(json_encode($xmlstring),true);
  151. return $val;
  152. }
  153. // 验证支付宝支付配置是否正确
  154. public function VerifyAliPayConfig($alipay = [])
  155. {
  156. if (!empty($alipay)) {
  157. // 时间戳当订单号
  158. $order_number = getTime();
  159. // 引入文件
  160. vendor('alipay.pagepay.service.AlipayTradeService');
  161. vendor('alipay.pagepay.buildermodel.AlipayTradeQueryContentBuilder');
  162. // 实例化加载订单号
  163. $RequestBuilder = new \AlipayTradeQueryContentBuilder;
  164. $out_trade_no = trim($order_number);
  165. $RequestBuilder->setOutTradeNo($out_trade_no);
  166. // 处理支付宝配置数据
  167. $config['app_id'] = $alipay['app_id'];
  168. $config['merchant_private_key'] = $alipay['merchant_private_key'];
  169. $config['charset'] = 'UTF-8';
  170. $config['sign_type'] = 'RSA2';
  171. $config['gatewayUrl'] = 'https://openapi.alipay.com/gateway.do';
  172. $config['alipay_public_key'] = $alipay['alipay_public_key'];
  173. // 实例化支付宝配置
  174. $aop = new \AlipayTradeService($config);
  175. // 返回结果
  176. $result = $aop->IsQuery($RequestBuilder, 'admin_pay');
  177. $result = json_decode(json_encode($result), true);
  178. // 判断结果
  179. if ('40004' == $result['code'] && 'Business Failed' == $result['msg']) {
  180. // 用于支付宝支付配置验证
  181. return 'ok';
  182. } else if ('40001' == $result['code'] && 'Missing Required Arguments' == $result['msg']) {
  183. return '商户私钥错误!';
  184. } else if (is_array($result)) {
  185. $msg = !empty($result['sub_msg']) ? $result['sub_msg'] : '请确保配置正确,且检查支付宝平台的权限';
  186. return $msg;
  187. } else {
  188. return $result;
  189. }
  190. }
  191. }
  192. }