123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- /**
- * @note: 微信支付
- * @author: jdzor <895947580@qq.com>
- * @date: 2019/3/15
- */
- namespace payment\wechat;
- class BaseWechat
- {
- const API_URL_PREFIX = 'https://api.mch.weixin.qq.com'; //接口API URL前缀
- protected $signType = 'MD5'; //签名方式
- protected $appId; //公众账号ID
- protected $mchId; //商户号
- protected $key; //支付密钥
- protected $sslcertPath; //证书路径
- protected $sslkeyPath; //证书路径
- protected $notifyUrl; //支付结果回调通知地址
- protected function __construct($config)
- {
- isset($config['appid']) || json_error('缺少参数:appid');
- isset($config['mch_id']) || json_error('缺少参数:mch_id');
- isset($config['key']) || json_error('缺少参数:key');
- $this->appId = $config['appid']; //支付、退款、企业付款使用
- $this->mchId = $config['mch_id'];
- $this->key = $config['key'];
- }
- //生成签名
- protected function makeSign($param)
- {
- //签名步骤一:按字典序排序数组参数
- ksort($param);
- $param = array_filter($param);
- $string = $this->toUrlParams($param);
- //签名步骤二:在string后加入KEY
- $string = $string . "&key=" . $this->key;
- //签名步骤三:MD5加密
- $string = md5($string);
- //签名步骤四:所有字符转为大写
- $result = strtoupper($string);
- return $result;
- }
- //参数拼接 url: key=value&key=value
- protected function toUrlParams($param)
- {
- $string = '';
- if ($param) {
- $array = [];
- foreach ($param as $key => $val) {
- $array[] = $key . '=' . $val;
- }
- $string = implode("&", $array);
- }
- return $string;
- }
- //输出xml字符
- protected function dataToXml($param)
- {
- if (!is_array($param) || count($param) <= 0) return false;
- $xml = "<xml>";
- foreach ($param as $key => $val) {
- if (is_numeric($val)) {
- $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
- } else {
- $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
- }
- }
- $xml .= "</xml>";
- return $xml;
- }
- //将xml转为array
- protected function xmlToArray($xml)
- {
- if (!$xml) return false;
- //禁止引用外部xml实体
- libxml_disable_entity_loader(true);
- $xmlString = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
- $array = json_decode(json_encode($xmlString), true);
- return $array;
- }
- //产生一个指定长度的随机字符串 不长于32位
- protected function getRandomString($length = 32)
- {
- $str = '';
- $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
- for ($i = 0; $i < $length; $i++) {
- $str .= $strPol[mt_rand(0, strlen($strPol) - 1)];
- }
- return $str;
- }
- //post方式提交xml到对应的接口url
- protected function postXmlCurl($xml, $url, $useCert = false, $second = 30)
- {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_TIMEOUT, $second);
- curl_setopt($ch, CURLOPT_URL, self::API_URL_PREFIX . $url);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //生产环境设置为2
- curl_setopt($ch, CURLOPT_HEADER, false); //设置header
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //要求结果为字符串且输出到屏幕上
- if ($useCert) {
- //使用证书:cert 与 key 分别属于两个.pem文件
- curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
- curl_setopt($ch, CURLOPT_SSLCERT, $this->sslcertPath);
- curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
- curl_setopt($ch, CURLOPT_SSLKEY, $this->sslkeyPath);
- }
- //post提交方式
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
- if (!($data = curl_exec($ch))) $data = ['errno' => curl_errno($ch), 'error' => curl_error($ch)] + curl_getinfo($ch);
- curl_close($ch);
- return $data;
- }
- //get方式提交
- protected function getCurl($url)
- {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置cURL允许执行的最长秒数
- curl_setopt($ch, CURLOPT_HEADER, false); //是否抓取头文件的信息,默认值为false,表示不显示响应头
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- if (!($data = curl_exec($ch))) $data = ['errno' => curl_errno($ch), 'error' => curl_error($ch)] + curl_getinfo($ch);
- //转码
- $fromEncoding = 'auto'; //未知原编码,通过auto自动检测后,转换编码为utf-8
- if (is_array($data)) {
- $data = json_decode(mb_convert_encoding(json_encode($data), 'UTF-8', $fromEncoding), true);
- } else {
- $data = json_decode(mb_convert_encoding($data, 'UTF-8', $fromEncoding), true);
- }
- curl_close($ch);
- return $data;
- }
- }
|