停车场场景下支付宝扫码支付应调用哪个接口?
结论
如果停车场展示付款二维码,由用户打开支付宝扫码支付,应调用支付宝当面付的预创建交易接口:
alipay.trade.precreate
接口调用成功后会返回 qr_code。停车场系统需要将这段内容生成二维码并展示,用户扫码后完成付款。
如果是停车场设备扫描用户支付宝中的付款码,则应改用:
alipay.trade.pay
判断使用哪个接口,主要看扫码方向:
- 用户扫描停车场二维码:
alipay.trade.precreate - 停车场设备扫描用户付款码:
alipay.trade.pay
为什么使用 alipay.trade.precreate
alipay.trade.precreate 用于支付宝当面付的扫码支付模式。停车场系统先创建一笔待支付订单,支付宝返回二维码内容,再由用户扫码付款。
停车场只是具体的业务场景,并不会因此自动对应某个专用支付接口。车辆入场记录、车牌识别、停车时长和费用计算通常由停车场业务系统负责,支付宝接口则用于创建交易、确认支付结果和办理退款。
如果项目接入的是支付宝停车行业解决方案、无感支付或代扣产品,可能需要另行申请相关产品并使用其他接口,不能直接沿用普通扫码支付流程。具体使用哪个接口,应以商户实际签约的产品和支付宝开放平台当前文档为准。
接入步骤
1. 计算停车费用
根据车牌、入场时间、免费时长和计费规则生成停车订单。每笔订单都应有唯一的商户订单号,例如:
PARK202609131530001
订单金额必须由服务端计算,不能直接采用前端提交的金额。
2. 调用预创建交易接口
请求 alipay.trade.precreate 时,主要业务参数包括:
out_trade_no:停车场系统中的唯一订单号total_amount:应付金额,单位为元subject:订单标题timeout_express:可选,订单允许支付的时间notify_url:异步通知地址,一般设置在请求对象或公共请求参数中
3. 展示付款二维码
接口调用成功后,从返回值中读取 qr_code,生成二维码并展示在出口终端、缴费机或网页上。
不要自行拼接支付宝付款链接,也不要直接把 qr_code 作为普通文本展示给用户。
4. 确认支付结果
支付结果应以支付宝服务端的异步通知为主,也可以调用以下接口主动查询订单状态:
alipay.trade.query
确认交易状态为 TRADE_SUCCESS 或业务允许接受的其他成功状态后,才能将停车订单标记为已支付并执行抬杆放行。
Java 示例
下面的示例只展示核心调用方式。网关地址、应用 ID、应用私钥、支付宝公钥和签名方式都应从安全配置中读取,不要硬编码在源码中。
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
public class ParkingPaymentService {
private final AlipayClient alipayClient;
public ParkingPaymentService(
String gateway,
String appId,
String appPrivateKey,
String alipayPublicKey) {
this.alipayClient = new DefaultAlipayClient(
gateway,
appId,
appPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
}
public String createPaymentQrCode(
String orderNo,
String amount,
String plateNumber,
String notifyUrl) throws AlipayApiException {
AlipayTradePrecreateRequest request =
new AlipayTradePrecreateRequest();
request.setNotifyUrl(notifyUrl);
String bizContent = String.format(
"{\"out_trade_no\":\"%s\","
+ "\"total_amount\":\"%s\","
+ "\"subject\":\"停车缴费-%s\","
+ "\"timeout_express\":\"10m\"}",
orderNo,
amount,
plateNumber
);
request.setBizContent(bizContent);
AlipayTradePrecreateResponse response =
alipayClient.execute(request);
if (!response.isSuccess()) {
throw new IllegalStateException(
"支付宝预创建交易失败,code="
+ response.getCode()
+ ", subCode="
+ response.getSubCode()
+ ", message="
+ response.getSubMsg()
);
}
return response.getQrCode();
}
}
生产环境中,建议使用 JSON 序列化组件构造 biz_content,以免车牌号或订单标题包含特殊字符时出现转义错误。
异步通知处理
收到支付宝的异步通知后,停车场服务端至少要完成以下处理:
- 使用支付宝公钥验证通知签名。
- 核对
app_id是否属于当前应用。 - 核对
out_trade_no是否存在。 - 核对
total_amount是否与本地订单金额一致。 - 检查订单是否已经处理,保证接口幂等。
- 确认交易成功后更新订单,并返回纯文本
success。
不能只根据浏览器跳转结果、客户端提示或二维码页面状态判断付款是否成功。
注意事项
- 同一笔停车订单不要重复生成不同的
out_trade_no,以免造成重复付款。 - 二维码应设置合理的有效期。停车费用可能随时间变化,二维码过期后,需要重新计算金额并创建新订单。
- 金额建议使用字符串形式的十进制数,例如
"12.50",不要使用浮点数计算停车费用。 - 支付异步通知可能重复发送,因此订单更新和抬杆指令必须具备幂等性。
- 如果支付成功但抬杆失败,应保留交易号、订单号和设备执行记录,方便补放行或人工处理。
- 退款应调用
alipay.trade.refund,并由停车场系统记录退款状态,不能直接将本地订单改为已退款。 - 接入前应确认支付宝商户账号已经开通相应的支付产品,并正确配置应用密钥、支付宝公钥、网关地址和异步通知地址。
- 如果需要按车牌自动扣款,车辆离场时无须扫码,则属于无感支付或代扣场景,需要另行确认签约能力和对应接口。
alipay.trade.precreate无法完成自动扣款。
备注:内容仅供参考。
