支付宝网页支付返回 missing-timestamp 错误如何处理?
结论
missing-timestamp 表示提交到支付宝网关的请求缺少有效的公共参数 timestamp。调用网页支付接口时,需要把 timestamp 放在请求顶层,通常使用 yyyy-MM-dd HH:mm:ss 格式,并在生成签名前加入请求参数。
使用支付宝官方 SDK 时,建议直接输出 SDK 生成的完整支付表单。不要自行拆分、拼接或过滤表单字段,以免遗漏 timestamp 或造成签名失效。
常见原因
该错误通常由以下情况引起:
- 请求中没有
timestamp。 timestamp被错误地放进了biz_content。- 参数名写成了
timeStamp、time_stamp等其他形式。 - 生成签名后才添加
timestamp,导致请求参数与签名不一致。 - 嵌入 SDK 返回的 HTML 表单时,只保留了部分隐藏字段。
- 手动拼接支付 URL 时遗漏了
timestamp,或对其进行了错误编码。 - 前端重新组装参数时过滤掉了空值字段。
网页支付请求使用的是商户发起请求时的时间戳,不是支付宝异步通知中的 notify_time,也不是 JavaScript 毫秒时间戳。
正确的参数位置
以 alipay.trade.page.pay 为例,timestamp 应与 app_id、method、format、charset、sign_type 等公共参数处于同一层级:
app_id=商户应用ID
method=alipay.trade.page.pay
format=JSON
charset=utf-8
sign_type=RSA2
timestamp=2026-09-09 14:30:00
version=1.0
notify_url=https://example.com/alipay/notify
return_url=https://example.com/alipay/return
biz_content={...}
sign=签名值
不要把它写进 biz_content:
{
"biz_content": {
"out_trade_no": "ORDER_202609090001",
"total_amount": "100.00",
"subject": "订单支付",
"product_code": "FAST_INSTANT_TRADE_PAY",
"timestamp": "2026-09-09 14:30:00"
}
}
timestamp 是公共请求参数,不属于业务参数 biz_content。
使用官方 SDK 生成支付表单
官方 SDK 通常会根据配置自动生成公共参数并完成签名。以下是 Java SDK 的典型用法:
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
appId,
merchantPrivateKey,
"json",
"UTF-8",
alipayPublicKey,
"RSA2"
);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl("https://example.com/alipay/return");
request.setNotifyUrl("https://example.com/alipay/notify");
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setTotalAmount("100.00");
model.setSubject("订单支付");
model.setProductCode("FAST_INSTANT_TRADE_PAY");
request.setBizModel(model);
AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
if (response.isSuccess()) {
String formHtml = response.getBody();
// 将完整表单 HTML 返回给浏览器
} else {
// 记录 response.getCode()、response.getSubCode() 和 response.getSubMsg()
}
这里要完整输出 response.getBody(),不要只提取其中的 biz_content、sign 或部分 <input> 标签,然后重新生成表单。
服务端可以直接返回 SDK 生成的内容:
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write(formHtml);
如果需要将表单嵌入现有页面,也必须保留 SDK 生成的全部隐藏字段和表单提交逻辑。
手动组装请求时的处理方式
如果项目没有使用官方 SDK,需要在签名前生成时间戳:
String timestamp = java.time.LocalDateTime.now()
.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
params.put("timestamp", timestamp);
之后按支付宝接口要求处理:
- 准备全部公共参数和业务参数。
- 将
timestamp加入顶层参数集合。 - 对待签名参数排序并生成签名。
- 添加
sign参数。 - 正确进行 URL 编码。
- 通过表单
POST或接口规定的方式提交到支付宝网关。
必须先加入 timestamp,再计算签名:
Map<String, String> params = new HashMap<>();
params.put("app_id", appId);
params.put("method", "alipay.trade.page.pay");
params.put("format", "JSON");
params.put("charset", "utf-8");
params.put("sign_type", "RSA2");
params.put("timestamp", timestamp);
params.put("version", "1.0");
params.put("biz_content", bizContent);
// 此时再使用私钥对待签名内容签名
String sign = createSign(params, merchantPrivateKey);
params.put("sign", sign);
createSign 的具体实现应遵循当前支付宝接口文档,也可以直接使用官方 SDK。不要自行猜测参数排序、字符集或编码规则。
排查网页嵌入过程
在浏览器开发者工具的 Network 面板中找到提交至支付宝网关的请求,检查其中是否包含以下参数:
timestamp: 2026-09-09 14:30:00
如果请求中没有该字段,问题出在表单生成或页面嵌入环节。如果页面源代码中有该字段,但实际请求中没有,需要检查 JavaScript 是否重建了表单或过滤了隐藏字段。
表单应包含类似内容:
<form method="post" action="https://openapi.alipay.com/gateway.do">
<input type="hidden" name="app_id" value="...">
<input type="hidden" name="method" value="alipay.trade.page.pay">
<input type="hidden" name="timestamp" value="2026-09-09 14:30:00">
<input type="hidden" name="biz_content" value="...">
<input type="hidden" name="sign" value="...">
<button type="submit">支付</button>
</form>
这段代码只用于说明字段位置。实际请求应优先使用 SDK 生成,不能直接照搬示例中的省略值。
注意事项
- 参数名必须写成小写的
timestamp。 - 时间格式不能使用 Unix 秒数或 JavaScript 毫秒数,例如
1788935400000。 - 不要把
timestamp放入biz_content。 - 修改
timestamp后必须重新计算sign。 - 生成签名和提交请求时应使用相同的字符集,常见配置为
UTF-8。 - 不要再次对 SDK 返回的整个表单进行 HTML 转义,否则可能破坏字段内容。
- 如果服务器时间明显不准确,应先同步系统时间。即使字段存在,异常时间也可能引发其他请求校验错误。
- 沙箱环境和正式环境应分别使用对应的网关、应用配置和密钥,不能混用。
最稳妥的处理方式是由服务端使用支付宝官方 SDK 创建网页支付请求,再将 SDK 返回的完整表单原样交给浏览器提交。这样既能避免嵌入页面时遗漏 timestamp,也能减少签名和编码错误。
备注:内容仅供参考。
