PAYATHON 2026

alipay-easysdk PHP 统一下单如何获取 $buyerId?

支付老李

明确结论

$buyerId 是付款用户的支付宝用户 ID,通常是以 2088 开头的 user_id,不是商户订单号、手机号或应用的 app_id。

调用以下代码时:

Factory::payment()->common()->create(
    $subject,
    $outTradeNo,
    $totalAmount,
    $buyerId
);

底层使用的是 alipay.trade.create。创建交易时,订单会绑定到 $buyerId 对应的支付宝账户。如果换用其他支付宝账户扫码付款,可能会出现:

该交易是由另外一个支付宝账户创建的,请更换支付宝账户付款或重新下单 [AE150003018]

在实际付款人尚未确定的扫码支付场景中,不要随意填写或固定 $buyerId。这类场景一般应使用 alipay.trade.precreate,也就是 EasySDK 的当面付预创建接口。

为什么扫码时无法获取 $buyerId

alipay.trade.create 要求在创建订单时提供 buyer_id,但用户扫码发生在订单创建之后。

如果任何支付宝用户都可以扫码付款,商户生成二维码时还不知道最终付款人是谁,自然无法提前取得准确的 $buyerId。这种流程不适合使用 alipay.trade.create,因为该接口会将交易绑定到指定账户。

示例代码里的 $buyerId 通常只是演示参数,不能直接用于生产环境。如果填入开发者、商户人员或其他测试账户的支付宝用户 ID,订单就会绑定到该账户。

方案一:扫码付款使用预创建接口

线下扫码、PC 页面展示二维码等先生成二维码、再由任意用户扫码的场景,应使用当面付预创建接口:

<?php

use Alipay\EasySDK\Kernel\Factory;

$result = Factory::payment()
    ->faceToFace()
    ->preCreate(
        '订单标题',
        'ORDER_202609080001',
        '0.01'
    );

if (!empty($result->qrCode)) {
    $qrCode = $result->qrCode;

    // 使用二维码组件将 $qrCode 生成为二维码图片
    echo $qrCode;
}

这个接口不需要传入 $buyerId。用户扫码并登录支付宝后,支付宝会按照实际付款账户完成交易。

$result->qrCode 通常只是二维码内容,不一定是能直接显示的图片地址。商户还需要通过二维码生成组件,将它转换成二维码图片。

不同版本的 alipay-easysdk 在具体类名和返回字段写法上可能略有差异,请以项目实际安装版本的 EasySDK 接口定义为准。

方案二:需要绑定用户时,通过支付宝授权获取

如果业务要求当前登录的支付宝用户为自己创建订单并付款,可以先让用户完成支付宝 OAuth 授权,再用授权码换取用户 ID。

基本流程如下:

  1. 引导用户访问支付宝授权地址。
  2. 用户确认授权后,支付宝跳转到商户配置的回调地址,并携带 auth_code。
  3. 使用 auth_code 调用 alipay.system.oauth.token。
  4. 从响应中取得 user_id。
  5. 将这个 user_id 作为 $buyerId 创建订单。

EasySDK 的调用方式通常如下:

<?php

use Alipay\EasySDK\Kernel\Factory;

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

if ($authCode === '') {
    throw new RuntimeException('缺少支付宝授权码 auth_code');
}

$tokenResult = Factory::base()
    ->oauth()
    ->getToken($authCode);

$buyerId = $tokenResult->userId ?? '';

if ($buyerId === '') {
    throw new RuntimeException('未能从授权结果中取得支付宝 user_id');
}

$orderResult = Factory::payment()
    ->common()
    ->create(
        '订单标题',
        'ORDER_202609080002',
        '0.01',
        $buyerId
    );

echo $orderResult->tradeNo;

获取授权码时,需要按照支付宝网页授权流程构造授权地址,并正确配置回调地址和授权范围。授权码通常有时效限制,而且只能使用一次,不应缓存后重复换取。

方案三:网页或移动端支付使用对应产品接口

如果只是希望用户跳转到支付宝完成付款,不需要在创建订单时绑定指定账户,可以根据终端类型选择对应接口:

// PC 网站支付
Factory::payment()
    ->page()
    ->pay($subject, $outTradeNo, $totalAmount, $returnUrl);
// 手机网站支付
Factory::payment()
    ->wap()
    ->pay($subject, $outTradeNo, $totalAmount, $returnUrl);
// App 支付
Factory::payment()
    ->app()
    ->pay($subject, $outTradeNo, $totalAmount);

具体参数请以当前 EasySDK 版本为准。选择支付产品时,要看接口是否符合实际付款流程:

  • 任意用户扫码:使用 alipay.trade.precreate。
  • 已知并且必须绑定某个支付宝用户:通过授权取得 user_id,再使用 alipay.trade.create。
  • PC 网站跳转支付:使用电脑网站支付。
  • 手机浏览器跳转支付:使用手机网站支付。
  • App 内唤起支付宝:使用 App 支付。

注意事项

以下内容都不能代替 $buyerId:

  • 商户的 app_id
  • 商户支付宝账户 ID
  • 登录手机号
  • 邮箱地址
  • OpenID
  • 示例代码中的固定 2088... 值
  • 支付完成后异步通知中的其他账号字段

通过 OAuth 取得的 $buyerId 必须属于当前准备付款的用户。即使已经成功取得某个用户的 user_id,如果把订单二维码交给另一个账户扫描,仍可能出现账户不一致错误。

如果创建订单前无法确认实际付款账户,就不要调用必须传入 $buyerId 的 common()->create()。扫码付款应改用 faceToFace()->preCreate()。

备注:内容仅供参考。