開通微信支付支付產品
首先要在微信支付申請成為 微信支付商戶。
選擇開通具體的支付產品
成為微信支付商戶后在管理后台選擇微信支付中的具體支付產品並申請開通如 JSAPI 。
將支付商戶與公眾號關聯
這一步是可選的,是由具體的支付產品是否需要與公眾號交互決定,如本例中的JSAPI就需要公眾號的支持。擁有支付功能的商戶需要與某公眾號關聯,才能互相獲取相應權限和數據,如JSAPI就需要通過關聯的公眾號獲取用戶 openid 用於識別用戶。關聯的方法是進入商戶后台 APPID授權管理 頁面,新增提交要關聯某公眾號申請,需要輸入的 APPID 要從被關聯的公眾號處獲得。申請提交后該公眾號在 微信支付 商戶號管理 待關聯商戶號 處進行確認授權。
一通頭疼的配置( !!-- )
管理后台配置
-
支付授權目錄
進入商戶后台 開發配置 支付配置,新增 公眾號支付 的支付授權目錄,該目錄是商家的后台(開發)服務也就是向微信支付發起請求的服務器的程序運行目錄,支持路徑,但不支持自定義端口。應設置為接口所在目錄並以/結尾,即如果接口完整路徑為 http://domain/wxpay/jsapi.php 那該目錄應該被設置為 http://domain/wxpay/ 而不應該是其它任何形式。
-
公眾號接口權限
進入公眾號后台,進入 設置 公眾號設置 功能設置 網頁授權域名,將網頁授權域名按官方指導設置為開發服務器上允許獲取微信用戶 openid 的域名,也就是微信授權數據回調要訪問的域名,只有先在微信這兒登了記的域名微信才會向其傳輸數據,相當於白名單。本例中,將目錄設置為 wxpay.txxxt.com,並將該頁面中微信提供的驗證文件按要求放到目錄下,即可正確設置。可以通過查看 開發 接口權限 網頁授權獲取用戶基本信息 的顯示結果判斷是否設置完畢。
-
用於開發調試的微信號要關注該公眾號
-
在公眾號內綁定開發人員微信號
進入該公眾號的管理后台,開發 開發者工具 web開發者工具 頁面中,點擊 綁定開發者微信號 將關注了該公眾號的開發所用的微信號添加到列表中,在使用 web開發者工具 時用被綁定的微信號登錄開發者工具,將可以獲取到相關數據,如 openid,否則無法獲取,因為公眾號不認識當前調用它的人。
開發環境准備
-
Web(H5+后端接口)可以使用任何習慣的工具開發即可
-
下載 微信web開發者工具
在開發/調試中,涉及到微信Api調用(訪問微信服務器)的,均需使用 微信web開發者工具 的公眾號網頁功能訪問要調試的頁面,不能使用普通瀏覽器。因為 開發者工具 具有普通瀏覽器沒有的微信Api特性。
-
本例中項目路徑 http://wxpay.txxxt.com/jsapi/,getCode.php 接口創建獲取 code 的完整鏈接並發出請求,codeCallback.php 接口用於接收從微信發出的回調,成功將包含 code 的值,log.php 記錄日志,jsapi_access_log.log 為日志文件。PHP 作為接口開發語言,使用 微信web開發者工具 公眾號網頁調試功能訪問接口跟蹤結果。
開發實踐
第一步,用戶同意授權,獲取 code
code 是用來取得 openid 的鑰匙,先訪問微信指定的api取得 code,再拿 code 去換取 openid 是第一步要做的事情。
獲取 code 只需按照微信給出的固定訪問方式,拼接參數,請求指定接口,如無錯誤即可獲得,詳見下
這是微信的標准接口,我們需要處理里邊幾個參數
- appid,必填,在 微信公眾平台 基本配置 公眾號開發信息 開發者ID(APPID) 處獲取
- redirect_uri,必填,urlencode處理,如參數無誤微信接口將跳轉回調此地址,並附帶上結果參數,詳見下方 返回值 說明
- response_type,必填,返回類型,固定填寫字符串 code
- scope,必填,應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且, 即使在未關注的情況下,只要用戶授權,也能獲取其信息 )
- state,選填,開發者自定義參數,可以填寫a-zA-Z0-9,最多128字節,重定向后會帶上
- #wechat_redirect,必填,無論直接打開還是做頁面302重定向,必須帶此參數
按微信要求,除參數名和參數值要正確填寫外,順序也不可更改,否則請求將失敗,拼接完整請求並通過header方式訪問見下例
//header('content-type:application:json;charset=utf8');
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET');
header('Content-type: text/html; charset=utf-8');
$appId = ""; // 此處填寫公眾號 appid
$redirectUrl = "http://wxpay.txxxt.com/jsapi/openIdRedirect.php"; //此處填寫回調地址
$state = strval(time()); // 模擬自定義 state 參數
$baseUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?";
//拼接字符串得到完整接口地址,要保證參數順序與官方接口示例一致
$requestUrl = $baseUrl;
$requestUrl = $requestUrl."appid=".$appId;
$requestUrl = $requestUrl."&redirect_uri=".urlencode($redirectUrl);
$requestUrl = $requestUrl."&response_type=code&scope=snsapi_base"; // 不調用授權頁的方式
$requestUrl = $requestUrl."&state=".$state;
$requestUrl = $requestUrl."#wechat_redirect";
header("Location: $requestUrl"); //返回並直接跳轉到拼接完成的接口地址去
exit();
看一個拼接好的地址樣例
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcc70xxxxxxxxxxbbf&redirect_uri=http%3A%2F%2Fwxpay.txxxt.com%2Fjsapi%2FopenIdRedirect.php&response_type=code&scope=snsapi_base&state=1561360134#wechat_redirect
返回值說明 接口訪問成功的話,微信會根據 redirect_uri 回調如下
http://wxpay.txxxt.com/jsapi/openIdRedirect.php?code=081vlfXQ11LXM11TiPTQ19n7XQ1vlfXq&state=xxxxxx
接收回調的接口要有能處理 code 的能力,詳見下
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET');
header('Content-type: text/html; charset=utf-8');
$code = isset($_GET['code']) ? $_GET['code'] : "";
$state = isset($_GET['state']) ? $_GET['state'] : "";
if($code == ""){
echo("獲取失敗,人家沒給有效的 code");
} else {
echo("獲取成功,拿到了 code");
}
處理回調的核心邏輯其實很簡單,就是判斷 code 的有效性,有值就對了,否則就參照官方文檔的錯誤碼檢查問題原因。回顧一下剛才的過程
- 使用web開發者工具訪問 getCode.php 接口,拼接完整請求地址,獲得 code
- 訪問成功微信回調
- 回調接口記錄了微信回調結果,查看日志,的確收到了 code 值
第二步,AppID + AppSecret + code 獲取 openid
首先,通過公眾號的 微信公眾平台 開發 基本配置 開發者ID 開發者密碼(AppSecret) IP白名單 ,獲取 AppID 和 AppSecret 兩個關鍵信息(APPID第一步已經獲得),需要注意的是,雖然微信的官方Wiki教程中並沒有提到設置IP白名單,但在設置 AppSecret 時是被提示需要一並設置的。
按開發文檔要求拼接參數,請求以下鏈接獲取access_token
四個參數均為必填項,其中 grant_type 的值 authorization_code 為固定值,代碼示例如下
******http
第一步將獲取到的 code = 011L1Tzo16tbFj0L7zAo1riQzo1L1Tzm 拼接完整
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxccxxxxxxxxxbbf&secret=2axxxxxxxxxxxxxxxxxx22&code=011L1Tzo16tbFj0L7zAo1riQzo1L1Tzm&grant_type=authorization_code
在 code 有效期內請求該接口獲得響應結果,成功返回JSON如下
{
"access_token": "22_sAk0YqHOr8f71n0WYGs8jXkdOqgpl_b4Yag3KMStE1oTPJRHjSxdDVEH6E0Ma_WdQ6gflPB5Tkr0Rmpv0VK5Bw",
"expires_in": 7200,
"refresh_token": "22_VU66fwGFZtq9XpX9s0r0k0d5p4zKQhJ-D_QnQiIo2BMfzMOzPaiVfPfCOWBGalWZtKsevxqcmgUud9zATlc5Xg",
"openid": "oHxxxxxxxxxxxxxxxxxxmg",
"scope": "snsapi_base"
}
錯誤將返回
{"errcode":40029,"errmsg":"invalid code"}
至此,snsapi_base 方式獲取 openid 的過程已經結束,下一篇將講述如何使用 openid 請求預支付交易標識。