@ 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"确定失败:在零端上显示失败条目 结果,aFAIL编号 :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