支付回调等接口必须强制绕过缓存,应通过location正则直接禁用proxy_cache,或用map配合proxy_cache_bypass与proxy_no_cache实现细粒度控制,并拦截敏感响应头、非200状态码及添加调试头验证生效。

支付回调、Webhook、订单通知等业务目录必须强制绕过缓存,否则可能造成重复处理、状态错乱或资金风险。这类接口本质是非幂等、强状态依赖、且通常不带用户会话,仅靠路径特征就可精准识别和拦截。
用 location 正则匹配直接关闭缓存
最简明可靠的方式是在对应路径的 location 块中彻底禁用缓存功能,不依赖变量判断:
- 对所有以 /pay/notify、/webhook/、/callback/ 开头的请求,直接关闭 proxy_cache:
location ~ ^/(pay|webhook|callback|notify|order/status) {
proxy_pass http://backend;
proxy_cache off;
}
该写法无需 map、无需变量、不查缓存也不存缓存,语义清晰,运维友好,适合关键路径。
配合 proxy_cache_bypass + proxy_no_cache 实现细粒度控制
若需保留缓存能力(例如同一服务下部分子路径仍可缓存),推荐用 map 提前定义路径规则,再成对启用绕过指令:
- 在 http 块中定义路径标识变量:
map $request_uri $skip_payment_cache {
~*^/pay/notify 1;
~*^/webhook/alipay 1;
~*^/api/v1/order/callback 1;
default 0;
} - 在对应 location 中同步启用两个指令:
proxy_cache_bypass $skip_payment_cache;
proxy_no_cache $skip_payment_cache;
这样既跳过缓存读取,也阻止响应写入缓存,双重保险。
补充防护:拦截非 GET 方法与敏感响应头
支付回调虽多为 POST,但不能只依赖方法判断——有些系统用 GET 携带签名参数回调。建议叠加防护:
- 禁止缓存含 Set-Cookie 或 X-Order-Status 等业务头的响应:
proxy_ignore_headers Set-Cookie X-Order-Status; - 对返回非 200 的响应(如验签失败返回 400),避免被缓存污染:
proxy_cache_valid 400 401 403 0s; - 添加调试头验证效果:
add_header X-Cache-Status $upstream_cache_status;
确保回调请求响应头中为 BYPASS 或无该字段,而非 HIT/MISS。
验证是否真正生效
绕过配置容易“看起来生效”,实则漏判。建议三步验证:
- 用 curl 模拟真实回调请求:
curl -X POST https://yoursite.com/pay/notify -d "out_trade_no=abc"
检查响应头中 X-Cache-Status 是否缺失或为 BYPASS; - 查看 Nginx access 日志,确认该路径请求的 $upstream_cache_status 字段值为 - 或 BYPASS;
- 临时在后端加日志输出,确认每次回调都触发了新执行逻辑,而非返回旧缓存内容。


















