关于 onestore-web-sdk
面向 HTML5 游戏开发者的技能,用于集成 ONE store H5 Game SDK。它涵盖 SDK 设置、问题诊断和发布前检查,不负责游戏公司的服务器工作或 ONE store 注册。
主要功能
- 01SDK 集成与启动流程设置
- 02激励广告和应用内购买
- 03iframe 嵌入问题诊断
- 04故障排查与发布前检查
适用场景
- 01为 HTML5 游戏添加 SDK
- 02实现激励广告或应用内购买
- 03排查 ONE store 应用内的加载故障
- 04在发布前检查游戏
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ one-store/ onestore_web_sdk_skills --skill onestore-web-sdk安装后在 Claude Code 中输入/onestore-web-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/checks.mddiagnose.mdembed-requirements.mdgame-template.html.txtsdk-context.md详细介绍
ONE store H5 游戏 SDK 集成
帮助 HTML5 游戏开发者接入 ONE store H5 Game SDK、诊断问题,并在发布前检查游戏。ONE store 应用(Android WebView)会在 iframe 中加载游戏页面,SDK 负责处理与应用的所有通信。
重要
使用用户所用的语言回答。 此技能以英语编写,但大多数用户使用韩语。请使用用户所用的语言回答,并翻译所有展示的内容:表格标题、判定用语、填写表单,以及末尾的建议消息。仅保留结构。代码标识符、SDK 常量和
reason字符串保持不变。此技能中的菜单路径格式为韩语标签 (英语标签);请使用与用户所用语言相符的标签。发送前,请检查第一句话、表格标题和结尾建议是否使用了用户所用的语言。
此技能的功能
如果用户询问此技能能做什么,或未提出具体请求就调用此技能,请展示下表并立即运行状态检查。用户可以使用日常语言提出请求,无需知道流程名称。
| 命令 | 日常语言示例 | 操作 |
|---|---|---|
doctor | “ONE store 集成进展到哪一步了?” / “지금 어디까지 됐어?” | 状态检查。 用表格报告已有内容和缺少内容。不要编辑文件 |
integrate | “添加 ONE store SDK,让我可以发布这款游戏” / “원스토어 SDK 붙여줘” | 加载 SDK,接好启动流程(init → loading → start),并放置生命周期监听器 |
ads | “添加激励广告” / “리워드 광고 붙여줘” | 放置广告代码,包括 requestId 和奖励策略 |
iap | “添加应用内购买” / “결제 붙여줘” | 放置购买和商品查询代码,包括用于在服务端验证 purchaseToken 的钩子 |
embed | “只有在应用内才会失败” / “앱에서만 안 떠” | 检查 iframe 嵌入要求(references/embed-requirements.md) |
fix <原因或症状> | “屏幕一片空白” / “reason is no_fill” | 诊断。 提供原因、复现方法、修复方案和验证事项(references/diagnose.md) |
check | “运行发布前检查” / “릴리즈 전에 점검해줘” | 完整的发布前检查清单。不要编辑文件 |
命令词
用户可以直接使用命令词调用流程。在 Claude Code 中,格式为
/onestore-web-sdk <command>(例如 /onestore-web-sdk doctor),命令词会作为技能参数传入(ARGUMENTS: doctor)。其他工具调用技能的方式各不相同,有些用户也会直接在聊天中输入 onestore doctor 或 /원스토어 진단。这些用法一视同仁。
- 单独使用命令词表示立即运行相应流程。 不要询问用户想做什么。只有目标文件不明确时才询问(规则 3)
- 调用技能时未提供命令词 → 运行状态检查并展示上表
- 建议下一步操作时,先给出日常语言请求,因为这种表达适用于所有工具;然后再附上 Claude Code 格式
还要说明职责范围:游戏公司的服务端工作(接收回调、验证 purchaseToken、消耗购买项)以及 ONE store 注册(广告位 ID、商品、测试 URL)由用户负责;此技能不涵盖 ONE store 托管页面或应用。
需要用户提供的值
只有四项:三项来自 ONE store,另一项取决于游戏公司的服务器设计。 许多用户一开始并不知道需要准备什么,因此请提前告知,并说明每项值的获取方式。
| 值 | 获取方式 | 缺失时的影响 |
|---|---|---|
| SDK version | 联系用户的 ONE store 对接人,或查看发行说明。以 v 开头。如果对方没有特别说明,建议使用最新版本 v1.1.0 | 可以先使用 v1.1.0 继续操作 |
广告位 ID(placementId) | 在 ONEconsole 中申请:Apps >(游戏)> 수익화 > 인앱 광고(Monetization > In-App Ads),每种广告类型(激励广告、插屏广告)各需一个。参见 ONEconsole:인앱 광고(In-App Ads) | 所有广告请求都会失败,且没有备用方案 |
应用内商品 ID(productId) | ONEconsole:Apps >(游戏)> 수익화 > 인앱 상품(Monetization > In-App Products)。仅限托管商品 | 购买会因 invalid_request 而失败 |
requestId 的生成方式 | 由游戏公司的服务器设计决定。建议在服务器上生成,并将其映射到用户 | 无法判断回调通知中的奖励属于谁 |
索取值时,请提供可填写的表单
只说“缺少 X”会让用户不知道要获取什么、该去哪里获取。 请将以下表单按原样翻译成用户使用的语言,让他们复制、填写并粘贴回来。
SDK version: (leave blank to use the latest, v1.1.0)
Fill this in only if ONE store gave you a specific version. It starts with v.
It goes into the {{version}} part of the CDN URL.
Ad placement ID: (write it here, e.g. rewarded rew_xxxx, interstitial int_xxxx)
Request it in ONEconsole: Apps > (the game) > 수익화 > 인앱 광고
(Monetization > In-App Ads). Rewarded and interstitial
IDs are issued separately, so say which one this is.
In-app product ID: (write it here, e.g. gem_100, gem_1000)
The product ID registered in ONEconsole under 수익화 > 인앱 상품 (Monetization > In-App Products).
If there are several, list them all separated by commas. (Managed products only.)
requestId issuing: (server-issued / generated on the client)
The tracking key for rewarded ad rewards. The postback must tell you which user
the reward belongs to, so issuing it on your server and mapping it to the user
is recommended.
- 将值的空位留空。 如果预填示例值,有些用户会直接照用
- 不要使用真实值作为示例。 不要把你在项目中找到的 ID 填入表单。 已知的值可以在句子中提及,但表单中的值应留空
- 如果某项尚未注册或生成,请说明必须先完成 ONE store 侧的操作
- 收到值后,说明你将把它们填入哪个文件
无需等到拿到这些值才能开始集成。 加载 SDK、接好启动流程并添加监听器,将值的位置保留为 TODO,然后提供表单并暂停。不要因等待这些值而阻塞进度。
轮到你执行下一步时,告诉用户该怎么说
如果剩余工作由你来完成,用户只需提出请求。 如果你只是描述要做什么,用户会以为得自己动手,进而卡住。给出请求,而不是任务: 写成用户可以复制发送的内容,并放入代码块中,以便醒目展示。
Send this next:
Add a ONE store rewarded ad to the game
I will wire it with the reward policy (show the reward only on rewarded, grant it through
the server postback). In Claude Code you can also send /onestore-web-sdk ads.
After that:
Run the ONE store pre-release check
- 将每项请求与其结果配对,让用户清楚每项请求的作用,并自行选择
- 如果还有多个步骤,按顺序全部列出。 只提供当前步骤,会让用户每到一步都再次卡住
- 如果既有用户要做的工作(ONE store 注册、服务器代码),也有你要做的工作,请分开列出
核心规则
- 不要编造 SDK API。 只能使用
references/sdk-context.md中列出的方法、字段、事件和reason值。如果其中没有相关内容,请说明需要确认。即使其他平台的游戏 SDK(例如 Facebook Instant Games)中有看起来相似的名称,也不要映射使用。 - 从
references/game-template.html.txt获取集成代码。 这是基于官方示例的参考代码,涵盖启动流程、广告、购买和生命周期。将代码添加到现有游戏时,移动相关部分,但保留调用顺序和分支结构,尤其是err分支、奖励分支(仅rewarded)和reason分支。若代码放置后不适用,再进行调整。 - 根据证据确定目标。 如果没有证据表明游戏入口 HTML 和启动代码位于何处,或存在多个候选项,请先询问,不要猜测。
- 明确作答或提问。不要含糊其辞。 不要用“可能”或“通常”来回避。如果缺少作出判断所需的信息,请针对该信息提问。
- 引用证据时使用
path:line格式。 使用相对于项目根目录的路径加行号(例如index.html:47)。工具显示链接的方式各不相同,这种格式便于阅读,并且在大多数工具中都可点击。不要使用绝对路径或file://链接。没有证据位置的判断必须修正。提供公开指南的 URL 以供进一步阅读;参考文件供你使用,不要提供给用户。 - 以接下来的步骤收尾。 不要以你做了什么收尾。如果下一步由用户完成,请给出具体到可立即操作的步骤(菜单路径、完整命令)。如果由你完成,请提供用户可以发送的请求。如果因缺少值而暂停,请说明需要提供哪些内容才能继续。如果没有后续事项,请明确说明。用户问“我现在该做什么?”就说明没有遵守此规则。
- 不要覆盖现有文件。 展示现有内容并询问。
- 范围仅限游戏客户端代码。 对于游戏公司的服务端(postback 和 PNS 接收、
purchaseToken验证、消耗处理),只创建钩子,并说明实现由用户负责。不要搭建服务端框架。
首先:状态检查(doctor)
对于开放式请求(“添加它”“进展如何?”“现在该做什么?”)、未提出请求时调用此技能,或尚不清楚项目状态时,先运行状态检查。即使在集成过程中也必须如此:阅读文件后再作判断,不要凭记忆回答。
- 按照
references/checks.md中的清单 A - 只读,不要编辑任何文件
- 仅使用以下四种判断:已存在 / 缺失 / 不适用 / 需要确认。按照规则 5 使用
path:line格式引用证据 - 展示完整表格。 目的是展示已完成的内容(发布前检查则相反,只列出需要修复的内容)
- 在表格下方给出下一步(规则 6)。如果缺少值,请提供表单(仅列出缺失值);如果下一步由你完成,请提供用户可以发送的请求
- 除非用户已告知你继续,否则到此为止,让用户选择
集成步骤
仅处理状态检查发现的缺失项。
1. 加载 SDK
将其放在游戏入口 HTML 文档的顶层,且位于游戏脚本之前。
<script type="module">
import { createSDK } from "https://h5sdk.onestore.net/lib/v1.1.0/onestore-h5-sdk.min.js";
</script>
- 版本号以
v开头。使用用户提供的版本,否则使用最新版本v1.1.0。 不要因为版本号而停止进度 - 如果游戏自行创建了 iframe,初始化会在其中失败。必须放在游戏文档的顶层
- 如果游戏使用打包工具(例如 webpack),请将导入放在游戏入口最前面,并检查其运行顺序与直接从 HTML 加载时一致
- 仅靠标签顺序无法保证执行顺序。
type="module"会在文档解析完成后运行,因此即使普通<script src>标签写在 SDK 标签之后,游戏脚本也会先于 SDK 运行。为游戏脚本添加type="module"或defer,使其在 SDK 之后运行,并且只有在startGameAsync()成功后才启动游戏
2. 启动流程和生命周期
将 references/game-template.html.txt 中的脚本部分放入适合游戏启动代码的位置。必需的调用顺序和规则定义在 references/sdk-context.md 中。放置后,务必告知用户:
-
在调用
initializeAsync()之前注册监听器(pause/resume/exit)。 初始化后事件可能立即到达 -
在
exit中,只能在 0.5 秒内同步保存。 无需再次调用quit()。游戏自行调用quit()时不会触发exit,因此要在调用它之前保存 -
onBackPressed必须是同步函数。 应用会等待 200 ms 获取结果 -
不支持的环境会返回
err,而不是拒绝。不要移除if (info.err)分支。在该分支中,应让游戏在不使用 SDK 的情况下仍可游玩(只关闭广告和购买界面),这样游戏在开发期间也能在普通浏览器中运行 -
将加载进度与实际资源加载关联起来。模板中的演示计时器只是占位内容
-
如果游戏将对象保存在全局变量中,不要让它与某个元素的
id同名。 浏览器会将带有id的元素作为同名属性暴露在window上。使用<canvas id="game">时,在游戏代码覆盖它之前,window.game就是该 canvas;先运行的启动代码会因此报错:window.game.start is not a function。请使用以游戏命名的全局变量(例如window.StarCatcher),并让启动代码在调用前检查对象是否就绪 -
当 SDK 代码和游戏代码位于不同脚本中时,调用游戏对象前要等待它就绪。 SDK 脚本会先运行,而
initializeAsync()的结果可能在游戏脚本运行前就已返回(在普通浏览器中几乎会立即返回)。此时调用游戏对象会抛出错误,导致游戏无法启动。SDK 代码中对游戏的所有调用(err分支、startGameAsync之后、pause/resume、ringerSilent)都应通过类似下面的辅助函数进行:// Game scripts load with type="module" or defer, so they have all run by DOMContentLoaded function whenGame(fn) { if (window.MyGame) fn(window.MyGame); else document.addEventListener("DOMContentLoaded", () => fn(window.MyGame), { once: true }); } // whenGame((game) => game.start());如果游戏对象是在脚本顶层创建的,这种方式就可行。如果游戏稍后才创建该对象(例如加载资源之后),则让游戏自行发送“ready”信号
3. 广告
放置代码前,请检查是否存在 placementId。如果没有,请放置包含 TODO 的代码,并通过表单询问其值。放置代码后,务必告知用户以下三点,因为每一点都可能引发事故:
- 仅当
status === "rewarded"时才发放奖励。dismissed和failed(包括no_fill)都不代表已获得奖励 - 不要根据客户端的
rewarded结果发放奖励。 奖励需通过 SSV → 验证 → 游戏公司的服务器回调确认,游戏应向自己的服务器查询奖励是否已发放。另行说明,接收回调是用户的责任 - 激励广告必须提供
requestId。 SDK 不会生成此 ID。建议由服务器签发,并将其与用户关联
如果用户还没有广告位 ID,请按以下顺序告知他们在 ONEconsole 中的操作步骤(来源: ONEconsole:应用内广告(In-App Ads),英文版 https://onestore-dev.gitbook.io/dev/eng/docs/apps/product/monetization/iaa):
在 Apps 下选择游戏后,这两个菜单都会显示在游戏侧边栏中。
- 在 상품관리 > Web 상품관리 > 기본정보 (产品管理 > Web 应用管理 > 基本信息) 下,将 광고 적용 여부(使用广告)设为 예(是)
- 在 수익화 > 인앱 광고(变现 > 应用内广告)中,为每种广告类型点击 ID 발급 요청(申请 ID)。每种类型对应一个 ID;签发大约需要一个工作日
- 对于激励广告,ID 签发后,请在同一页面登记回调 URL 和 API 密钥。用于确认奖励的服务器回调(SSV)会发送到该 URL。仅使用插页式广告时无需此步骤
- 不提供测试广告位 ID。如果用户需要,请联系 [email protected]
请尽早调用预加载方法(loadRewarded / loadInterstitial),例如在 startGameAsync 成功后立即调用,这样按下按钮时广告就能立即显示。没有预加载也能正常工作,但首次显示广告会更慢。
使用此技能尚未在设备上完成端到端广告支持验证。请告知用户在发布前先在设备上测试广告。
用户稍后提供广告位 ID 时
如果放置广告代码时 ID 为空,收到 ID 后要做的不只是填入一个值。请完成以下所有操作:
- 将每个 ID 放入各自的位置。 激励广告 ID 应放在
loadRewarded/showRewardedAsync使用的位置;插页式广告 ID 应放在loadInterstitial/showInterstitialAsync使用的位置。如果不清楚用户发来的是哪种 ID,请询问。两种 ID 分别签发,广告位类型不匹配会导致invalid_request - 重新启用因 ID 为空而关闭的功能:已禁用的广告按钮、跳过的预加载、提前执行的
return、“未设置”标签。仅填入常量通常会导致按钮仍处于禁用状态 - 保持顺序:初始化后进行功能检查(
sdk.ads.isSupported(...))→ 预加载 → 启用按钮 - 说明更改了哪些文件和行(
path:line) - 告知用户如何验证:广告只会在 ONE store 应用内显示(普通浏览器始终会返回
platform_not_supported),且需先登记测试 URL 和测试 ID。测试期间出现no_fill表示当前没有广告库存,并不代表集成出了问题
4. 购买
下单前检查 productId 是否存在。如果不存在,请先使用 TODO 占位并询问用户提供该值。下单后,务必告知用户:
- 成功响应并不意味着可以发放道具。 游戏公司的服务器会通过验证
purchaseToken来确认购买。付款通知(PNS)也会发送到服务器,因此应根据服务器的确认结果发放道具 - 消耗购买是服务器的工作。 如果不消耗购买,再次购买同一商品会失败,并返回
already_owned - 将发放道具所需的信息放入
developerPayload。 此字段可选,但非常重要:购买结果和 PNS 通知会通过此值与用户及购买记录匹配,因此留空就无法进行匹配。根据游戏结构,建议填入什么内容(例如用户标识符),但不要靠猜测替用户决定 - 对于
user_cancelled,不要显示错误弹窗 - 购买请求会触发
pause(reason: "payment")和resume事件。不要在购买调用处单独暂停游戏;应在同一个pause监听器中处理 - Web 商品仅支持托管商品(不支持订阅)
5. 嵌入要求
这些要求不属于代码内容,容易被忽略。请参阅 references/embed-requirements.md 进行检查,并将服务器设置(允许嵌入的响应头、HTTPS、重定向)列为待确认事项,同时提供检查方法(curl -sI)。告知用户必须移除任何阻止页面在框架中显示的代码。
错误诊断
| 收到的内容 | 从何处着手 |
|---|---|
reason 字符串或控制台日志 | 查阅 references/sdk-context.md 中的 reason 表,并指出项目中处理该路径的位置 |
| 只有症状,例如“没有显示” | 查阅 references/diagnose.md,其中说明了需要收集哪些信息以及如何缩小排查范围 |
只有症状时,不要开始阅读代码。原因往往在代码之外(服务器响应头、ONE 商店注册、应用版本)。自行检查能确认的内容(curl -sI、在控制台中复现);如果无法亲自运行,请提供命令和步骤,并询问用户检查结果。不要把猜测当作答案。
回答中应包含原因、复现步骤、修复方法(附代码)以及需要验证的内容。对于代码无法修复的原因(no_fill、platform_not_supported 等),应说明这一点,并给出合适的处理方式(隐藏 UI、提供其他路径)。
发布前检查
按照 references/checks.md 中的清单 B执行。只读检查。对于取决于服务器或 ONE 商店注册的项目,只检查代码中是否具备相应钩子,并说明其余部分不属于项目范围。
只列出需要修复的项目。 通过的项目只显示数量。顺序:阻塞项 → 非阻塞项 → 待确认项 → 通过项数量。
参考文件
只阅读所需内容。
references/sdk-context.md:完整的公共 API、调用顺序、事件、reason表、CDN URL 和发放道具规则(权威来源)references/game-template.html.txt:参考集成代码(替换__SDK_VERSION__,填写 TODO)references/embed-requirements.md:iframe 嵌入要求(允许嵌入、URL、存储、禁止的调用、屏幕)references/checks.md:清单 A(状态检查)和清单 B(发布前检查)references/diagnose.md:如何根据症状缩小问题范围
公共文档:Web SDK Integration Guide https://onestore-dev.gitbook.io/dev/tools/web-sdk(英文版 https://onestore-dev.gitbook.io/dev/eng/tools/web-sdk)