微信小程序调用手册
兑换用户同意后的手机号
消费手机号按钮返回的一次性 code,并校验 OpenID 与小程序归属;只输出脱敏结果。
← 返回平台功能接入准备
- 小程序为已认证非个人主体,符合地域与类目要求,并有手机号能力可用额度。
- 使用普通 HTTPS 调用模式;若后台启用 API 加密,需先按官方方案适配加密、签名与验签。
- 先完成后台 token 获取与用户登录关联。手机号按钮 code 与 wx.login code 不相同。
准备环境变量
示例值需要替换为自己的凭证或资源 ID。代码在本机或服务端运行;密钥不应放进公开网页。
WX_MINI_ACCESS_TOKEN- 同一小程序的后台 token,来自本平台的 stable-token 手册。
WX_MINI_APP_ID- 自有小程序 AppID,不是公众号 AppID。
WX_MINI_PHONE_CODE- 来自手机号按钮 bindgetphonenumber 回调,有效 5 分钟且只能消费一次。
WX_MINI_OPENID- 与手机号按钮操作属于同一用户,作为服务端绑定关系校验。
export WX_MINI_ACCESS_TOKEN='replace_with_current_backend_token'
export WX_MINI_APP_ID='wx_replace_with_your_miniprogram_appid'
export WX_MINI_PHONE_CODE='replace_with_phone_button_code'
export WX_MINI_OPENID='replace_with_same_user_openid'以上 export 适用于 macOS / Linux 的终端。按调用步骤保存代码文件,再在同一终端执行。
调用步骤
- 01
小程序页面放置 <button open-type="getPhoneNumber" bindgetphonenumber="onPhone"> 并处理用户同意后的 e.detail.code。
- 02
把该 code 经自己的服务交给后台,并设置 WX_MINI_PHONE_CODE、该用户的 OpenID、小程序 AppID 和后台 token。
- 03
运行下方服务端代码,校验返回 watermark.appid;业务按授权目的处理手机号,本例只显示脱敏结果。
调用 01
校验并换取手机号
openid 参数用于核对 code 对应用户,不接受任意用户的手机号查询。
POST
https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${WX_MINI_ACCESS_TOKEN}请求头
Content-Typeapplication/json
参数说明
参数表可左右滑动,查看完整说明。
| 字段 / 位置 | 类型 / 必填 | 说明 |
|---|---|---|
access_tokenQuery | string必填 | 当前小程序后台 token。 |
code请求体 | string必填 | 手机号按钮提供的动态凭证,不是登录 code。 |
openid请求体 | string可选 | 可选绑定校验;本例必须设置同一用户 OpenID。 |
调用代码
替换示例 ID 与请求体内容后运行。
// Node.js 22+,保存为 request.mjs,环境变量在同一终端设置。
const required = name => {
const value = process.env[name];
if (!value) throw new Error('缺少环境变量 ' + name);
return value;
};
async function request(url, body) {
const response = await fetch(url, {
method: body === undefined ? 'GET' : 'POST',
headers: { 'Content-Type': 'application/json' },
...(body === undefined ? {} : { body: JSON.stringify(body) }),
redirect: 'error', signal: AbortSignal.timeout(20000),
});
const raw = await response.text();
if (!response.ok) throw new Error('HTTP ' + response.status);
let result;
try { result = JSON.parse(raw); } catch { throw new Error('平台未返回有效 JSON'); }
if (!result || typeof result !== 'object' || Array.isArray(result)) throw new Error('响应结构不正确');
if (Object.hasOwn(result, 'errcode') && result.errcode !== 0) {
throw new Error('微信业务错误 ' + result.errcode + ': ' + (result.errmsg || ''));
}
return result;
}
const appId = required('WX_MINI_APP_ID');
const url = new URL('https://api.weixin.qq.com/wxa/business/getuserphonenumber');
url.search = new URLSearchParams({ access_token: required('WX_MINI_ACCESS_TOKEN') }).toString();
const result = await request(url, {
code: required('WX_MINI_PHONE_CODE'), openid: required('WX_MINI_OPENID'),
});
const info = result.phone_info;
if (!info?.phoneNumber || info.watermark?.appid !== appId) {
throw new Error('手机号响应缺失或不属于当前小程序');
}
// 本例仅核对成功与归属,不在日志暴露完整手机号;业务端按授权目的处理 info。
const phone = String(info.phoneNumber);
console.log(JSON.stringify({ verified: true, countryCode: info.countryCode,
maskedPhone: phone.length > 7 ? phone.slice(0, 3) + '****' + phone.slice(-4) : '***',
timestamp: info.watermark.timestamp }, null, 2));
返回示例
虚构结构示意,手机号已脱敏,不是实测结果。真实响应中的号码仅用于获授权的业务。 以下为结构示意,非本站实测结果。
{
"errcode": 0,
"errmsg": "ok",
"phone_info": {
"phoneNumber": "138****0000",
"purePhoneNumber": "138****0000",
"countryCode": "86",
"watermark": {
"timestamp": 1791993600,
"appid": "WX_APPID_EXAMPLE"
}
}
}常见错误与排查
40029手机号 code 不正确、已消费或超时。- 由用户重新操作手机号按钮,不复用旧 code。
40013账号和产生 code 的小程序不匹配。- 核对后台 token、小程序 AppID 与前端 code 是否同一账号。
45009 / 45011日配额或调用频率受限。- 按官方后台额度控制请求,不重复强制刷新或无限重试。
调用注意
- 该快速验证不保证每次实时核验;需要实时验证的业务应另评估官方实时验证组件。
注意事项
- 标准价每次组件成功 0.03 元;1000 次体验额度由开发、体验、正式版本共用。
- 扣费发生在客户端成功回调阶段,不以本例后台脚本最终成功为前提。
- 用户拒绝或没有额度时,应提供适合业务的替代流程,不能强行要求无关手机号。
核验来源
本站按官方资料整理本场景的必要调用步骤与代码,覆盖范围以本页列出的接口为准。官方资料用于追溯规范及查看变更。
- 01手机号资格、费用、授权与code规则核验日期 2026-10-15
- 02API 加密适配核验日期 2026-10-15
- 03getPhoneNumber 服务端参数核验日期 2026-10-15
