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; }
} }