分享封装的一个PHP微信支付的类库(扫码、H5、小程序)

分享封装的一个PHP微信支付的类库(扫码、H5、小程序),第1张

概述分享封装的一个PHP微信支付的类库(扫码、H5、小程序) PHP微信支付类传参直接使用(扫码、H5、小程序)

在我们编写相关支付的时候,经常会使用微信支付,

在PHP中使用微信支付还是比较简单的,

微信支付文档:https://pay.weixin.qq.com/wiki/doc/API/index.HTML

这里简单介绍微信支付的几种使用,

这里微信支付我封装了一个微信支付的类库,

直接传递参数就可使用:

首先把配置文件填写完整(细心不要填错,否则会导致签名错误):

$config = array(    'appID'         => '', // 微信支付appID    'xcxappID'      => '', // 微信小程序appID    'mch_ID'        => '', // 微信支付 mch_ID 商户收款账号    'key'           => '', // 微信支付key    'appsecret'     => '', // 公众帐号secert(公众号支付专用)    'notify_url'    => '', // 接收支付状态的连接  改成自己的回调地址    'redirect_uri'  => '', // 公众号支付时,没有code,获取openID使用);

对于相关支付我也也成了函数便于使用,

微信扫码支付:

/** * [qrcodePay 微信扫码支付] * @param  [type] $order [订单信息数组] * @return [type]        [description] * $order = array( *      'body'          => '', // 产品描述 *      'total_fee'     => '', // 订单金额(分) *      'out_Trade_no'  => '', // 订单编号 *      'product_ID'    => '', // 产品ID(可用订单编号) * ); */public static function qrcodePay($order=NulL){    if(!is_array($order) || count($order) < 4){        dIE("数组数据信息缺失!");    }    $order['Trade_type'] = 'NATIVE'; // Native支付    $result = self::unifIEdOrder($order);    $decodeurl = urldecode($result['code_url']);    return $decodeurl; // 使用返回链接直接生成二维码}

微信H5支付:

/** * [weixinH5 微信H5支付] * @param  [type] $order [订单信息数组] * @return [type]        [description] * $order = array( *      'body'          => '', // 产品描述 *      'total_fee'     => '', // 订单金额(分) *      'out_Trade_no'  => '', // 订单编号 *      'product_ID'    => '', // 产品ID(可用订单编号) * ); */public static function h5Pay($order=NulL){    if(!is_array($order) || count($order) < 4){        dIE("数组数据信息缺失!");    }    $order['Trade_type'] = 'MWEB'; // H5支付    $result = self::unifIEdOrder($order);    if ($result['return_code']=='SUCCESS' && $result['result_code']=='SUCCESS')        return $result['mweb_url']; // 返回链接让用户点击跳转    if ($result['err_code_des'])        dIE($result['err_code_des']);    return false;}

微信小程序支付:

/** * [xcxPay 获取Jssdk需要用到的数据] * @param  [type]  $order [订单信息数组] * @param  boolean $type  [区分是否是小程序,默认 true] * @return [type]         [description] * $order = array( *      'body'          => '', // 产品描述 *      'total_fee'     => '', // 订单金额(分) *      'out_Trade_no'  => '', // 订单编号 *      'product_ID'    => '', // 产品ID(可用订单编号) *      'openID'        => '', // 用户openID * ); */public static function xcxPay($order=NulL,$type=true){    if(!is_array($order) || count($order) < 5){        dIE("数组数据信息缺失!");    }    $order['Trade_type'] = 'JsAPI'; // 小程序支付    $result = self::unifIEdOrder($order,$type);    if ($result['return_code']=='SUCCESS' && $result['result_code']=='SUCCESS') {        $data = array (            'appID'     => $type ? $this->config['xcxappID'] : $this->config['appID'],            'timeStamp' => time(),            'nonceStr'  => self::get_rand_str(32, 0, 1), // 随机32位字符串            'package'   => 'prepay_ID='.$result['prepay_ID'],            'signType'  => 'MD5', // 加密方式        );        $data['paySign'] = self::makeSign($data);        return $data; // 数据小程序客户端    } else {        if ($result['err_code_des'])            dIE($result['err_code_des']);        return false;    }}

使用方法(这里已小程序支付为示例):

<?PHPinclude './WeixinPay.PHP';$get = $_GET;$weixinpay = new \feng\WeixinPay($config);$order_sn = time().rand(1000,9999);$order = array(    'body'          => '测试商品', // 产品描述    'total_fee'     => '1', // 订单金额(分)    'out_Trade_no'  => $order_sn, // 订单编号    'product_ID'    => $order_sn, // 产品ID(可用订单编号)    'openID'        => $get['openID'], // 用户openID);$re = $weixinpay->xcxPay($order);dIE(Json_encode($re)); // JsON化直接返回小程序客户端

如下代码是封装好的完整支付类文件(WeixinPay.PHP),

可以根据自己需求随意修改(不定期修改完善 Gitee 与 GitHub):

<?PHP/** * @Author: [FENG] <[email protected]> * @Date:   2019-09-06 09:50:30 * @Last ModifIEd by:   [FENG] <[email protected]> * @Last ModifIEd time: 2020-10-08T17:33:39+08:00 */namespace feng;error_reporting(E_ALL);ini_set('display_errors', '1');// 定义时区ini_set('date.timezone','Asia/Shanghai');class WeixinPay{    // 定义相关配置项    private static $sslcert_path = './cert/apiclient_cert.pem'; // 证书(退款时使用)    private static $sslkey_path = './cert/apiclient_key.pem'; // 证书(退款时使用)    private static $referer = '';    private static $config = array(        'appID'         => '', // 微信支付appID        'xcxappID'      => '', // 微信小程序appID        'mch_ID'        => '', // 微信支付 mch_ID 商户收款账号        'key'           => '', // 微信支付key        'appsecret'     => '', // 公众帐号secert(公众号支付专用)        'notify_url'    => '', // 接收支付状态的连接  改成自己的回调地址        'redirect_uri'  => '', // 公众号支付时,没有code,获取openID使用    );    /**     * [__construct 构造函数]     * @param [type] $config [传递微信支付相关配置]     */    public function __construct($config=NulL, $referer=NulL){        $config && self::$config = $config;        self::$referer = $referer ? $referer : $_SERVER['http_HOST'];    }    /**     * [unifIEdOrder 统一下单]     * @param  [type]  $order [订单信息(必须包含支付所需要的参数)]     * @param  boolean $type  [区分是否是小程序,是则传 true]     * @return [type]         [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_fee'     => '', // 订单金额(分)     *      'out_Trade_no'  => '', // 订单编号     *      'product_ID'    => '', // 产品ID     *      'Trade_type'    => '', // 类型:JsAPI--JsAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付     * );     */    public static function unifIEdOrder($order, $type=NulL)    {        $weixinpay_config = array_filter(self::$config);        // 获取配置项        $config = array(            'appID'             => empty($type) ? $weixinpay_config['appID'] : $weixinpay_config['xcxappID'],            'mch_ID'            => $weixinpay_config['mch_ID'],            'nonce_str'         => 'test',            'spbill_create_ip'  => self::get_iP(),            'notify_url'        => $weixinpay_config['notify_url']        );        $data = array_merge($order, $config); // 合并配置数据和订单数据        $sign = self::makeSign($data); // 生成签名        $data['sign'] = $sign;        $xml = self::array_to_xml($data);        $url = 'https://API.mch.weixin.qq.com/pay/unifIEdorder';//接收xml数据的文件        $header[] = "Content-type: text/xml";//定义content-type为xml,注意是数组        $ch = curl_init ($url);        curl_setopt($ch, CURLOPT_URL, $url);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 兼容本地没有指定curl.cainfo路径的错误        curl_setopt($ch, CURLOPT_REFERER, self::$referer);        //设置 referer        curl_setopt($ch, CURLOPT_httpheader, $header);        curl_setopt($ch, CURLOPT_POST, 1);        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);        $response = curl_exec($ch);        if(curl_errno($ch)){            dIE(curl_error($ch)); // 显示报错信息;终止继续执行        }        curl_close($ch);        $result = self::xml_to_array($response);        if ($result['return_code']=='FAIL')            dIE($result['return_msg']); // 显示错误信息        if ($result['result_code']=='FAIL')            dIE($result['err_code_des']); // 显示错误信息        $result['sign'] = $sign;        $result['nonce_str'] = 'test';        return $result;    }    /**     * [qrcodePay 微信扫码支付]     * @param  [type] $order [订单信息数组]     * @return [type]        [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_fee'     => '', // 订单金额(分)     *      'out_Trade_no'  => '', // 订单编号     *      'product_ID'    => '', // 产品ID(可用订单编号)     * );     */    public static function qrcodePay($order=NulL)    {        if(!is_array($order) || count($order) < 4){            dIE("数组数据信息缺失!");        }        $order['Trade_type'] = 'NATIVE'; // Native支付        $result = self::unifIEdOrder($order);        $decodeurl = urldecode($result['code_url']);        return $decodeurl;        // qrcode($decodeurl);        // qrcodeWithPicture($decodeurl);    }    /**     * [JsPay 获取Jssdk需要用到的数据]     * @param  [type] $order [订单信息数组]     * @return [type]        [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_fee'     => '', // 订单金额(分)     *      'out_Trade_no'  => '', // 订单编号     *      'product_ID'    => '', // 产品ID(可用订单编号)     * );     */    public static function JsPay($order=NulL,$code=NulL){        $config=self::$config;        if (!is_array($order) || count($order) < 4)            dIE("数组数据信息缺失!");        if (count($order) == 5) {            $data = self::xcxPay($order, false); // 获取支付相关信息(获取非小程序信息)            return $data;        }        empty($code) && $code = $_GET['code'];        // 如果没有get参数没有code;则重定向去获取openID;        if (empty($code)) {            $out_Trade_no = $order['out_Trade_no']; // 获取订单号            $redirect_uri = $config['redirect_uri']; // 返回的url            $redirect_uri = urlencode($redirect_uri);            $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appID='.$config['appID'].'&redirect_uri='.$redirect_uri.'&response_type=code&scope=snsAPI_base&state='.$out_Trade_no.'#wechat_redirect';            header('Location: '.$url);        } else {            // 组合获取prepay_ID的url            $url = 'https://API.weixin.qq.com/sns/oauth2/access_token?appID='.$config['appID'].'&secret='.$config['appsecret'].'&code='.$code.'&grant_type=authorization_code';            $result = self::curl_get_contents($url); // curl获取prepay_ID            $result = Json_decode($result,true);            $order['openID'] = $result['openID']; // 获取到的openID            $data = self::xcxPay($order, false); // 获取支付相关信息(获取非小程序信息)            return $data;        }    }    /**     * [xcxPay 获取Jssdk需要用到的数据]     * @param  [type]  $order [订单信息数组]     * @param  boolean $type  [区分是否是小程序,默认 true]     * @return [type]         [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_fee'     => '', // 订单金额(分)     *      'out_Trade_no'  => '', // 订单编号     *      'product_ID'    => '', // 产品ID(可用订单编号)     *      'openID'        => '', // 用户openID     * );     */    public static function xcxPay($order=NulL,$type=true)    {        if(!is_array($order) || count($order) < 5){            dIE("数组数据信息缺失!");        }        $order['Trade_type'] = 'JsAPI'; // 小程序支付        $result = self::unifIEdOrder($order,$type);        if ($result['return_code']=='SUCCESS' && $result['result_code']=='SUCCESS') {            $data = array (                'appID'     => $type ? self::$config['xcxappID'] : self::$config['appID'],                'timeStamp' => (string)time(),                'nonceStr'  => self::get_rand_str(32, 0, 1), // 随机32位字符串                'package'   => 'prepay_ID='.$result['prepay_ID'],                'signType'  => 'MD5', // 加密方式            );            $data['paySign'] = self::makeSign($data);            return $data; // 数据小程序客户端        } else {            if ($result['err_code_des'])                dIE($result['err_code_des']);            return false;        }    }    /**     * [weixinH5 微信H5支付]     * @param  [type] $order [订单信息数组]     * @return [type]        [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_fee'     => '', // 订单金额(分)     *      'out_Trade_no'  => '', // 订单编号     *      'product_ID'    => '', // 产品ID(可用订单编号)     * );     */    public static function h5Pay($order=NulL)    {        if(!is_array($order) || count($order) < 4){            dIE("数组数据信息缺失!");        }        $order['Trade_type'] = 'MWEB'; // H5支付        $result = self::unifIEdOrder($order);        if ($result['return_code']=='SUCCESS' && $result['result_code']=='SUCCESS')            return $result['mweb_url']; // 返回链接让用户点击跳转        if ($result['err_code_des'])            dIE($result['err_code_des']);        return false;    }    /**     * [refund 微信支付退款]     * @param  [type] $order [订单信息]     * @param  [type] $type  [是否是小程序]     * $order = array(     *      'body'          => '', // 退款原因     *      'total_fee'     => '', // 商品价格(分)     *      'out_Trade_no'  => '', // 订单编号     *      'transaction_ID'=> '', // 微信订单号     * );     */    public static function refund($order, $type=NulL)    {        $config = self::$config;        $data = array(            'appID'         => empty($type) ? $config['appID'] : $config['xcxappID'] ,            'mch_ID'        => $config['mch_ID'],            'nonce_str'     => 'test',            'total_fee'     => $order['total_fee'],         //订单金额     单位 转为分            'refund_fee'    => $order['total_fee'],         //退款金额 单位 转为分            'sign_type'     => 'MD5',                       //签名类型 支持HMAC-SHA256和MD5,默认为MD5            'transaction_ID'=> $order['transaction_ID'],    //微信订单号            'out_Trade_no'  => $order['out_Trade_no'],      //商户订单号            'out_refund_no' => $order['out_Trade_no'],      //商户退款单号            'refund_desc'   => $order['body'],              //退款原因(选填)        );        // $unifIEd['sign'] = self::makeSign($unifIEd, $config['KEY']);        $sign = self::makeSign($data);        $data['sign'] = $sign;        $xml = self::array_to_xml($data);        $url = 'https://API.mch.weixin.qq.com/secAPI/pay/refund';//接收xml数据的文件        $response = self::postXmlSSLCurl($xml,$url);        $result = self::xml_to_array($response);        // 显示错误信息        if ($result['return_code']=='FAIL') {            dIE($result['return_msg']);        }        $result['sign'] = $sign;        $result['nonce_str'] = 'test';        return $result;    }    /**     * [notify 回调验证]     * @return [array] [返回数组格式的notify数据]     */    public static function notify()    {        $xml = file_get_contents('PHP://input', 'r'); // 获取xml        if (!$xml)            dIE('暂无回调信息');        $data = self::xml_to_array($xml); // 转成PHP数组        $data_sign = $data['sign']; // 保存原sign        unset($data['sign']); // sign不参与签名        $sign = self::makeSign($data);        // 判断签名是否正确  判断支付状态        if ($sign===$data_sign && $data['return_code']=='SUCCESS' && $data['result_code']=='SUCCESS') {            $result=$data;        }else{            $result=false;        }        // 返回状态给微信服务器        if ($result) {            $str='<xml><return_code><![cdaTA[SUCCESS]]></return_code><return_msg><![cdaTA[OK]]></return_msg></xml>';        }else{            $str='<xml><return_code><![cdaTA[FAIL]]></return_code><return_msg><![cdaTA[签名失败]]></return_msg></xml>';        }        echo $str;        return $result;    }    /**     * [makeSign 生成签名]     * 本方法不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值     * @param  [type] $data [description]     * @return [type]       [description]     */    public static function makeSign($data)    {        // 去空        $data = array_filter($data);        //签名步骤一:按字典序排序参数        ksort($data);        $string_a = http_build_query($data);        $string_a = urldecode($string_a);        //签名步骤二:在string后加入key        $config = self::$config;        $string_sign_temp = $string_a."&key=".$config['key'];        //签名步骤三:MD5加密        $sign = md5($string_sign_temp);        // 签名步骤四:所有字符转为大写        $result = strtoupper($sign);        return $result;    }    /**     * [xml_to_array 将xml转为array]     * @param  [type] $xml [xml字符串]     * @return [type]      [转换得到的数组]     */    public static function xml_to_array($xml)    {        //禁止引用外部xml实体        libxml_disable_entity_loader(true);        $result = Json_decode(Json_encode(simplexml_load_string($xml, 'SimpleXMLElement', liBXML_NOcdaTA)), true);        return $result;    }    /**     * [array_to_xml 输出xml字符]     * @param  [type] $data [description]     * @return [type]       [description]     */    public static function array_to_xml($data)    {        if(!is_array($data) || count($data) <= 0){            dIE("数组数据异常!");        }        $xml = "<xml>";        foreach ($data as $key=>$val){            if (is_numeric($val)){                $xml .= "<".$key.">".$val."</".$key.">";            }else{                $xml .= "<".$key."><![cdaTA[".$val."]]></".$key.">";            }        }        $xml .= "</xml>";        return $xml;    }    /**     * [curl_get_contents get请求]     * @param  [type] $url [请求地址]     * @return [type]      [description]     */    public static function curl_get_contents($url)    {        $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, $url);                //设置访问的URL地址        // curl_setopt($ch,CURLOPT_header,1);               //是否显示头部信息        curl_setopt($ch, CURLOPT_TIMEOUT, 5);               //设置超时        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['http_USER_AGENT']);   //用户访问代理 User-Agent        curl_setopt($ch, CURLOPT_REFERER, self::$referer);        //设置 referer        curl_setopt($ch, CURLOPT_FolLOWLOCATION, 1);        //跟踪301        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        //返回结果        $r=curl_exec($ch);        curl_close($ch);        return $r;    }    /**     * [postXmlSSLCurl 需要使用证书的请求]     * @param  [type]  $xml    [xml数据]     * @param  [type]  $url    [post请求地址]     * @param  integer $second [description]     * @return [type]          [description]     */    public static function postXmlSSLCurl($xml,$url,$second=30)    {        $ch = curl_init();        //超时时间        curl_setopt($ch,CURLOPT_TIMEOUT,$second);        //这里设置代理,如果有的话        //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');        //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);        //设置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, self::$sslcert_path);        //默认格式为PEM,可以注释        curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');        curl_setopt($ch,CURLOPT_SSLKEY, self::$sslkey_path);        //post提交方式        curl_setopt($ch,CURLOPT_POST, true);        curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);        $data = curl_exec($ch);        //返回结果        if($data){            curl_close($ch);            return $data;        } else {            $error = curl_errno($ch);            echo "curl出错,错误码:$error"."<br>";            curl_close($ch);            return false;        }    }    /** fengkui.net     * [get_rand_str 获取随机字符串]     * @param  integer $randLength    [长度]     * @param  integer $addtime       [是否加入当前时间戳]     * @param  integer $includenumber [是否包含数字]     * @return [type]                 [description]     */    public static function get_rand_str($randLength=6,$addtime=1,$includenumber=0)    {        if ($includenumber)            $chars='abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789';        $chars='abcdefghijklmnopqrstuvwxyz';        $len=strlen($chars);        $randStr='';        for ($i=0;$i<$randLength;$i++){            $randStr .= $chars[rand(0,$len-1)];        }        $tokenvalue = $randStr;        $addtime && $tokenvalue=$randStr.time();        return $tokenvalue;    }    /** fengkui.net     * [get_iP 定义一个函数get_iP() 客户端IP]     * @return [type] [description]     */    public static function get_iP()    {        if (getenv("http_CLIENT_IP"))            $ip = getenv("http_CLIENT_IP");        else if(getenv("http_X_FORWARDED_FOR"))            $ip = getenv("http_X_FORWARDED_FOR");        else if(getenv("REMOTE_ADDR"))            $ip = getenv("REMOTE_ADDR");        else $ip = "UnkNow";        if(preg_match('/^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1 -9]?\d))))$/', $ip))            return $ip;        else            return '';    }}
总结

以上是编程之家为你收集整理的分享封装的一个PHP微信支付的类库(扫码、H5、小程序)全部内容,希望文章能够帮你解决分享封装的一个PHP微信支付的类库(扫码、H5、小程序)所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/997394.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存