WeChat Mini Program Server API
Server-side Python SDK for WeChat (Weixin) Mini Programs. Handles the backend half of Mini Program interactions: login verification (jscode2session), access token management, template messages, and encrypted data decryption. The dominant community SDK is wechatpy — no official Tencent Python SDK exists. Mini Program frontend runs in WeChat's JavaScript runtime (WXML/WXSS); Python handles server-side API calls only.
Warnings
- breaking Phone number retrieval API changed in base library 2.21.2. Old pattern (encryptedData + iv AES decrypt using session_key) still works but is deprecated. New pattern: frontend button callback returns a `code`, server exchanges it via POST /wxa/business/getuserphonenumber. The two codes (wx.login code vs phone code) are NOT interchangeable.
- breaking getPhoneNumber and getRealtimePhoneNumber components are paid since August 28, 2023. Standard price: ¥0.03/call (quick verification) and ¥0.04/call (real-time verification). Each Mini Program account gets 1000 free calls for development. Production usage requires prepaid balance on WeChat Open Platform.
- breaking `unionid` is NOT always returned by jscode2session. It only appears if the Mini Program is bound to a WeChat Open Platform account AND the user has authorized it. Many tutorials assume unionid is always present, causing KeyError in production.
- breaking access_token is a global credential with a 2-hour TTL and a 2000 calls/day refresh limit. Calling getAccessToken on every request will exhaust the daily quota and lock out all users. wechatpy caches it in-process but does NOT share across multiple server instances.
- gotcha session_key must NEVER be sent to the frontend or logged. It is used server-side to decrypt sensitive user data. If session_key leaks, attackers can decrypt all encrypted user data. WeChat will invalidate session_key on wx.login() re-call.
- gotcha Phone number API requires Mini Program registered as non-individual entity with WeChat verification. Individual developer accounts (个人开发者) cannot access getPhoneNumber even with balance. Overseas entities (non-China business registration) are also blocked.
- gotcha wechatpy v1.8.18 is the last PyPI release and the package is effectively in maintenance mode (Snyk flags it as inactive). Core APIs remain functional but new WeChat features may not be supported.
- gotcha WeChatClient (for Official Accounts/MP) and WeChatMiniProgram (for Mini Programs) are different classes with different API surfaces. Official Account tutorials are the majority online — importing the wrong client causes silent failures or wrong endpoint calls.
Install
-
pip install 'wechatpy[cryptography]' -
pip install wechatpy
Imports
- WeChatMiniProgram
from wechatpy.miniprogram import WeChatMiniProgram
Quickstart
from wechatpy.miniprogram import WeChatMiniProgram
import requests
APPID = 'your_appid'
SECRET = 'your_appsecret'
# Initialize client
client = WeChatMiniProgram(APPID, SECRET)
# Step 1: Exchange wx.login() code for openid + session_key
# Frontend calls wx.login() and sends the code to your server
def login(js_code):
result = client.code_to_session(js_code)
# result = {'openid': '...', 'session_key': '...', 'unionid': '...' (if linked)}
openid = result['openid']
session_key = result['session_key']
# NEVER send session_key to frontend — generate your own custom token
return openid, session_key
# Step 2: Get phone number (NEW method, base library >= 2.21.2)
# Frontend button fires bindgetphonenumber event, returns e.detail.code
# Send that code to your server:
def get_phone_number(phone_code):
# phone_code is different from wx.login() code — do NOT mix them
resp = requests.post(
'https://api.weixin.qq.com/wxa/business/getuserphonenumber',
params={'access_token': client.access_token},
json={'code': phone_code}
)
data = resp.json()
return data['phone_info']['phoneNumber'] # e.g. '+8613800138000'
# Step 3: Global access_token (cache this — 2hr TTL, shared across all users)
print(client.access_token) # auto-fetched and cached by wechatpy