支付宝网页应用实现扫码登录和网页支付需签约哪些能力?
明确结论
如果要搭建一个同时支持支付宝扫码登录和网页支付的网站,通常需要在支付宝开放平台为网页应用申请两类能力:
-
支付宝登录或会员授权能力
- 通过支付宝 OAuth 2.0 获取用户授权。
- 使用
alipay.system.oauth.token换取user_id和访问令牌。 - 如果还要获取头像、昵称等资料,需要申请相应的会员信息能力,并调用
alipay.user.info.share。该接口和权限能否申请,以应用后台当前显示的内容为准。
-
电脑网站支付
- 产品名称通常是“电脑网站支付”。
- 核心接口为
alipay.trade.page.pay。 - 适用于 PC 浏览器中的收银台支付。用户也可以使用支付宝 App 扫描收银台二维码付款。
如果网站只需识别支付宝用户,不需要头像、昵称等扩展资料,通常完成 OAuth 授权并取得稳定的 user_id 即可,无需获取完整的会员信息。
“扫码登录”和“当面付”不是一回事。扫码登录用于用户身份授权,当面付则由商家生成付款码,供用户扫码支付。两者的用途和签约能力都不同。
为什么需要这些能力
扫码登录和网页支付是两个彼此独立的流程:
- 登录流程用于确认“当前访问者是谁”,需要取得用户授权和身份标识。
- 支付流程用于完成订单付款,需要开通支付产品,并配置交易签名和回调验签。
应用开通支付能力后,并不会自动获得读取用户资料的权限。同样,开通用户授权能力也不意味着应用可以收款。因此,这两项能力需要分别申请,并配置在同一个应用中。
申请和配置步骤
1. 创建网页应用
在支付宝开放平台控制台创建网页或移动应用,填写应用名称、使用场景和网站地址等信息,再按照控制台要求提交审核。
审核通过后,应用会获得 app_id。
2. 配置应用密钥
生成应用私钥和应用公钥,把应用公钥上传到支付宝开放平台,同时保存平台提供的支付宝公钥或支付宝公钥证书。
生产环境中需要妥善保管以下信息:
app_id- 应用私钥
- 支付宝公钥或支付宝公钥证书
- 应用证书及相关根证书(采用证书模式时)
应用私钥只能保存在服务端,不能写入 JavaScript、HTML、移动端安装包或公开代码仓库。
3. 申请支付宝登录相关能力
进入应用的能力或产品管理页面,查找并申请支付宝会员授权、支付宝登录或获取会员信息等相关能力。后台名称可能随平台调整,申请时应重点确认该能力是否支持:
- OAuth 用户授权
- 使用
auth_code换取访问令牌 - 获取支付宝用户的唯一标识
- 获取会员公开信息(业务确实需要时)
还要配置授权回调地址。该地址必须能由服务端访问,并与发起授权时传入的 redirect_uri 一致。
4. 签约电脑网站支付
在应用中申请“电脑网站支付”,填写经营信息、网站信息和结算账户等资料,提交签约审核。
支付功能通常还需要配置:
- 支付同步返回地址
return_url - 支付异步通知地址
notify_url - 签名方式,通常使用
RSA2 - 网关环境,开发阶段可以先使用沙箱
具体准入条件与账号主体、经营类目及平台当前规则有关,应以开放平台控制台显示的申请条件为准。
扫码登录实现流程
常见的实现流程如下:
- 服务端生成随机
state,并保存到当前会话。 - 浏览器跳转到支付宝 OAuth 授权页面。
- 用户在页面中确认授权。页面是否直接显示扫码入口,取决于支付宝当前的页面设计和访问终端。
- 支付宝携带
auth_code和state跳回业务网站。 - 服务端校验
state。 - 服务端调用
alipay.system.oauth.token换取用户标识。 - 根据支付宝
user_id查找或创建本站账号,并建立登录会话。
授权地址示例:
https://openauth.alipay.com/oauth2/publicAppAuthorize.htm
?app_id=你的APP_ID
&scope=auth_user
&redirect_uri=URL编码后的回调地址
&state=随机防伪字符串
实际请求时,应把地址拼接成一行,并对 redirect_uri 和 state 进行 URL 编码。
以下 PHP 示例用于生成授权地址:
<?php
session_start();
$appId = '你的APP_ID';
$redirectUri = 'https://www.example.com/alipay/oauth/callback';
$state = bin2hex(random_bytes(16));
$_SESSION['alipay_oauth_state'] = $state;
$query = http_build_query([
'app_id' => $appId,
'scope' => 'auth_user',
'redirect_uri' => $redirectUri,
'state' => $state,
]);
$authorizeUrl =
'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?' . $query;
header('Location: ' . $authorizeUrl);
exit;
处理回调时,先检查 state:
<?php
session_start();
$authCode = $_GET['auth_code'] ?? '';
$state = $_GET['state'] ?? '';
$expectedState = $_SESSION['alipay_oauth_state'] ?? '';
unset($_SESSION['alipay_oauth_state']);
if (
$authCode === '' ||
$expectedState === '' ||
!hash_equals($expectedState, $state)
) {
http_response_code(400);
exit('Invalid OAuth callback');
}
// 使用支付宝官方 SDK 调用 alipay.system.oauth.token。
// grant_type 设置为 authorization_code,code 设置为 $authCode。
// 成功后使用返回的 user_id 绑定本站账号。
auth_code 有有效期,而且通常只能使用一次,因此不能将它作为用户标识保存。账户绑定应以接口返回的支付宝用户标识为准。
网页支付实现流程
电脑网站支付通常按以下流程实现:
- 业务服务端创建本地订单。
- 服务端调用
alipay.trade.page.pay。 - 将支付宝返回的表单或跳转内容发送给浏览器。
- 用户在支付宝收银台完成付款。
- 支付宝向
notify_url发送异步通知。 - 服务端验证签名并核对订单信息。
- 确认信息无误后,把本地订单更新为已支付。
PHP SDK 的调用结构示例:
<?php
// 以下类名以对应版本的支付宝官方 PHP SDK 为准。
$aop = new AopClient();
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
$aop->appId = '你的APP_ID';
$aop->rsaPrivateKey = '你的应用私钥';
$aop->alipayrsaPublicKey = '支付宝公钥';
$aop->signType = 'RSA2';
$aop->format = 'json';
$aop->charset = 'UTF-8';
$request = new AlipayTradePagePayRequest();
$request->setNotifyUrl(
'https://www.example.com/alipay/payment/notify'
);
$request->setReturnUrl(
'https://www.example.com/alipay/payment/return'
);
$request->setBizContent(json_encode([
'out_trade_no' => 'ORDER_202609130001',
'product_code' => 'FAST_INSTANT_TRADE_PAY',
'total_amount' => '99.00',
'subject' => '网站订单',
], JSON_UNESCAPED_UNICODE));
$form = $aop->pageExecute($request);
echo $form;
不同版本 SDK 的安装方式、命名空间和证书配置方法可能不同。实现时应查阅所用版本的官方 SDK 文档,不要混用不同版本的示例。
支付通知必须核对的内容
浏览器跳转到 return_url,不能作为订单已支付的唯一依据。同步返回可能被伪造,也可能因为用户关闭页面而没有到达。
处理异步通知时,至少要完成以下检查:
- 使用支付宝公钥验证签名。
- 确认
app_id属于当前应用。 - 确认
out_trade_no对应本地订单。 - 确认
total_amount与本地订单金额一致。 - 核对收款方标识,例如
seller_id。 - 判断
trade_status是否符合业务要求。 - 保证同一通知重复到达时,不会导致重复发货或重复记账。
- 处理成功后,按照支付宝协议返回
success。
关键金额的存储和比较应使用十进制定点数,或采用以“分”为单位的整数,不要直接使用二进制浮点数。
常见误区
把当面付当成扫码登录能力
“当面付”主要用于扫码收款,常用接口包括 alipay.trade.precreate,不能代替用户登录授权。
只有网站确实需要主动生成支付二维码时,才有必要进一步评估是否申请当面付。普通的电脑网站支付通常使用 alipay.trade.page.pay。
直接用手机号作为登录依据
支付宝授权不一定会返回手机号。手机号权限通常还有单独的准入和授权要求。
账号体系应优先使用支付宝返回的稳定用户标识,再让用户自行绑定本站手机号。
在浏览器中保存私钥
签名、换取令牌和创建支付请求都应由服务端完成。前端只负责跳转、展示页面以及提交必要的业务请求。
混用沙箱和生产配置
沙箱和生产环境的应用编号、密钥、网关及账号数据彼此独立。切换到生产环境时,需要整体替换相关配置,并重新验证授权回调、支付通知和证书链。
常规的能力组合是“支付宝 OAuth 登录或会员授权能力”加“电脑网站支付”。如果登录后还要读取头像、昵称等资料,需要再申请相应的会员信息权限。如果网站希望自行生成付款二维码,而不是进入电脑网站收银台,则需要根据实际支付场景评估“当面付”等其他产品。
备注:内容仅供参考。
