//*
*构建微信支付
* @return Response
*/
公共函数wx pay (
{
$input=Request:all (;
$openId=$input['openId'] '? 空值;
//判断金额是否为正整数
$ input [ ' total _ fee ' ]=$ input [ ' total _ fee ' ] * 100;
if (! preg_match ()/^[1-9][0-9]*$/)、$input['total_fee'] ) }{
返回'金额错误';
}
//验证订单
$ order _ id=intval $ input [ ' order _ id ' ];
$order=order:3360where(id )、$order_id )-first );
if (! $订单
返回“订单不存在”
}
$notify_url='回调地址';
$data=[
' out _ trade _ no '=$ order-order _ code,
' total_fee'=$input['total_fee'],
' openid'=$input['openId'],
' body'=$input['body']? 空值,
' created_at'=Carbon:now (),
' updated_at'=Carbon:now (),
];
$ data [ ' notify _ URL ' ]=$ notify _ URL;
//调用微信支付汇总下单
$ result=$ this -统一订单($ data );
//要求失败
if (! $result
//要求失败
}
if ($ result [ ' return _ code ' ]==' fail '|$ result [ ' result _ code ' ]==' fail ' ) ) )。
//调用错误
}
//调用支付数据签名字段
$timeStamp=time (;
$appid=$result['appid'];
$ nonce _ pay=str _ shuffle ($ result [ ' nonce _ str ' ] ); //随机字符串
$package=$result['prepay_id'];
$signType='MD5 ';
$key=Common:KEY;
$ string pay=' appid='.$ appid.' nonce str='.$ nonce _ pay.' package=prepay _ id='.$ package.' sign type
$paysign=strtoupper(MD5 ) $stringpay );
//这些参数必须返回小部件组件并显示支付页面
$pay_data=array (
' nonceStr'=$nonce_pay,
' package'='prepay_id=' . $package,
' timestamp '=(字符串) $timeStamp,
' paySign'=$paySign,
' signType'=$signType
);
返回$ pay _ data;
}
//*
*小程序的批量订购方法
* @param $data
*阵列(
* 'out_trade_no'=商户订单编号、
* 'total_fee'=总额、
* 'openid'=用户id、
* 'body'=商品说明
* )
* @ return bool
*/
publicfunctionunifiedorder (阵列$数据) )。
{
$ common=(新公共);
$ params [ ' appid ' ]=$ common 33603360 shop _ id;
$params['mch_id']=$c
ommon::MCH_ID;$params['nonce_str'] = $common->GenRandomString();//随机字符串
$params['body'] = $data['body'];//商品描述
$params['out_trade_no'] = $data['out_trade_no'];//商户订单号
$params['total_fee'] = $data['total_fee'];//总金额
$params['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];//终端IP
$params['notify_url'] = $data['notify_url'];//通知地址
$params['trade_type'] = 'JSAPI';//交易类型
$params['openid'] = $data['openid'];//用户标识
//$this->params['detail'] = $data['detail'] ?? null;//商品详情
//$this->params['attach'] = $data['attach'] ?? null;//附加数据
ksort($params);
//获取签名数据
$sign = $common->Sign($params);
$params['sign'] = $sign;//签名
$xml = $common->DataToXml($params);
$response = $common->PostXmlCurl($xml, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
if (!$response) {
return false;
}
return $common->XmlToData($response);
}
common.php 文件内容入下:
/**
* 产生一个指定长度的随机字符串,并返回给用户
* @param $len //产生字符串的长度
* @return string 随机字符串
*/
public function GenRandomString($len = 32)
{
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
$charsLen = count($chars) - 1;
// 将数组打乱
shuffle($chars);
$output = "";
for ($i = 0; $i < $len; $i++) {
$output .= $chars[mt_rand(0, $charsLen)];
}
return $output;
}
/**
* 签名 $data要先排好顺序
* @param $data
* @return string
*/
public function Sign($data)
{
ksort($data);
$stringA = '';
foreach ($data as $key => $value) {
if (!$value) continue;
if ($stringA) $stringA .= '&' . $key . "=" . $value;
else $stringA = $key . "=" . $value;
}
$wx_key = $this::KEY;//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
$stringSignTemp = $stringA . '&key=' . $wx_key;
return strtoupper(md5($stringSignTemp));
}
/**
* 将xml转为array
* @param string $xml
* return array
* @return bool|mixed
*/
public function XmlToData($xml)
{
if (!$xml) {
return false;
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
/**
* 输出xml字符
* @param $params //参数名称
* return string 返回组装的xml
*
* @return bool|string
*/
public function DataToXml($params)
{
if (!is_array($params) || count($params) <= 0) {
return false;
}
$xml = "";
foreach ($params as $key => $val) {
if (is_numeric($val)) {
$xml .= "" . $val . "" . $key . ">";
} else {
$xml .= "" . $key . ">";
}
}
$xml .= "";
return $xml;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
* @return bool|string
* @throws
*/
public function PostXmlCurl($xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
//
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $useCert);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $useCert ? 2 : 0);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($useCert == true) {
//TODO 以下两种方式需选择一种
/*------- --第一种方法,cert 与 key 分别属于两个.pem文件--------------------------------*/
//使用证书:cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, '绝对路径');
//默认格式为PEM,可以注释
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, '绝对路径');
/**
* 补充 当找不到ca根证书的时候还需要rootca.pem文件
* TODO 注意,微信给出的压缩包中,有提示信息:
* 由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书,
* 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载
*/
//curl_setopt($ch, CURLOPT_CAINFO,self::APICLIENT_CA);
/*----------第二种方式,两个文件合成一个.pem文件----------------------------------------*/
//curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return false;
}
}