支付宝是否支持类似JSAPI接入的二维码支付
结论
支持。支付宝的“当面付”支持扫码支付。商户服务端调用 alipay.trade.precreate 创建支付订单后,接口会返回 qr_code。商户将其渲染成二维码,用户使用支付宝扫码即可付款。
这并不是将现有的 JSAPI 支付链接直接转换为二维码。扫码支付和 JSAPI 支付是两套不同的支付流程,需要分别开通对应产品。商户还要在服务端完成预下单、处理异步通知并查询订单状态。
接入流程
1. 开通支付能力
先在支付宝开放平台创建应用,再根据业务需要申请“当面付”等支持扫码收款的产品。
一般还要完成以下配置:
- 配置应用公钥或支付宝公钥证书。
- 妥善保存应用私钥,并且只在服务端使用。
- 配置支付结果的异步通知地址。
- 确认应用、商户账号和支付产品都已完成签约,当前状态可用。
支付宝开放平台可能调整产品名称和开放条件,请以当前控制台和官方接口文档为准。
2. 服务端创建预下单
用户确认订单后,商户服务端调用:
alipay.trade.precreate
常用业务参数有:
out_trade_no:商户订单号,必须唯一。total_amount:订单金额,单位为元。subject:订单标题。timeout_express:允许支付的时间,可根据业务需要设置。
调用成功后,响应中的 qr_code 就是二维码的原始内容。前端或服务端使用二维码组件进行编码即可,不要修改或拼接这段内容。
Java 示例
下面是核心调用方式。不同版本的支付宝 Java SDK 在类名和请求模型上可能略有差异,请以项目实际安装的 SDK 接口为准。
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
public class AlipayQrPayService {
private static final String GATEWAY =
"https://openapi.alipay.com/gateway.do";
public String createQrCode(
String appId,
String merchantPrivateKey,
String alipayPublicKey,
String notifyUrl,
String outTradeNo,
String totalAmount,
String subject) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(
GATEWAY,
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount(totalAmount);
model.setSubject(subject);
model.setTimeoutExpress("10m");
AlipayTradePrecreateRequest request =
new AlipayTradePrecreateRequest();
request.setBizModel(model);
request.setNotifyUrl(notifyUrl);
AlipayTradePrecreateResponse response =
alipayClient.execute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
"支付宝预下单失败,code=" + response.getCode()
+ ", subCode=" + response.getSubCode()
+ ", message=" + response.getSubMsg()
);
}
return response.getQrCode();
}
}
返回给前端的数据可以采用以下格式:
{
"outTradeNo": "ORDER_202609130001",
"qrCode": "支付宝接口返回的二维码内容"
}
前端使用二维码库渲染 qrCode:
new QRCode(document.getElementById("qrcode"), {
text: response.qrCode,
width: 240,
height: 240
});
支付结果处理
用户扫描二维码后,支付不一定已经完成。商户必须通过服务端确认订单状态,不能只看前端页面的提示。
可以同时采用以下两种方式:
- 接收支付宝发送到
notify_url的异步通知。 - 收银台页面通过商户服务端轮询
alipay.trade.query,查询订单状态。
服务端收到异步通知后,至少要完成这些校验:
- 验证支付宝签名。
- 确认
app_id属于当前应用。 - 确认
out_trade_no对应的订单存在。 - 核对
total_amount与商户订单金额是否一致。 - 核对收款方身份。
- 检查订单是否已经处理,防止重复入账。
- 只有确认支付成功后,才能更新商户订单状态。
支付宝可能重复发送异步通知,因此订单更新必须具备幂等性。通知处理完成后,还要按照支付宝的要求返回成功响应。
静态二维码与动态二维码的区别
如果“自行生成二维码”是指将任意固定 URL 或商户订单号制作成二维码,并希望支付宝扫码后自动发起支付,通常行不通。支付宝扫码支付所用的二维码内容应由支付接口返回,或者使用平台明确提供的收款码产品。
如果每笔交易的金额和订单都不同,建议每笔订单调用一次 alipay.trade.precreate,生成对应的动态二维码。这样可以:
- 让二维码与商户订单一一对应。
- 由服务端控制支付金额。
- 准确处理超时、关闭、退款和对账。
- 避免信任用户端传入的支付金额。
注意事项
- 私钥、签名和支付宝网关调用都必须放在服务端,不能写入浏览器或 App。
out_trade_no应全局唯一。同一订单重复请求时,金额和商品信息必须保持一致。- 为二维码设置合理的有效期。超时后停止展示,并根据实际情况调用
alipay.trade.close关闭未支付订单。 - 不要根据“二维码已扫描”或前端跳转结果判断支付是否成功。
- 二维码内容必须原样编码,不能进行 URL 解码、转义或截断。
- 服务商代商户调用时,还要按照服务商模式处理授权关系和相关参数。
- 沙箱环境与生产环境的网关、应用配置和密钥不能混用。
标准接入方式是由服务端调用 alipay.trade.precreate 获取 qr_code,商户将其渲染成二维码供用户使用支付宝扫码付款,再由服务端通过异步通知和订单查询确认最终支付结果。
备注:内容仅供参考。
