Facebook javascript payment dialog 加载后消失且未调用 callback
结论
问题不在 fbPurchaseCallback,而是 payments_get_items 返回的商品数据没有通过 Facebook 支付对话框的完整校验。代码中最明显的问题是:
image_url: "images/coin.png"
product_url: "images/coin.png"
这两个值都是相对路径,且 product_url 指向的还是图片。它们必须是 Facebook 服务器可以直接访问的完整 URL,其中 product_url 应指向商品介绍页面。校验失败后,旧版支付对话框可能直接关闭,不一定会调用 JavaScript callback。
修正方法
将相关地址改为公开可访问的绝对 HTTPS URL:
FB.ui({
method: 'pay',
order_info: {
pkgnum: d.id,
title: d.name,
description: d.desc,
price: d.cost,
image_url: 'https://example.com/images/coin.png',
product_url: 'https://example.com/products/coin-package',
userid: username
},
purchase_type: 'item'
}, fbPurchaseCallback);
payments_get_items 的响应也要返回相同的有效地址:
{
"content": [
{
"pkgnum": 20,
"title": "Lolname",
"description": "Loldesc",
"price": 100,
"image_url": "https://example.com/images/coin.png",
"product_url": "https://example.com/products/coin-package",
"userid": "254884",
"item_id": "254884"
}
],
"method": "payments_get_items"
}
还需要检查以下几点:
- URL 无需登录,也不依赖 Cookie 或来源页 Referer。
- URL 不会重定向到登录页,也不会返回 404 页面或证书错误。
image_url返回真实图片,并带有正确的Content-Type。product_url指向商品页面,不能与image_url指向同一张图片。- 回调页面只输出 Facebook 要求的 JSON,不能混入 PHP warning、HTML、调试文本或 UTF-8 BOM。
price符合该版 API 要求的数值类型和有效范围。
为什么修改 price 后反而能看到错误
把 price 改成明显错误的类型后,请求会在较早的参数校验阶段失败。Facebook 因而能够显示结构化错误,并将错误结果传给 fbPurchaseCallback。
原数据可能通过了初步校验,之后才在解析商品 URL、图片或服务器响应时失败。旧版支付 UI 对这类后续错误的处理并不稳定,常见表现是 loading 消失、窗口关闭,同时没有执行页面中的 callback。
不要在查询商品时完成发货
payments_get_items 只用于读取商品信息。Facebook 请求了这个接口,并不表示付款已经成功,因此不能在这个阶段增加余额、发放商品或将订单标记为已支付。
数据库变更应放在支付状态更新流程中,并且只能在服务端确认支付成功后执行。处理逻辑还要具备幂等性,避免同一订单因重复通知而多次发货。
调试建议
如果改用完整 URL 后仍然失败,可以按以下顺序检查:
- 浏览器开发者工具中的 JavaScript 错误。
payments_get_items接口的原始响应正文和 HTTP 状态码。- Facebook 能否通过公网访问图片和商品页面。
- 服务端日志中是否出现 warning、超时或响应格式错误。
- 应用的支付配置、商品状态和测试账号权限。
FB.ui({ method: 'pay' }) 和 payments_get_items 都属于 Facebook 的旧版支付接口。如果当前项目仍在运行,而不是只维护历史代码,还需要先确认该接口及对应产品类型是否仍受支持。如果接口已经停用,仅修改 callback 或商品数据无法恢复支付功能。
备注:内容仅供参考。
