<?php
/**
* Created by snow.
* IDE: PhpStorm
* Date: 2019/3/29
* Time: 8:33
*/
namespace app\park\controller;
use think\Request;
class NewPay
{
private $APPID = ;//小程序ID
private $WE_CHAT_PAY_KEY = ;//微信支付秘钥
private $MCH_ID = ;//微信支付商户号
public function pay()
{
$request = Request::instance();
//fee: 支付的金额
//openId:从前端传来,
//notify:支付成功回调url,暂时不用
$openid=$request->post('open_id');
$billid=$request->post('bill_id');
$fee=$request->post('fee');
$payResult = $this->make($fee, '第二次付款', $request->ip(), $openid, '回调地址');
if (is_null($payResult)) {
return [
'code' => 300,
'msg' => 'pay error'
];
}
$orderId = $payResult['orderNum'];//随机生成的订单号
$responseData = $payResult['response'];
if (isset($responseData['return_code']) && $responseData['return_code'] == 'SUCCESS') {//下单成功
//构造返回数据
$dataArr = [
'appId' => $this->APPID,
'nonceStr' => $this->getRandChar(30),
'package' => 'prepay_id=' . $responseData['prepay_id'],
'signType' => 'MD5',
'timeStamp' => (string)time()
];
$dataArr['paySign'] = $this->signString($dataArr);
unset($dataArr['appId']);
return [
'code' => 200,
'result' => [
'billId' => $billid,
'payData' => $dataArr
],
];
}
//下单失败返回
return [
'code' => 400,
'msg' => 'make order error'
];
}
public function make($fee, $body, $requestIP, $openId, $notify)
{
$data['appid'] = $this->APPID;//小程序Id
$data['mch_id'] = $this->MCH_ID;//微信商户号
$data['nonce_str'] = $this->getRandChar(30);//30为随机字符
$data['out_trade_no'] = $this->makeOrderId();//商户订单号,10位时间戳+6位随机
$data['body'] = $body;//商品描述
$data['total_fee'] = $fee;//金额
$data['spbill_create_ip'] = $requestIP;//终端ip
$data['notify_url'] = $notify;//通知地址
$data['trade_type'] = 'JSAPI';
$data['openid'] = $openId;
$sign = $this->signString($data);
$data['sign'] = $sign;
$xmlData = $this->arrayToXML($data);
$result = $this->sendData($xmlData, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
if (is_null($result)) {//网络错误
return null;
}
$payResult = $this->xmlToArray($result);
//xml字符串转数组,返回
return [
'orderNum' => $data['out_trade_no'],
'response' => $payResult
];
}
/*
* 发送数据到微信服务器,获取支付信息
*/
private function sendData($data, $url)
{
$ch = curl_init();
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//不校验ssl证书
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
if (curl_errno($ch)) {
return null;
}
curl_close($ch);
return $result;
}
/**
* 生成签名
* @param $dataArr
* @return string
*/
public
function signString($dataArr)
{
ksort($dataArr);//参数必须由abcd排序
$buff = "";
foreach ($dataArr as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
$buff .= '&key=' . $this->WE_CHAT_PAY_KEY;
return md5($buff);
}
/**
* 获取指定长度随机字符串
* @param $length
* @return null|string
*/
public
function getRandChar($length)
{
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol) - 1;
for ($i = 0; $i < $length; $i++) {
$str .= $strPol[rand(0, $max)];
}
return $str;
}
/**
* 生成商户订单号,10位时间戳+6位随机
* @return string
*/
public
function makeOrderId()
{
return time() . mt_rand(100000, 999999);
}
/**
* 数组转xml
* @param $arr
* @return string
*/
public
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;
}
/**
* xml字符串转数组
* @param $xmlStr
* @return array
*/
public function xmlToArray($xmlStr)
{
try {
return (array)simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);
} catch (\Exception $e) {
return null;
}
}
}