微信 什麼是微信也不多說,跟前面的支付寶一樣的 微信支付 微信支付也有個沙箱環境,沙箱環境官方文檔 由文檔中那句很顯眼的話所得,即使是測試環境也需要真實的商戶號,所以這個就沒法想支付寶那樣用沙箱賬號來演示了。至於為什麼沒有沙箱賬號這就不得而知了,想接入微信支付商戶的朋友,請移步先註... ...
微信
什麼是微信也不多說,跟前面的支付寶一樣的
微信支付
微信支付也有個沙箱環境,沙箱環境官方文檔
由文檔中那句很顯眼的話所得,即使是測試環境也需要真實的商戶號,所以這個就沒法想支付寶那樣用沙箱賬號來演示了。至於為什麼沒有沙箱賬號這就不得而知了,想接入微信支付商戶的朋友,請移步先註冊為商戶,上傳相關資料審核後方可使用:傳送門
所以關於微信支付,由於這些種種限制,就不去註冊商戶了,所以支付方面本文在此略過,感興趣的朋友自己去研究了,我看微信的文檔也很淺顯易懂的
微信模板消息推送
因為微信的模板消息推送改版,現在需要認證的微信企業號才能玩,所以目前來說我們只能使用微信給的沙箱測試平臺了,傳送門
用你的微信登錄,之後會給我們自動生成一個id 和key:
還有一個測試的可用公眾賬號:
接著按微信官方給的文檔:模板消息推送
其實大概的流程就是這樣:
1.預設情況下,用戶的微信只和微信服務端有聯繫,且微信服務端里有用戶的唯一ID,而我們的平臺的目標是要通過公眾號給用戶發消息
2.但是預設用戶的微信和我們平臺的微信不相通的,如隔了一道牆
3.我們給用戶一個頁面,頁面上有我們的二維碼,讓用戶掃碼關註我們的公眾號
4.在第3步操作也是通過微信的服務端作為中間人完成的,且當用戶關註成功的同時,微信服務端會把用戶ID自動回傳(或者說回調)給我們平臺的公眾號
5.拿到用戶ID之後,我們的微信公眾號就可以給用戶推送消息了
其實步驟是挺簡單的,上面5步中,其實實際的業務邏輯只有第3,第4和第5三個步驟,且這幾個步驟里每個的請求url都需要通過微信服務端來完成,所以還需要再看下微信的官方文檔給我們解說的
前期準備:
1,修改地址:
還是剛纔那個申請測試賬號頁面,滑動下麵,找到網頁賬號這裡,點修改
看到的提示,寫得很清楚,我這裡只是作為測試而已,這個地址不能是127.0.0.1換回地址了,至少得是區域網地址,因為一會兒用手機微信測試時需要調用這個地址,所以你的手機得和電腦是同一個區域網段,當然真實的使用時是公網的地址
點擊確認之後,顯示通過安全檢測的話就配置成功了
2.還要創建一個模板,獲取一個模板id
點新增測試模板:添加模板時註意格式,比如下麵的{{first.DATA}},這個【.DATA】才是我們需要添加的數據,其他都不是,就好比Python中的字元串格式化一樣,做類比理解就很能懂了
按照文檔給的提示操作就行,提交之後如下,所以你如果填錯了,只能刪除重新添加,不能修改
3.作為接收信息的用戶微信號必須關註測試賬號:
4.如果有需要的話,設置js的sdk url
當然是要調用微信的sdk時才會用到這個
代碼實現
前面的準備工作准備好之後,開始寫代碼
不過,先通過微信的文檔,得知我們此時需要用的url:
1.綁定url:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
相關參數:
參數 |
必須 |
說明 |
appid |
是 |
公眾號的唯一標識(這個就是我們前面申請的) |
redirect_uri |
是 |
授權後重定向的回調鏈接地址(我們前面申請的) |
response_type |
是 |
返回類型,請填寫code |
scope |
是 |
應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且,即使在未關註的情況下,只要用戶授權,也能獲取其信息) |
state |
否 |
重定向後會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128位元組,該值會被微信原樣返回,我們可以將其進行比對,防止別人的攻擊。 |
#wechat_redirect |
否 |
直接在微信打開鏈接,可以不填此參數。做頁面302重定向時候,必須帶此參數 |
2.獲取token的url
https://api.weixin.qq.com/sns/oauth2/access_token
相關參數:
appid |
您的測試id號 |
secret |
您的測試id的secret |
code |
微信自動回傳的參數,用request.GET.get("code")獲取 |
grant_type |
authorization_code |
3.發送模板消息的介面
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
4.發送非模板,正文消息的url
https://api.weixin.qq.com/cgi-bin/message/custom/send
相關參數跟模板消息的參數一樣
真正的代碼實現
好的,開始碼代碼,乾!
創建一個名為WachatTest的django項目,app名就是app:
然後因為要生成二維碼,此處運用了qrcode.js的第三方js庫 文件下載:點我
根目錄創建static目錄,存放如下文件,wx.jpg就是剛纔那個測試微信公眾號的圖片,我把它下載下來並更名為wx.jpg了
url:
html:
settings:
還是配置文件部分,如果你啟動項目時提示ALLOW_HOSTS之類的錯誤,作如下更改:
views:
與模板相關的配置,註意與之前創建的模板對應
model,db_index=True的意思是自動在數據創建索引的意思
運行項目之前記得遷移資料庫,並寫入幾個數據作為測試
啟動項目,登錄再關註,不多說
登錄成功之後,綁定頁面,點擊按鈕之後,把這個測試的公眾號二維碼圖片轉成了帶有一些參數的url,然後qrcode把這個帶有參數的url轉成了二維碼:
我用一個微信號測試掃碼之後(前提必須先關註那個微信公眾測試號才能授權),點擊允許
然後會跳轉到這個界面,表示成功授權
現在再做最終的模板消息發送,訪問/sendmsg:
查看手機端信息,得到的信息正好是我們之前設置的
大概的流程就走完了,因為我只是測試,沒有做得多麼高大上,其實比如那個模板消息,可以根據不同的用戶發不同的數據,或者這段數據直接搞一個form表單,讓非開發人員也可以使用它,點擊發送就行了,還有上面說的那個當前用戶的問題,只給當前用戶發,不給沒有操作的人發,或者定向群發啥啥的,反正主要的開發邏輯就這些,其他的隨便玩,玩出花來都可以
微信官方的全部流程:傳送門
相關的代碼:
import hashlib from django.db import models class UserInfo(models.Model): username = models.CharField("用戶名", max_length=64, unique=True) password = models.CharField("密碼", max_length=64) uid = models.CharField(verbose_name='個人唯一ID', max_length=64, unique=True) wx_id = models.CharField(verbose_name="微信ID", max_length=128, blank=True, null=True, db_index=True) def save(self, *args, **kwargs): # 創建用戶時,為用戶自動生成個人唯一ID if not self.pk: m = hashlib.md5() m.update(self.username.encode(encoding="utf-8")) self.uid = m.hexdigest() super(UserInfo, self).save(*args, **kwargs)models
from django.contrib import admin from django.urls import path from app import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('bind/', views.bind), path('bind_qrcode/', views.bindQrcode), path('callback/', views.callback), path('sendmsg/', views.sendmsg) ]urls
from django.shortcuts import render, HttpResponse, redirect from django.http import JsonResponse from django.conf import settings import requests from app import models import json # Create your views here. def login(request): """ 用戶登錄 :param request: :return: """ # models.UserInfo.objects.create(username='luffy',password=123) if request.method == "POST": user = request.POST.get('user') pwd = request.POST.get('pwd') obj = models.UserInfo.objects.filter(username=user, password=pwd).first() if obj: request.session['user_info'] = {'id': obj.id, 'name': obj.username, 'uid': obj.uid} return redirect('/bind/') else: return render(request, 'login.html') def bind(request): """用戶綁定頁面""" return render(request, 'auth.html') def bindQrcode(request): """生成二維碼""" ret = {'code': 1000} try: access_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={appid}&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_userinfo&state={state}#wechat_redirect" access_url = access_url.format( appid=settings.WECHAT_CONFIG["app_id"], redirect_uri=settings.WECHAT_CONFIG["redirect_uri"], state=request.session['user_info']['uid'] ) ret['data'] = access_url except Exception as e: ret['code'] = 1001 ret['msg'] = str(e) return JsonResponse(ret) def callback(request): """ 用戶在手機微信上掃碼後,微信自動調用該方法。 用於獲取掃碼用戶的唯一ID,以後用於給他推送消息。 :param request: :return: """ code = request.GET.get("code") # 用戶UID state = request.GET.get("state") # 獲取該用戶openId(用戶唯一,用於給用戶發送消息) res = requests.get( url="https://api.weixin.qq.com/sns/oauth2/access_token", params={ "appid": settings.WECHAT_CONFIG["app_id"], "secret": settings.WECHAT_CONFIG["appsecret"], "code": code, "grant_type": 'authorization_code', } ).json() # 獲取的到openid表示用戶授權成功 openid = res.get("openid") if openid: models.UserInfo.objects.filter(uid=state).update(wx_id=openid) response = "<h1>授權成功 %s </h1>" % openid else: response = "<h1>用戶掃碼之後,手機上的提示</h1>" return HttpResponse(response) def get_access_token(): """獲取token""" result = requests.get( url='https://api.weixin.qq.com/cgi-bin/token', params={ "grant_type": "client_credential", "appid": settings.WECHAT_CONFIG['app_id'], "secret": settings.WECHAT_CONFIG['appsecret'], } ).json() if result.get('access_token'): access_token = result.get('access_token') else: access_token = None return access_token def send_content_msg(user_id, access_token): """內容消息發送""" body = { 'touser': user_id, 'msgtype': 'text', 'text': { 'content': '內容。。。。。不是模板消息' } } response = requests.post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', params={ 'access_token': access_token }, data=bytes(json.dumps(body, ensure_ascii=False), encoding='utf-8') ) result = response.json() return result def send_template_msg(user_id, access_token): """模板消息發送""" result = requests.post( url='https://api.weixin.qq.com/cgi-bin/message/template/send', params={ 'access_token': access_token }, json={ "touser": user_id, "template_id": settings.WECHAT_CONFIG['template_id'], "data": { "first": { "value": "微信模板頁面發送消息", "color": "#173177" }, "kw1": { "value": "卧槽調這個參數搞了有點久", "color":"#173177" }, "kw2": { "value": "可不是咋地" }, "kw3": { "value": "就看這次能不能成功了" }, } } ) result = result.json() return result def sendmsg(requet): access_token = get_access_token() # 這裡由於我本來就只有一個數據,所以直接寫死了,真實的開發當然是用當前登錄用戶掃碼關註的用戶對應 userobj = models.UserInfo.objects.filter(id=1).first() # 發送模板消息 result = send_template_msg(userobj.wx_id, access_token) # 發送正文消息 # result = send_content_msg(userobj.wx_id, access_token) if result.get('errcode') == 0: return HttpResponse('發送成功') return HttpResponse('發送失敗')views
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶授權</title> <script src="{% static "js/jquery.min.js" %}"></script> <script src="{% static "js/jquery.qrcode.min.js" %}"></script> <script src="{% static "js/qrcode.js" %}"></script> </head> <body> <input onclick="userauth() " type="button" value="關註我們有驚喜哦"> <div> <img style="height: 100px;width: 100px" src="{% static 'img/wx.jpg' %}"> </div> <div id="qrcode" style="width: 250px;height: 250px;background-color: white;margin: 100px auto;"></div> <script type="text/javascript"> function userauth() { $.ajax({ url: '/bind_qrcode/', type: 'GET', success: function (data) { console.log(data); $('#qrcode').empty().qrcode({text: data.data}); } }); } </script> </body> </html>html:auth.html
ALLOWED_HOSTS = ['192.168.0.8'] STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) # ############# 微信 ############## WECHAT_CONFIG = { 'app_id': '您的微信app測試id', # 微信給的測試app id 'appsecret': '您的微信app測試secret', # 微信給的測試app sercret 'redirect_uri': 'http://您的功能變數名稱地址/callback/', # 用戶關註之後微信回傳地址 'template_id': "您的微信測試模板id" # 模板id }settings主要的改動部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="post"> {% csrf_token %} <input type="text" name="user" placeholder="用戶名"> <input type="password" name="pwd" placeholder="密碼"> <input type="submit" value="登錄"> </form> </body> </html>html:login.html
總結:
感覺還是挺簡單的,就是對於剛接觸的朋友來說的話,可能不習慣去看第三方的API文檔,也不知道怎麼下手,多研究就行了,熟練了就很快了
微信支付那個,我沒有企業相關材料,而且就算有,也不敢那麼隨意的就為了做個測試就去申請什麼的,所以相關的還是看官方文檔吧