Google Checkout 生产环境 Notification API callbacks 无通知
结论
Sandbox 和 production 是两个独立环境。Sandbox 中配置的 callback URL、Merchant ID、Merchant Key 及订单不会自动迁移到生产环境。
如果生产环境完全没有收到通知,Integration Console 也是空的,通常表示 Google Checkout 尚未尝试向该生产账户的回调地址发送请求。请先检查:
- callback URL 是否配置在生产商户账户中,而不只是在 Sandbox 中配置。
- 生产交易是否使用生产环境的 Merchant ID、Merchant Key 和 Checkout endpoint。
- 是否确实创建并推进了一笔生产订单,使其进入会触发 notification 的状态。
- SSL 证书、DNS、防火墙和公网访问是否符合生产环境要求。
如果 Integration Console 中已经出现回调错误,再检查应用的身份验证、XML 解析和 acknowledgment 响应。
Google Checkout 已经停止服务。以下内容仅适用于维护历史系统、归档环境或兼容旧接口,不能用于重新开通生产服务。
先确认生产环境配置
登录生产商户账户,进入 Integration Settings,检查以下设置:
- API callback URL 是完整的 HTTPS 地址。
- URL 指向生产服务器,而不是 Sandbox、测试域名或内网地址。
- Notification API 已启用,并选择了应用实际支持的通知格式。
- 保存设置后重新进入页面,确认修改已经生效。
- 生产系统使用生产账户对应的 Merchant ID 和 Merchant Key。
不要混用两套凭据。即使 callback 程序完全相同,Sandbox 凭据也不能用于生产订单或生产通知的身份验证。
还要核对创建 Checkout 请求时使用的 endpoint。历史接口的 Sandbox 地址和生产地址不同,具体地址应以该系统当年采用的 Google Checkout API 文档及客户端库版本为准。不要仅靠删除 URL 中的 sandbox 字样来推断生产地址。
确认是否真正触发了通知
保存 callback URL 本身不会产生 notification。只有在生产环境中完成一笔能够触发通知的交易,或使订单状态发生相应变化,系统才会发送通知。
排查时记录以下信息:
- 生产订单号;
- 下单时间及服务器时区;
- 使用的 Merchant ID;
- Checkout 请求实际提交到的 endpoint;
- 买家是否完成结账;
- 订单是否进入预期状态。
如果订单仍然创建在 Sandbox,生产账户的 Integration Console 不会留下记录。
生产测试可能涉及真实支付和费用。测试前应确认当时账户适用的测试政策,不要向生产环境提交虚构卡号,也不要假设生产环境支持 Sandbox 测试凭据。
检查 HTTPS 和网络连通性
生产环境对 HTTPS 的验证通常比内部测试严格。callback 地址至少应符合以下要求:
- 使用受信任 CA 签发且未过期的证书;
- 证书域名与 callback 主机名一致;
- 服务器发送完整的证书链;
- 不使用自签名证书;
- 公网 DNS 能够正确解析;
- 目标端口可以从互联网访问;
- 防火墙、WAF、反向代理或 CDN 未拦截 Google Checkout 的请求;
- callback 不要求浏览器登录、验证码或交互式跳转;
- HTTPS URL 不会先重定向到 HTTP。
还需检查 IPv4、IPv6 和多节点部署。如果域名解析到多个地址,其中任何一个节点配置错误,都可能导致间歇性失败。
可以按照生产订单的下单时间,在服务器访问日志中搜索 callback 路径。如果完全找不到请求记录,应继续检查生产账户配置、订单所在环境、DNS 和外围网络。如果访问日志中有请求,但应用日志中没有记录,则需要检查反向代理路由和访问控制。
正确处理 callback
回调处理程序应读取原始 POST body,使用生产凭据验证请求,解析 XML,并返回该 notification 对应的 acknowledgment。不要返回普通 HTML 页面,也不要只记录通知后返回空响应。
下面是一个简化的处理结构,用于说明主要流程。XML namespace 和认证方式必须与历史系统实际启用的 Google Checkout Notification API 模式一致:
receive HTTPS POST
↓
validate production credentials
↓
read raw request body
↓
parse XML securely
↓
extract serial-number
↓
persist notification idempotently
↓
return notification-acknowledgment
示例响应:
<?xml version="1.0" encoding="UTF-8"?>
<notification-acknowledgment
xmlns="http://checkout.google.com/schema/2"
serial-number="SERIAL_NUMBER_FROM_NOTIFICATION" />
serial-number 必须取自当前 notification,不能写成固定值。namespace 也必须与收到的消息及所用 API schema 匹配。
下面是较接近实际应用的伪代码:
async function handleGoogleCheckoutCallback(req, res) {
const rawXml = await readRawBody(req);
if (!authenticateWithProductionCredentials(req)) {
res.statusCode = 401;
res.end();
return;
}
const notification = parseXmlSecurely(rawXml);
const serialNumber = notification.serialNumber;
await saveNotificationIdempotently(serialNumber, rawXml);
res.statusCode = 200;
res.setHeader("Content-Type", "application/xml; charset=UTF-8");
res.end(`<?xml version="1.0" encoding="UTF-8"?>
<notification-acknowledgment
xmlns="http://checkout.google.com/schema/2"
serial-number="${escapeXml(serialNumber)}" />`);
}
这段代码只用于说明流程,不能直接替代旧版 Google Checkout SDK 的完整实现。实际字段位置、认证头和 schema 版本,应以现有集成收到的报文为准。
常见应用层问题
如果 Integration Console 中已经出现请求或错误,请逐项检查:
- 返回状态是否为
2xx; - 响应是否在超时前完成;
Content-Type是否正确;- acknowledgment XML 格式是否正确;
serial-number是否与请求一致;- Web 框架是否提前解析或破坏了原始 XML body;
- Basic Authentication 或其他历史认证配置是否使用生产 Merchant Key;
- XML namespace 是否被解析器忽略或错误处理;
- 数据库异常是否导致接口返回
500; - CSRF 防护是否误拦截服务端 callback;
- callback 路由是否只允许
GET,没有正确接受POST。
通知可能重复投递,因此应使用 serial-number 或业务事件标识进行幂等处理。可以先持久化原始报文,再异步执行耗时业务,避免内部处理过慢,无法及时返回确认响应。
推荐排查顺序
- 在生产商户账户中重新确认并保存 callback URL。
- 核对生产 Merchant ID、Merchant Key 和 Checkout endpoint。
- 确认一笔真实的生产订单已经成功创建,并发生了与通知对应的状态变化。
- 查看 Web 服务器、负载均衡器、WAF 和应用日志。
- 从公网验证 DNS、TLS 证书链及 callback 路径的可访问性。
- 如果 Integration Console 中出现错误,根据 HTTP 状态码和响应内容修正认证或 acknowledgment。
- 如果控制台始终为空,服务器也没有请求记录,请先确认账户仍具备历史服务能力,再联系相应的账户支持渠道,并提供 Merchant ID、订单号、发生时间、时区和 callback URL。
最重要的判断是,Integration Console 为空通常不表示 XML 响应有误,而是生产环境尚未产生 notification,或者 Google Checkout 尚未尝试投递。先确认生产账户、生产凭据、生产 endpoint 和实际订单全部对应同一环境,再检查回调代码。
备注:内容仅供参考。
