二次开发中如何查询手机号是否注册并开通支付宝支付
明确结论
支付宝开放平台没有公开接口可供第三方输入任意手机号,查询该号码是否注册了支付宝,也无法通过手机号判断对应账户能否正常支付。
这类信息属于用户账户和隐私数据。常规的二次开发应采用以下流程:
- 引导用户完成支付宝授权或登录。
- 使用授权码换取
auth_token。 - 在用户授权范围内获取
user_id、open_id等账户标识。 - 根据业务场景创建支付订单,通过实际支付结果判断交易是否成功。
如果需要判断免密支付、周期扣款或代扣协议等签约能力,应查询对应产品的签约状态,而不是查询手机号。
为什么不能直接查询手机号
手机号不是支付宝开放平台向第三方提供的通用账户查询键。即使业务系统已经保存了用户的手机号,也不能通过公开 API 批量验证以下信息:
- 手机号是否注册了支付宝;
- 手机号当前绑定了哪个支付宝账户;
- 账户是否已经实名认证;
- 账户是否被冻结或受到限制;
- 账户是否有足够余额或可用的付款方式;
- 账户能否完成某一笔具体支付。
账户状态和交易可用性会受到风控、身份验证、支付渠道、交易金额及交易场景等因素影响,因此不存在一个长期有效的“已开通支付”布尔值供第三方查询。
推荐实现方案
1. 让用户主动完成支付宝授权
业务系统生成支付宝 OAuth 授权地址,引导用户在支付宝侧确认授权。授权完成后,回调地址会收到一次性的 auth_code。
授权地址、授权范围和相关参数应以当前接入产品的支付宝开放平台文档为准。不要自行扩大授权范围,也不要通过手机号探测支付宝账户是否存在。
2. 使用授权码换取访问令牌
服务端调用 alipay.system.oauth.token,使用 auth_code 换取用户访问令牌。
下面是支付宝 Java SDK 的示意代码。具体的 SDK 类名和返回字段可能因版本不同而有所变化:
AlipayClient alipayClient = new DefaultAlipayClient(
gatewayUrl,
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipaySystemOauthTokenRequest request =
new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode(authCode);
AlipaySystemOauthTokenResponse response =
alipayClient.execute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
"支付宝授权失败: " + response.getSubCode() + " - " + response.getSubMsg()
);
}
String accessToken = response.getAccessToken();
String userId = response.getUserId();
auth_code 应由服务端使用,并严格遵守接口规定。商户私钥和 access_token 都不能传给前端,也不应写入公开日志。
3. 在授权范围内读取用户信息
如果应用已经申请并获准使用相关能力,可以调用 alipay.user.info.share 获取授权用户的信息:
AlipayUserInfoShareRequest request =
new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response =
alipayClient.execute(request, accessToken);
if (!response.isSuccess()) {
throw new IllegalStateException(
"获取支付宝用户信息失败: "
+ response.getSubCode()
+ " - "
+ response.getSubMsg()
);
}
String userId = response.getUserId();
String openId = response.getOpenId();
String mobile = response.getMobile();
手机号是否返回,取决于应用权限、授权范围、产品规则以及用户实际授权情况。业务系统不能假设 mobile 一定存在,也不应通过反复授权来探测其他手机号是否注册。
应优先保存支付宝提供的稳定用户标识,并建立类似下面的绑定关系:
业务用户 ID -> 支付宝 user_id/open_id
不要把手机号作为支付宝账户的唯一标识。用户可能更换手机号,支付宝为不同应用提供的用户标识规则也可能不同。
如何判断用户能否支付
如果需要确认用户能否完成某笔付款,可靠的方法是创建真实业务订单,再根据支付宝异步通知或主动查询结果更新订单状态。可以根据接入场景选择以下接口:
alipay.trade.page.pay:电脑网站支付;alipay.trade.wap.pay:手机网站支付;alipay.trade.app.pay:App 支付;alipay.trade.create:创建交易;alipay.trade.query:查询交易状态。
支付页面能够正常唤起,只表示支付流程已经开始,并不代表付款成功。最终结果应以验签通过的异步通知为主,同时结合 alipay.trade.query 进行补偿查询。
处理异步通知时,至少应校验以下内容:
签名
app_id
seller_id
out_trade_no
total_amount
trade_status
同一条通知可能重复发送,因此更新订单状态时必须保证幂等性。
如果查询的是签约功能
“开通支付宝支付功能”需要结合具体业务来判断。普通付款、免密支付、周期扣款和代扣协议属于不同的能力。
如果业务需要确认用户是否已经签署免密或代扣协议,应在用户主动签约后保存协议号,再通过对应产品的协议查询接口检查协议状态。具体接口名称和参数取决于签约产品,应以该产品当前的开放平台文档及应用已经获得的权限为准。
即使查询签约状态,通常也应使用支付宝用户标识或协议号,不能使用任意手机号查询。
注意事项
- 不要通过撞库、批量试单或枚举手机号来判断支付宝注册状态。
- 不要把授权成功视为已经完成实名认证或具备正常付款能力。
- 不要仅凭前端跳转结果将订单标记为已支付。
- 手机号、支付宝用户标识和访问令牌都应作为敏感数据处理。
access_token应加密存储,并按照有效期和刷新机制进行管理。- 支付接口必须由服务端调用,私钥不能放在网页、小程序或 App 客户端中。
- API 权限、字段返回规则及用户标识体系可能调整。正式接入前,应以当前支付宝开放平台文档和应用后台实际开通的能力为准。
备注:内容仅供参考。
