> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/sdk/v3.md).

# v3

`@apps-in-toss/web-framework` 3.0.0 `最新`已发布为。现在 `npm install @apps-in-toss/web-framework`执行后会安装 3.0.0。

3.0.0 是为 Web 迷你应用开发重新整理了 SDK 结构的重大更新。你可以在这份文档中查看 2.x 与 3.0.0 的差异。

### 一览

* 公开 API 已按领域对象重新整理。按领域分组的旧函数会以 deprecated 形式保留，因此无需修改代码也能直接运行。
* 包变轻了。安装体积从约 27MB 缩减到约 660KB。
* 配置文件 `granite.config.ts`在 `apps-in-toss.config.ts`已改为。 `npx ait migrate v3` 可以通过命令自动转换。
* 沙盒应用不支持 3.0。我们预计会提供支持在 devtools 中 mock API。到那之前，请通过控制台签发的二维码在 Toss App 中测试。

### 领域对象 API

3.0.0 的公开 API 按功能单元归类为领域对象。按领域分组的旧单独函数已被 deprecated，请使用相同功能的领域成员。

```typescript
// 2.x 方式——可以运行，但会显示 deprecated 警告。
import { openCamera } from "@apps-in-toss/web-framework";
const image = await openCamera();

// 3.0 方式
import { Device } from "@apps-in-toss/web-framework";
const image = await Device.openCamera();
```

旧函数从函数名称到接收的值、返回的值都与 2.x 完全相同。因此，2.x 代码无需修改就能在 3.0 中编译并运行。不过，编辑器中会显示 deprecated 标记，建议新代码使用领域成员来编写。

#### 旧 API 与领域成员对应表

| 域名           | 旧 API（deprecated）                  | 新 API                           |
| ------------ | ---------------------------------- | ------------------------------- |
| 剪贴板          | `getClipboardText`                 | `Clipboard.getText`             |
| 剪贴板          | `setClipboardText`                 | `Clipboard.setText`             |
| 设备           | `fetchAlbumItems`                  | `Device.getAlbumItems`          |
| 设备           | `fetchAlbumPhotos`                 | `Device.getPhotos`              |
| 设备           | `fetchContacts`                    | `Device.getContacts`            |
| 设备           | `getCurrentLocation`               | `Device.getLocation`            |
| 设备           | `getLocale`                        | `Device.locale`                 |
| 设备           | `getPlatformOS`                    | `Device.os`                     |
| 设备           | `generateHapticFeedback`           | `Device.triggerHaptic`          |
| 设备           | `openCamera`                       | `Device.openCamera`             |
| 设备           | `openURL`                          | `Device.openURL`                |
| 设备           | `startUpdateLocation`              | `Device.subscribeLocation`      |
| 环境           | `getDeviceId`                      | `Environment.deviceId`          |
| 环境           | `getGroupId`                       | `Environment.groupId`           |
| 环境           | `getOperationalEnvironment`        | `Environment.environment`       |
| 环境           | `getTossAppVersion`                | `Environment.tossAppVersion`    |
| 环境           | `env.getDeploymentId`              | `Environment.deploymentId`      |
| 环境           | `getSchemeUri`                     | `Environment.initialURL`        |
| 环境           | `getNetworkStatus`                 | `Environment.getNetworkStatus`  |
| 环境           | `getServerTime`                    | `Environment.getServerTime`     |
| File         | `saveBase64Data`                   | `File.saveBase64`               |
| File         | `openPDFViewer`                    | `File.openPDFViewer`            |
| Game         | `openGameCenterLeaderboard`        | `Game.openLeaderboard`          |
| Game         | `submitGameCenterLeaderBoardScore` | `Game.setLeaderboardScore`      |
| Game         | `getGameCenterGameProfile`         | `Game.getUserProfile`           |
| Game         | `getUserKeyForGame`                | `User.getAnonymousKey`          |
| Game         | `grantPromotionRewardForGame`      | `Promotion.grantReward`         |
| Notification | `requestNotificationAgreement`     | `Notification.requestAgreement` |
| Promotion    | `grantPromotionReward`             | `Promotion.grantReward`         |
| Promotion    | `contactsViral`                    | `Promotion.openContactsInvite`  |
| Review       | `requestReview`                    | `评价请求`                          |
| 安全区域         | `getSafeAreaInsets`                | `SafeArea.get`                  |
| 安全区域         | `SafeAreaInsets.subscribe`         | `SafeArea.subscribe`            |
| Screen       | `closeView`                        | `Screen.close`                  |
| Screen       | `setScreenAwakeMode`               | `Screen.setAwakeMode`           |
| Screen       | `setSecureScreen`                  | `Screen.setSecure`              |
| Screen       | `setIosSwipeGestureEnabled`        | `Screen.setIosSwipeBack`        |
| Screen       | `setDeviceOrientation`             | `Screen.setOrientation`         |
| 分享           | `getTossShareLink`                 | `Share.createLink`              |
| 分享           | `分享`                               | `Share.sendMessage`             |
| TossAuth     | `appLogin`                         | `TossAuth.login`                |
| TossAuth     | `getIsTossLoginIntegratedService`  | `TossAuth.isIntegrated`         |
| TossAuth     | `appsInTossSignTossCert`           | `TossAuth.sign`                 |
| TossPay      | `checkoutPayment`                  | `TossPay.authorize`             |
| TossPay      | `requestTossPayPaysBilling`        | `TossPay.authorizeSubscription` |
| 用户           | `getAnonymousKey`                  | `User.getAnonymousKey`          |
| 用户           | `getConsentedUserData`             | `User.getConsentedData`         |
| 用户           | `getDeclaredAgeRange`              | `User.getDeclaredAgeRange`      |

`SafeAreaInsets`是 `安全区域`是类似这样的对象。可以继续沿用原来的名称。

#### 保持不变的 API

下面这些 API 不会按领域归类，而是以原有形式提供。你可以继续使用，不会有 deprecated 提示。

* 对象型 API： `IAP`, `Storage`, `TossAds`, `GoogleAdMob`, `分析`, `partner`
* 广告： `loadFullScreenAd`, `showFullScreenAd`
* 权限： `getPermission`, `requestPermission`, `openPermissionDialog`和权限错误类
* 事件： `appsInTossEvent`, `graniteEvent`, `tdsEvent`
* 环境： `isMinVersionSupported`, `getAppsInTossGlobals`

#### 新增 API

* `PermissionError`: 权限错误的公共父类已公开。 `error instanceof PermissionError`可一次性处理所有权限错误。
* `TossPay` 领域对象：在 2.x 中 `checkoutPayment` 只有相同的单独函数，但在 3.0 中 `TossPay.authorize`, `TossPay.authorizeSubscription`已按其归类。

#### 旧函数与领域成员的行为差异

不只是名称变更，部分行为契约也做了改进。迁移时请确认以下差异。

* 常量型 API 不是通过函数调用，而是作为属性读取。例如 `getLocale()`是 `Device.locale`变为， `getDeviceId()`是 `Environment.deviceId`变为。
* 领域成员在不受支持的 Toss App 版本中 `UNSUPPORTED_APP_VERSION` 或 `UNSUPPORTED_OS_VERSION` 会抛出带有代码的错误。旧函数则按 2.x 约定 `undefined`或 `'ERROR'` 等值返回。例如 `getAnonymousKey`失败时会 `'ERROR'`返回，但 `User.getAnonymousKey`会抛出错误。 `error.code`可根据其分支显示“请更新 Toss App”之类的提示。
* `Share.createLink`接受对象参数。 `getTossShareLink(path, ogImageUrl)`是 `Share.createLink({ path, ogImageUrl })`变为。
* `IAP.createOneTimePurchaseOrder` 响应中的商品标识符使用 `sku`。 `productId` 字段已 deprecated。

### 配置文件变更

配置文件名称 `granite.config.ts`在 `apps-in-toss.config.ts`已改为，部分选项也有变更。

| 2.x（`granite.config.ts`)          | 3.0 (`apps-in-toss.config.ts`) | 说明                                       |
| --------------------------------- | ------------------------------ | ---------------------------------------- |
| `web` (host, port, commands)      | 移除                             | 开发服务器和构建执行已从 SDK 中 `package.json` 迁移到脚本。 |
| `brand.displayName`, `brand.icon` | 移除                             | `brand`中 `primaryColor`只保留了。             |
| `webViewProps`                    | `webView`                      | 名称已更改。下级选项保持不变， `type`仅移除了。              |
| `webViewProps.type`               | 移除                             | WebView frame type 选项已移除。                |
| `outdir`                          | `webBundleDir`                 | 只是名称变更。默认值为 `dist`相同。                    |

配置类型名称也 `AppsInTossWebConfig`在 `AppsInTossConfig`已改为。

Web 开发服务器和构建现在 `package.json` 可直接在脚本中运行。

```json
{
  "scripts": {
    "dev": "vite dev",
    "build": "vite build && ait build",
    "deploy": "ait deploy"
  }
}
```

### 包结构变更

| 项目           | 2.x          | 3.0                                                                  |
| ------------ | ------------ | -------------------------------------------------------------------- |
| 安装体积         | 约 27MB       | 约 660KB                                                              |
| 模块格式         | 仅 ESM        | ESM + CJS 双模式                                                        |
| dependencies | 13 个         | 4 个（`@apps-in-toss/cli`, `@webview-bridge/web`, `semver`, `valibot`) |
| 许可证          | 仅 LICENSE 文件 | `Apache-2.0` 注明                                                      |

CJS 环境（`require`，旧版打包器）中也能使用了，而且依赖减少后安装更快，与其他包的版本冲突顾虑也减少了。

### 沙盒与开发环境 Mock

沙盒应用不支持 3.0。我们正在准备尽快提供 devtools，让你即使没有沙盒应用也能在本地开发环境中 mock API。

在此之前，用 3.0 制作的迷你应用请通过 App in Toss 控制台签发的二维码在 Toss App 中测试。

### 迁移到 3.0.0

提供自动迁移命令。配置文件转换和 `package.json` 脚本重构会自动处理。

```bash
npx ait migrate v3
```

此命令会执行以下操作。

* `granite.config.ts`将 `apps-in-toss.config.ts`转换为（`brand`是 `primaryColor`仅保留， `webViewProps`是 `webView`更改为， `outdir`是 `webBundleDir`更改为， `web` 删除块）。
* `package.json`的 `dev`, `build` 重构脚本。
* 如果转换前验证失败，不会修改文件，而是会告知原因和解决方法。

迁移后，请将 bundle 上传到控制台，并通过二维码在 Toss App 中测试。

#### 请务必确认

* 如果发布用 SDK 3.x 构建的 bundle，就无法回滚到 2.x。请通过二维码充分测试后再发布。
* 从 3.0 起，迷你应用会在 `https://<appName>.web.tossmini.com`（Live）和 `https://<appName>.private-web.tossmini.com`（QR 测试）Origin 中运行。请将这两个域名注册到 API 服务器的 CORS 允许列表中。
* 如果使用 TDS， `@toss/tds-mobile`和 `@toss/tds-mobile-ait`请一并更新到 2.4.1 以上。
* 3.0.0-rc.1 和 rc.2 因依赖问题无法安装。请务必使用 3.0.0 正式版。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/sdk/v3.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
