PAYATHON 2026

Facebook Payment API 仅返回 created_time

支付小周

结论

只返回 created_time,通常不表示支付记录缺失,也无法据此判断支付是否成功。常见原因是请求没有通过 fields 指定返回字段,或者访问令牌无权读取完整的 Payment 对象。

支付状态通常记录在 actions 字段中,不要假定 Payment 对象一定有顶层 status 字段。查询时应明确请求 actions 等所需字段,并使用创建该支付的应用所对应的有效访问令牌。

原则上,Test User payment 和 live payment 的返回结构相同,主要区别是测试支付不会产生真实的资金结算。如果字段和令牌均正确,测试支付仍然只返回 created_time,可能是旧版 Graph API 的测试支付行为异常,也可能是平台问题,需要用最小化请求继续确认。

正确查询方式

不要只请求 Payment ID:

GET https://graph.facebook.com/v3.1/{payment_id}

应明确指定所需字段,例如:

GET https://graph.facebook.com/v3.1/{payment_id}?fields=id,created_time,actions,items,user,application&access_token={access_token}

使用 cURL 时可以写成:

curl -G \
  "https://graph.facebook.com/v3.1/${payment_id}" \
  --data-urlencode "fields=id,created_time,actions,items,user,application" \
  --data-urlencode "access_token=${access_token}"

具体支持哪些字段,应以对应 Graph API 版本的 Payment 对象定义为准。如果同时请求多个字段后收到字段不存在的错误,可以逐个减少字段,不要直接删除 fields 参数。

如何判断支付状态

Payment 的状态信息通常在 actions 数组中。典型结构如下:

{
  "id": "PAYMENT_ID",
  "created_time": "2018-01-01T12:00:00+0000",
  "actions": [
    {
      "type": "charge",
      "status": "completed",
      "currency": "USD",
      "amount": "1.00",
      "time_created": "2018-01-01T12:00:00+0000",
      "time_updated": "2018-01-01T12:00:01+0000"
    }
  ]
}

业务代码需要找到对应的支付动作,并检查其 status,例如:

function isPaymentCompleted(payment) {
  return Array.isArray(payment.actions) &&
    payment.actions.some(action =>
      action.type === 'charge' &&
      action.status === 'completed'
    );
}

不要只检查 HTTP 状态码、created_time 或 Payment ID。这些信息只能说明对象存在或请求成功,不能证明付款已经完成。

支付验证还应核对以下内容:

  • Payment 是否属于当前应用;
  • 用户和订单标识是否与本地订单一致;
  • 商品、币种和金额是否符合预期;
  • 是否存在退款、拒付或其他后续动作;
  • 同一 Payment ID 是否已经处理过,以免重复发货。

Test User payment 的预期结果

接口权限和请求字段相同时,Test User payment 应返回与 live payment 基本相同的对象结构,包括已请求且有权读取的 actions、items、user 等字段。

测试支付主要有以下特点:

  • 用于验证支付流程和回调处理;
  • 不代表真实扣款或实际结算;
  • 某些结算、退款或争议数据可能不如真实生产支付完整;
  • 仍应提供足够的信息,用于判断测试交易的状态。

因此,不应把”测试支付只会返回 created_time”当作正常业务规则。如果明确请求 actions 后仍未返回,应继续检查访问令牌、应用归属,以及测试支付是否完成了确认流程。

Live payment 的预期结果

即使是 live payment,在未指定 fields 时也不保证自动返回文档列出的全部字段。Graph API 的对象文档列出的是可查询字段,并不表示默认响应会包含所有字段。

授权正确并明确请求字段后,生产支付通常会返回服务端验证所需的数据。如果 actions 为空、缺失或状态尚未完成,业务端不应发货,而应等待支付更新通知或再次查询。

排查步骤

建议依次检查:

  1. 在请求中加入 fields=id,created_time,actions,先验证最重要的字段。
  2. 确认 payment_id 完整,并且对应的支付由当前应用创建。
  3. 确认访问令牌来自同一个应用,而且尚未失效。
  4. 检查响应中是否有 error、权限提示或字段级错误。
  5. 确认测试用户已经完成支付确认,而不是只创建了支付对象。
  6. 使用同一请求分别查询一笔测试支付和一笔已知完成的 live payment,对比两者的 actions。
  7. 记录完整响应、请求时间、Graph API 版本和 Payment ID,然后向 Meta 开发者支持渠道报告。

诊断时可以先请求:

GET /v3.1/{payment_id}?fields=id,created_time,actions

如果 actions 能正常返回,再逐步加入其他字段。这样更容易判断问题出在字段选择上,还是支付对象的数据本身存在异常。

是否有其他开发者遇到过

类似情况可能发生,常见原因包括:

  • 误以为对象文档中的字段都会默认返回;
  • 请求没有使用 fields;
  • 使用了其他应用的访问令牌;
  • 测试支付没有走完完整流程;
  • Graph API 旧版本在测试支付环境中存在行为差异。

不过,仅凭”只返回 created_time”无法确认这是普遍的平台故障,也不能断定所有 Test User payment 都会如此。只有在 API 版本、字段列表和应用令牌均相同,而且支付已经完成的条件下仍能稳定复现,才更可能是 Facebook 平台侧异常。

注意事项

Graph API v3.1 已经是历史版本。旧版接口的实际行为和权限模型可能与当前平台不同,通常也不适合作为新系统的实现依据。维护遗留系统时,应保留当时的完整请求和响应以便排查。如果准备重新接入,应以当前 Meta 官方文档和仍受支持的产品能力为准。

无论使用测试支付还是生产支付,都应由服务端验证支付结果。客户端提交的 status、金额或商品信息不能直接作为发货依据。

备注:内容仅供参考。