安卓设备对接支付宝支付方案
1. 结论
推荐把“支付能力”放在后端,安卓设备只负责展示订单、采集付款码或唤起支付宝 SDK、展示支付状态。私钥、签名、异步通知验签、订单最终状态判断都必须在后端完成。
按设备形态优先选择:
| 场景 | 推荐模式 | 原因 | 安卓端职责 |
|---|---|---|---|
| 普通手机 App,用户手机上装有支付宝 | App 支付 | 体验最完整,可直接唤起支付宝 App 完成支付。 | 请求后端下单,拿到已签名 orderInfo,调用支付宝 Android SDK。 |
| 收银/消费设备,顾客出示支付宝付款码 | 当面付条码支付 | 最适合固定设备,设备不依赖安装支付宝 App,收银员或设备扫码即可扣款。 | 扫码获取 auth_code,提交后端发起支付,轮询/订阅订单状态。 |
| 自助终端,顾客用手机扫设备屏幕二维码 | 当面付扫码支付 | 适合无扫码枪或顾客自助场景,设备展示动态二维码。 | 请求后端生成二维码,展示二维码,轮询/接收支付状态。 |
| 内嵌网页、临时跳转支付页 | H5/网页支付 | 只作为补充方案。对原生设备体验、回跳、风控和稳定性不如前三种。 | 打开 WebView/浏览器并处理回跳,最终仍以后端订单状态为准。 |
2. 总体架构
推荐架构如下:
安卓设备 |-- 创建本地订单/业务订单 |-- 选择支付方式 |-- App 支付:调用后端获取签名 orderInfo,再调用支付宝 SDK |-- 条码支付:采集用户付款码 auth_code,交给后端 |-- 扫码支付:展示后端返回的动态二维码 |-- 查询后端订单状态并展示结果 业务后端 |-- 生成商户订单号 out_trade_no |-- 调用支付宝开放平台接口 |-- 保存支付流水、请求号、支付宝交易号 |-- 接收支付宝异步通知并验签 |-- 必要时主动查询交易状态 |-- 推送/返回最终支付结果给设备 支付宝开放平台 |-- App 支付 SDK |-- 当面付交易创建/支付/查询接口 |-- 异步通知 notify_url
关键原则:
- 安卓端不保存支付宝应用私钥,不参与最终验签。
- 客户端支付结果只作为“页面提示”,不能作为发货、出餐、开闸、扣余额的最终依据。
- 最终业务动作以后端验签后的异步通知,或后端主动查询支付宝交易状态为准。
- 所有支付入口都要统一落到同一套订单状态机,避免 App 支付、条码支付、扫码支付各走各的状态。
3. 方案 A:App 支付
适用场景
用户在自己的 Android 手机上使用 App,下单后跳转支付宝 App 完成付款。此方案不适合大多数固定消费机,因为固定设备通常不是顾客本人手机,也不应登录顾客支付宝账号。
交互流程
- 安卓 App 创建业务订单,请求后端
/pay/alipay/app/create。 - 后端生成
out_trade_no,组装支付宝 App 支付参数并用商户应用私钥签名。 - 后端返回
orderInfo给安卓端。 - 安卓端在非 UI 线程调用支付宝 SDK 的
PayTask.payV2(orderInfo, true)。 - 安卓端解析 SDK 返回结果并提示用户。
- 后端接收支付宝
notify_url异步通知,验签后更新订单。 - 安卓端向后端查询订单最终状态,决定是否进入业务完成页。
安卓端要点
- 引入支付宝 Android SDK,按官方文档配置混淆规则、权限和依赖。
PayTask.payV2必须放到子线程执行,执行后切回主线程更新 UI。- 返回码
9000可提示“支付处理中/支付成功待确认”,仍需查询后端状态。 - 用户取消、网络异常、结果未知都不能直接关单,应进入“待支付/待确认”并允许继续查询或重新支付。
4. 方案 B:当面付条码支付
适用场景
收银员或设备扫描顾客支付宝付款码,适合食堂消费机、收银机、无人售卖、自助核销设备。设备不需要安装支付宝 App。
交互流程
- 安卓设备展示订单金额,引导顾客出示支付宝付款码。
- 设备通过扫码枪、摄像头或硬件扫码模块读取付款码
auth_code。 - 安卓端提交
out_trade_no、金额、付款码到后端/pay/alipay/barcode/pay。 - 后端调用支付宝当面付条码支付接口。
- 后端根据同步结果、异步通知、主动查询结果判断交易是否成功。
- 安卓端轮询或通过 WebSocket/MQTT/长轮询获取订单状态,成功后执行出餐、开闸、打印等业务动作。
设备端要点
- 扫码后立即禁用重复提交按钮,防止同一个付款码和订单重复请求。
- 付款码属于敏感数据,日志中必须脱敏,不能完整打印。
- 遇到
WAIT_BUYER_PAY、网络超时、结果未知时,设备应展示“支付确认中”,后端继续查询。 - 设备离线时不能本地扣款,必须提示网络异常或走离线记账的独立风控流程。
5. 方案 C:当面付扫码支付
适用场景
设备屏幕展示动态二维码,顾客用支付宝 App 扫码付款。适合没有扫码枪、顾客自助操作、屏幕面积足够的设备。
交互流程
- 安卓设备请求后端
/pay/alipay/qrcode/create。 - 后端调用支付宝预创建交易接口,拿到二维码内容或二维码链接。
- 安卓端生成并展示二维码,同时开始倒计时。
- 顾客用支付宝 App 扫码付款。
- 后端接收异步通知或主动查询订单状态。
- 安卓端轮询后端状态,支付成功后进入业务完成流程。
设备端要点
- 二维码必须绑定订单号、金额和有效期,过期后重新生成。
- 付款成功前禁止修改金额;修改订单后必须作废旧二维码。
- 二维码页要提供取消支付、重新生成、返回订单页能力。
6. 后端接口建议
| 接口 | 用途 | 关键入参 | 关键出参 |
|---|---|---|---|
POST /pay/alipay/app/create |
创建 App 支付订单 | 业务订单号、金额、商品描述、设备号/用户号 | pay_order_no、out_trade_no、orderInfo |
POST /pay/alipay/barcode/pay |
付款码支付 | 业务订单号、金额、auth_code、设备号 |
pay_order_no、状态、错误码、下一步动作 |
POST /pay/alipay/qrcode/create |
生成顾客扫码二维码 | 业务订单号、金额、商品描述、有效期 | pay_order_no、二维码内容、过期时间 |
GET /pay/orders/{pay_order_no} |
查询支付状态 | 支付单号 | 支付状态、支付宝交易号、支付时间、失败原因 |
POST /pay/alipay/notify |
支付宝异步通知回调 | 支付宝通知参数 | 按支付宝要求返回成功/失败文本 |
POST /pay/refund |
退款 | 支付单号、退款金额、退款原因 | 退款单号、退款状态 |
7. 订单状态机
| 状态 | 含义 | 设备端表现 | 可流转到 |
|---|---|---|---|
CREATED |
支付单已创建,未发起支付 | 显示待支付 | PAYING、CLOSED |
PAYING |
已发起支付,等待结果 | 显示支付中,禁用重复提交 | SUCCESS、FAILED、UNKNOWN、CLOSED |
UNKNOWN |
网络或支付宝返回结果不确定 | 显示确认中,继续查询 | SUCCESS、FAILED、CLOSED |
SUCCESS |
支付宝确认支付成功 | 展示成功并触发业务动作 | REFUNDING |
FAILED |
支付失败或用户取消 | 允许重新支付或返回 | PAYING、CLOSED |
CLOSED |
订单关闭 | 不可继续支付,需重新下单 | 终态 |
REFUNDING / REFUNDED |
退款中/已退款 | 展示售后状态 | 终态或部分退款态 |
8. 安全与合规要求
- 支付宝应用私钥只放后端密钥管理系统或受控配置,不能放进 APK、前端包、设备配置文件。
- 异步通知必须验签,并校验
app_id、seller_id、out_trade_no、金额、订单状态。 - 同一个
out_trade_no必须幂等处理,通知重复到达不能重复出餐、重复开闸、重复发货。 - 支付金额以后端订单金额为准,安卓端传入金额只能作为展示或二次校验。
- 付款码、买家账号、手机号、支付宝交易号等日志要脱敏;生产日志不要打印完整请求体。
- 设备与后端通信必须走 HTTPS,并带设备鉴权、时间戳、nonce、防重放机制。
- 退款、撤销、关单接口要做操作员权限控制和审计记录。
9. 安卓端改造清单
- 支付方式页:支付宝 App 支付、付款码支付、扫码支付按设备能力显示。
- 支付 SDK 封装:把支付宝 SDK 调用封装成独立模块,业务页面不直接拼接支付参数。
- 扫码模块:统一接收扫码枪按键输入、串口扫码模块、摄像头扫码结果。
- 状态查询:支付中页面定时查询后端状态,建议 1-2 秒一次,超过设定时间后转人工确认或失败页。
- 异常页:覆盖用户取消、二维码过期、付款码无效、网络异常、订单已关闭、金额不一致、结果未知。
- 本地日志:记录支付单号、业务订单号、设备号、错误码、耗时;敏感字段脱敏。
- 灰度开关:按门店、设备型号、应用版本控制支付方式开关。
10. 后端改造清单
- 开通支付宝开放平台应用与对应产品能力,配置应用网关、公钥证书或公钥模式、异步通知地址。
- 封装支付宝 SDK/HTTP 客户端,统一签名、验签、错误码映射、重试策略。
- 设计支付单表、支付流水表、通知记录表、退款表。
- 实现 App 支付下单、条码支付、扫码预创建、交易查询、关单、退款、异步通知。
- 实现幂等锁:按业务订单号和支付单号防止并发重复发起支付。
- 实现定时补偿:对
PAYING、UNKNOWN状态定时查询支付宝并修正状态。 - 对接财务对账:支付宝交易号、商户订单号、退款单号、结算时间要可导出。
11. 测试验收清单
| 类别 | 验收项 |
|---|---|
| 正常链路 | App 支付成功、付款码支付成功、扫码支付成功,后端状态与设备 UI 一致。 |
| 异常链路 | 用户取消、余额不足、付款码过期、二维码过期、网络断开、支付宝返回处理中。 |
| 幂等 | 重复点击、重复扫码、重复异步通知、设备重启后查询同一订单,不产生重复业务动作。 |
| 金额校验 | 安卓端篡改金额、后端订单金额变化、折扣/优惠后金额不一致时必须拒绝支付或重新下单。 |
| 安全 | APK 中无私钥;日志无完整付款码;notify 验签失败不更新订单。 |
| 补偿 | 支付结果未知后,后端定时查询能恢复到成功/失败/关闭。 |
| 退款 | 全额退款、部分退款、重复退款、退款失败、退款对账可追溯。 |
12. 推荐实施路径
- 先确认设备形态:个人手机 App 还是固定收银/自助设备。
- 固定设备优先落地当面付条码支付;如果没有扫码硬件,再落地扫码支付。
- 后端先打通统一支付单、异步通知验签、交易查询、幂等状态机。
- 安卓端先接支付创建和状态查询,再接扫码/SDK 调用。
- 联调沙箱或测试商户,完成正常链路和异常链路。
- 灰度到单门店/单设备型号,确认支付成功率、耗时、异常恢复和对账。
- 再扩大到全量设备。