微信支付
2020-04-26 本文已影响0人
响呼雷
<?php
namespace wechatpay;
use think\Exception;
class WechatPay
{
//=======【基本信息设置】=====================================
//微信公众号身份的唯一标识
protected $APPID = "";//填写您的appid。微信公众平台里的
protected $APPSECRET = "";
//受理商ID,身份标识
protected $MCHID = '';//商户id
//商户支付密钥Key
protected $KEY = '';
//回调通知接口
protected $APPURL = 'https://******/user/Allot/wechatCallback';
//交易类型
protected $TRADETYPE = 'JSAPI';
//商品类型信息
protected $BODY = '';
//终端ip
protected $IP = '';
protected $SSLCERT_PATH = '';//证书路径
protected $SSLKEY_PATH = '';//证书路径
protected $openid;
protected $totalFee;
protected $out_trade_no;
//微信支付类的构造函数
public function __construct($openid, $totalFee, $out_trade_no)
{
$this->openid = $openid; //用户唯一标识
$this->totalFee = $totalFee * 100; //总价
$this->out_trade_no = $out_trade_no;//订单编号
}
//微信支付
public function pay()
{
$result = $this->weixinapp();
return $result;
}
//对微信统一下单接口返回的支付相关数据进行处理
private function weixinapp()
{
$unifiedorder = $this->unifiedorder();
$parameter = array(
'appId' => $this->APPID,//小程序ID
'timeStamp' => '' . time() . '',//时间戳
'nonceStr' => $this->createNoncestr(),//随机串
'package' => 'prepay_id=' . $unifiedorder['prepay_id'],//数据包
'signType' => 'MD5'//签名方式
);
$parameter['paySign'] = $this->getSign($parameter);
$parameter['out_trade_no'] = $unifiedorder['out_trade_no'];
return $parameter;
}
/*
*请求微信统一下单接口
*/
private function unifiedorder()
{
$parameters = array(
'appid' => $this->APPID,//小程序id
'mch_id' => $this->MCHID,//商户id
'spbill_create_ip' => $this->IP,//终端ip
'notify_url' => $this->APPURL, //通知地址
'nonce_str' => $this->createNoncestr(),//随机字符串
'out_trade_no' => $this->out_trade_no,//商户订单编号
'total_fee' => floatval($this->totalFee), //总金额
'openid' => $this->openid,//用户openid
'trade_type' => $this->TRADETYPE,//交易类型
'body' => $this->BODY, //商品信息
);
$parameters['sign'] = $this->getSign($parameters);
$xmlData = $this->arrayToXml($parameters);
$xml_result = $this->postXmlCurl($xmlData,'https://api.mch.weixin.qq.com/pay/unifiedorder',60);
$result = $this->xmlToArray($xml_result);
$result['out_trade_no'] = $parameters['out_trade_no'];
return $result;
}
public function order_number($openid)
{
return md5($openid . time() . rand(10, 99));//32位
}
//数组转字符串方法
protected function arrayToXml($arr)
{
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
protected function xmlToArray($xml)
{
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
//发送xml请求方法
protected function postXmlCurl($xml, $url, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new Exception("curl出错,错误码:$error");
}
}
/*
* 对要发送到微信统一下单接口的数据进行签名
*/
protected function getSign($Obj)
{
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . $this->KEY;
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
/*
*排序并格式化参数方法,签名时需要使用
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
/*
* 生成随机字符串方法
*/
protected function createNoncestr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
}