@ait-kit/api-core

中文文档
0.6.0发布于 2026/10/14MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 3628

在Toss服务器API适配器和mTLS运输端口中运行时中性键入Apps.

中文使用文档
文档目录9 节
  1. IAP订单核查合同
  2. 信件收件人
  3. 智能消息发送结果
  4. 匿名密钥和验证
  5. 可收回的晋升补助金
  6. 结果语义
  7. 消费者的责任
  8. 收件人隐私和数字标识
  9. 匿名用户认证( SDK 3. 6+)

@ ait- kit/ api- 核心

在Toss服务器APIS和mTLS传输中,Apps的运行时中性键入适配器.

npm install @ait-kit/api-core
import { createAppsInTossApiRpcFromOptions } from "@ait-kit/api-core";

const tossApi = createAppsInTossApiRpcFromOptions({
  mode: "forward",
  mtlsClient
});

IAP订单核查合同

iapOrderStatus 以供养者所证实的与供养者所证实的,加以区别 问. 赠款决定必须基于 verified永远不要 ok数字 :

  • ok: true - 那个 get-order-status 查询成功, 提供者 返回一个造型良好的有效载荷。 缺少光谱要求的有效载荷 orderId 或者说 status 失败 error: "INVALID_RESPONSE" 改为 正在从请求中补齐。 证据领域必须是真正的字符串: a 一个 orderId, (中文(简体) ), status,或当前可选字段(sku, (中文(简体) ), statusDeterminedAt, (中文(简体) ), reason以数组、对象、数字或 布尔是 INVALID_RESPONSE 被胁迫的价值观从未被用作 核查证据。 失败信封FAIL, (中文(简体) ), ERROR, (中文(简体) ), NETWORK_ERROR, (中文(简体) ), TIMEOUT(即使相互矛盾,也没有任何证据) success 载荷随身携带,未识别 resultType 值为 INVALID_RESPONSE从来没有乐观的成功.
  • verified: true - 供应商测试状态是 PAYMENT_COMPLETED 或者说 PURCHASED 财务报告和审定财务报表 提供者返回 orderId 匹配请求. 回应 orderId编号 :sku 完全来自供应商的有效载荷; 请求值是期望值,绝不是证据.
  • verificationCode 要求每一次未证实的成功: PAYMENT_INCOMPLETE (可重试,待取再克之流被保留),, PAYMENT_FAILED, (中文(简体) ), PAYMENT_REFUNDED, (中文(简体) ), MINIAPP_MISMATCH, (中文(简体) ), ORDER_NOT_FOUND (可重审), ORDER_ID_MISMATCH, (中文(简体) ), UNKNOWN_STATUS, (中文(简体) ), PROVIDER_STATUS_ERROR,或 STUB_EVIDENCE。 。 。 .
  • skuCheck - 呼叫者通过预期时在场 sku数字 : MATCHED, (中文(简体) ), MISMATCHED,或 NOT_PROVIDED提供方 sku 可选 在官方API中,一个失踪的SKU从不翻转 verified;没有 补充检查终点,关于应付款状况的不完整证据 只能通过同样的电话重新排队.
  • stub: true ——标出合成活字模输出. 积分反应编织 (单位:千美元) PAYMENT_COMPLETED 发展秩序 verified (单位:千美元)verificationCode: "STUB_EVIDENCE"),所以这个部署不慎 在站台模式下运行,不能允许以编造的数据进行采购。 发展 想要执行赠与逻辑的流量必须明确选择通过检查 stub: true。 。 。 .

赠与例子—— verified 单是确认 请求命令 ID; 当您的目录需要特定产品时, 也会 需要SKU在入计前进行比较:

const result = await tossApi.iapOrderStatus({ orderId, sku: "SKU_100_COINS" });
if (!result.ok) {
  // The lookup itself failed (transport, provider error, INVALID_RESPONSE):
  // no grant decision can be made from this response.
  throw new Error(`order status lookup failed: ${result.failureReason ?? result.error}`);
}

// verified: provider attests a payable status for THIS order.
// skuCheck: the product evidence matches what the caller expects.
const grantable =
  result.verified === true && !result.stub && result.skuCheck?.status === "MATCHED";
// NOT_PROVIDED means the provider omitted SKU evidence: the order is paid,
// but which product it bought is unconfirmed — decide explicitly.

信件收件人

normalizeMessageRecipient 转出遗产 { userKey, tossUserKey, anonKey } 输入为单个 MessageRecipient (单位:千美元){ kind: "user", userKey } 或者说 { kind: "anonymous", anonKey }) (中文(简体) ). 必须提供完全一个标识符: 无,不止一个,错误类型或空的值的请求 拒绝字符串( e)INVALID_MESSAGE_RECIPIENT 以便他们派遣许多使者, INVALID_CONTEXT_RECIPIENT 散装 contextList 页:1 站台和前进模式。 每个 API 转换收件人本身 :

  • 单次(和测试)发送 将收件人载入请求头中: x-toss-user-key 用户收件人, x-anon-key 对于匿名者. (释放的较早期 x-user-key,而官方API没有 定义; 现在可以删除重写标题的消费者代理代码 。 )
  • 批量发送 携带收件人进入 contextList 弹体字段( e)userKey 编号 : anonKey从头到尾都没有.

智能消息发送结果

smartMessageSend 编号 : smartMessageBulkSend 只报告成功 提供者实际返回的发送结果证据. providerStatus 有三个含义:

  • "SENT" - 发送结果包含实数(明确数字) msgCount 联 合 国 0 或频道计数确认交货.
  • "FAILED" 确定失败:在零端上显示失败条目 结果,a FAIL编号 :ERROR 或4xx拒绝. providerErrorCode 镜像提供者返回的代码; 频道结果、 故障原因, 财务报告和审定财务报表 contentIds 为部分成功而保留.
  • "UNKNOWN" ——结果无法确定:无证据机构 (空对象, HTML 错误页, SUCCESS 信封没有发送 、结果、错误的计数、未确认的或结果含糊不清 resultType (单位:千美元)NETWORK_ERROR, (中文(简体) ), TIMEOUT),或5xx响应. 这些 携带内部 error: "INVALID_RESPONSE" 标记(参数/验证) 保留 providerRequestId 关联性,但绝不是捏造的 sentAt. 电文可能已经或可能已经发送: 状态出局——不要断言不交货,不要自动发送 仅此一个信号.

同一证据规则适用于单次和批量发送以及 已经正常的响应( 只有此模块本身的) SENT编号 :FAILED 词汇来回; 其他的都是 UNKNOWN) (中文(简体) ).

匿名密钥和验证

verifyAnonKey 电话 POST /api-partner/v1/apps-in-toss/users/anon-key/verify 键在 x-anon-key 头曰. 结果为三态:

  • { ok: true, valid: true } 编号 : { ok: true, valid: false } 确定 供应商的判决.
  • { ok: false, ... } (单位:千美元)ProviderFailure)——未获得判决 (运输失败, 非-2xx, FAIL 信封如出错) 4010, (中文(简体) ), 反应不当)。 永远不要翻译为 valid: false。 。 。 .

前缀 : sDK的车 getAnonymousKey() 决定: { type: "HASH", hash } 编辑 hash 值是关键。 服务器 API 完全期望 数值。 使用自己的前缀装饰所储存标识符的应用程序 (例如 anon: 或者说 anonymous-)必须先剥去自己的前缀 调用; 套件传送按键字节, 并且从不添加或删除 前缀在任一方向.

可收回的晋升补助金

promotionRewardGrant (遗产)连锁钥匙的发行、执行和结果 在一个电话里寻找。 明显的三步相通 使它们脱钩 数据库位于各阶段之间:

// The recipient identity the grant is for — exactly one of userKey /
// tossUserKey / anonKey, the same value you will execute with. Strip your
// own storage prefix first; the kit transmits identifiers byte-for-byte.
const recipientKey = "anon:stored-hash"; // your app-prefixed storage form
const recipientAnonKey = recipientKey.replace(/^anon:/, "");

// 1. Issue a transaction key for that recipient. Prepare carries the
//    recipient as the single identity header and sends no request body;
//    a call with a missing, duplicated, or malformed recipient is rejected
//    before anything is dispatched.
const prepared = await tossApi.promotionPrepareReward({ anonKey: recipientAnonKey });
if (!prepared.ok) throw new Error(prepared.failureReason);

// 2. Persist the key BEFORE executing. Bind it to the owner, the recipient
//    identifier you prepared with, the promotion code, the amount, and
//    your own request id — see the storage guidance below.
await db.promotionGrants.insert({
  providerTransactionKey: prepared.providerTransactionKey,
  ownerId: session.userId,          // who initiated the grant
  recipientKey,                     // exactly what you prepared with
  promotionCode: "WELCOME_EVENT",
  amount: 1000,
  requestId: request.id,            // your idempotency/tracing id
  stage: "PREPARED"
});

// 3. Execute the grant with the stored key and the SAME recipient.
const executed = await tossApi.promotionExecuteReward({
  providerTransactionKey: prepared.providerTransactionKey,
  promotionCode: "WELCOME_EVENT",
  amount: 1000,
  anonKey: recipientAnonKey // or userKey / tossUserKey
});

// 4. Confirm the outcome. If step 3 crashed or returned UNKNOWN, re-run
//    only this step — status issues no keys and executes no grants.
const status = await tossApi.promotionRewardStatus({
  providerTransactionKey: prepared.providerTransactionKey,
  promotionCode: "WELCOME_EVENT",
  anonKey: recipientAnonKey
});
// status.status: "GRANTED" | "PENDING" | "FAILED" | "NOT_FOUND" | "UNKNOWN"

结果语义

  • SUBMITTED (执行)系指提供人接受请求——确认 (a) 地位步骤;不是最后赠款状态.
  • UNKNOWN 运输故障,5xx,或 无法解析的反应 。 交易密钥总是保存到您可以 通过状态查询解决结果. 从不 处理 UNKNOWN 作为 确定失败, 不自动重执行: 提供者 拒绝同键重执行错误 4113 (“ 已经授予 / ),但官方合同没有文件证明一意孤行 重复执行.
  • 明显失败( 执行) ok: false状态 "FAILED")只来自 提供商判断 — FAIL 信封有错误代码, 4xx, 或 文档 FAILED 状态( 提供者将旧预算滚回) .
  • "NOT_FOUND" 有文件证明的错误 4111:没有赠款记录 键(从未执行,或记录已消失).
  • 官方API用品 没有赠款时间戳和没有文件记录的密钥 过期5. 答复情况报告 checkedAt (当你观察 并且从不捏造 grantedAt 从你的要求时间.
  • 传递您自己的请求标识符 没有 让外部 ——只把它当作追踪元数据.

消费者的责任

提供者仅通过交易密钥来复制. 您的应用程序 :

  • 存储: 将密钥保存到所有者, 收件人标识符, 促销代码,金额, 以及您在执行前的请求 id,所以丢失 执行响应总是可以针对您打算做的事情解决的.
  • 所有权检查: 验证呼叫者拥有存储的赠款前 执行或投票.
  • 货币管制: 防止同一密钥的两个执行 赛车(遗产 4113的拒绝是提供商的支持,而不是 (合同).
  • 编辑器更新余额: GRANTED和设计 UNKNOWN 处理( 用备份重试状态查询) 而不是 猜测.

遗产 promotionRewardGrant 保持其原始行为,包括 治疗电话供应者 providerTransactionKey 由此而来 仅 —— 传递一个已存在的密钥从不会通过该 API 触发执行 .

见 AIT 工具包库 用于支持的 API, Cloudflare 绑定、示例和发布注释.

收件人隐私和数字标识

晋升准备/执行/地位抑制 failureReason 当文本包含时 提交收件人(包括简短的ID和修剪头拼写). 提供方出错代码,交易密钥和结果语义保存. 它保护返回的失败文本; 原始运输日志和通用的 mTLS 中继器仍然是呼叫者的责任.

数字 userKey 财务报告和审定财务报表 tossUserKey 必须是安全的整数。 分数和不安全 在发送前拒绝数字, 包括单个/ 块智能信件 请求。 对大ID使用精确的字符串; 转换已四舍五入的数字 到字符串无法恢复原始标识符.

匿名用户认证( SDK 3. 6+)

exchangeAnonAuthCode({ code }, { mode: "forward", mtlsClient, signal }) 交换新 SDK 发布的代码 { ok: true, anonKey }。使用一个 请求截止日期的应用程序控制中止信号。 立即进行交流; 代码为单用,5分钟后失效. 帮手提出一个请求, 永远不要自动重试, 也永远不要返回假身份 . 失败包含固定错误类别,而不是提供者的有效载荷或秘密. 取消返回 ABORTED,与 UPSTREAM_UNAVAILABLE; 没有 结果包括运输例外或呼叫者提供的中止理由.

verifyAnonKey 检查密钥是否存在; 它不认证调用者 . 在发布您自己的会话前先认证代码交换 。 订购所有权, 保留每个账户的赠款路线、预防再玩和持久采购分类账 申请的责任。 该助手本身并不授权购买.

正式合同: https://developers-apps-in-toss.toss.im/api/user-key.md 互联网档案馆的存檔,存档日期2014-12-21

版本与发布记录

@ait-kit/api-core 共发布 11 个版本,首次发布于 2026/06/30;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.6.0latest2026/10/1424 天前
0.5.12026/09/211 个月前
0.5.02026/09/171 个月前
0.4.22026/09/171 个月前
0.4.12026/09/161 个月前
0.4.02026/09/161 个月前

关于 @ait-kit/api-core 的常见问题

@ait-kit/api-core 是什么?

在Toss服务器API适配器和mTLS运输端口中运行时中性键入Apps.

如何安装 @ait-kit/api-core?

在项目目录运行 npm install @ait-kit/api-core,或使用 pnpm add / yarn add / bun add。

@ait-kit/api-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@ait-kit/api-core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@ait-kit/api-core 可以商用吗?

@ait-kit/api-core 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@ait-kit/api-core 的下载量有多少?

根据 npm 官方下载统计,@ait-kit/api-core 在 2026/10/05 – 2026/11/03 这 30 天内被下载 3,628 次,日均约 121 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@ait-kit/api-core 还在维护吗?

最新版本 0.6.0 发布于 2026/10/14(24 天前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/06/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。