使用条件
1、商户号(或同主体其他非服务商商户号)已入驻90日
2、商户号(或同主体其他非服务商商户号)有30天连续正常交易
3、 登录微信支付商户平台-产品中心,开通企业付款。
官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
注释的应该非常清楚了,就不多解释了,因为公司没权限最后没能完全验证,只能验证到没权限,应该没有问题了,欢迎交流
<?php /** * 企业支付个人 * Created by PhpStorm. * User: heimiao * Date: 2018/6/13 * Time: 17:45 */ class paypre { private $APPID; private $MCHID; private $getip; private $key; private $sslcert_path; private $sslkey_path; public function __construct() { $this->APPID = 'appid'; $this->MCHID = 'mchid'; //商户号 $this->getip = 'ip'; //IP 可以是服务器IP 也可以是客户端 $this->key = 'keykeykeykey'; //商户密钥 $this->sslcert_path = '/apiclient_cert.pem'; //pem文件路径 $this->sslkey_path = '/apiclient_key.pem'; } /** * 企业支付 * @param string $openid 用户openID * @param string $trade_no 单号 * @param string $money 金额 * @param string $desc 描述 * @return string XML 结构的字符串 */ public function pay($openid, $trade_no, $money, $desc) { $data = array( 'mch_appid' => $this->APPID, 'mchid' => $this->MCHID, 'nonce_str' => self::getNonceStr(), //随机字符串 'partner_trade_no' => $trade_no, //商户订单号,需要唯一 'openid' => $openid, 'check_name' => 'NO_CHECK', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK: 'amount' => $money * 100, //付款金额单位为分 'desc' => $desc, 'spbill_create_ip' => $this->getip, //'re_user_name' => 'jorsh', //收款人用户姓名 *选填 //'device_info' => '1000', //设备号 *选填 ); //生成签名 $data['sign'] = self::makeSign($data); //构造XML数据 $xmldata = self::arrToXml($data); // 请求URL $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //发送post请求 $res = self::curl_post_ssl($url, $xmldata); var_dump($res); } /** * 随机字符串 * @param int $length * @return string */ private static function getNonceStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 签名 * @param $data * @return string */ private function makeSign($data) { // 关联排序 ksort($data); // 字典排序 $str = http_build_query($data); // 添加商户密钥 $str .= '&key=' . $this->key; // 清理空格 非常恶心调了半天 $str = urldecode($str); $str = md5($str); // 转换大写 $result = strtoupper($str); return $result; } /** * 数组转XML * @param $data * @return string */ private static function arrToXml($data) { $xml = "<xml>"; // 遍历组合 foreach ($data as $k=>$v){ $xml.='<'.$k.'>'.$v.'</'.$k.'>'; } $xml .= '</xml>'; return $xml; } /** * 企业付款发起请求 * 此函数来自:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip */ public function curl_post_ssl($url, $xmldata, $second=30,$aHeader=array()){ $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //以下两种方式需选择一种 //第一种方法,cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT,$this->sslcert_path); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,$this->sslkey_path); //第二种方式,两个文件合成一个.pem文件 //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem'); if( count($aHeader) >= 1 ){ curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); } curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata); $data = curl_exec($ch); if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "call faild, errorCode:$error\n"; curl_close($ch); return false; } } /** * 测试使用 */ public function ceshi() { $this->pay('这里是openid', '订单号', '金额', '描述'); } }