前言
最近在調試微信相關的接口,但是由於微信官方出於安全的考慮,對於調用接口的域名有限制。微信授權與微信支付統一下單接口在本地可以通過更改 host 的方式來調試,微信服務器也能跳轉回來,但是微信支付異步通知這里;微信官方強制讓設置支付授權目錄,且是通過 ICP 備案的域名,因此不采取特殊手段,本地是無法接收到微信的異步通知回調請求的,只能部署到線上環境測試。
前置條件
為了解決這個問題,折騰了好幾天,才搞出來了,究其根本原因,還是對於 Nginx 不太熟悉。所以在此記錄一下。
內網轉發
如果想本地進行調試,並且想讓微信服務器請求回調回來,則本地必須要有一個外網域名,這里我們是用 Ngrok內網轉發 來實現;Ngrok 的配置就是將本地項目的端口映射到分配的外網域名,具體配置參考官網教程文檔,此處不再贅述。
我的配置是:
http://topn.free.ngrok.cc -> 127.0.0.1:8080
配置測試支付目錄
前面提到了,微信支付異步通知會對支付域名目錄有要求,因此,支付時的域名必須要在設置的支付域名目錄下。
首先需要在 微信商戶平台 中配置 商戶秘鑰,支付授權目錄。
這里支付授權目錄配置的是以后線上的支付授權目錄
http://pay.domain.com/wechat/public/
然后再加一條本地測試支付的臨時授權目錄,這個目錄最好在本地測試完成后,進行刪除。
http://pay.domain.com/testpay/
必知的 Nginx 語法
proxy_pass 后的 url 加不加 / 的區別
這里列舉 nginx 的 proxy_pass 語法,是為了下一步針對 nginx 的配置進行修改。
這里訪問 http://127.0.0.1/proxy/test.html
測試 proxy_pass 后面的 url 加與不加 / 的區別
server {
listen 80;
server_name 127.0.0.1;
<span class="hljs-attribute">location</span> /proxy/ {
<span class="hljs-attribute">proxy_pass</span> http://192.168.0.100/;
}
}
以上 location 會代理到 http://192.168.0.100/test.html 即相當於是絕對根路徑,則 Nginx 不會把 location 中的路徑部分代理走。
server {
listen 80;
server_name 127.0.0.1;
<span class="hljs-attribute">location</span> /proxy/ {
<span class="hljs-attribute">proxy_pass</span> http://192.168.0.100;
}
}
以上 location 會代理到 http://192.168.0.100/proxy/test.html 即相當於相對路徑。
代理支付域名到第三方域名
知道上一步 proxy_pass 后 / 的作用后,就開始來配置支付域名指向的服務器上的 nginx 的配置文件。
server {
listen 80;
server_name pay.domain.com;
<span class="hljs-attribute">location</span> /testpay/ {
<span class="hljs-attribute">proxy_set_header</span> Host vcmq.free.ngrok.cc;
<span class="hljs-attribute">proxy_pass</span> http://vcmq.free.ngrok.cc/wide/;
}
<span class="hljs-attribute">location</span> / {
<span class="hljs-attribute">proxy_pass</span> http://payServer;
}
}
配置中的 wide 是我項目的名稱;
注意:這里的 proxy_set_header Host 必須配置,否則進入 location 塊后,會提示 tunnel pay.domain.com not found
。
當訪問 pay.domain.com/testpay/create 微信統一下單接口時, 會代理到 http://vcmq.free.ngrok.cc/wide/create;
需要注意的是,在統一下單接口,設置 notify_url 的值要為配置的支付授權目錄,比如我的 http://pay.domain.com/testpay/notify,這個異步通知回調 URL 限定是 POST 請求,可以在異步回調方法打斷點,然后通過 postman 工具發送 post 請求到 http://pay.domain.com/testpay/notify,看是否可以正常進入斷點,如果正常進入斷點,恭喜你配置好了 Nginx 回調這一塊。
注意: 統一下單接口參數中提交的參數 notify_url ,如果鏈接無法訪問,商戶將無法接收到微信通知。
通知 url 必須為直接可訪問的 url ,不能攜帶參數。示例:notify_url:“https://pay.weixin.qq.com/wxpay/pay.action”
另外要注意,如果支付目錄中配置的是 https 的,那么 notify_url 也一定要保持一致是 https 的。
統一下單並完成支付完成后,微信服務器會請求統一下單接口中的 notify_url,經過服務器 nginx 進行代理后,會代理到 本地的內網轉發域名異步通知回調接口 http://vcmq.free.ngrok.cc/wide/notify, 從而達到了本地接收微信支付異步通知回調請求的目的。
如果地址不在支付授權目錄下,會提示當前 Url 未注冊。因為是代理過去,因此地址欄的地址不會改變,這也是不能簡單使用 nginx 的 rewrite 的原因。
如有疑問,可以聯系我。