车载支付系统:从场景到落地的完整实践

各位同学,今天我们来聊聊车载支付。说实话,这个功能在几年前还被认为是「锦上添花」,但现在已经是智能座舱的标配能力了。我参与过几个量产项目的支付模块开发,踩过不少坑,今天把这些经验分享给你。

车载支付的核心场景

先想想看,用户在车上什么时候需要付钱?

  • 加油/充电:到站自动识别车辆,车内确认支付,不用下车掏手机
  • 停车缴费:出场时自动扣费,我见过有些方案还要扫码,体验很差
  • 车内购物:买咖啡、点外卖、续费会员服务
  • ETC 相关:高速通行费自动结算

这些场景有个共同点:用户正在驾驶或即将驾驶。所以支付流程必须极简,最好一次点击甚至零点击完成。

核心原则:车载支付不是把手机支付搬到大屏上,而是重新设计一套适合驾驶场景的交互流程。

安全支付流程设计

安全是车载支付的生命线。我刚开始做的时候,觉得只要调通第三方 SDK 就行了,结果被安全评审打回来三次……

一个标准的车载支付流程,通常包含这几个环节:

  1. 身份认证:确认当前驾驶员是账户持有人。可以用指纹、人脸、或者手机蓝牙配对
  2. 订单生成:车机端生成订单,包含金额、商户、时间戳
  3. 签名加密:订单信息用私钥签名,防止篡改
  4. 支付网关处理:车机将签名后的订单发给支付服务端
  5. 用户确认:大屏显示关键信息(金额、商户),用户点击确认
  6. 结果回调:支付成功/失败通知车机

我的经验:第5步「用户确认」千万别省。有些团队想做成全自动扣款,但出了纠纷很难追溯。留一个确认步骤,既是安全底线,也是用户体验的缓冲。

NFC 支付:近场支付的正确姿势

NFC 在车载场景下,主要用于两个地方:

  • 手机靠近车机:用手机 NFC 模拟银行卡或交通卡
  • 车机读取外部卡片:比如加油站的自助支付终端

Android Automotive 对 NFC 的支持,其实和手机端差不多。核心 API 是 NfcAdapter。但有个坑——车机的 NFC 天线位置和手机不一样。我记得有一次测试,工程师把 NFC 读卡区设计在了中控屏下方,结果用户把手机贴上去死活读不到……后来发现天线被金属支架屏蔽了。

// 初始化 NFC 适配器
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter == null) {
    // 车机不支持 NFC,降级到二维码
    return;
}

// 注册前台调度,让车机优先处理 NFC 事件
PendingIntent pendingIntent = PendingIntent.getActivity(
    context, 0,
    new Intent(context, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
    PendingIntent.FLAG_IMMUTABLE
);

nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null);

注意:车机熄火或进入休眠时,NFC 芯片可能会断电。你需要监听电源状态,在合适的时机重新初始化 NFC。我曾经因为这个 bug,导致用户加油后无法支付,在加油站堵了十分钟……

二维码支付:兼容性最好的方案

说实话,NFC 虽然方便,但普及率还是不如二维码。尤其在中国市场,二维码支付是绝对的主流。车载场景下,二维码有两种用法:

  • 车机生成付款码:大屏显示二维码,用户用手机扫码支付
  • 车机扫描外部码:用摄像头扫商家的收款码

生成付款码的逻辑比较简单,但要注意安全:

// 生成动态付款码
public Bitmap generatePaymentQrCode(String orderId, long amount) {
    // 构建支付参数
    JSONObject payload = new JSONObject();
    payload.put("order_id", orderId);
    payload.put("amount", amount);
    payload.put("timestamp", System.currentTimeMillis());
    payload.put("expire_in", 120); // 2分钟过期

    // 用商户私钥签名
    String sign = signPayload(payload.toString(), merchantPrivateKey);
    payload.put("sign", sign);

    // 生成二维码
    QRCodeWriter writer = new QRCodeWriter();
    BitMatrix bitMatrix = writer.encode(payload.toString(), BarcodeFormat.QR_CODE, 400, 400);
    // ... 转换为 Bitmap 显示
}

避坑指南:二维码一定要加过期时间。我曾经见过一个项目,二维码永久有效,结果用户截屏后被人盗刷。设置 60-120 秒过期,配合动态签名,基本能防住大部分攻击。

知识体系总览

下面这张图,是我自己整理的车载支付知识结构。你可以把它当作学习路线图:

车载支付系统 加油/充电支付 停车缴费 车内购物 ETC通行 安全支付流程:身份认证 → 订单生成 → 签名加密 → 网关处理 → 用户确认 → 结果回调 NFC 支付 NfcAdapter · 天线布局 · 电源管理 二维码支付 动态码生成 · 签名 · 过期机制 ⚠ 关键注意:天线位置测试 · 休眠唤醒处理 · 二维码过期 · 用户确认不可省略 —— 以上每一条都是我踩过的坑

支付安全:不可忽视的细节

安全这块我再多说几句。车载支付和手机支付最大的不同,是攻击面更大。车机可能被越狱,OBD 接口可能被接入恶意设备,甚至 Wi-Fi 热点都可能被伪造。

我建议你至少做到这几点:

  • 敏感数据不落地:支付密钥、用户 token 不要存本地文件,用 Android Keystore 或 TEE 环境
  • 通信全链路加密:车机到支付网关必须走 HTTPS,证书做 pinning
  • 支付结果双重校验:不要只依赖回调通知,车机要主动查询支付状态
  • 异常检测:短时间内多次支付失败、金额异常等,触发风控

血的教训:我曾经在一个项目里,把商户私钥硬编码在了 so 文件中。结果被安全团队用反编译工具直接扒了出来……后来全部改成了从安全芯片读取。记住,没有绝对的安全,只有不断加固的过程。

小结

车载支付这块,说白了就是「场景驱动,安全兜底」。先把用户真正需要的支付场景列清楚,再围绕安全流程做技术选型。NFC 和二维码各有优劣,我的建议是两者都支持,让用户自己选。

嗯,今天就先聊到这里。下一章我们会深入 Android Automotive 的支付 SDK 集成细节,包括如何对接支付宝和微信的车载版 SDK。到时候我会把完整的代码工程分享出来。


公众号:蓝海资料掘金营,微信deep3321