APP支付下单参数timeout_express与time_expire有何区别?
结论
在支付宝 APP 支付下单接口 alipay.trade.app.pay 中:
timeout_express表示订单创建后的可支付时长,属于相对时间,例如30m、2h。time_expire表示订单失效的具体时刻,属于绝对时间,例如2026-09-13 18:30:00。
这两个参数都用于控制订单的支付有效期。如果业务已经算出明确的截止时间,可优先使用 time_expire;如果只要求订单在创建后的一段时间内有效,使用 timeout_express 更方便。两者同时传入时,通常以 time_expire 为准,因此建议只设置其中一个。
本文以支付宝开放平台的 alipay.trade.app.pay 接口为准。不同版本或封装 SDK 的参数限制可能有所调整,接入时还需核对当前接口文档。
两个参数的主要区别
| 对比项 | timeout_express | time_expire |
|---|---|---|
| 含义 | 从订单创建时间开始计算的有效时长 | 订单失效的具体日期和时间 |
| 时间类型 | 相对时间 | 绝对时间 |
| 示例 | 30m、2h、1d | 2026-09-13 18:30:00 |
| 适用场景 | 所有订单采用统一支付时限 | 订单必须在指定时刻统一截止 |
| 计算方式 | 支付宝根据创建时间计算失效点 | 商户直接指定失效点 |
| 同时传入 | 一般不建议 | 通常优先于 timeout_express |
timeout_express 的具体含义
例如提交:
{
"timeout_express": "30m"
}
这表示订单创建成功后,用户大约有 30 分钟完成支付。超过有效期,订单将无法继续正常支付,并进入相应的超时关闭流程。
常见单位包括:
m:分钟
h:小时
d:天
c:当天
例如:
15m 15分钟
2h 2小时
1d 1天
1c 当天
1c 并不等同于普通的“24 小时”,而是表示当天截止。如果订单在晚上 23
1c 后,订单可能在当天结束时失效,并不会继续有效一整天。
允许设置的最短时长、最大时长,以及接口是否支持 1c,需要以当前接口文档为准。不要自行传入 1.5h 之类的小数形式,可以改写为:
90m
time_expire 的具体含义
time_expire 用于直接指定订单的失效时间,通常采用以下格式:
yyyy-MM-dd HH:mm:ss
例如:
{
"time_expire": "2026-09-13 18:30:00"
}
这表示订单在该时间之后不能继续支付。它适用于有统一截止时间的业务,例如:
- 活动报名统一在当天 18 截止;
- 票务订单需要在开场前失效;
- 同一批订单需要在固定时间关闭;
- 商户系统已经计算出准确的支付截止时间。
使用绝对时间时,需要注意商户服务器时间、时区和支付宝系统时间之间的差异。
应该如何选择
如果业务规则是“用户下单后 30 分钟内完成支付”,只需传入:
{
"timeout_express": "30m"
}
如果业务规则是“所有订单都在 2026 年 9 月 13 日 18
截止”,只需传入:{
"time_expire": "2026-09-13 18:30:00"
}
可以按以下方式处理:
- 先确定业务使用相对时长还是固定截止时间。
- 相对时长使用
timeout_express。 - 固定截止时间使用
time_expire。 - 尽量只传一个参数,避免后续维护时产生歧义。
- 商户系统应同步保存订单失效时间,不能只依赖支付平台判断。
- 收到支付结果后,仍要检查商户订单是否已经过期。
APP 支付下单示例
以下示例只展示与本文相关的 biz_content。实际请求还需要提供 app_id、签名、编码、请求方法等公共参数。
使用相对有效期:
{
"out_trade_no": "ORDER_20260913_0001",
"total_amount": "99.00",
"subject": "会员服务",
"product_code": "QUICK_MSECURITY_PAY",
"timeout_express": "30m"
}
使用绝对失效时间:
{
"out_trade_no": "ORDER_20260913_0002",
"total_amount": "99.00",
"subject": "会员服务",
"product_code": "QUICK_MSECURITY_PAY",
"time_expire": "2026-09-13 18:30:00"
}
不建议同时传入两个参数:
{
"out_trade_no": "ORDER_20260913_0003",
"total_amount": "99.00",
"subject": "会员服务",
"product_code": "QUICK_MSECURITY_PAY",
"timeout_express": "30m",
"time_expire": "2026-09-13 18:30:00"
}
两者同时存在时,通常按照 time_expire 处理。为避免商户系统、SDK 和支付平台对有效期产生不同理解,最好在生成请求前只保留一种配置。
服务端计算示例
如果业务内部统一使用“有效分钟数”,但接口需要传入绝对时间,可以在服务端完成转换:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
int validMinutes = 30;
String timeExpire = LocalDateTime.now()
.plusMinutes(validMinutes)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(timeExpire);
如果系统涉及多个时区,应明确指定业务时区,不要直接使用服务器的默认时区:
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
String timeExpire = ZonedDateTime.now(zoneId)
.plusMinutes(30)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
注意事项
订单超时不等于商户状态已经同步关闭
订单超过支付期限后,支付平台可能不再允许付款,但商户数据库中的订单状态不会自动、可靠地变成“已关闭”。商户需要结合以下机制维护订单状态:
- 处理支付异步通知;
- 主动查询支付结果;
- 定时关闭超时订单;
- 必要时调用交易关闭接口;
- 对迟到的通知进行幂等处理。
回调到达时必须再次校验
收到支付成功通知后,不能直接发货,还需要校验:
out_trade_no
trade_status
total_amount
seller_id 或 app_id
商户订单当前状态
商户订单失效时间
订单恰好处于超时边界时,商户还需制定明确的处理规则:以支付平台确认的支付成功时间为准,还是以商户订单的截止时间为准。
不要把客户端时间作为依据
用户可以修改 APP 客户端的系统时间。订单失效时间应由商户服务端生成并判断,客户端倒计时只用于展示。
预留少量时间误差
如果活动有严格的截止时间,不宜将支付平台的失效时间设置在业务截止时间之后。设置时还要考虑网络延迟、服务端时钟误差和下单请求耗时。
简单来说,timeout_express 回答“还能支付多久”,time_expire 回答“最晚支付到几点”。统一支付时长使用前者,固定截止时间使用后者。
备注:内容仅供参考。
