import httpx from . import config class WeChatError(Exception): pass def code_to_openid(code): resp = httpx.get( "https://api.weixin.qq.com/sns/jscode2session", params={ "appid": config.WECHAT_APPID, "secret": config.WECHAT_SECRET, "js_code": code, "grant_type": "authorization_code", }, timeout=10, ) data = resp.json() if data.get("errcode") or "openid" not in data: raise WeChatError(data.get("errmsg", "无效的登录 code")) return data["openid"] def _get_access_token(): resp = httpx.get( "https://api.weixin.qq.com/cgi-bin/token", params={ "grant_type": "client_credential", "appid": config.WECHAT_APPID, "secret": config.WECHAT_SECRET, }, timeout=10, ) data = resp.json() if not data.get("access_token"): raise WeChatError(data.get("errmsg", "获取微信 access_token 失败")) return data["access_token"] def get_phone_number(phone_code): access_token = _get_access_token() resp = httpx.post( "https://api.weixin.qq.com/wxa/business/getuserphonenumber", params={"access_token": access_token}, json={"code": phone_code}, timeout=10, ) data = resp.json() if data.get("errcode") != 0: raise WeChatError(data.get("errmsg", "获取手机号失败")) phone_info = data.get("phone_info") or {} return phone_info.get("purePhoneNumber") or phone_info.get("phoneNumber")