PHP 微信支付 企业支付个人 企业转账个人 企业转零钱

使用条件

  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', '订单号', '金额', '描述');
    }
}

猜你喜欢

转载自blog.csdn.net/sym134/article/details/80693229