PHP微信發(fā)紅包幫助類(lèi)WeChatReder.class

Class态贤,代碼是根據(jù)git一個(gè)代碼修改得

<?php
/**
 * Email:zhaojunlike@gmail.com
 * Date: 2017/2/17
 * Time: 8:54
 */

namespace Common\WxRed;

class WeChatReder
{

    protected $red_packet_url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
    protected $config = [];
    protected $parameters;

    public function __construct($config = [])
    {
        $this->config = array_merge($this->config, $config);
    }

    public function setParameter($k, $v)
    {
        $this->parameters[$k] = $v;
    }

    public function getParameter($k)
    {
        return $this->parameters[$k];
    }

    public function create_noncestr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
            //$str .= $chars[ mt_rand(0, strlen($chars) - 1) ];
        }
        return $str;
    }

    protected final function check_packet()
    {
        if ($this->parameters["nonce_str"] == null ||
            $this->parameters["mch_billno"] == null ||
            $this->parameters["mch_id"] == null ||
            $this->parameters["wxappid"] == null ||
            $this->parameters["nick_name"] == null ||
            $this->parameters["send_name"] == null ||
            $this->parameters["re_openid"] == null ||
            $this->parameters["total_amount"] == null ||
            $this->parameters["max_value"] == null ||
            $this->parameters["total_num"] == null ||
            $this->parameters["wishing"] == null ||
            $this->parameters["client_ip"] == null ||
            $this->parameters["act_name"] == null ||
            $this->parameters["remark"] == null ||
            $this->parameters["min_value"] == null
        ) {
            return false;
        }
        return true;

    }

    /**
     * 例如:
     * appid:    wxd930ea5d5a258f4f
     * mch_id:    10000100
     * device_info:  1000
     * Body:    test
     * nonce_str:  ibuaiVcKdpRxkhJA
     * 第一步:對(duì)參數(shù)按照 key=value 的格式,并按照參數(shù)名 ASCII 字典序排序如下:
     * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_i
     * d=10000100&nonce_str=ibuaiVcKdpRxkhJA";
     * 第二步:拼接支付密鑰:
     * stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d"
     * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A
     * 9CF3B7"
     */
    protected function get_sign()
    {
        if (!isset($this->config['partnerkey']) || $this->check_packet() === false) {
            return false;
        }
        ksort($this->parameters);
        $unSignParaString = $this->formatQueryParaMap($this->parameters, false);
        return $this->sign($unSignParaString, $this->config['partnerkey']);
    }

    private function sign($content, $key)
    {
        $signStr = $content . "&key=" . $key;
        return strtoupper(md5($signStr));
    }

    private function verifySignature($content, $sign, $md5Key)
    {
        $signStr = $content . "&key=" . $md5Key;
        $calculateSign = strtolower(md5($signStr));
        $tenpaySign = strtolower($sign);
        return $calculateSign == $tenpaySign;
    }

    //生成紅包接口XML信息
    /*
    <xml>
        <sign>![CDATA[E1EE61A91C8E90F299DE6AE075D60A2D]]</sign>
        <mch_billno>![CDATA[0010010404201411170000046545]]</mch_billno>
        <mch_id>![CDATA[888]]</mch_id>
        <wxappid>![CDATA[wxcbda96de0b165486]]</wxappid>
        <nick_name>![CDATA[nick_name]]</nick_name>
        <send_name>![CDATA[send_name]]</send_name>
        <re_openid>![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]</re_openid>
        <total_amount>![CDATA[200]]</total_amount>
        <min_value>![CDATA[200]]</min_value>
        <max_value>![CDATA[200]]</max_value>
        <total_num>![CDATA[1]]</total_num>
        <wishing>![CDATA[恭喜發(fā)財(cái)]]</wishing>
        <client_ip>![CDATA[127.0.0.1]]</client_ip>
        <act_name>![CDATA[新年紅包]]</act_name>
        <act_id>![CDATA[act_id]]</act_id>
        <remark>![CDATA[新年紅包]]</remark>
        <logo_imgurl>![CDATA[https://xx/img/wxpaylogo.png]]</logo_imgurl>
        <share_content>![CDATA[share_content]]</share_content>
        <share_url>![CDATA[https://xx/img/wxpaylogo.png]]</share_url>
        <share_imgurl>![CDATA[https:/xx/img/wxpaylogo.png]]</share_imgurl>
        <nonce_str>![CDATA[50780e0cca98c8c8e814883e5caa672e]]</nonce_str>
    </xml>
    */
    public function create_hongbao_xml($retcode = 0, $reterrmsg = "ok")
    {
        //var_dump($this->parameters);
        //生成簽名
        $this->setParameter('sign', $this->get_sign());
        dump($this->parameters);
        return $this->arrayToXml($this->parameters);
    }


    public function sendRedPacket($vars, $ssl = [], $second = 30, $aHeader = [])
    {
        $ch = curl_init();
        //超時(shí)時(shí)間
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //這里設(shè)置代理璧针,如果有的話(huà)
        //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
        //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $this->red_packet_url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //以下兩種方式需選擇一種
        //第一種方法大诸,cert 與 key 分別屬于兩個(gè).pem文件
        if (array_key_exists("cert", $ssl) && array_key_exists('key', $ssl) && array_key_exists('rootca', $ssl)) {
            curl_setopt($ch, CURLOPT_SSLCERT, $ssl['cert']);
            curl_setopt($ch, CURLOPT_SSLKEY, $ssl['key']);
            curl_setopt($ch, CURLOPT_CAINFO, $ssl['rootca']);
        }
        if (count($aHeader) >= 1) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }

        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
        $data = curl_exec($ch);
        if ($data) {
            curl_close($ch);
            $responseObj = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
            return $responseObj;
        } else {
            $error = curl_errno($ch);
            //echo "call faild, errorCode:$error\n";
            curl_close($ch);
            return false;
        }
    }

    private function genAllUrl($toURL, $paras)
    {
        $allUrl = null;
        if (null == $toURL) {
            die("toURL is null");
        }
        if (strripos($toURL, "?") == "") {
            $allUrl = $toURL . "?" . $paras;
        } else {
            $allUrl = $toURL . "&" . $paras;
        }

        return $allUrl;
    }

    private function splitParaStr($src, $token)
    {
        $resMap = array();
        $items = explode($token, $src);
        foreach ($items as $item) {
            $paraAndValue = explode("=", $item);
            if ($paraAndValue != "") {
                $resMap[$paraAndValue[0]] = $parameterValue[1];
            }
        }
        return $resMap;
    }

    private function formatQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v && "sign" != $k) {
                if ($urlencode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

    private function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            //  if (null != $v && "null" != $v && "sign" != $k) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= strtolower($k) . "=" . $v . "&";
            //}
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

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

}

調(diào)用方法 require or load,由于我的是多微信端管理避乏,所以定自行修改匹配代碼


        $MCHID = "";
        $money = 1 * 100;
        $openid = "";

        $config = ['partnerkey' => '', 'appid' => ''];
        $redHelper = new WeChatReder($config);

        $redHelper->setParameter("nonce_str", $redHelper->create_noncestr());//隨機(jī)字符串爷耀,丌長(zhǎng)于 32 位
        $redHelper->setParameter("mch_billno", OrderHelper::createOrderNo());//訂單號(hào)
        $redHelper->setParameter("mch_id", $MCHID);//商戶(hù)號(hào)
        $redHelper->setParameter("wxappid", $config['appid']);

        $redHelper->setParameter("nick_name", '騰訊');//提供方名稱(chēng)
        $redHelper->setParameter("send_name", '騰訊');//紅包發(fā)送者名稱(chēng)
        $redHelper->setParameter("re_openid", $openid);//相對(duì)于醫(yī)脈互通的openid
        $redHelper->setParameter("total_amount", $money);//付款金額,單位分
        $redHelper->setParameter("min_value", $money);//最小紅包金額拍皮,單位分
        $redHelper->setParameter("max_value", $money);//最大紅包金額歹叮,單位分
        $redHelper->setParameter("total_num", 1);//紅包収放總?cè)藬?shù)
        $redHelper->setParameter("wishing", '感謝您參加搶紅包,祝您新年快樂(lè)铆帽!');//紅包祝福詫
        $redHelper->setParameter("client_ip", '127.0.0.1');//調(diào)用接口的機(jī)器 Ip 地址
        $redHelper->setParameter("act_name", "test");//活勱名稱(chēng)
        $redHelper->setParameter("remark", '告訴你的朋友一起來(lái)?yè)尲t包吧');//備注信息
//      $redHelper->setParameter("logo_imgurl", RES_DOMAIN.'assets/images/getheadimg.jpg');//商戶(hù)logo的url
//      $redHelper->setParameter("share_content", '一起來(lái)?yè)孾騰訊]紅包吧');//分享文案
//      $redHelper->setParameter("share_url", RES_DOMAIN);//分享鏈接
//      $redHelper->setParameter("share_imgurl", RES_DOMAIN.'assets/images/getheadimg.jpg');//分享的圖片url


        $postXml = $redHelper->create_hongbao_xml();
        $weid = 1;
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
        $ssl['cert'] = SSL_PATH . "{$weid}/apiclient_cert.pem";
        $ssl['key'] = SSL_PATH . "{$weid}/apiclient_key.pem";
        $ssl['rootca'] = SSL_PATH . "{$weid}/rootca.pem";

        if (!file_exists($ssl['key'])) {
            exit("證書(shū)不存在");
        }
        $rest = $redHelper->sendRedPacket($postXml, $ssl);
        var_dump($rest);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咆耿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爹橱,更是在濱河造成了極大的恐慌萨螺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異慰技,居然都是意外死亡椭盏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)掏颊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人艾帐,你說(shuō)我怎么就攤上這事乌叶。” “怎么了掩蛤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵枉昏,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我揍鸟,道長(zhǎng)兄裂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任阳藻,我火速辦了婚禮晰奖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘腥泥。我一直安慰自己匾南,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布蛔外。 她就那樣靜靜地躺著蛆楞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夹厌。 梳的紋絲不亂的頭發(fā)上豹爹,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音矛纹,去河邊找鬼臂聋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛或南,可吹牛的內(nèi)容都是我干的孩等。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼采够,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肄方!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蹬癌,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扒秸,失蹤者是張志新(化名)和其女友劉穎播演,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伴奥,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡写烤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拾徙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洲炊。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖尼啡,靈堂內(nèi)的尸體忽然破棺而出暂衡,到底是詐尸還是另有隱情,我是刑警寧澤崖瞭,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布狂巢,位于F島的核電站,受9級(jí)特大地震影響书聚,放射性物質(zhì)發(fā)生泄漏唧领。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一雌续、第九天 我趴在偏房一處隱蔽的房頂上張望斩个。 院中可真熱鬧,春花似錦驯杜、人聲如沸受啥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滚局。三九已至,卻和暖如春顽频,著一層夾襖步出監(jiān)牢的瞬間核畴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工冲九, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跟束。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓莺奸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親冀宴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灭贷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容