您的位置:首页 > 移动开发 > 微信开发

php 微信红包 发送方法【干货】

2017-05-20 14:38 204 查看
最新开发微信第三方平台小应用需要用到微信红包功能,下面共享下我的做法。

首先获取后台的配置信息

        $settings = $module['config'];   

定义常量

        define('ROOT_PATH', dirname(__FILE__));

        define('DS', DIRECTORY_SEPARATOR);

        define('SIGNTYPE', "sha1");

        define('PARTNERKEY',$settings['password']);

        define('APPID',$settings['appid']);

        define('ADDONS_ROOT', IA_ROOT .'/addons/'.$name);

        define('CERT_ROOT', ATTACHMENT_ROOT .'/'.$name.'/cert/'); // 证书的路径

生成订单号

        $mch_billno = $settings['mchid'].date('YmdHis').rand(1000, 9999);//订单号

导入并调用红包类

        include_once(IA_ROOT.'/addons/'.$name.'/pay/WxHongBaoHelper.php');

        $commonUtil = new CommonUtil();

        $wxHongBaoHelper = new WxHongBaoHelper();

        $wxHongBaoHelper->setParameter("nonce_str", $commonUtil->create_noncestr());//随机字符串,不长于32位

        $wxHongBaoHelper->setParameter("mch_billno", $mch_billno);//订单号

        $wxHongBaoHelper->setParameter("mch_id", $settings['mchid']);//商户号

        $wxHongBaoHelper->setParameter("wxappid", $settings['appid']);

        //$wxHongBaoHelper->setParameter("nick_name", $settings['nick_name']);//提供方名称

        //$wxHongBaoHelper->setParameter("send_name", $settings['send_name']);//红包发送者名称

        $wxHongBaoHelper->setParameter("nick_name", $_W['account']['name']);//提供方名称

        $wxHongBaoHelper->setParameter("send_name", $_W['account']['name']);//红包发送者名称

        $wxHongBaoHelper->setParameter("re_openid", $openid);//相对于医脉互通的openid

        $wxHongBaoHelper->setParameter("total_amount", $price * 100);//付款金额,单位分

        $wxHongBaoHelper->setParameter("min_value", 1);//最小红包金额,单位分

        $wxHongBaoHelper->setParameter("max_value", 200);//最大红包金额,单位分

        $wxHongBaoHelper->setParameter("total_num", 1);//红包发放总人数

        //$wxHongBaoHelper->setParameter("wishing", $settings['wishing']);//红包祝福诧

        $wxHongBaoHelper->setParameter("wishing", "恭喜恭喜");//红包祝福诧

        $wxHongBaoHelper->setParameter("client_ip", $settings['ip']);//调用接口的机器 Ip 地址

        //$wxHongBaoHelper->setParameter("act_name", $settings['act_name']);//活劢名称

        $wxHongBaoHelper->setParameter("act_name", "提现红包");//活劢名称

        //$wxHongBaoHelper->setParameter("remark", $settings['remark']);//备注信息

        $wxHongBaoHelper->setParameter("remark", "恭喜获得提现红包");//备注信息

        $wxHongBaoHelper->setParameter("logo_imgurl", "https://www.baidu.com/img/bdlogo.png");//商户logo的url

        $postXml = $wxHongBaoHelper->create_hongbao_xml();

        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';

        $responseXml = $wxHongBaoHelper->curl_post_ssl($url, $postXml);

        $responseObj = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);

        $return_code=$responseObj->return_code;

        $result_code=$responseObj->result_code;

判断返回结果

if($return_code=='SUCCESS'){

            if($result_code=='SUCCESS'){

                $result['type'] = "ok";

                return $result;

            }else{

                if($responseObj->err_code=='NOTENOUGH'){

                    $result['content'] =  "后台繁忙,请稍后再试!";

                    $result['type'] = 'error';

                    return $result;

                }else if($responseObj->err_code=='TIME_LIMITED'){

                    $result['content'] =  "现在非红包发放时间,请在北京时间0:00-8:00之外的时间前来领取";

                    $result['type'] = 'error';

                    return $result;

                }else if($responseObj->err_code=='SYSTEMERROR'){

                    $result['content'] =  "系统繁忙,请稍后再试!";

                    $result['type'] = 'error';

                    return $result;

                }else if($responseObj->err_code=='DAY_OVER_LIMITED'){

                    $result['content'] =  "今日红包已达上限,请明日再试!";

                    $result['type'] = 'error';

                    return $result;

                }else if($responseObj->err_code=='SECOND_OVER_LIMITED'){

                    $result['content'] =  "每分钟红包已达上限,请稍后再试!";

                    $result['type'] = 'error';

                    return $result;

                }

                $result['content'] =  "红包发放失败!".$responseObj->return_msg."!请稍后再试!";

                $result['type'] = 'error';

                return $result;

            }

        }

        if($return_code== 'FAIL'){

            $result['content'] =  $responseObj->return_msg;

            $result['type'] = 'error';

            return $result;

        }

下面是WxHongBaoHelper.php定义

<?php

/**

 * 微信红包类

 */

include_once("CommonUtil.php");

include_once("SDKRuntimeException.class.php");

include_once("MD5SignUtil.php");

class WxHongBaoHelper

{

    var $parameters; //cft 参数

    function __construct()

    {

    }

    function setParameter($parameter, $parameterValue) {

        $this->parameters[CommonUtil::trimString($parameter)] = CommonUtil::trimString($parameterValue);

    }

    function getParameter($parameter) {

        return $this->parameters[$parameter];

    }

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

    }

    function check_sign_parameters(){

        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

    第一步:对参数按照 key=value 的格式,并按照参数名 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(){

        try {

            if (null == PARTNERKEY || "" == PARTNERKEY ) {

                throw new SDKRuntimeException("密钥不能为空!" . "<br>");

            }

            if($this->check_sign_parameters() == false) {   //检查生成签名参数

                throw new SDKRuntimeException("生成签名参数缺失!" . "<br>");

            }

            $commonUtil = new CommonUtil();

            ksort($this->parameters);

            $unSignParaString = $commonUtil->formatQueryParaMap($this->parameters, false);

            $md5SignUtil = new MD5SignUtil();

            return $md5SignUtil->sign($unSignParaString,$commonUtil->trimString(PARTNERKEY));

        }catch (SDKRuntimeException $e)

        {

            die($e->errorMessage());

        }

    }

    //生成红包接口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[恭喜发财]]</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>

    */

    function create_hongbao_xml($retcode = 0, $reterrmsg = "ok"){

        try {

            //var_dump($this->parameters);

            $this->setParameter('sign', $this->get_sign());

            //var_dump($this->parameters);

            $commonUtil = new CommonUtil();

            return  $commonUtil->arrayToXml($this->parameters);

        }catch (SDKRuntimeException $e)

        {

            die($e->errorMessage());

        }

    }

    function curl_post_ssl($url, $vars, $second=30,$aHeader=array())

    {

        global $_W;

        $uniteid = $_W['uniacid'];

        load()->func("logging");

        logging_run($url.":".$vars,'','secend');

        $ch = curl_init();

        logging_run('begin'.$ch.'end','','ch');

        //超时时间

        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文件

        curl_setopt($ch,CURLOPT_SSLCERT,CERT_ROOT.'/apiclient_cert.pem.'.$uniteid);

        curl_setopt($ch,CURLOPT_SSLKEY,CERT_ROOT.'/apiclient_key.pem.'.$uniteid);

        curl_setopt($ch,CURLOPT_CAINFO,CERT_ROOT.'/rootca.pem.'.$uniteid);

        logging_run(CERT_ROOT.'/apiclient_cert.pem.'.$uniteid,'','penpen');

        //curl_setopt($ch,CURLOPT_SSLCERT,ROOT_PATH.DS.'pay'.DS.'apiclient_cert.pem');

        //curl_setopt($ch,CURLOPT_SSLKEY,ROOT_PATH.DS.'pay'.DS.'apiclient_key.pem');

        //curl_setopt($ch,CURLOPT_CAINFO,ROOT_PATH.DS.'pay'.DS.'rootca.pem');

        //第二种方式,两个文件合成一个.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,$vars);

        $data = curl_exec($ch);

        logging_run($data,'','data111');

        if($data){

            curl_close($ch);

            return $data;

        }

        else {

            $error = curl_errno($ch);

            //echo "call faild, errorCode:$error\n";

            curl_close($ch);

            return false;

        }

    }

}

?>

CommonUtil.php

<?php

/**

 */

class CommonUtil{

    /**

     *

     *

     * @param toURL

     * @param paras

     * @return

     */

    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;

    }

    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;

    }

    /**

     *

     *

     * @param src

     * @param token

     * @return

     */

    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;

    }

    /**

     * trim

     *

     * @param value

     * @return

     */

    static function trimString($value){

        $ret = null;

        if (null != $value) {

            $ret = $value;

            if (strlen($ret) == 0) {

                $ret = null;

            }

        }

        return $ret;

    }

    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;

    }

    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;

    }

    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;

    }

}

?>

MD5SignUtil.php

<?php

/**

 */

class MD5SignUtil {

    function sign($content, $key) {

        try {

            if (null == $key) {

                throw new SDKRuntimeException("财付通签名key不能为空!" . "<br>");

            }

            if (null == $content) {

                throw new SDKRuntimeException("财付通签名内容不能为空" . "<br>");

            }

            $signStr = $content . "&key=" . $key;

            return strtoupper(md5($signStr));

        }catch (SDKRuntimeException $e)

        {

            die($e->errorMessage());

        }

    }

    function verifySignature($content, $sign, $md5Key) {

        $signStr = $content . "&key=" . $md5Key;

        $calculateSign = strtolower(md5($signStr));

        $tenpaySign = strtolower($sign);

        return $calculateSign == $tenpaySign;

    }

}

?>

SDKRuntimeException.class.php

<?php

/**

 */

class  SDKRuntimeException extends Exception {

    public function errorMessage()

    {

        return $this->getMessage();

    }

}

?>

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微信 应用