


Yii2.0 implements backend development of WeChat public accounts
This article contains a lot of content, including WeChat access, obtaining WeChat user information, WeChat payment, and obtaining JSSDK configuration parameters. If the reader does not have a subjective understanding of WeChat development, it is recommended that the reader first study WeChat Public Platform Developer Documentation and then read this article for better results! In addition, the chapter-by-section version of this article can be found on the blog of Babao Porridge.
Access WeChat
Yii2 background configuration
1. Configure token parameters in app/config/params.php
return [ //微信接入 'wechat' =>[ 'token' => 'your token', ], ];
2. Configure routing in app/config/main.php
Because the interface module uses RESTful API, you need to define routing rules.
'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ [ 'class' => 'yii\rest\UrlRule', 'controller' => 'wechat', 'extraPatterns' => [ 'GET valid' => 'valid', ], ], ], ],
3. Create a new WechatController in app/controllers
<?php namespace api\controllers; use Yii; use yii\rest\ActiveController; class WechatController extends ActiveController { public $modelClass = ''; public function actionValid() { $echoStr = $_GET["echostr"]; $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; //valid signature , option if($this->checkSignature($signature,$timestamp,$nonce)){ echo $echoStr; } } private function checkSignature($signature,$timestamp,$nonce) { // you must define TOKEN by yourself $token = Yii::$app->params['wechat']['token']; if (!$token) { echo 'TOKEN is not defined!'; } else { $tmpArr = array($token, $timestamp, $nonce); // use SORT_STRING rule sort($tmpArr, SORT_STRING); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } }
WeChat public account background configuration
Configure the URL and Token in the WeChat public account background, and then submit for verification.
URL:http://app.demo.com/wechats/valid Token:your token
Getting user information
User table design
CREATE TABLE `wechat_user` ( `id` int(11) NOT NULL, `openid` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `nickname` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '微信昵称', `sex` tinyint(4) NOT NULL COMMENT '性别', `headimgurl` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '头像', `country` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '国家', `province` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '省份', `city` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '城市', `access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `refresh_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ALTER TABLE `wechat_user` ADD PRIMARY KEY (`id`);
Related interfaces for getting user information
1. User authorization interface: getting access_token, openid, etc.; Obtain and save user information to the database
public function actionAccesstoken() { $code = $_GET["code"]; $state = $_GET["state"]; $appid = Yii::$app->params['wechat']['appid']; $appsecret = Yii::$app->params['wechat']['appsecret']; $request_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$appsecret.'&code='.$code.'&grant_type=authorization_code'; //初始化一个curl会话 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $request_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); $result = $this->response($result); //获取token和openid成功,数据解析 $access_token = $result['access_token']; $refresh_token = $result['refresh_token']; $openid = $result['openid']; //请求微信接口,获取用户信息 $userInfo = $this->getUserInfo($access_token,$openid); $user_check = WechatUser::find()->where(['openid'=>$openid])->one(); if ($user_check) { //更新用户资料 } else { //保存用户资料 } //前端网页的重定向 if ($openid) { return $this->redirect($state.$openid); } else { return $this->redirect($state); } }
2. Obtain user information from WeChat
public function getUserInfo($access_token,$openid) { $request_url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN'; //初始化一个curl会话 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $request_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); $result = $this->response($result); return $result; }
3. Obtain user information interface
public function actionUserinfo() { if(isset($_REQUEST["openid"])){ $openid = $_REQUEST["openid"]; $user = WechatUser::find()->where(['openid'=>$openid])->one(); if ($user) { $result['error'] = 0; $result['msg'] = '获取成功'; $result['user'] = $user; } else { $result['error'] = 1; $result['msg'] = '没有该用户'; } } else { $result['error'] = 1; $result['msg'] = 'openid为空'; } return $result; }
WeChat payment
1 .WeChat payment interface: packaged payment data
public function actionPay(){ if(isset($_REQUEST["uid"])&&isset($_REQUEST["oid"])&&isset($_REQUEST["totalFee"])){ //uid、oid、totalFee $uid = $_REQUEST["uid"]; $oid = $_REQUEST["oid"]; $totalFee = $_REQUEST["totalFee"]; $timestamp = time(); //微信支付参数 $appid = Yii::$app->params['wechat']['appid']; $mchid = Yii::$app->params['wechat']['mchid']; $key = Yii::$app->params['wechat']['key']; $notifyUrl = Yii::$app->params['wechat']['notifyUrl']; //支付打包 $wx_pay = new WechatPay($mchid, $appid, $key); $package = $wx_pay->createJsBizPackage($uid, $totalFee, $oid, $notifyUrl, $timestamp); $result['error'] = 0; $result['msg'] = '支付打包成功'; $result['package'] = $package; return $result; }else{ $result['error'] = 1; $result['msg'] = '请求参数错误'; } return $result; }
2. Receive asynchronous payment result notification sent by WeChat
public function actionNotify(){ $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); // if ($postObj === false) { die('parse xml error'); } if ($postObj->return_code != 'SUCCESS') { die($postObj->return_msg); } if ($postObj->result_code != 'SUCCESS') { die($postObj->err_code); } //微信支付参数 $appid = Yii::$app->params['wechat']['appid']; $mchid = Yii::$app->params['wechat']['mchid']; $key = Yii::$app->params['wechat']['key']; $wx_pay = new WechatPay($mchid, $appid, $key); //验证签名 $arr = (array)$postObj; unset($arr['sign']); if ($wx_pay->getSign($arr, $key) != $postObj->sign) { die("签名错误"); } //支付处理正确-判断是否已处理过支付状态 $orders = Order::find()->where(['uid'=>$postObj->openid, 'oid'=>$postObj->out_trade_no, 'status' => 0])->all(); if(count($orders) > 0){ //更新订单状态 foreach ($orders as $order) { //更新订单 $order['status'] = 1; $order->update(); } return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; } else { //订单状态已更新,直接返回 return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; } }
3. WeChat payment class WechatPay.php
<?php namespace api\sdk; use Yii; class WechatPay { protected $mchid; protected $appid; protected $key; public function construct($mchid, $appid, $key){ $this->mchid = $mchid; $this->appid = $appid; $this->key = $key; } public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp){ $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->key, ); $unified = array( 'appid' => $config['appid'], 'attach' => '支付', 'body' => $orderName, 'mch_id' => $config['mch_id'], 'nonce_str' => self::createNonceStr(), 'notify_url' => $notifyUrl, 'openid' => $openid, 'out_trade_no' => $outTradeNo, 'spbill_create_ip' => '127.0.0.1', 'total_fee' => intval($totalFee * 100), 'trade_type' => 'JSAPI', ); $unified['sign'] = self::getSign($unified, $config['key']); $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($unifiedOrder === false) { die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { die($unifiedOrder->err_code); } $arr = array( "appId" => $config['appid'], "timeStamp" => $timestamp, "nonceStr" => self::createNonceStr(), "package" => "prepay_id=" . $unifiedOrder->prepay_id, "signType" => 'MD5', ); $arr['paySign'] = self::getSign($arr, $config['key']); return $arr; } public static function curlGet($url = '', $options = array()){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function curlPost($url = '', $postData = '', $options = array()){ if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16){ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i<$length; $i++){ $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public static 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; } public static function getSign($params, $key){ ksort($params, SORT_STRING); $unSignParaString = self::formatQueryParaMap($params, false); $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); return $signStr; } protected static function formatQueryParaMap($paraMap, $urlEncode = false){ $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v){ if (null != $v && "null" != $v) { if ($urlEncode) { $v = urlencode($v); } $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff)>0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } }
Get JS- SDK's config parameters
According to the WeChat public platform developer documentation:
All pages that need to use JS-SDK must first inject configuration information, otherwise it will not be called (the same URL only needs to be called once , the SPA web app that changes the url can be called every time the url changes. Currently Android WeChat client does not support the new H5 feature of pushState, so using pushState to implement the web app page will cause signatures Failed, this problem will be fixed in Android 6.2).
That is:
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });
1. Wechat payment class WechatPay.php
<?php namespace api\sdk; use Yii; class WechatPay { public function getSignPackage($url) { $jsapiTicket = self::getJsApiTicket(); $timestamp = time(); $nonceStr = self::createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=".$jsapiTicket."&noncestr=".$nonceStr."×tamp=".$timestamp."&url=".$url; $signature = sha1($string); $signPackage = array( "appId" => $this->appid, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } public static function getJsApiTicket() { //使用Redis缓存 jsapi_ticket $redis = Yii::$app->redis; $redis_ticket = $redis->get('wechat:jsapi_ticket'); if ($redis_ticket) { $ticket = $redis_ticket; } else { $accessToken = self::getAccessToken(); $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$accessToken; $res = json_decode(self::curlGet($url)); $ticket = $res->ticket; if ($ticket) { $redis->set('wechat:jsapi_ticket', $ticket); $redis->expire('wechat:jsapi_ticket', 7000); } } return $ticket; } public static function getAccessToken() { //使用Redis缓存 access_token $redis = Yii::$app->redis; $redis_token = $redis->get('wechat:access_token'); if ($redis_token) { $access_token = $redis_token; } else { $appid = Yii::$app->params['wechat']['appid']; $appsecret = Yii::$app->params['wechat']['appsecret']; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret; $res = json_decode(self::curlGet($url)); $access_token = $res->access_token; if ($access_token) { $redis->set('wechat:access_token', $access_token); $redis->expire('wechat:access_token', 7000); } } return $access_token; } public static function curlGet($url = '', $options = array()){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function curlPost($url = '', $postData = '', $options = array()){ if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16){ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i<$length; $i++){ $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } }
2. Get config parameter interface
public function actionConfig(){ if (isset($_REQUEST['url'])) { $url = $_REQUEST['url']; //微信支付参数 $appid = Yii::$app->params['wechat']['appid']; $mchid = Yii::$app->params['wechat']['mchid']; $key = Yii::$app->params['wechat']['key']; $wx_pay = new WechatPay($mchid, $appid, $key); $package = $wx_pay->getSignPackage($url); $result['error'] = 0; $result['msg'] = '获取成功'; $result['config'] = $package; } else { $result['error'] = 1; $result['msg'] = '参数错误'; } return $result; }
The above is the detailed content of Yii2.0 implements backend development of WeChat public accounts. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Scrapy implements article crawling and analysis of WeChat public accounts. WeChat is a popular social media application in recent years, and the public accounts operated in it also play a very important role. As we all know, WeChat public accounts are an ocean of information and knowledge, because each public account can publish articles, graphic messages and other information. This information can be widely used in many fields, such as media reports, academic research, etc. So, this article will introduce how to use the Scrapy framework to crawl and analyze WeChat public account articles. Scr

The difference between WeChat public account authentication and non-authentication lies in the authentication logo, function permissions, push frequency, interface permissions and user trust. Detailed introduction: 1. Certification logo. Certified public accounts will obtain the official certification logo, which is the blue V logo. This logo can increase the credibility and authority of the public account and make it easier for users to identify the real official public account; 2. Function permissions. Certified public accounts have more functions and permissions than uncertified public accounts. For example, certified public accounts can apply to activate the WeChat payment function to achieve online payment and commercial operations, etc.

Python is an elegant programming language with powerful data processing and web crawling capabilities. In this digital era, the Internet is filled with a large amount of data, and crawlers have become an important means of obtaining data. Therefore, Python crawlers are widely used in data analysis and mining. In this article, we will introduce how to use Python crawler to obtain WeChat public account article information. WeChat official account is a popular social media platform for publishing articles online and is an important tool for promotion and marketing of many companies and self-media.

How to use Laravel to develop an online ordering system based on WeChat official accounts. With the widespread use of WeChat official accounts, more and more companies are beginning to use them as an important channel for online marketing. In the catering industry, developing an online ordering system based on WeChat public accounts can improve the efficiency and sales of enterprises. This article will introduce how to use the Laravel framework to develop such a system and provide specific code examples. Project preparation First, you need to ensure that the Laravel framework has been installed in the local environment. OK

In today's Internet era, WeChat official accounts have become an important marketing channel for more and more companies. If you want your WeChat official account to implement more functions, you often need to write corresponding interfaces. This article will use PHP language as an example to introduce how to build a WeChat public account API interface. 1. Preparation Before writing the WeChat public account API interface, the developer needs to have a WeChat public account and apply for developer interface permissions in the WeChat public platform. After the application is successful, you can obtain the relevant developer AppID and AppSe

The public account can not only post one article per day, but can publish up to eight articles at a time. How to publish multiple articles: 1. Click "Material Management" on the left, and then click "New Graphic and Text Material" to start editing. First article; 2. After editing the first article, click the + sign under the first article on the left and click "Graphic Message" to edit the second article; 3. After finishing multiple images and text, click " Save and send in bulk" to complete the publishing of multiple articles.

With the popularity of the Internet and the widespread use of mobile devices, WeChat official accounts have become an indispensable part of corporate marketing. Through WeChat public accounts, companies can easily interact with users, promote products and services, and increase brand awareness. In order to better develop WeChat public account applications, more and more developers and companies choose to use Go language to build WeChat public account applications. Go language is a programming language developed by Google. Its syntax is concise and suitable for building high-performance, high-concurrency real-time applications. In terms of ease of use and

With the gradual popularity of WeChat public accounts in social networks, more and more developers have begun to get involved in the field of WeChat public account development. Among them, PHP, as a common back-end programming language, has also begun to be widely used in the development of WeChat public accounts. This article will introduce the basic knowledge and common techniques of PHP in WeChat public account development. 1. Basics of PHP and WeChat public account development WeChat public account development WeChat public account refers to an Internet application based on the WeChat platform, which can provide users with different types of services and content, such as information push
