Firefox OS privileged packaged app 无法获取 fxpay 商品
结论
404 BAD_API_RESPONSE 并不表示”商品列表为空”,而是 Firefox Marketplace 无法根据请求中的应用标识找到对应的应用。
日志显示,fxpay 使用的 origin 是:
http://url10.infinitgame.com
因此,请求地址变成了:
/api/v1/payments/http%3A%2F%2Furl10.infinitgame.com/in-app/
但这个 privileged packaged app 在清单中声明的应用源是:
app://url10.infinitgame.com
这两个 origin 并不相同。最常见的情况是,fxpay 实际运行在远程游戏门户页面中,而不是打包应用的 app:// 上下文中。
使用 real products 还有一个前提:应用已在 Firefox Marketplace 中建立对应记录,商品也归属于这个应用标识。至于应用是否必须”公开发布”,需要区分以下情况:
- 应用必须先提交或注册到 Marketplace,才能为其创建真实商品并配置支付。
- 是否需要向所有用户公开,取决于当时 Marketplace 的审核和发布流程。但未提交、未签名,或者仅通过 Simulator 本地安装的包,不能算作完整的 production Marketplace 应用。
- Firefox OS Simulator 无法完整验证真实的运营商或 Bango 支付流程。最终测试需要在受支持的真实设备、国家和支付环境中完成。
为什么 fake products 可以正常工作
fake products 是 fxpay 在客户端生成的测试数据。它不查询 Marketplace,也不要求应用具有有效的 Marketplace 身份。
关闭 fake products 后:
fxpay.configure({
fakeProducts: false
});
fxpay 会读取当前安装应用的信息,例如 navigator.mozApps.getSelf() 返回的应用对象及其 origin,然后访问 Marketplace 的商品 API。
如果 fxpay 运行在这个远程页面中:
http://url10.infinitgame.com
它拥有的只是普通 Web origin。即使该页面由 packaged app 打开,也不会自动继承:
app://url10.infinitgame.com
Marketplace 收到的因而是网站 origin,而不是 packaged app origin。应用标识不存在时,接口会返回 404 {"detail":"Not found"}。如果应用存在,只是没有启用任何商品,通常会成功返回一个空列表,而不是返回应用级别的 404。
将支付逻辑放回 packaged app
fxpay 库和调用支付 API 的代码应包含在应用包内,并由 app://url10.infinitgame.com 页面执行。例如:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>T-Games</title>
<script src="/js/fxpay.min.js"></script>
<script src="/js/payments.js"></script>
</head>
<body>
<div id="portal"></div>
</body>
</html>
payments.js 可以先检查当前应用身份:
navigator.mozApps.getSelf().onsuccess = function () {
var app = this.result;
console.log("Installed app:", app);
console.log("App origin:", app && app.origin);
console.log("Manifest URL:", app && app.manifestURL);
if (!app) {
console.error("This page is not running as an installed packaged app");
return;
}
fxpay.configure({
fakeProducts: false
});
fxpay.getProducts().then(function (products) {
console.log("Products:", products);
}).catch(function (error) {
console.error("Error getting products:", error);
});
};
不同版本的 fxpay 可能使用略有差异的 Promise API,但有一点不变:调用代码必须运行在已安装 packaged app 的上下文中。
如果游戏门户仍需从服务器加载,可以由 packaged app 通过 XHR 获取数据,也可以把远程内容放进 iframe。支付操作应交给 packaged app 的父页面处理,远程页面通过 postMessage 请求父页面发起购买。不要让 iframe 或跳转后的远程页面直接调用 fxpay。
核对 Marketplace 中的应用 origin
Marketplace 商品必须绑定到同一个应用记录。请确认以下三处完全一致:
- 安装后的应用对象:
navigator.mozApps.getSelf().onsuccess = function () {
console.log(this.result.origin);
console.log(this.result.manifestURL);
};
- 提交到 Marketplace 的 packaged app manifest。
- 创建 real products 时选择的 Marketplace 应用。
如果安装后的结果是:
app://url10.infinitgame.com
商品 API 就应按这个 origin 查询,而不是使用:
http://url10.infinitgame.com
不要试图通过手工拼接 API URL 修复这个问题。应先修正 fxpay 的执行环境和应用安装方式,让它从已安装的应用对象中读取正确身份。
另外:
"developer": {
"url": "http://url0.infinitgame.com"
}
这里填写的是开发者信息,不会决定支付 API 使用哪个应用 origin。
manifest 建议
可以继续使用自定义 packaged-app origin,但它必须与 Marketplace 中登记并签名的应用保持一致:
{
"version": "1.0.0",
"name": "T-Games",
"description": "T-games service de malade",
"launch_path": "/index.html",
"type": "privileged",
"origin": "app://url10.infinitgame.com",
"icons": {
"16": "/img/icon-16.png",
"48": "/img/icon-48.png",
"128": "/img/icon-128.png"
},
"developer": {
"name": "Serial Screener",
"url": "http://url0.infinitgame.com"
},
"permissions": {
"systemXHR": {
"description": "Required to access payment API"
}
},
"chrome": {
"navigation": true
},
"csp": "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"
}
如果 Marketplace 在提交过程中为应用分配了其他 app:// origin,应以实际安装后的 app.origin 和 Marketplace 应用记录为准。创建商品或发放收据后,不要随意修改 origin。对支付系统来说,新的 origin 通常意味着另一个应用。
原配置中的:
"default-src *"
范围过宽。虽然这不是此次 404 的直接原因,但 privileged app 应尽量限制允许加载和连接的来源。如果需要访问远程游戏服务,可以明确添加 connect-src、img-src 或 frame-src,不必开放所有默认来源。
推荐的排查顺序
- 确认 fxpay 文件确实包含在 ZIP 包内,而不是只部署在游戏门户服务器上。
- 确认调用
fxpay.getProducts()的页面仍是app://...页面,没有提前跳转到http://...。 - 输出
navigator.mozApps.getSelf()的origin和manifestURL。 - 确认 Marketplace 中的商品属于同一个应用记录,并且处于 active 状态。
- 从 Marketplace 提供的正式或审核安装渠道安装签名包,不要只根据 Simulator 的本地开发安装结果判断 production payments 是否可用。
- 在真实 Firefox OS 设备上验证购买流程,同时检查国家、运营商、Bango 账户和商品可售区域是否匹配。
当前首先要修正的是请求中错误的 http:// 应用身份,而不是商品本身。只有让 fxpay 在正确的 packaged-app 上下文中运行,并确保该身份与 Marketplace 中的应用及商品记录一致,才能正确查询 real products。
备注:内容仅供参考。
