1.配置
//微信支付配置"wx_pay_config" => [ 'appId' => '********', 'mchId' => '**********', 'key' => '**********', 'notify_url' => config('app.notify_url').'wxCallback',],
2.下单
扫码支付
$config = config('dailian.wx_pay_config');
$wPay = new \WxControl($config);
$pay_arr = $wPay->unifiedorder('云顶之弈代练', $order['order_num'], 1??$order['price'], 'NATIVE');
if (isset($pay_arr['err_code']) ||$pay_arr['return_code'] != 'SUCCESS' || $pay_arr['result_code'] != 'SUCCESS')
return wx_errorReturn(null, -1201, $pay_arr['err_code_des']);
$pay_str = $pay_arr['code_url'];
APP支付
$config = config('dailian.wx_pay_config');
$wPay = new \WxControl($config);
$pay_arr = $wPay->unifiedorder('云顶之弈代练', $order['order_num'], 1??$order['price'], 'APP');
if (isset($pay_arr['err_code']) ||$pay_arr['return_code'] != 'SUCCESS' || $pay_arr['result_code'] != 'SUCCESS')
return wx_errorReturn(null, -1201, $pay_arr['err_code_des']);
$pay_str = $wPay->returnWxPayParams($pay_arr);
工具类
class WxControl
{
public $appId;
public $mchId;
public $notify_url;
public $secret;
public function __construct($config = []){
$config || $config = config('const.wx_pay_config');
$this->appId = $config['appId'];
$this->mchId = $config['mchId'];
$this->key = $config['key'];
$this->notify_url = $config['notify_url'];
$this->secret = config('const.wx_app_config')['secret'];
}
/**
* 微信统一下单
*/
public function unifiedorder($body, $out_trade_no, $total_price, $trade_type = "JSAPI")
{
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$qdata = [
'appid' => $this->appId,
'mch_id' => $this->mchId,
'nonce_str' => getNonceStr(),
'body' => $body,
'out_trade_no' => $out_trade_no,
'total_fee' => $total_price,
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'notify_url' => $this->notify_url,
'trade_type' => $trade_type,
// 'openid' => $openid,
];
//签名步骤一:去除空字符
$signData = array_filter($qdata);
//签名步骤二:按字典序排序参数
ksort($signData);
$string = toUrlParams($signData);
//签名步骤二:在string后加入KEY
$string = $string . "&key=" . $this->key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$sign = strtoupper($string);
//添加签名
$qdata['sign'] = $sign;
$xml = toXml($qdata);
//发送请求
$http = new \HttpClient();
$result = $http->postXmlCurl($xml, $url);
return $resultArr = xmlToArray($result);
}
//检查回调参数验证签名
public function checkSign($data){
$sign = $data['sign'];
$data['sign']="";
// $data['sign']="";
//签名步骤一:去除空字符
$signData = array_filter($data);
//签名步骤二:按字典序排序参数
ksort($signData);
$string = toUrlParams($signData);
//签名步骤二:在string后加入KEY
$string = $string . "&key=" . $this->key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$signA = strtoupper($string);
//添加签名
if($sign == $signA) return true;
return false;
}
/**
* 返回微信支付的参数
*/
public function returnWxPayParams($param)
{
//根据返回的字段再进行一次签名
$arr = [
'appid' => $param['appid'],
'partnerid' => $param['mch_id'],
'prepayid' => $param['prepay_id'],
'package' => 'Sign=WXPay',
'noncestr' => $param['nonce_str'],
'timestamp' => time(),
];
ksort($arr);
$arr = array_filter($arr);
$str = "";
foreach ($arr as $k=>$v){
if($str) $str .= "&";
$str.="{$k}={$v}";
}
$str.="&key=".$this->key;
$sign = strtoupper(md5($str));
$arr['sign'] = $sign;
return $arr;
}
3.前端调起支付
4.回调
回调里面要验证签名参数和金额是否与商户所保存的金额数据相等
$str = file_get_contents('php://input');
$data = simplexml_load_string($str, 'SimpleXMLElement', LIBXML_NOCDATA);
$data = json_decode(json_encode($data), true);
$config = config('const.wx_pay_config');
//验证商户号
if($config['mchId']!=$data['mch_id']) {
Log::error('商户号不对');exit;
}
//验签
$wx = new \WxControl($config);
$flage = $wx->checkSign($data);
if($flage) { $status = $data['return_code'] == 'SUCCESS' || $data['code'] = 10000; if($status){
$order = Db::name('order')->where('order_num', $order_num)->where('status',0)->find();
if($order['price']*100 != $money){
Log::error('金额不对');//exit;
} }
}