摘要:如果讀者對微信開發沒有一個主觀上的認識,那么建議讀者先研讀微信公眾平臺開發者文檔,然后再閱讀本文,效果更佳另外本文的分章節版本可以在八寶粥的博客找到。在中新建微信公眾號后臺配置在微信公眾號后臺配置和,然后提交驗證即可。
本文內容較多,包括微信接入、獲取微信用戶信息、微信支付、JSSDK配置參數獲取等部分。如果讀者對微信開發沒有一個主觀上的認識,那么建議讀者先研讀微信公眾平臺開發者文檔,然后再閱讀本文,效果更佳!另外本文的分章節版本可以在八寶粥的博客找到。
接入微信 Yii2后臺配置20160712-Update:微信開發的完整例子已經整理在Github,歡迎查看: yii2-wechat-demo。
1.在app/config/params.php中配置token參數
return [ //微信接入 "wechat" =>[ "token" => "your token", ], ];
2.在app/config/main.php中配置路由
因為接口模塊使用的RESTful API,所以需要定義路由規則。
"urlManager" => [ "enablePrettyUrl" => true, "enableStrictParsing" => true, "showScriptName" => false, "rules" => [ [ "class" => "yii estUrlRule", "controller" => "wechat", "extraPatterns" => [ "GET valid" => "valid", ], ], ], ],
3.在app/controllers中新建WechatController
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; } } } }微信公眾號后臺配置
在微信公眾號后臺配置URL和Token,然后提交驗證即可。
URL:http://app.demo.com/wechats/valid Token:your token獲取用戶信息 用戶表設計
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`);獲取用戶信息的相關接口
1.用戶授權接口:獲取access_token、openid等;獲取并保存用戶資料到數據庫
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.從微信獲取用戶資料
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.獲取用戶資料接口
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; }微信支付
1.微信支付接口:打包支付數據
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.接收微信發送的異步支付結果通知
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 ""; } else { //訂單狀態已更新,直接返回 return " "; } }
3.微信支付類 WechatPay.php
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 = "獲取JS-SDK的config參數"; foreach ($arr as $key => $val){ if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "" . $key . ">"; } else { $xml .= "<" . $key . ">" . $key . ">"; } } $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; } }
根據微信公眾平臺開發者文檔:
所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用(同一個url僅需調用一次,對于變化url的SPA的web app可在每次url變化時進行調用,目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。
即:
wx.config({ debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: "", // 必填,公眾號的唯一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: "", // 必填,生成簽名的隨機串 signature: "",// 必填,簽名,見附錄1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 });
1.微信支付類 WechatPay.php
$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.獲取config參數接口
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; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21760.html
摘要:極致的插件機制,系統內的系統,安裝和卸載不會對原來的系統產生影響強大的功能完全滿足各階段的需求,支持用戶多端訪問后臺微信前臺等,系統中的系統。多入口模式,多入口分為后臺前端,微信,對內接口,對外接口,不同的業務,不同的設備,進入不同的入口。 RageFrame 2.0 為二次開發而生,讓開發變得更簡單 項目地址:https://github.com/jianyan74/... 前言 這...
摘要:極致的插件機制,系統內的系統,安裝和卸載不會對原來的系統產生影響強大的功能完全滿足各階段的需求,支持用戶多端訪問后臺微信前臺等,系統中的系統。多入口模式,多入口分為后臺前端,微信,對內接口,對外接口,不同的業務,不同的設備,進入不同的入口。 RageFrame 2.0 為二次開發而生,讓開發變得更簡單 項目地址:https://github.com/jianyan74/... 前言 這...
摘要:多入口模式,多入口分為后臺前端,微信,其他或接口對接,不同的業務不同的設備進入不同的入口。對接微信公眾號,使用了一款優秀的微信非官方,系統內已集成了該,調用方式會在文檔說明,也可直接看其文檔進入深入開發。 RageFrame 為二次開發而生,讓開發變得更簡單。 前言 RageFrame項目創建于2016年4月16日,基于Yii2框架開發的應用開發引擎,目前正在成長中,目的是為了集成更多...
摘要:微信公眾號支付就是微信商城的一種支付方式,微信支付隨著微信的推廣使用也被廣泛應用。微信公眾平臺的地址是。代碼分析我們需要獲取到關注微信公眾號的人的。回調的方法使用以上就是我的微信支付。 序言 隨著微信被越來越多的人使用,微信商城成為如今的熱門。每一個商城都需要有自己的支付方式,微信商城也不例外。微信公眾號支付就是微信商城的一種支付方式,微信支付隨著微信的推廣使用也被廣泛應用。今天我主要...
閱讀 3027·2023-04-25 18:06
閱讀 3272·2021-11-22 09:34
閱讀 2857·2021-08-12 13:30
閱讀 2045·2019-08-30 15:44
閱讀 1661·2019-08-30 13:09
閱讀 1630·2019-08-30 12:45
閱讀 1715·2019-08-29 11:13
閱讀 3608·2019-08-28 17:51