精华内容
下载资源
问答
  • .NET 发送微信公众号模板消息 解压密码 www.shcodetool.com
  • 微信公众号消息模板推送demo,亲测能用,替换下参数就能用
  • 首先要去微信公众号开通模板消息 通过之后 可以进行申请模板id 实现代码 public function guestbook(){ //此处模拟前端表单ajax提交 $input_data = input("post."); // if(isset($input_data) && ....

    小程序下单后 微信公众号也一并提示功能

    首先要去微信公众号开通模板消息

    通过之后 可以进行申请模板id

    实现代码

     public function guestbook(){
            //此处模拟前端表单ajax提交
            $input_data = input("post.");
    //        if(isset($input_data) && !empty($input_data)){
    
    
                $openid = '用户openid';
                $time_str = strtotime(date("Y-m-d 0:0:0",time()));
                //检查今天是否有提交过
    //            $check = Db::name("guestbook")->where('openid',$openid)->where('create_time',">=",$time_str)->find();
    //            if(isset($check) && !empty($check)){
    //                return ['code'=>-3];
    //            }else{
                    //提交成功,触发信息推送
                    $data=[
                        'touser'=>$openid,
                        'template_id'=>'模板消息id',
                        'url'=>'http://weixin.qq.com/download',
                        'topcolor'=>"#FF0000",
                        'data'=>array(
                            'first'=>array('value'=>"订单支付成功",'color'=>"#fc0101"),
                            'keyword1'=>array('value'=>1111,'color'=>"#173177"),
                            'keyword2'=>array('value'=>'1111','color'=>"#173177"),
                            'keyword3'=>array('value'=>1800,'color'=>"#173177"),
                            'keyword4'=>array('value'=>'1111','color'=>"#173177"),
                            'remark'=>array('value'=>"您的报名信息已提交,请耐心等待",'color'=>"#173177"),
                        )
                    ];
    
                    $get_all_access_token = $this->getWxAccessToken();
    
    
                    $json_data= str_replace("\\/", "/", json_encode($data, JSON_UNESCAPED_UNICODE));;//转化成json数组让微信可以接收
    
    
                    $url="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$get_all_access_token;//模板消息请求URL
    
                    $res=$this->https_request($url,urldecode($json_data));//请求开始
    
    
                    $res=json_decode($res,true);
    
                    if($res['errcode']==0 && $res['errcode']=="ok"){
                        return ['code'=>1];
                    }else{
                        return ['code'=>-4];
                    }
               // }
            //}
        }
    
    
    
    
        public function https_request($url,$data = null){
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            if (!empty($data)){
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($curl);
            curl_close($curl);
            return $output;
        }

    用户的openid 在上篇说过 https://blog.csdn.net/wanganji5252/article/details/100929442

    可以和小程序中的unionid 进行比对 拿出保存好的openid

    getWxAccessToken() 方法也在上篇中进行说明

    这样就可以给指定的用户发送相对应的模板消息了

     

    展开全文
  • 微擎微信公众号消息模板

    千次阅读 2019-04-20 20:34:18
    sendTplNotice() 说明 sendTplNotice($touser, $template_id, $postdata, $url = ‘’, $topcolor = ‘#FF683F’) 发送模版消息 参数 ...$postdata 根据模板规则完善消息 $url 详情页链接 $topc...

    sendTplNotice()

    说明
    sendTplNotice($touser, $template_id, $postdata, $url = ‘’, $topcolor = ‘#FF683F’)
    发送模版消息

    参数
    $touser 粉丝openid
    $template_id 模板id,需要在公众平台后台添加得到id值
    $postdata 根据模板规则完善消息
    $url 详情页链接
    $topcolor 模板内容字体颜色,不填默认为#FF683F
    返回值
    error
    可用is_error判断,详见《错误处理》

    success
    返回boolean值:true

    示例
    微信公众平台后台模板消息格式如下:

    {{first.DATA}}
    订单号:{{keyword1.DATA}}
    套餐名称:{{keyword2.DATA}}
    消费金额:{{keyword3.DATA}}
    {{remark.DATA}}
    发送 $postdata 内容时,对应格式如下:

    $data = array(
    ‘first’ => array(
    ‘value’ => “订单提交成功!”,
    ‘color’ => ‘#ff510’
    ),
    ‘keyword1’ => array(
    ‘value’ => ‘1008’,
    ‘color’ => ‘#ff510’
    ),
    ‘keyword2’ => array(
    ‘value’ => ‘黄焖鸡米饭’,
    ‘color’ => ‘#ff510’
    ),
    ‘keyword3’ => array(
    ‘value’ => ‘388元’,
    ‘color’ => ‘#ff510’
    ),
    ‘remark’ => array(
    ‘value’ => “欢迎您再次订购” ,
    ‘color’ => ‘#ff510’
    ),
    );
    $account_api = WeAccount::create();
    $result = $account_api->sendTplNotice(‘oPUOlw7yvucjUrZhzG6gd8VdILa4’, ‘vJcJSes4vaVYv7sVEvOsRCGpZz8R3I4U1ODBbXcEBq8’, d a t a ) ; p r i n t r ( data); print_r( data);printr(result);

    展开全文
  • 微信 JSAPI 支付 微信内部起调H5支付 支付完成发送公众号消息模板 JSAPI支付 openID是必传的,所以这里先获取用户openID,想要获取openID,首先我们要拿到code,再获取openID JS: <script> // 强制关注...

    微信 JSAPI 支付 微信内部起调H5支付 支付完成跳转公众号并发送公众号消息模板

    JSAPI支付 openID是必传的,所以这里先获取用户openID,想要获取openID,首先我们要拿到code,再获取openID

    JS:

    <script>
        // 强制关注公众号,获取openid
        getCode = function () {
            var code = getUrlParam('code'); // 截取路径中的code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openId
            var local = window.location.href;
            var APPID = 'xxxxxxxxxx';
            if (code == null || code === '') {
                window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID + '&redirect_uri=' + encodeURIComponent(local) + '&response_type=code&scope=snsapi_base&state=#wechat_redirect'
            } else {
                getOpenId(code) //把code传给后台获取用户信息
            }
        };
    
        //获取地址栏的参数
        getUrlParam= function (name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
            var r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]); return null;
        };
        //页面执行调用
        getCode();
    </script>
    

    页面加载 执行 getCode方法,获取URL中的code,如果没有code,起调公众号获取code接口,然后会跳转到 redirect_uri 这个参数对应的URL路径,这个URL后面会自动拼接出请求的code,这里的 redirect_uri 还是本网页链接地址,这样再次执行 getCode方法的时候就能获取到URL链接后面的 code 。

    然后根据 code ajax请求后端 起调公众号获取网页授权access_token接口 ,这个接口会返回 openID 和 access_token

    JS:

    	//把code传给后台,得到openid
        getOpenId = function (code) {
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: "{:U('getOpenid')}",
                data: { code: code },
                success: function (res) {
                    if (res.status == -1) {
                        alert(result.msg);
                        return false;
                    } else {
                    	// 起调统一下单接口
                        unifiedorder(res.data.openid);
                    }
                }
            });
        };
    

    后端接口PHP :

    function getOpenid(){
            $code = I('post.code');
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxx&secret=xxxxxxxxxxxxxxxx&code=$code&grant_type=authorization_code";
            $data = file_get_contents($url);
            if($data){
                $this->ajaxReturn(array('data'=>json_decode($data,true),'msg'=>'获取成功','status'=>1));
            }else{
                $this->ajaxReturn(array('data'=>'','msg'=>'获取失败','status'=>0));
            }
        }
    

    拿到 openID 以后传给后端,起调JSAPI支付统一下单接口,拿到参数 prepay_id

    JS:

     	// 起调统一下单接口
        unifiedorder = function(openid){
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: "{:U('index')}",
                data: { openid: openid },
                success: function (result) {
                    if (result.status == 0) {
                        alert(result.msg);
                        return false;
                    } else {
                        h5();
                    }
                }
            });
        };
    

    PHP:

    public function index()
        {
            if(IS_POST){
                $time = time();
                $key = "支付密钥";
                $post['appid'] = "xxxxxxxxxxxx";
                $post['body'] = '商品购买';
                $post['mch_id'] = "商户ID";
                $post['nonce_str'] = $this->randomkeys(32);      //随机字符串
                $post['notify_url'] = "https://".$_SERVER['HTTP_HOST'] . '/index.php/Api/Native/notify_url';  //支付完成回调地址url,不能带参数;
                $post['openid'] = I('post.openid');  // openID
                $post['out_trade_no'] = $time.rand(10000,99999);  // 订单号
                $post['spbill_create_ip'] = $_SERVER['SERVER_ADDR'];    //服务器终端的ip
                $post['total_fee'] = 1;                        //总金额 最低为一分钱 必须是整数
                $post['trade_type'] = 'JSAPI';                          //交易类型 默认JSAPI
                $sign = $this->MakeSign($post, $key);                   //签名
                $res['key'] = $key;
                $post['sign'] = $sign;
                $post_xml = $this->arrToXml($post);
                //统一下单接口prepay_id
                $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
                $xml = $this->http_request($url, $post_xml);            //POST方式请求http
                $array = $this->xml_to_array($xml);                     //将【统一下单】api返回xml数据转换成数组,全要大写
                if ($array['return_code'] == "SUCCESS" && $array['result_code'] == "SUCCESS") {
                    $sign_arr['appId'] = $array['appid'];
                    $sign_arr['nonceStr'] = $this->randomkeys(32);      //随机字符串
                    $sign_arr['package'] = "prepay_id=".$array['prepay_id'];
                    $sign_arr['signType'] = "MD5";
                    $sign_arr['timeStamp'] = $time;
                    $newSign = $this->MakeSign($sign_arr, $key);                   //签名
                    $result['data'] = $sign_arr;
                    $result['newSign'] = $newSign;
                    $result['status'] = 1;
                    $result['msg'] = '统一下单成功';
                    $this->ajaxReturn($result);
                } else {
                    $result['status'] = 0;
                    $result['msg'] = '统一下单失败';
                    $this->ajaxReturn($result);
                }
            }else{
                $this->display();
            }
        }
    

    这里拿到 prepay_id 这个参数,起到H5支付页面

    JS:

    	// 起调H5支付
        function onBridgeReady() {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId": result.data.appId,     //公众号名称,由商户传入
                    "timeStamp": result.data.timeStamp,         //时间戳,自1970年以来的秒数
                    "nonceStr": result.data.nonceStr, //随机串
                    "package": result.data.package,
                    "signType": "MD5",         //微信签名方式:
                    "paySign": result.newSign //微信签名
                },
                function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        // 使用以上方式判断前端返回,微信团队郑重提示:
                        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                        window.location.href = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=xxxxxxMw==#wechat_redirect";
                    }
                });
        }
        
        h5 = function () {
            if (typeof WeixinJSBridge == "undefined") {
                if (document.addEventListener) {
                    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                } else if (document.attachEvent) {
                    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                }
            } else {
                onBridgeReady();
            }
        };
    

    JSAPI支付 微信内部起调 H5 是要 appId nonceStr package signType timeStamp paySign 这六个参数的,其中 paySign 签名是 前面五个参数的生成的签名,签名加密的类型要和发起统一支付下单接口生成的sign签名一致,完成加密以后将六个参数返回给前端,前端拿到参数调起微信H5支付页面。

    H5支付页面:
    在这里插入图片描述
    支付完成页面:
    在这里插入图片描述
    公众号模板消息发送是在回调接口(支付结果通知接口,以下称呼回调接口)里处理的,回调接口会返回支付人是否关注支付APPID对应的公众号参数 is_subscribe
    在这里插入图片描述
    这个地方可以看到下面有一个关注公众号,如果没有关注公众号,就不能发送公众号模板消息,所以我们要在支付回调接口中进行发送模板消息处理,延时发送模板消息,确保能在支付完成能够点击关注以后再发送消息,但是我们都知道回调接口是有通知频率的,微信总共会发起多次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m)。所以我这里做了一个操作记录表,当然我是需要这个操作记录,所以就顺便就能用这个作为判断依据,如果不需要操作记录,可以做一个缓存。

    public function notify_url()
        {
            $xml = file_get_contents('php://input');
            $extend_content = json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));//转换格式
            file_put_contents('./xcxPay.txt', 'xcx_post33: ' . $xml . "\r\n", FILE_APPEND);
    
            $post = json_decode($extend_content, true);
    
            $postSign = $post['sign'];
            unset($post['sign']);
            /* 微信官方提醒:
             *  商户系统对于支付结果通知的内容一定要做【签名验证】,
             *  并校验返回的【订单金额是否与商户侧的订单金额】一致,
             *  防止数据泄漏导致出现“假通知”,造成资金损失。
             */
           
            $user_sign = $this->MakeSign($post, "xxxxxxxxxxx");   //再次生成签名,与$postSign比较
    
            /*
            * 首先判断,订单是否已经更新为ok,因为微信会总共发送8次回调确认
            * 其次,订单已经为ok的,直接返回SUCCESS
            * 最后,订单没有为ok的,更新状态为ok,返回SUCCESS
            */
            if ($post['return_code'] == 'SUCCESS' && $postSign == $user_sign) {
    
                // 用户openid
                $openid = $post['openid'];
                // 用户是否关注公众账号,Y-关注,N-未关注
                $is_subscribe = $post['is_subscribe'];
    
                $data['post'] = $post;
                if($is_subscribe == "Y"){
                	// 发送公众号模板消息
                    $res = self::sendNotice($openid,$post['out_trade_no']);
                    $data['res'] = $res;
                    M('logs')->add(array('content' => json_encode($data),'orderId' => $post['out_trade_no']));
                    $this->return_success_v1();
                }else{
                    sleep(10);
                    $log = M('logs')->where(array('orderId' => $post['out_trade_no']))->find();
                    if($log){
                        $this->return_success_v1();
                    }else{
                        $res = self::sendNotice($openid,$post['out_trade_no']);
                        $data['res'] = $res;
                        M('logs')->add(array('content' => json_encode($data),'orderId' => $post['out_trade_no']));
                        $this->return_success_v1();
                    }
                }
            } else {
                $this->return_success_v1();
            }
        }
    

    如果已经关注了,直接发送消息,如果没有关注公众号,睡眠10秒以后,查询操作记录表中是否已经有操作记录,这里为什么要查询操作记录表是为了确保回调如果通知了两次,不会发送两条消息模板。

    我这边支付完成以后会跳转一个页面,这个页面是微信公众号的页面,但是现在微信更新到7以后,这个页面在公众号就找不到了,但是这个链接是可以用,这里面 __biz= 后面的参数获取可以参照这个网址H5跳转公众号
    但是这个网址的操作只能在低版本微信上可以,目前的微信已经没有了,我也是在低版本微信中,才找到这个 __biz= 后面的参数,但是我这边并没有作者说的关注按钮一闪即逝的情况,所以我不保证所有手机都可以,当然这个链接也可以换成公众号其他的页面
    https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=xxxxxxxx==#wechat_redirect
    在这里插入图片描述

    发送的模板消息
    在这里插入图片描述

    JS完整代码:

    <script>
        // 强制关注公众号,获取openid
        getCode = function () {
            var code = getUrlParam('code'); // 截取路径中的code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openId
            var local = window.location.href;
            var APPID = 'xxxxxxxxxxxxx';
            if (code == null || code === '') {
                window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + APPID + '&redirect_uri=' + encodeURIComponent(local) + '&response_type=code&scope=snsapi_base&state=#wechat_redirect'
            } else {
                getOpenId(code) //把code传给后台获取用户信息
            }
        };
    
        //把code传给后台,得到openid
        getOpenId = function (code) {
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: "{:U('getOpenid')}",
                data: { code: code },
                success: function (res) {
                    if (res.status == -1) {
                        alert(result.msg);
                        return false;
                    } else {
                        unifiedorder(res.data.openid);
                    }
                }
            });
        };
    
        // 起调统一下单接口
        unifiedorder = function(openid){
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: "{:U('index')}",
                data: { openid: openid },
                success: function (result) {
                    if (result.status == 0) {
                        alert(result.msg);
                        return false;
                    } else {
                        h5();
                    }
                }
            });
        };
    
        // 起调H5支付
        function onBridgeReady() {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId": result.data.appId,     //公众号名称,由商户传入
                    "timeStamp": result.data.timeStamp,         //时间戳,自1970年以来的秒数
                    "nonceStr": result.data.nonceStr, //随机串
                    "package": result.data.package,
                    "signType": "MD5",         //微信签名方式:
                    "paySign": result.newSign //微信签名
                },
                function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        // 使用以上方式判断前端返回,微信团队郑重提示:
                        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                        window.location.href = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=xxxxxxxx==#wechat_redirect";
                    }
                });
        }
        h5 = function () {
            if (typeof WeixinJSBridge == "undefined") {
                if (document.addEventListener) {
                    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                } else if (document.attachEvent) {
                    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                }
            } else {
                onBridgeReady();
            }
        };
    
        //获取地址栏的参数
        getUrlParam= function (name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
            var r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]); return null;
        };
        //页面执行调用
        getCode();
    </script>
    

    PHP完整代码:

    class NativeController extends Controller{
    
        /**
         * 微信支付
         * @param int $i
         * @return mixed
         */
        public function index()
        {
            if(IS_POST){
                $time = time();
                $key = "xxxxxxxxxxxxxxx";
                $post['appid'] = "xxxxxxxxxxxx";
                $post['body'] = '商品购买';
                $post['mch_id'] = "xxxxxxxxxxx";
                $post['nonce_str'] = $this->randomkeys(32);      //随机字符串
                $post['notify_url'] = "https://".$_SERVER['HTTP_HOST'] . '/index.php/Api/Native/notify_url';  //支付完成回调地址url,不能带参数;
                $post['openid'] = I('post.openid');
                $post['out_trade_no'] = $time.rand(10000,99999);
                $post['spbill_create_ip'] = $_SERVER['SERVER_ADDR'];    //服务器终端的ip
                $post['total_fee'] = 1;                        //总金额 最低为一分钱 必须是整数
                $post['trade_type'] = 'JSAPI';                          //交易类型 默认JSAPI
                $sign = $this->MakeSign($post, $key);                   //签名
                $res['key'] = $key;
                $post['sign'] = $sign;
                $post_xml = $this->arrToXml($post);
                //统一下单接口prepay_id
                $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
                $xml = $this->http_request($url, $post_xml);            //POST方式请求http
                $array = $this->xml_to_array($xml);                     //将【统一下单】api返回xml数据转换成数组,全要大写
                if ($array['return_code'] == "SUCCESS" && $array['result_code'] == "SUCCESS") {
                    $sign_arr['appId'] = $array['appid'];
                    $sign_arr['nonceStr'] = $this->randomkeys(32);      //随机字符串
                    $sign_arr['package'] = "prepay_id=".$array['prepay_id'];
                    $sign_arr['signType'] = "MD5";
                    $sign_arr['timeStamp'] = $time;
                    $newSign = $this->MakeSign($sign_arr, $key);                   //签名
                    $result['data'] = $sign_arr;
                    $result['newSign'] = $newSign;
                    $result['status'] = 1;
                    $result['msg'] = '统一下单成功';
                    $this->ajaxReturn($result);
                } else {
                    $result['status'] = 0;
                    $result['msg'] = '统一下单失败';
                    $this->ajaxReturn($result);
                }
            }else{
                $this->display();
            }
        }
    
        /**
         * 小程序商家模式回调 目前在使用
         */
        public function notify_url()
        {
            $xml = file_get_contents('php://input');
            $extend_content = json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));//转换格式
            file_put_contents('./xcxPay.txt', 'xcx_post33: ' . $xml . "\r\n", FILE_APPEND);
    
            $post = json_decode($extend_content, true);
    
            $postSign = $post['sign'];
            unset($post['sign']);
            /* 微信官方提醒:
             *  商户系统对于支付结果通知的内容一定要做【签名验证】,
             *  并校验返回的【订单金额是否与商户侧的订单金额】一致,
             *  防止数据泄漏导致出现“假通知”,造成资金损失。
             */
            $user_sign = $this->MakeSign($post, "xxxxxxxxxxxxx");   //再次生成签名,与$postSign比较
    
            /*
            * 首先判断,订单是否已经更新为ok,因为微信会总共发送8次回调确认
            * 其次,订单已经为ok的,直接返回SUCCESS
            * 最后,订单没有为ok的,更新状态为ok,返回SUCCESS
            */
            if ($post['return_code'] == 'SUCCESS' && $postSign == $user_sign) {
    
                // 用户openid
                $openid = $post['openid'];
                // 用户是否关注公众账号,Y-关注,N-未关注
                $is_subscribe = $post['is_subscribe'];
    
                $data['post'] = $post;
                if($is_subscribe == "Y"){
                    $res = self::sendNotice($openid,$post['out_trade_no']);
                    $data['res'] = $res;
                    M('logs')->add(array('content' => json_encode($data),'orderId' => $post['out_trade_no']));
                    $this->return_success_v1();
                }else{
                    sleep(10);
                    $log = M('logs')->where(array('orderId' => $post['out_trade_no']))->find();
                    if($log){
                        $this->return_success_v1();
                    }else{
                        $res = self::sendNotice($openid,$post['out_trade_no']);
                        $data['res'] = $res;
                        M('logs')->add(array('content' => json_encode($data),'orderId' => $post['out_trade_no']));
                        $this->return_success_v1();
                    }
                }
            } else {
                $this->return_success_v1();
            }
        }
    
        /**
         * 随机字符串
         */
        public function randomkeys($length)
        {
            $pattern = '1234567890abcdefghijklmnopqrstuvwxyz
                       ABCDEFGHIJKLOMNOPQRSTUVWXYZ,./&l
                      t;>?;#:@~[]{}-_=+)(*&^%$?!';    //字符池
            $key = '';
            for ($i = 0; $i < $length; $i++) {
                $key .= $pattern{mt_rand(0, 35)};    //生成php随机数
            }
            return $key;
        }
    
        /**
         * 生成签名, $KEY就是支付key
         * @param $params
         * @param $KEY
         * @return string
         */
        public function MakeSign($params, $KEY)
        {
            //签名步骤一:按字典序排序数组参数
            ksort($params);
            $string = $this->ToUrlParams($params);  //参数进行拼接key=value&k=v
            //签名步骤二:在string后加入KEY
            $string = $string . "&key=" . $KEY;
            //签名步骤三:MD5加密
            $string = md5($string);
            //签名步骤四:所有字符转为大写
            $result = strtoupper($string);
            return $result;
        }
    
        public function arrToXml($item)
        {
            $xml = "<xml>";
            foreach ($item as $key => $val) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
            $xml .= "</xml>";
            return $xml;
        }
    
        /**
         * 调用接口, $data是数组参数
         * @param $url
         * @param null $data
         * @param array $headers
         * @return bool|string
         */
        public function http_request($url, $data = null, $headers = array())
        {
            $curl = curl_init();
            if (count($headers) >= 1) {
                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            }
            curl_setopt($curl, CURLOPT_URL, $url);
    
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    
            if (!empty($data)) {
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $output = curl_exec($curl);
            curl_close($curl);
            return $output;
        }
    
        /**
         * 数组转化
         * @param $xml
         * @return bool|mixed
         */
        public function xml_to_array($xml)
        {
            if (!$xml) {
                return false;
            }
            //将XML转为array
            //禁止引用外部xml实体
            libxml_disable_entity_loader(true);
            $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            return $data;
        }
    
        /**
         * 将参数拼接为url: key=value&key=value
         * @param $params
         * @return string
         */
        public function ToUrlParams($params)
        {
            $string = '';
            if (!empty($params)) {
                $array = array();
                foreach ($params as $key => $value) {
                    $array[] = $key . '=' . $value;
                }
                $string = implode("&", $array);
            }
            return $string;
        }
    
        /**
         * 给微信发送确认订单金额和签名正确,SUCCESS信息 -xzz0521
         */
        private function return_success_v1()
        {
            $xml_post = '<xml>
                        <return_code>SUCCESS</return_code>
                        <return_msg>OK</return_msg>
                        </xml>';
            echo $xml_post;
            exit;
        }
    
        /**
         * 发送模板消息
         * @param $openid
         * @param $out_trade_no
         * @return bool|string
         */
        public function sendNotice($openid,$out_trade_no){
    
            //$token = M('access_token_native')->find();
            $token = M('access_token')->find();
            // token 过期
            if (!$token || $token['expires_in'] <= time() - $token['addtime']) {
                // 重新获取token
                $file_contents = self::getAccessToken();
                $access_token = $file_contents->access_token;
            } else {
                $access_token = $token['token'];
            }
    
            $template_id = "xxxxxxxxxxxxxxx";
    
            $value = array(
                "productType" => array(
                    "value" => "消费金额",
                    "color" => "#4a4a4a"
                ),
                "name" => array(
                    "value" => "0.01元",
                    "color" => "#4a4a4a"
                ),
                "time" => array(
                    "value" => date("Y-m-d H:i:s"),
                    "color" => "#4a4a4a"
                ),
                "remark" => array(
                    "value" => "秀山丽水欢迎您,欢迎前来丽水旅游及购买土特产!",
                    "color" => "#ff0000"
                ),
    
            );
            $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $access_token;
            $dd = array();
            $dd['touser'] = $openid;
            $dd['template_id'] = $template_id;
            $dd['url'] = "https://xxxxxx.com";
            $dd['data'] = $value;                    //模板内容,不填则下发空模板
            $result = $this->https_curl_json($url, $dd, 'json');
            return $result;
        }
    
        /**
         * @return mixed
         */
        public function getAccessToken(){
            $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxxxxxxxxxxx&secret=xxxxxxxxxxxx';
            $headerArray =array("Content-type:application/json;","Accept:application/json");
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
            $result = curl_exec($curl);
            curl_close($curl);
            $escape_token = json_decode($result);
            if($escape_token->access_token){
                $data = [
                    'token' => $escape_token->access_token,
                    'expires_in' => $escape_token->expires_in,
                    'addtime' => time(),
                ];
                $res = M('access_token')->find();
                if ($res) {
                    M('access_token')->save($data);
                } else {
                    M('access_token')->add($data);
                }
            }
            return $escape_token;
        }
    
        /**
         * 发送Post 请求
         * @param $url
         * @param $data
         * @param $type
         * @return bool|string
         */
        function https_curl_json($url, $data, $type)
        {
            if ($type == 'json') {
                $headers = array("Content-type: application/json;charset=UTF-8", "Accept: application/json", "Cache-Control: no-cache", "Pragma: no-cache");
                $data = json_encode($data);
            }
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    
            if (!empty($data)) {
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            $output = curl_exec($curl);
            if (curl_errno($curl)) {
                echo 'Errno' . curl_error($curl);//捕抓异常
            }
            curl_close($curl);
            return $output;
        }
    
        /**
         * 获取openID
         */
        function getOpenid(){
            $code = I('post.code');
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxxxxxx&secret=xxxxxxxxxxxx&code=$code&grant_type=authorization_code";
            $data = file_get_contents($url);
            if($data){
                $this->ajaxReturn(array('data'=>json_decode($data,true),'msg'=>'获取成功','status'=>1));
            }else{
                $this->ajaxReturn(array('data'=>'','msg'=>'获取失败','status'=>0));
            }
        }
    }
    
    展开全文
  • CRMEB多商户使用,新增一个消息模板或订阅消息。因为操作的逻辑是一样的,所以这里就以消息模板来操作的,订阅消息大同小异。 一、 先登录自己的微信公众号后台,申请模板。我这里以《访客接待消息通知》为例,下图...

    CRMEB多商户使用,新增一个消息模板或订阅消息。因为操作的逻辑是一样的,所以这里就以消息模板来操作的,订阅消息大同小异。
    一、 先登录自己的微信公众号后台,申请模板。我这里以《访客接待消息通知》为例,下图是我申请好的截图。

    在这里插入图片描述
    二、将刚才申请的模板信息填写到平台后台的模板管理中去,如下图:
    在这里插入图片描述

    三、代码实现部分,以下 … … 是省略了源代码中的未修改的代码部分:

    1. 修改配置文件,config/template.php 文件,因为我们增加的是微信公众号消息,所以在wechat数组下增加一行,这里的键可以自定义,值就是刚才申请的模板编号,如图:
      在这里插入图片描述
    2. 增加模板消息的内容设定,所有模板消息或者订阅消息的内容都在crmeb/services/WechatTemplateMessageService.php文件中实现的。
    • 修改入口文件,因为我们这个模板需要传入额外的参数,但是原来的方法中并没有这个,所以我们增加一个$data[‘data’] ?? []参数的传入。

       public  function sendTemplate(array $data)
       {
          $res = $this->templateMessage($data['tempCode'],$data['id'], $data['data'] ?? []);
          if(!$res || !is_array($res))
              return true;
      	...
      	...
       }
      
    • 新增模板消息的内容设定

       public  function templateMessage(string $tempCode,  $id, $params = [])
      {
          $bill_make = app()->make(UserBillRepository::class);
          $order_make = app()->make(StoreOrderRepository::class);
          $refund_make = app()->make(StoreRefundOrderRepository::class);
          $order_status_make = app()->make(StoreOrderStatusRepository::class);
      
          switch ($tempCode) {
         	... 
         	...
           case'SERVER_NOTICE':
                  /*
                  {{first.DATA}}
                  访客姓名:{{keyword1.DATA}}
                  联系方式:{{keyword2.DATA}}
                  项目名称:{{keyword3.DATA}}
                  {{remark.DATA}}
                   */
                  $mer = app()->make(MerchantRepository::class)->get($params['mer_id']);
                  $user = app()->make(UserRepository::class)->get($id);
                  $data[] = [
                      'tempCode' => 'SERVER_NOTICE',
                      'uid' => $id,
                      'data' => [
                          'first' => '亲,您有新的消息请注意查看~',
                          'keyword1' => $user['nickname'],
                          'keyword2' => $mer['mer_name'],
                          'keyword3' => $params['keyword3'],
                          'remark' => ''
                      ],
                      'link' => '',
                      'color' => null
                  ];
                  break;
              default:
                  return false;
                  break;
          }
          return $data;
      }
      

    四、修改需要调用的代码

    • 上面就将模板消息的内容也设定好了,现在就去需要使用的地方调用就好了,我们找到客服消息的监听文件,然后替换之前的发短信提醒的地方,如下图:
      在这里插入图片描述

    这样我们就完成了整个的流程开发了,重启一下项目服务,即可。

    展开全文
  • 回复普通消息时,使用 \n 即可换行,但是如果想在模板消息中换行,使用 \n 会出现错误 data format error 解决办法是,使用\\n 当初百度了半天没答案,今天突发奇想,歪打正着。应该是微信服务器那边做了次转义的...
  • package net.mingsoft.common.wx.pojo; public class WxTagsEntity { private String id; //标签id private String name; //标签名称 private String count; //此标签下粉丝数 public String getId() { ...}
  • 首先我们要在公众号里面去申请(新建一个消息模板),我这里只是申请别人已经有了的模板 这个唯一的ID就是你触发这个模板的时候的唯一标示,而其他一些内容,部分是固定的,部分是可改动的(用{{}}括起来的内容就是) ...
  • 在公众平台实现发送模板消息功能,只能通过公众平台的接口开发实现,或者通过第三方平台微号帮功能模板消息群发实现,均能为微信公众号发送模板消息功能,模板消息发送不占用公众号每月的群发次数,模板消息仅用于...
  • senparclsx15 个回复• 查看 467 次• 62天前sy8746811815 个回复• 查看 389 次• 7天前magiboy13 个回复• 查看 758 次• 120天前yintingji12 个回复• 查看 701 次• 130天前LXL.WxDeveloper11 个回复• 查看 358...
  • Java 实现微信公众号模板消息推送,demo
  • 微信公众号发送模板消息 -- PHP后台

    万次阅读 2020-05-19 16:26:04
    微信公众号发送模板消息 直接看代码吧: /** * 发送模板消息 */ public function send_notice(){ $appid = '填写你的appid'; $appsecret = '填写你的appsecret '; $access_token_url = '...
  • 微信公众号开通模板消息功能 步骤一. 登录微信公众平台 登陆【微信公众号】——【功能】——【添加功能插件】——【模板消息】 消息模板中,点击模板库,主行业选择为 IT科技-互联网|电子商务,副行业选择为 餐饮|...
  • 微信公众号模板消息跳转小程序

    万次阅读 2019-01-15 13:36:02
    公众号发送模板消息这里就不说了,详情可以去看我之前发的微信公众号开发之模板消息。 前几天因业务需求,需要点击模板消息跳转小程序,所以在此发篇博客记录一下。 代码如下: public void textTemplate(String ...
  • 微信小程序,公众号发送模板消息

    千次阅读 2018-11-13 16:39:50
    小程序发送模板消息公众号有一点不同的可能就是小程序需要一个form_id,这个是发起支付或者提交表单的时候才能获取到,提交表单得到的formId有效期7天且只能用一次,支付获得的预订单Id可以使用三次,公众号则不...
  • 为了避免小程序的模板消息发送不稳定(用户七天不登录小程序,则获取不到对应的formid,那么用户就收不到小程序的模板消息),此时需要发送公众号模板消息来代替之,并且相对稳定,没有次数限制,没有天数限制,...
  • VB制作公众号信息模板、客户消息,自动更新token,查询mysql语句实时推送模板消息
  • 微信公众号模板消息开发,完整php代码$template=array( 'touser'=>'o_pQ5uH2ACQXU5JvnQETNqiEep-o', 'template_id'=>'f9opVsMh2Y7boafO6wAJ8-DyEjcv2lbzKDT_8NDYjLc', 'url'=>'www.tdperson.com/demo/', 'top...
  • 微信公众号发送模板消息 附上微信公众平台文档链接:https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl 实现思路: 1.在公众平台配置好参数(授权地址、授权回调地址、模板消息模板 。三者...
  • 公众号发送模板消息40165错误

    千次阅读 2020-06-17 16:18:56
    今天在做公众号发送模板消息的功能的时候报了一个错误"errcode":40165,"errmsg":"invalid weapp pagepath hint",网上也找了很多资料,发现很多人都有遇过同样的问题。解决方法大体上有3种,一种是把字段改成page,...
  • 微信公众号-模板消息管理

    千次阅读 2018-12-23 16:59:33
    微信公众号-模板消息管理 ...模板消息仅用于公众号向用户发送重要的服务...本文主要介绍基于C#开发实现公众号模板消息的管理功能。“模板消息功能的推出,将极大地增强服务号的服务通知能力”,在一些一直期待微信模板...
  • 自己在微信公众平台中申请模板消息的id;这里没有没有提供获取用户openid的方法,我在之前的一个博客中有写过获取用户openid的代码;需要注意的是,有一点很坑,那就是在获取用户openid的时候会返回给你一个token;...
  • 主要为大家详细介绍了java微信公众号发送消息模板,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,032
精华内容 21,212
关键字:

公众号消息模板