<?php
//商户付款 到 个人
class mchPay{protected $key = 'c2a7d6411111111f1662e795'; //商户号API KEYprotected $appId = 'wxbb111111f5e5f04';protected $mchid = '141111582';protected $CertPem = BASE_ROOT_PATH.'/data/cert/apiclient_cert.pem'; //证书的位置 绝对路径protected $KeyPem = BASE_ROOT_PATH.'/data/cert/apiclient_key.pem'; //证书的位置 绝对路径/* 商户付款到 用户零钱 out_trade_no 外单订单号 openid 用户openid total_fee 操作的金额*/public function payToChange($data){ $params = array(); $params['mch_appid'] = $this->appId; $params['mchid'] = $this->mchid; $params['nonce_str'] = $this->createNoncestr(); $params['partner_trade_no'] = $data['out_trade_no']; $params['openid'] = $data['openid']; $params['check_name'] = 'NO_CHECK'; $params['amount'] = $data['total_fee']; $params['desc'] = '提现'; $params['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; $params['sign'] = $this->getSign($params); $postXml = $this->arrayToXml($params); $resXml = $this->postXmlCurl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers',$postXml,30,true); $resData = $this->xmlToArray($resXml); if(!$resData || $resData['return_code']!='SUCCESS' || $resData['result_code']!='SUCCESS') return false; // var_dump($resData); return $resData;}/* 商户付款到 用户银行卡 out_trade_no 外单订单号 total_fee 操作的金额 enc_bank_no 收款用户的银行卡号 enc_true_name 收款用户的姓名 bank_code 收款银行对应的编号 微信文档获取*/public function payToBank($data){ $params = array(); $params['mch_id'] = $this->mchid; $params['nonce_str'] = $this->createNoncestr(); $params['partner_trade_no'] = $data['out_trade_no']; $params['enc_bank_no'] = $data['enc_bank_no']; $params['enc_true_name'] = $data['enc_true_name']; $params['amount'] = $data['total_fee']; $params['bank_code'] = $data['bank_code']; $params['sign'] = $this->getSign($params); $postXml = $this->arrayToXml($params); $resXml = $this->postXmlCurl('https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank',$postXml,30); $resData = $this->xmlToArray($resXml); if(!$resData || $resData['return_code']!='SUCCESS' || $resData['result_code']!='SUCCESS') return false; return $resData; }//作用:生成签名private function getSign($Obj) { $Parameters = array(); 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_;}///作用:格式化参数,签名过程需要使用private 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;} //将数组转换为xml格式 private 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转换成数组private function xmlToArray($xml) { //禁止引用外部xml实体 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring), true); return $val;} //作用:产生随机字符串,不长于32位private 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;}//发送请求private function postXmlCurl($url,$xml, $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); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, $this->CertPem); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, $this->KeyPem); //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); set_time_limit(0); //运行curl $data = curl_exec($ch); //返回结果 if ($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); var_dump($error); curl_close($ch); return false; }}}//支付到用户零钱$obj = new mchPay();$params = array( 'out_trade_no' => date('YmdHis'), 'openid' => 'ouD2222222228', 'total_fee' => 100, );$res = $obj->payToChange($params); ?>商户付款给用户是需要用到证书的,证书的申请在商户后台。一步步申请即可。还有就是如果一直报签名错误, 可以先到签名工具里对签名进行验证。 如果在签名工具里校验签名是正确的,那很有可能是api key的问题,重新在商户后台 ,设置一下api key,一般就可以正常了
...