私は最近、WeChat PC Web ページの WeChat 関連機能を開発しています。初心者の観点から見ると、オンラインで見つかる投稿のほとんどは、基本的に WeChat で提供されているもののコピーです。パブリック プラットフォーム。ドキュメント。パラメーターを使用した WeChat QR コードの開発プロセスでまだ多くの落とし穴に遭遇しました。皆さんの役に立つことを願って、ここに開発プロセスを詳しく記録します。
この開発には認証サービス アカウントを使用しています。
1 インターフェイスでは、thinkPHP フレームワークを使用してプログラムを開発しました。モジュール (装飾) の 1 つのアクション ディレクトリに新しいクラスを作成します (例: WechatAction.class.php)、新しいパブリック メソッドを作成します。アクションに、たとえば: URLRedirect()
を入力すると、この URL に入力する内容はhttp://[IP]:[port]/index.php/Decoration/Wechat/UrlRedirect となり、 [トークン] に、EncodingAESKey かどうかを指定してトークンを入力し、[確認] をクリックします。WeChat はこの URL に取得リクエストを送信します。これには多くのパラメーターが含まれており、このアクセスが WeChat サーバーによって要求されているかどうかを確認できます。私自身は検証していませんが、検証が成功した場合、つまり get リクエストのパラメータである echostr がそのまま返される場合は、 return や ajaxReturn を使用します。開発には thinkPHP を使用し、echo I('echostr');
を使用するだけです。その後、インターフェイスの検証は成功します。2 パラメータ化されたQRコードの役割
WeChatにはパラメータ化されたQRコードの2種類があり、1つは一時的なQRコード、もう1つは永続的なQRコードですが、永続的なQRコードの生成数に制限がある 今回実装したい機能は、ユーザーがログインせずにWebサイト上の商品を利用できる機能(特定の商品の詳細な見積りが取得できる機能)ですが、それはできません。ただし、この時点で、Web ページは QR コードを生成することができ、ユーザーは WeChat で QR コードをスキャンするだけで、公式アカウントにグラフィック メッセージが送信されます。グラフィック メッセージをクリックすると、そのユーザーがいつでも表示され、価格比較のために友人と共有できるようになります。したがって、一時的な QR コードは正常に使用できます。
上記は私がどのように使用するかです。ここでインタラクションプロセス全体を紹介します:
ユーザーがこの QR コードをスキャンすると、ユーザーが公式アカウントをフォローしている場合、ユーザーは直接会話ページに入ります。 WeChat サーバーは、前の手順で設定したサーバー URL にメッセージをプッシュします。これにはカスタム パラメーターを含めることができます。ユーザーが公式アカウントをフォローしていない場合、ユーザーはまず公式アカウントのフォローページに移動し、クリックすると公式アカウントの会話ページに直接アクセスします。パラメータをカスタマイズして、設定した URL にイベント メッセージをプッシュします。このパラメータとイベント タイプに基づいて次のアクションを制御できます。
3 具体的な開発プロセス
3.1 access_tokenを取得する
このaccess_tokenは、プログラムがWeChatインターフェースを呼び出すための証明書です。現在の有効期間は7200秒であるため、更新する必要があります。 access_token を定期的に取得します。
取得方法:
方法 : GET url :https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
パラメータAPPIDとAPPSECRETは、WeChat公式アカウント->基本設定にあります。通話が成功すると、次のJSONデータが表示されます。が返されます:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
ここで、access_token は呼び出し側インターフェイスの資格情報、expire_in はトークンの有効期限です。
私は個人的に access_token をデータベースに保存し、同時に有効期限を保存し、パブリック関数 getWechatAccessToken() をカプセル化します。 毎回、最初に access_token の有効期限が切れているかどうかを確認します。それ以外の場合は、データベースに保存されている access_token を直接使用してください。ただし、この access_token は毎日取得できる回数に制限があるはずです。以下は getWechatAccessToken() の具体的な実装です:
//获取access_token function getWechatAccessToken(){ $wechatInfo = M('wechat_info')->select(); $wechatInfo = array_reduce($wechatInfo, create_function('$result, $v', '$result[$v["conf_name"]] = $v;return $result;')); $expireTime = $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES']['conf_value']; //前面不用管,是我数据库相应设置 if (time() < $expireTime){ //access_token未过期 return $wechatInfo['PUBLIC_WECHAT_ACCESSTOKEN']['conf_value']; }else{ //access_token过期,重新获取 $baseUrl = C('WECHAT_PUBLIC_GET_ACCESS_TOKEN'); $url = str_replace("##APPSECRET##", $wechatInfo['PUBLIC_WECHAT_APPSECRET']['conf_value'], str_replace("##APPID##", $wechatInfo['PUBLIC_WECHAT_APPID']['conf_value'], $baseUrl)); $result = file_get_contents($url); $result = json_decode($result, true); if (array_key_exists('errorcode', $result)){ //失败重试一次 return false; }else{ M('wechat_info')->where(array('conf_name' => 'PUBLIC_WECHAT_ACCESSTOKEN'))->save(array('conf_value' => $result['access_token'])); M('wechat_info')->where(array('conf_name' => 'PUBLIC_WECHAT_ACCESSTOKEN_EXPIRES'))->save(array('conf_value' => time()+$result['expires_in']-200)); return $result['access_token']; } } }
C('WECHAT_PUBLIC_GET_ACCESS_TOKEN') = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
これをカプセル化した後は、いつでも安心して使用できます。
3.2 一時的なQRコードの作成
3.2.1 Get ticket
请求方式: POST 接口:https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN POST数据: {"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}
インターフェースURLのTOKENは3.1で取得したaccess_token、投稿データのexpire_秒はQRコード一時的な QR コードの action_name は、QR_SCENE に固定されています。これは、アプリケーション内のオーダーの ID として設定される 32 ビットの整数です。 , そして、WeChatサーバーはいつか設定したインターフェースにこの値を返し、この値をもとに対応する注文データをWebページに表示することになります。
以下は、一時的な QR コードを生成するカプセル化されたメソッドです:
//创建临时二维码 function getTemporaryQrcode($orderId){ $accessToken = getWechatAccessToken(); $url = str_replace("##TOKEN##", $accessToken, C('WECHAT_PUBLIC_GET_TEMPORARY_TICKET')); $qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": '.$orderId.'}}}'; $result = api_notice_increment($url, $qrcode); $result = json_decode($result, true); return urldecode($result['url']); }
メソッド api_notice_increment() は、おそらく WeChat インターフェイスのため、私がカプセル化した POST メソッド関数です。 POST メソッドとパラメーターの制限は比較的厳しく、これには長い時間がかかりましたが、最終的に、オンラインで使用できるカプセル化された POST メソッドを見つけました。WeChat がエラーを返した場合は、これを使用することをお勧めします。少なくとも、WeChat インターフェイスをテストしたとき、postman を使用してテストしたところ、すべてのエラーが返されました。JSON 文字列を使用する必要があります。これは非常に厳密な JSON 文字列でなければなりません。このメソッドは次のとおりです:
function api_notice_increment($url, $data){ $ch = curl_init(); $header = "Accept-Charset: utf-8"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $tmpInfo = curl_exec($ch); if (curl_errno($ch)) { curl_close( $ch ); return $ch; }else{ curl_close( $ch ); return $tmpInfo; } }
getTemporaryQrcode() 設定ファイルには誰でも見ることができるパラメーターがあります。これは実際には WeChat インターフェースのリンクです:
C('WECHAT_PUBLIC_GET_TEMPORARY_TICKET') = https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=##TOKEN##
このインターフェースの戻り値は次のとおりです:
{"ticket":"gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm3sUw==","expire_seconds":60,"url":"http:\/\/weixin.qq.com\/q\/kZgfwMTm72WWPkovabbI"}
ticket は次の通話に使用するバウチャー、expire_seconds は QR コードの有効期間、url は生成した QR コードをスキャンした後に開いたリンクです。したがって、QR コードを生成するメソッドを自分で実装する場合は、このステップで停止して URL の値を直接返し、この URL の値を使用して QR コードを生成する必要はありません。ローカルに保存できます。 phpqrcode を使用すると、PHP で QR コードを生成でき、非常に使いやすくなります。次のステップについても簡単に説明します。
3.2.2 QR コードアドレスの取得
请求方式: GET 接口:https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
このインターフェースの戻り値は画像であり、これを直接表示またはダウンロードすることができます。なので、詳しい表示方法が分かりません。
3.3 ユーザーが QR コードをスキャンした後に何が起こるか
3.3.1 扫描后发生了什么
上面提到了,用户扫描我们生成的临时二维码,如果用户未关注公众号,则首先会跳转到公众号的关注页面,点击关注后,会进入公众号的会话页面,同时会给我们设置的接口推送一个事件。如果用户已经关注了,用户微信会直接跳转到公众号会话页面,然后微信服务器会给我们设置的接口推送一个事件。
用户关注与否微信服务器给我们推送的事件是差不多的,只是新关注用户推送的事件中scene_id前面会加一个前缀。下面是微信公众平台文档的说明:
用户未关注时,进行关注后的事件推送
<xml><ToUserName><![CDATA[toUser]]></ToUserName> //开发者微信号<FromUserName><![CDATA[FromUser]]></FromUserName> //发送者账号(openid)<CreateTime>123456789</CreateTime> //消息创建时间(整型)<MsgType><![CDATA[event]]></MsgType> //消息类型 event<Event><![CDATA[subscribe]]></Event> //事件类型(subscribe)<EventKey><![CDATA[qrscene_123123]]></EventKey> //事件KEY值,qrscene_为前缀,后面为二维码参数值<Ticket><![CDATA[TICKET]]></Ticket> //二维码ticke值,可以用来换取二维码图片</xml>
用户已关注时的事件推送
<xml><ToUserName><![CDATA[toUser]]></ToUserName> //开发者微信号<FromUserName><![CDATA[FromUser]]></FromUserName> //发送者账号(openid)<CreateTime>123456789</CreateTime> //消息创建时间<MsgType><![CDATA[event]]></MsgType> //消息类型event<Event><![CDATA[SCAN]]></Event> //事件类型 event<EventKey><![CDATA[SCENE_VALUE]]></EventKey> //事件key值,是一个32位无符号整数,即创建二维码时的二维码scene_id<Ticket><![CDATA[TICKET]]></Ticket> //二维码的ticke,可以用来换取二维码图片</xml>
3.3.2 我们要做些什么
我们需要在自己填写的URL接口中接收这个事件,然后拿到我们需要的东西做我们想干的事儿。因为我要实现的功能比较简单,只需要拿到scene_id即可,因为这是我要展示给用户看的订单数据。下面是我写的接收和处理部分,比较简单,主要看一下应该怎么接收微信推送的事件:
public function urlRedirect(){ $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = (string)$postObj->FromUserName; $EventKey = trim((string)$postObj->EventKey); $keyArray = explode("_", $EventKey); if (count($keyArray) == 1) { //已关注者扫描 $this->sendMessage($fromUsername, $EventKey); } else { //未关注者关注后推送事件 $this->sendMessage($fromUsername, $keyArray[1]); } }
我没有使用其他参数,只是根据不同的推送事件拿到我想要的订单ID,然后这时候其实相当于你在这里用公众号的客服在跟扫码的这个用户对话,上段代码中调用的sendMessage()是使用客户账号给扫码用户发送一个图文消息,因为我在拿scen_id的同时也拿到了用户的openid,可以利用这个给用户发送消息。
下面是 sendMessage() 方法:
//给用户发送图文消息,点击跳转到报价页面 public function sendMessage($openid,$orderId){ $url = str_replace('##TOKEN##', getWechatAccessToken(), C('WECHAT_SEND_MESSAGE')); $redirectUrl = str_replace("##ORDERID##", $orderId, str_replace("##OPENID##", $openid, C('WECHAT_REDIRECT_URL_PRE'))); $orderInfo = M('order')->where(array('orderid' => $orderId))->field(array('totalMoney', 'savedMoney', 'roomarea'))->find(); $description = str_replace("##ROOMAREA##", intval($orderInfo['roomarea'] * 1.25), C('WECHAT_MESSAGE_BRIEF')); $description = str_replace("##TOTALBUDGET##", $orderInfo['totalMoney'], $description); $description = str_replace("##MARKETBUDGET##", $orderInfo['totalMoney']+$orderInfo['savedMoney'], $description); $description = str_replace("##SAVEMONEY##", $orderInfo['savedMoney'], $description); $dataStr = '{"touser":"' . $openid . '","msgtype":"news","news":{"articles":[{"title":"' . C('WECHAT_MESSAGE_TITLE') . '","description":"' . $description . '","url":"' . $redirectUrl . '","picurl":"' . C('WECHAT_MESSAGE_PICURL') . '""}]}}'; api_notice_increment($url, $dataStr); }
其中 C('WECHAT_SEND_MESSAGE') = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=##TOKEN##' 至于下面的一大段str_replace,就是在组给用户发送的文字而已,需要注意$dataStr的格式,这里面要求JSON字符串比较严格,必须所有的字符串都用双引号括起来。微信接口对POST参数的限制真心严格。
下面是微信公众平台开发者文档中要求发送图文消息的POST data格式:
{ "touser":"OPENID", "msgtype":"news", "news":{ "articles": [ { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" }, { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" } ] } }
其中url是用户点击这个消息之后打开的地址,这个时候我就组了一个自己网站的地址,是一个get请求地址,里面携带参数是用户的openid和订单id,这样用户点击开图文消息就可以看到自己刚才下单的内容了,因为需要在网页上展示用户的微信头像和昵称,所以我把openid也放到参数里,在页面加载前先拿到用户的个人信息和订单数据,再展示网页。这样流程:用户未登录下单 -> 生成微信二维码 -> 用户扫码关注公众号 -> 查看订单详细信息 就完成了。而且因为这个图文消息打开后的链接携带的参数是这个用户的额openid和其下单的订单ID,不管分享到哪儿,用什么浏览器打开都是可以访问的,且展示的也是这个用户的头像和昵称信息,这也是我要实现的一个效果。
更多微信开发—带参数二维码的使用 相关文章请关注PHP中文网!