PAYATHON 2026

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 后仍然失败,可以按以下顺序检查:

  1. 浏览器开发者工具中的 JavaScript 错误。
  2. payments_get_items 接口的原始响应正文和 HTTP 状态码。
  3. Facebook 能否通过公网访问图片和商品页面。
  4. 服务端日志中是否出现 warning、超时或响应格式错误。
  5. 应用的支付配置、商品状态和测试账号权限。

FB.ui({ method: 'pay' }) 和 payments_get_items 都属于 Facebook 的旧版支付接口。如果当前项目仍在运行,而不是只维护历史代码,还需要先确认该接口及对应产品类型是否仍受支持。如果接口已经停用,仅修改 callback 或商品数据无法恢复支付功能。

备注:内容仅供参考。