Django 實作微信公眾號介面,驗證簽名通過,測試工具回傳 XML 格式正確,但實際公眾號回覆「暫時無法服務」。
微信要求:
application/xml 或 text/xml<?xml version="1.0" encoding="UTF-8"?>原程式碼問題:time.time() 回傳浮點數,需轉換:
'createTime': int(time.time()) # 必須為整數
# 正確排序方式:字典序
tmpList = [token, timestamp, nonce]
tmpList.sort() # 此處正確
tmpstr = ''.join(tmpList) # 直接拼接,無分隔符
tmpstr = hashlib.sha1(tmpstr.encode('utf-8')).hexdigest()
微信後台可設定三種模式:
若後台設為安全模式,明文回應會失效。請檢查公眾平台「開發設定」→「消息加解密方式」。
import logging
logger = logging.getLogger(__name__)
def post(self, request):
logger.info(f"WeChat Request Body: {request.body.decode('utf-8')}")
# ... 處理邏輯 ...
response_xml = render_to_string('reply_text.xml', context)
logger.info(f"WeChat Response XML: {response_xml}")
return HttpResponse(response_xml, content_type='application/xml')
def post(self, request):
str_xml = smart_str(request.body)
xml = etree.fromstring(str_xml)
toUserName = xml.find('ToUserName').text
fromUserName = xml.find('FromUserName').text
createTime = int(time.time()) # 修正:整數秒
msgType = xml.find('MsgType').text
content = xml.find('Content').text
context = {
'toUserName': fromUserName, # 注意:回覆時 To/From 互換
'fromUserName': toUserName,
'createTime': createTime,
'msgType': 'text', # 固定回覆文字訊息
'content': content,
}
return render(request, 'reply_text.xml', context, content_type='application/xml')
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<ToUserName><![CDATA[{{ toUserName }}]]></ToUserName>
<FromUserName><![CDATA[{{ fromUserName }}]]></FromUserName>
<CreateTime>{{ createTime }}</CreateTime>
<MsgType><![CDATA[{{ msgType }}]]></MsgType>
<Content><![CDATA[{{ content }}]]></Content>
</xml>
知乎完整解析:Django 微信公眾號開發避坑指南
微信公眾號開發細節決定成敗,嚴格遵循協議規範是成功關鍵。