招标
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.

227 lines
6.2 KiB

3 years ago
<?php
/**
* Date: 2020/8/5 16:59
* User: chenlong <vip_chenlong@163.com>
*/
namespace weChat\pay;
use think\Exception;
trait BasicsAction
{
/**
* 初始加载
*/
private function init()
{
$this->getIp(); // 获取ip
$this->random(); // 生成随机数
$this->outTradeNo(); // 生成订单号
$this->time_start = date('YmdHis', $_SERVER['REQUEST_TIME']); // 开始时间
$this->time_expire = date('YmdHis', $_SERVER['REQUEST_TIME'] + 3600);// 结束时间
$this->sign_type = 'MD5'; // 签名加密方式
}
/**
* 获取appid等基础重要参数
* @param string $param
* @return mixed
*/
private function getParam(string $param)
{
$config_param = [
self::JS_API => '\\weChat\\common\\Config::xPay',
self::H5 => '\\weChat\\common\\Config::xPay',
self::APP => '\\weChat\\common\\Config::appPay',
self::NATIVE => '\\weChat\\common\\Config::sPay',
];
return call_user_func($config_param[$this->trade_type], $param);
}
/**
* 获取并设置客户端IP
*/
private function getIp()
{
$unknown = 'unknown';
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown)) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
/*
处理多层代理的情况
或者使用正则方式:$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
*/
if (false !== strpos($ip, ','))
$ip = explode(',', $ip)[0];
$this->spbill_create_ip = $ip;
}
/**
* 生成随机字符串
* @return string
*/
private function random()
{
$array = array_merge(range('A', 'Z'), range('a', 'z'), range(0, 9));
$random = mt_rand(24, 31);
$length = count($array);
$array[] = substr(time(), -1);
$string = '';
for ($i = 0; $i <= $random; ++$i) {
$string .= $array[mt_rand(0, $length)];
}
$this->nonce_str = $string;
return $string;
}
/**
* 生成签名
* @param array $signArray
* @return string
*/
private function sign(array $signArray = [])
{
if (empty($signArray)) {
foreach ($this as $key => $value) {
if ($key != 'key' && $value) $signArray[$key] = $value;
}
}
ksort($signArray);
$signString = '';
foreach ($signArray as $key => $value) {
$signString .= $key . '=' . $value . '&';
}
$signString .= 'key=' . $this->key;
$sign_type = $this->sign_type ?? 'md5';
$this->sign = strtoupper($sign_type($signString));
return $this->sign;
}
/**
* 生成订单号
*/
private function outTradeNo()
{
$this->out_trade_no = date('Ymd') . $_SERVER['REQUEST_TIME'] . mt_rand(100000, 999999);
}
/**
* 生成xml数据
* @param array $data
* @return string
*/
private function xml($data = [])
{
$data or $this->sign(); // 生成签名
$xml = '<xml>' . PHP_EOL;
foreach (($data ?: $this) as $k => $v) {
if ($v && $k != 'key') {
$xml .= "<{$k}>{$v}</{$k}>" . PHP_EOL;
}
}
$xml .= '</xml>';
return $xml;
}
/**
* 获取内部属性
* @param $attr
* @return string
*/
public function getAttr($attr = '')
{
return $this->$attr ?? '';
}
/**
* 设置appid,用于多个小程序一个后端
* @param $appId
* @return $this
*/
public function setAppId($appId)
{
if ($appId) {
$this->appid = $appId;
}
return $this;
}
/**
* 设置商户号和对应的秘钥
* @param $mch string 商户号
* @param $key string 秘钥
* @return $this
*/
public function setMchAndKey($mch, $key)
{
if (!empty($mch) && !empty($key)) {
$this->mch_id = $mch;
$this->key = $key;
}
return $this;
}
/**
* 设置场景值(H5支付时的)
* @param $url string 网站地址
* @param $name string 网站名字
*/
public function setSceneInfo($url, $name)
{
$scene_info = [
'store_info' => [
'type' => 'Wap',
'wap_url' => $url,
'wap_name' => $name
]
];
$this->scene_info = json_encode($scene_info, JSON_UNESCAPED_UNICODE);
}
/**
* 发起post请求
* @param string $url 路径
* @param mixed $data 数据
* @param array|null $cert 证书
* @return mixed
* @throws Exception
*/
private static function postRequest($url, $data, array $cert = null)
{
$headerArray = array("Content-type:application/xml;charset='utf-8'");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if ($cert !== null){
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'pem');
curl_setopt($curl, CURLOPT_SSLCERT, $cert['cert']);
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'pem');
curl_setopt($curl, CURLOPT_SSLKEY, $cert['key']);
}
$output = curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(curl_error($curl));
}
curl_close($curl);
return $output;
}
}