支付宝当面付未申请电脑支付宝,如何调用二维码支付?
结论
已经开通”支付宝当面付”的商户,无需再申请”电脑网站支付”,也可以生成收款二维码。
如果二维码由商户系统生成,供顾客使用支付宝扫码付款,应调用当面付的 alipay.trade.precreate 接口。调用成功后,接口会返回 qr_code,将其中的完整内容转换成二维码图片即可。
“电脑网站支付”和”当面付”是两个独立的支付产品:
alipay.trade.page.pay:用于电脑网站支付,跳转到支付宝收银台。alipay.trade.precreate:用于当面付预下单,由商户生成二维码供顾客扫码。alipay.trade.pay:顾客出示付款码,商户使用扫码枪读取并发起扣款。
你的场景应使用第二种接口。
调用流程
1. 确认应用和签约状态
先在支付宝开放平台创建应用,并确认以下事项:
- 应用已经上线或具备正式调用条件;
- 应用绑定了已签约当面付的商户账号;
- 当面付产品状态正常;
- 已配置应用公钥,并妥善保存应用私钥;
- 已取得支付宝公钥;
- 正式环境使用网关
https://openapi.alipay.com/gateway.do。
接口能否调用,最终取决于支付宝开放平台中该应用显示的产品权限。如果只完成了商户签约,却没有为对应应用配置这项能力,调用接口时仍可能收到无权限错误。
2. 调用预创建接口
由后端调用:
alipay.trade.precreate
常用业务参数如下:
| 参数 | 说明 |
|---|---|
out_trade_no | 商户订单号,必须唯一 |
total_amount | 订单金额,单位为元,例如 0.01 |
subject | 订单标题 |
timeout_express | 可选,订单允许支付的时间 |
notify_url | 支付结果异步通知地址 |
调用成功后,支付宝会返回类似下面的数据:
{
"alipay_trade_precreate_response": {
"code": "10000",
"msg": "Success",
"out_trade_no": "ORDER202609090001",
"qr_code": "https://qr.alipay.com/..."
},
"sign": "..."
}
生成二维码时,应使用 qr_code 字段的完整内容,不要使用订单号或请求地址。
3. 将 qr_code 转成二维码图片
后端可以直接生成二维码图片,也可以将 qr_code 返回给前端,再通过前端二维码组件渲染。例如:
<div id="qrcode"></div>
<script src="https://cdn.jsdelivr.net/npm/qrcodejs/qrcode.min.js"></script>
<script>
const qrCodeContent = "https://qr.alipay.com/实际接口返回内容";
new QRCode(document.getElementById("qrcode"), {
text: qrCodeContent,
width: 240,
height: 240
});
</script>
生产环境中不要写死示例地址。每笔订单都应调用 alipay.trade.precreate,并使用接口当次返回的 qr_code。
Java SDK 示例
下面采用支付宝 Java 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 AlipayQrPayExample {
private static final String SERVER_URL =
"https://openapi.alipay.com/gateway.do";
private static final String APP_ID =
"你的应用APP_ID";
private static final String APP_PRIVATE_KEY =
"你的应用私钥";
private static final String ALIPAY_PUBLIC_KEY =
"支付宝公钥";
private static final String NOTIFY_URL =
"https://example.com/payment/alipay/notify";
public static void main(String[] args) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(
SERVER_URL,
APP_ID,
APP_PRIVATE_KEY,
"json",
"UTF-8",
ALIPAY_PUBLIC_KEY,
"RSA2"
);
String outTradeNo = "ORDER202609090001";
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount("0.01");
model.setSubject("测试商品");
model.setTimeoutExpress("5m");
AlipayTradePrecreateRequest request =
new AlipayTradePrecreateRequest();
request.setBizModel(model);
request.setNotifyUrl(NOTIFY_URL);
AlipayTradePrecreateResponse response =
alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("商户订单号:" + response.getOutTradeNo());
System.out.println("二维码内容:" + response.getQrCode());
} else {
System.err.println("预下单失败");
System.err.println("code:" + response.getCode());
System.err.println("subCode:" + response.getSubCode());
System.err.println("subMsg:" + response.getSubMsg());
}
}
}
不要将应用私钥和支付宝公钥写入前端,也不要提交到公开代码仓库。实际项目中,应通过安全配置中心、环境变量或密钥管理服务读取这些信息。
支付结果处理
二维码生成成功只说明预下单成功,并不代表顾客已经付款。
顾客扫码支付后,系统应按以下流程确认订单状态:
- 接收支付宝发送到
notify_url的异步通知; - 验证通知签名;
- 检查
app_id、seller_id、out_trade_no和total_amount是否与本地订单一致; - 只有当交易状态为
TRADE_SUCCESS,或业务允许的TRADE_FINISHED时,才更新订单; - 向支付宝返回以下纯文本:
success
前端也可以定时请求自己的后端,再由后端调用 alipay.trade.query 查询订单状态。不过,轮询只适合更新页面状态或补偿异步通知,不能替代验签和订单信息校验。
常见问题
返回”无权限”或”产品未签约”
可以从以下几项开始排查:
- 当面付是否已经生效;
- 发起请求的
app_id是否绑定了正确的商户; - 应用是否已取得当面付接口权限;
- 正式环境与沙箱环境的账号、密钥是否混用。
返回签名错误
检查相关配置是否匹配:
- 使用的是否为应用私钥,而不是应用公钥;
- 验签时使用的是否为支付宝公钥;
- 签名方式是否为
RSA2; - 字符集是否一致;
- 密钥是否因换行、空格或配置转义而损坏。
二维码可以显示,但付款后订单不更新
这通常说明异步通知没有得到正确处理。需要检查:
notify_url是否可以从公网通过 HTTPS 访问;- 请求是否被登录验证、CSRF 校验或防火墙拦截;
- 是否正确验证了通知签名;
- 处理成功后是否返回纯文本
success; - 是否对重复通知做了幂等处理。
是否可以直接拼接二维码支付地址
不建议这样做。二维码内容应使用 alipay.trade.precreate 的实际返回值,不要自行拼接支付宝地址。请求签名、订单创建和支付状态确认都必须在服务端完成。
因此,只需调用当面付的 alipay.trade.precreate,取得 qr_code 后生成二维码。这个过程与是否申请电脑网站支付无关。
备注:内容仅供参考。
