PAYATHON 2026

alipay.fund.trans.uni.transfer如何获取收款方账号或UID?

支付老李

结论

优先通过支付宝会员授权获取当前登录用户的支付宝用户标识。服务端拿到一次性 auth_code 后,调用 alipay.system.oauth.token 换取令牌,再使用返回的用户标识发起转账。

如果授权结果返回可用于资金接口的 user_id,可以这样填写收款方信息:

payee_info.identity_type = ALIPAY_USER_ID
payee_info.identity = 用户授权得到的 user_id

不建议让用户手工填写支付宝登录账号。alipay.user.info.share 用于读取授权范围内的用户公开信息。接口是否返回 user_id、open_id,以及这些字段能否用于转账,要看应用类型、授权范围和支付宝当前的数据开放规则。除非转账文档明确支持,否则不能把 open_id 当作 ALIPAY_USER_ID 使用。

“实名证件信息比对验证”用于核验姓名、证件等信息,并不能查询支付宝账号或 UID。即使实名核验通过,接口也未必会返回可直接用于转账的支付宝账号。

推荐的业务流程

收款人绑定可以按以下流程设计:

  1. 收款人点击”绑定支付宝”。
  2. 跳转到支付宝会员授权页面。
  3. 支付宝回调业务系统,并携带一次性 auth_code。
  4. 服务端调用 alipay.system.oauth.token 换取 access_token。
  5. 从令牌响应中读取 user_id。如果业务还需要昵称、头像、认证状态等信息,再调用 alipay.user.info.share。
  6. 保存 UID 与当前业务用户的绑定关系。
  7. 转账时使用 UID,并将收款人姓名作为一致性校验字段。
  8. 首次绑定、换绑和高额转账时,增加短信验证、人工审核或二次确认。

这套流程建立的关系是:

业务系统用户
    ↓ 本人支付宝授权
支付宝 user_id
    ↓
alipay.fund.trans.uni.transfer

通过这种方式,可以确认 UID 来自当时登录并授权的支付宝用户,比手工填写手机号或邮箱形式的支付宝登录账号更可靠。

获取用户标识

网页应用通常需要先生成支付宝授权地址。以下代码只展示核心参数,实际地址和可用的 scope 应以应用后台及当前官方文档为准:

<?php

$appId = '你的应用 APPID';
$redirectUri = 'https://example.com/alipay/oauth/callback';

$query = http_build_query([
    'app_id'       => $appId,
    'scope'        => 'auth_user',
    'redirect_uri' => $redirectUri,
]);

$authorizeUrl =
    'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?' . $query;

header('Location: ' . $authorizeUrl);
exit;

回调地址收到 auth_code 后,由服务端换取令牌:

<?php

$authCode = $_GET['auth_code'] ?? '';

if ($authCode === '') {
    throw new RuntimeException('缺少 auth_code');
}

$request = new AlipaySystemOauthTokenRequest();
$request->setGrantType('authorization_code');
$request->setCode($authCode);

// $aop 为已经按证书模式初始化的官方 PHP SDK 客户端。
$response = $aop->execute($request);

if (!isset($response->access_token)) {
    throw new RuntimeException(
        '换取支付宝授权令牌失败:' .
        json_encode($response, JSON_UNESCAPED_UNICODE)
    );
}

$accessToken = $response->access_token;
$userId = $response->user_id ?? null;
$openId = $response->open_id ?? null;

不同版本 SDK 的响应对象结构可能不同。应根据官方 SDK 的实际返回结构判断错误码,再读取所需字段,不要假定所有应用都能同时取得 user_id 和 open_id。

如果令牌响应没有返回可用于转账的 user_id,不能强行把 open_id 填入 ALIPAY_USER_ID。此时需要检查:

  • 应用是否已经开通相应的会员能力;
  • 授权范围是否正确;
  • 当前应用类型是否允许获取该字段;
  • 转账产品是否支持当前返回的用户标识类型;
  • 支付宝是否已对该应用启用新的用户标识规则。

调用 alipay.user.info.share

取得 access_token 后,可以读取用户已经授权的公开信息:

<?php

$request = new AlipayUserInfoShareRequest();
$response = $aop->execute($request, $accessToken);

if (isset($response->code) && $response->code !== '10000') {
    throw new RuntimeException(
        '获取支付宝会员信息失败:' .
        json_encode($response, JSON_UNESCAPED_UNICODE)
    );
}

$userInfo = [
    'user_id'      => $response->user_id ?? null,
    'open_id'      => $response->open_id ?? null,
    'nick_name'    => $response->nick_name ?? null,
    'is_certified' => $response->is_certified ?? null,
];

使用这个接口时需要注意:

  1. 它只能返回用户明确授权且应用有权获取的字段。
  2. is_certified 一般只能说明账户是否完成支付宝实名认证,不能代替姓名与身份证号码的一致性核验。
  3. 它不能通过姓名查询支付宝 UID,也不能反查任意用户。

会员授权可以获取当前授权用户的标识,但不能根据姓名查询对方的支付宝账号。

使用 UID 发起单笔转账

确认取得的 user_id 可以作为 ALIPAY_USER_ID 后,可以这样组织转账业务参数:

<?php

$bizContent = [
    'out_biz_no'   => 'TRANSFER_' . date('YmdHis') . '_001',
    'trans_amount' => '100.00',
    'product_code' => 'TRANS_ACCOUNT_NO_PWD',
    'biz_scene'    => 'DIRECT_TRANSFER',
    'order_title'  => '用户提现',
    'payee_info'   => [
        'identity'      => $userId,
        'identity_type' => 'ALIPAY_USER_ID',
        'name'          => $realName,
    ],
];

$request = new AlipayFundTransUniTransferRequest();
$request->setBizContent(
    json_encode($bizContent, JSON_UNESCAPED_UNICODE)
);

$response = $aop->execute($request);

不同 SDK 发行包在证书模式的执行方法、命名空间和响应解析方式上可能存在差异,应以当前使用的 PHP SDK 为准。业务参数中的收款方信息应按以下形式填写:

{
  "payee_info": {
    "identity": "支付宝用户ID",
    "identity_type": "ALIPAY_USER_ID",
    "name": "收款人真实姓名"
  }
}

不要混用这些标识:

支付宝登录账号  → ALIPAY_LOGON_ID
支付宝用户 UID → ALIPAY_USER_ID
open_id         → 只有转账文档明确支持时才能使用相应类型

open_id、应用内会员编号、业务系统用户 ID 和支付宝 user_id 是不同的概念。

实名信息验证能力的定位

alipay.user.certdoc.certverify.preconsult 和 alipay.user.certdoc.certverify.consult 用于比对实名证件信息,例如检查用户提交的姓名与证件号码是否一致。

业务确实需要法定身份核验时,可以使用这项能力,但它不是支付宝账号查询服务:

  • 实名验证成功,不代表接口会返回支付宝登录账号。
  • 实名验证成功,不代表接口会返回转账所需的 user_id。
  • 不能通过姓名或身份证号反查任意支付宝账户。
  • 获得授权令牌只是调用流程的一部分,不会自动取得所有会员字段。

如果后台的”可调用产品”中没有这项能力,通常说明当前应用尚未签约、没有接口权限,或者不符合对应产品的准入条件。这类能力涉及实名和隐私数据,不能只靠代码调用开通。需要在支付宝开放平台确认产品签约入口、应用类型、商户资质、业务场景及隐私合规要求。如果后台没有申请入口,应通过支付宝开放平台的服务渠道确认准入情况。

应用已经上线或转账接口已经开通,都不能说明实名验证接口也已开通,因为两者属于不同的产品权限。

“获取会员信息”是否可以使用

如果应用后台显示”会员-获取会员信息”并且已经开通,通常可以按照会员授权流程接入。不过,最终能否取得转账所需的 user_id,仍要以实际授权响应和当前接口字段说明为准。

可以依次完成以下验证:

  1. 确认应用已经开通会员授权或获取会员信息能力。
  2. 使用应用自己的 app_id 完成一次真实授权。
  3. 检查 alipay.system.oauth.token 的原始响应。
  4. 检查 alipay.user.info.share 的原始响应。
  5. 区分 user_id 和 open_id。
  6. 对照 alipay.fund.trans.uni.transfer 当前支持的 identity_type。
  7. 在沙箱或小额真实业务中验证完整的绑定与转账流程。

如果只能取得 open_id,而转账接口只接受 ALIPAY_USER_ID 或 ALIPAY_LOGON_ID,就不能直接转换标识。需要向支付宝确认应用是否可以申请取得 user_id,或者转账产品是否支持与 open_id 对应的收款方标识类型。

PHP、v2 和证书模式的常见问题

授权回调必须防止伪造

生成授权地址时,应同时保存随机 state,并在回调时校验。auth_code 应由服务端处理,不能交给前端长期保存。

auth_code 不能重复使用

授权码通常只能使用一次,而且有效期较短。收到回调后应尽快换取令牌。换取失败时,不要无限重试同一个授权码。

不要把 access_token 写入普通日志

令牌、证件号码、支付宝账号、UID 和真实姓名都属于敏感信息。日志应做脱敏处理,同时限制数据库访问权限。

UID 必须和业务用户绑定

不要允许前端在每次提现时直接提交任意 user_id。服务端应读取此前通过授权绑定的 UID,例如:

$payeeUserId = $repository->getBoundAlipayUserId($currentUserId);

转账接口中的 identity 必须由服务端生成,不能信任前端传入的参数。

换绑需要重新授权

用户更换收款支付宝账户时,应重新完成支付宝授权和业务侧身份确认。换绑后可以设置冷静期,防止账号被盗后资金立即转出。

保留姓名校验

即使使用 UID,在业务允许且接口要求的情况下,仍建议填写收款人的真实姓名。UID 用于定位账户,姓名可以降低绑错账户和数据被篡改的风险。

做好幂等控制

out_biz_no 必须由服务端生成并保证唯一。遇到网络超时,应先查询原转账结果,不要立即更换业务单号重新转账,否则可能造成重复付款。

证书配置与会员授权是两回事

证书模式负责接口请求签名和支付宝响应验签,不会自动赋予会员信息或实名验证权限。即使应用公钥证书、支付宝公钥证书和支付宝根证书都配置正确,也不代表应用已经签约某个产品接口。

最终建议

如果只需要安全获取收款账户并完成转账,可以采用以下组合:

支付宝会员授权
+ alipay.system.oauth.token 获取用户标识
+ 必要时 alipay.user.info.share 获取授权信息
+ 服务端绑定 user_id
+ alipay.fund.trans.uni.transfer 使用 ALIPAY_USER_ID

如果业务还需要核验身份证和姓名,应在上述流程之外单独申请实名证件信息比对能力。实名验证用于判断身份信息是否匹配,会员授权用于确认当前登录的支付宝用户,转账接口则负责向该用户付款。这三项能力不能互相替代。

备注:内容仅供参考。