# @finverse/sdk-typescript 中文文档

规范地址：https://npmcn.com/package/%40finverse/sdk-typescript/

版本：0\.0\.427
npm 元数据更新时间：2026-11-13T05:20:55.517Z
中文译文更新时间：2026-11-14T19:13:30.185Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40finverse/sdk-typescript
原文对照：https://npmcn.com/package/%40finverse/sdk-typescript/?lang=original
项目主页：https://github.com/finversetech/sdk-typescript/#readme
源码仓库：https://github.com/finversetech/sdk-typescript

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：733 kB，49 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2022-03-01T07:46:16.695Z
- 最新版本发布：2026-11-13T05:20:55.289Z
- 近 30 天下载量：6689（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：419（近 12 个月 69 个）

## 中文简介

@ finvers/ sdk-typescript 的 OpenAPI 客户端

## 安装

```sh
npm install @finverse/sdk-typescript
```

也可以使用：`pnpm add @finverse/sdk-typescript`、`yarn add @finverse/sdk-typescript`、`bun add @finverse/sdk-typescript`

## README

# Finverse API - 类型脚本 SDK

这个SDK可以实现端到端后端与Finverse API的集成,包括API认证,机构连接,数据检索和支付操作.

## 安装

```
npm install @finverse/sdk-typescript
```

## API 概览

SDK分为两大类API:

| API 密码 | 目的 |
| --- | --- |
| **支付 API** | 建立支付链接、任务、支付和管理支付账户 |
| **数据 API** | 获取账户、交易、报表、余额历史和身份数据 |

API 共享认证并通过 `PublicApi` 财务报告和审定财务报表 `LinkApi`。 。 。 .

* * *

## 支付 API

Paying API 允许您创建出票支付链接,启动支付,管理任务,并处理与支付相关的业务.

### 密钥类和方法( M)

| 类 | 关键方法 |
| --- | --- |
| `PaymentApi` | `createPaymentLink`, (中文(简体) ), `getPaymentLink`, (中文(简体) ), `cancelPaymentLink`, (中文(简体) ), `createScheduledPayout`, (中文(简体) ), `getPayoutById`, (中文(简体) ), `createPaymentMethod`, (中文(简体) ), `createPayment`, (中文(简体) ), `getPayment`, (中文(简体) ), `createMandate`, (中文(简体) ), `getMandate`, (中文(简体) ), `authorizeMandate`, (中文(简体) ), `createPaymentUser`, (中文(简体) ), `createPaymentAccount`, (中文(简体) ), `listPaymentAccounts` |

### 付款流量(终到终)

支付链接流量 : **创建** → **重定向** → **回电** → **票价** → **结果**。 。 。 .

1.  **创建** - 通过API创建支付链接, 获取 `url` 财务报告和审定财务报表 `payment_link_id`。保存两者和 `unique_reference_id`。 。 。 .
2.  **重定向** – 将用户重定向到支付链接 URL(使用HTTP 303,因此重定向会跟随GET).
3.  **回电** – Finverse 重定向以 `payment_link_id` 财务报告和审定财务报表 `unique_reference_id` 查询参数。 校验它们符合你储存的.
4.  **票价** - 波尔 `GET /payment_links/{paymentLinkId}` 每2秒,最多30秒,直到 `session_status` 实值 `"COMPLETE"`。 。 。 .
5.  **结果** - 如果 `COMPLETE` 成功;否则错误.

> **警卫:** `FINVERSE_CLIENT_ID` 财务报告和审定财务报表 `FINVERSE_CLIENT_SECRET` 必须 **永远** 承诺提供或发送到前端。 只在服务器上使用(例如环境变量,秘密管理器).

#### 1\. 认证:获取客户访问托肯

```typescript
import { Configuration, PublicApi } from '@finverse/sdk-typescript';

const apiHost = process.env.FINVERSE_BASE_URL ?? "https://api.prod.finverse.net";
const clientId = process.env.FINVERSE_CLIENT_ID;
const clientSecret = process.env.FINVERSE_CLIENT_SECRET;

const configuration = new Configuration({ basePath: apiHost });
const customerTokenResp = await new PublicApi(configuration).generateCustomerAccessToken({
  client_id: clientId,
  client_secret: clientSecret,
  grant_type: 'client_credentials',
});

const customerAccessToken = customerTokenResp.data.access_token;
// Cache the token; refresh before expiry (use expires_in minus 60s buffer)
```

#### 2\. 建立支付链接

**支付模式** ——一次性支付. 要求数 `amount` (小型单位,如:1000=100.00港元), `currency`, (中文(简体) ), `sender`, (中文(简体) ), `payment_details`,以及 `link_customizations` 与 `redirect_uri`数字 :

```typescript
import { Configuration, PaymentApi } from '@finverse/sdk-typescript';
import crypto from 'crypto';

const configuration = new Configuration({
  basePath: apiHost,
  accessToken: customerAccessToken,
});
const paymentApi = new PaymentApi(configuration);

const uniqueReferenceId = crypto.randomUUID();
const callbackUrl = process.env.CALLBACK_URL; // e.g. https://yoursite.com/callback

const createResp = await paymentApi.createPaymentLink({
  mode: "PAYMENT",
  amount: 10000,  // 100.00 HKD
  currency: "HKD",
  unique_reference_id: uniqueReferenceId,
  sender: {
    external_user_id: "your-internal-user-id",
    name: "Customer Name",
    email: "customer@example.com",
  },
  payment_details: {
    description: "Order #12345",
    external_transaction_reference: "order-12345",  // max 35 chars
  },
  link_customizations: {
    ui_mode: "redirect",
    redirect_uri: callbackUrl,
  },
});

const paymentLinkId = createResp.data.payment_link_id;
const paymentUrl = createResp.data.url;

// Store paymentLinkId and uniqueReferenceId for callback verification
```

**设置模式** – 对于储蓄支付方法(例如点击到支付). 这样做 **没有** 通过 `amount`数字 :

```typescript
const createResp = await paymentApi.createPaymentLink({
  mode: "SETUP",
  currency: "HKD",
  unique_reference_id: uniqueReferenceId,
  sender: {
    external_user_id: "your-internal-user-id",
    name: "Customer Name",
    email: "customer@example.com",
  },
  payment_details: {
    description: "Save payment method",
    external_transaction_reference: "setup-12345",
  },
  link_customizations: {
    ui_mode: "redirect",
    redirect_uri: callbackUrl,
  },
  payment_setup_options: {
    future_payments: "CLICK_TO_PAY",
  },
});
```

#### 3\. 将用户重新定向到支付 URL

重新引导用户到 `paymentUrl`。 。 。 . **使用 HTTP 303** 因此浏览器跟随 GET( Finverse 期望得到) :

#### 4\. 召回处理器:填表

当 Finverse 重定向时, 读 `payment_link_id` 财务报告和审定财务报表 `unique_reference_id` 从查询参数。 校验它们与你存储的数值相符, 然后民意调查直到 `session_status` 实值 `COMPLETE`数字 :

```typescript
import { Configuration, PaymentApi } from '@finverse/sdk-typescript';

const paymentLinkId = req.query.payment_link_id as string;  // from callback URL
const uniqueReferenceId = req.query.unique_reference_id as string;

// Verify uniqueReferenceId matches what you stored
// if (uniqueReferenceId !== storedUniqueReferenceId) { return error; }

const configuration = new Configuration({
  basePath: apiHost,
  accessToken: customerAccessToken,
});
const paymentApi = new PaymentApi(configuration);

const POLL_INTERVAL_MS = 2000;
const POLL_TIMEOUT_MS = 30000;
const startTime = Date.now();

while (Date.now() - startTime < POLL_TIMEOUT_MS) {
  const getResp = await paymentApi.getPaymentLink(paymentLinkId);
  const sessionStatus = getResp.data.session_status;

  if (sessionStatus === "COMPLETE") {
    // Success – redirect to success page
    // Log getResp.data.payment for payment details
    break;
  }

  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
}

// If loop ended without COMPLETE → timeout, show error page
```

* * *

## 数据 API

Data API 使您能够检索财务数据:账户、交易、报表、平衡历史、身份和收入估计数.

### 密钥类和方法( M)

| 类 | 关键方法 |
| --- | --- |
| `LoginIdentityApi` | `getLoginIdentity`, (中文(简体) ), `listAccounts`, (中文(简体) ), `getAccount`, (中文(简体) ), `getAccountNumber`, (中文(简体) ), `listTransactionsByLoginIdentityId`, (中文(简体) ), `listTransactionsByAccountId`, (中文(简体) ), `getStatements`, (中文(简体) ), `getStatement`, (中文(简体) ), `getBalanceHistory`, (中文(简体) ), `getIdentity`, (中文(简体) ), `getIncomeEstimateByLoginIdentityId`, (中文(简体) ), `listCardDetails`, (中文(简体) ), `refreshLoginIdentity` |

### 数据检索流量( 端到端)

#### 1\. 认证:获取客户访问托肯

```typescript
import { Configuration, PublicApi } from '@finverse/sdk-typescript';

const apiHost = process.env.FINVERSE_BASE_URL ?? "https://api.prod.finverse.net";
const clientId = process.env.FINVERSE_CLIENT_ID;
const clientSecret = process.env.FINVERSE_CLIENT_SECRET;
const redirectUri = process.env.REDIRECT_URI;

const configuration = new Configuration({ basePath: apiHost });
const customerTokenResp = await new PublicApi(configuration).generateCustomerAccessToken({
  client_id: clientId,
  client_secret: clientSecret,
  grant_type: 'client_credentials',
});

const customerAccessToken = customerTokenResp.data.access_token;
```

#### 2\. 链接新机构:获取链接托肯和链接URL

```typescript
import { Configuration, LinkApi } from '@finverse/sdk-typescript';

const userId = "someUserId";
const state = "someUniqueState";
const linkConfig = new Configuration({
  basePath: apiHost,
  accessToken: customerAccessToken,
});
const linkTokenResp = await new LinkApi(linkConfig).generateLinkToken({
  client_id: clientId,
  user_id: userId,
  redirect_uri: redirectUri,
  state: state,
  response_mode: "form_post",
  response_type: "code",
  grant_type: "client_credentials",
});

console.log("linkUrl:", linkTokenResp.data.link_url);
```

#### 3\. 最终确定链接:登录身份访问托肯交换码

```typescript
import { LinkApi, TokenGrantTypeEnum } from '@finverse/sdk-typescript';

const code = "obtainAfterLink"; // from Finverse Link UI callback
const loginIdentityTokenResp = await new LinkApi(linkConfig).token(
  TokenGrantTypeEnum.AuthorizationCode,
  code,
  clientId,
  redirectUri,
);
const loginIdentityToken = loginIdentityTokenResp.data.access_token;
```

#### 4\. 获取数据:获取登录身份

```typescript
import { Configuration, LoginIdentityApi } from '@finverse/sdk-typescript';

const dataConfig = new Configuration({
  basePath: apiHost,
  accessToken: loginIdentityToken,
});
const loginIdentityResp = await new LoginIdentityApi(dataConfig).getLoginIdentity();
console.log("login identity:", loginIdentityResp.data.login_identity);
```

#### 5\. 投票登录身份状态直至做好准备

```typescript
import type { AxiosResponse } from 'axios';
import type { GetLoginIdentityByIdResponse } from '@finverse/sdk-typescript';

enum FinalStatus {
  ERROR = 'ERROR',
  DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL = 'DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL',
  DATA_RETRIEVAL_COMPLETE = 'DATA_RETRIEVAL_COMPLETE',
}

let loginIdentity: AxiosResponse<GetLoginIdentityByIdResponse>;
for (let i = 0; i < 20; i++) {
  loginIdentity = await new LoginIdentityApi(dataConfig).getLoginIdentity();
  const status = loginIdentity.data.login_identity.status;
  if (
    status === FinalStatus.ERROR ||
    status === FinalStatus.DATA_RETRIEVAL_COMPLETE ||
    status === FinalStatus.DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL
  ) {
    break;
  }
  await new Promise((resolve) => setTimeout(resolve, 3000));
}
```

#### 6\. 获取账户

```typescript
const accountsResp = await new LoginIdentityApi(dataConfig).listAccounts();
console.log("accounts:", accountsResp.data.accounts);
```

#### 7\. 获取交易(加页标)

```typescript
let offset = 0;
while (true) {
  const transactionsResp = await new LoginIdentityApi(dataConfig).listTransactionsByLoginIdentityId(
    offset,
    500  // limit: default 500, max 1000
  );
  const transactions = transactionsResp.data.transactions ?? [];
  console.log(`total: ${transactionsResp.data.total_transactions}, transactions: ${transactions.length}`);
  offset += transactions.length;
  if (offset >= transactionsResp.data.total_transactions) {
    break;
  }
}
```

#### 8\. 获取声明

```typescript
import { writeFileSync } from 'fs';

const statementsResp = await new LoginIdentityApi(dataConfig).getStatements();
const statements = statementsResp.data.statements ?? [];
console.log("statements:", statements);

// Download a statement (assuming at least one exists)
const statementId = statements[0].id;
const statementResp = await new LoginIdentityApi(dataConfig).getStatement(
  statementId,
  true,
  { responseType: "arraybuffer" }
);
writeFileSync("statement.pdf", Buffer.from(statementResp.data));
```

* * *

## 最佳做法

### 使用同步/等待

所有SDK方法都回归承诺. 使用 `async/await` 用于更清洁、可读的代码并避免召回地狱:

```typescript
async function fetchAccounts() {
  const config = new Configuration({ basePath: apiHost, accessToken: token });
  const response = await new LoginIdentityApi(config).listAccounts();
  return response.data.accounts;
}
```

### 正确处理 API 响应

API 方法返回 Axios `AxiosResponse` 对象。 通过 `.data`数字 :

```typescript
const tokenResp = await new PublicApi(config).generateCustomerAccessToken({ ... });
const accessToken = tokenResp.data.access_token;  // Correct: use .data

const accountsResp = await new LoginIdentityApi(config).listAccounts();
const accounts = accountsResp.data.accounts;  // Correct: use .data
```

### 使用导出类型和接口

利用 SDK 的导出类型来保证类型安全和更好的IDE支持 :

```typescript
import type {
  Account,
  CreatePaymentRequest,
  GetLoginIdentityByIdResponse,
} from '@finverse/sdk-typescript';

const paymentRequest: CreatePaymentRequest = {
  // ...
};
```

### 处理尝试/捕获物出错

将 API 呼叫在尝试/捕获块中 。 API 出错作为 HTTP 出错响应返回; SDK 可能投放到网络故障或验证错误上 :

```typescript
import axios from 'axios';

try {
  const response = await new LoginIdentityApi(config).listAccounts();
  return response.data.accounts;
} catch (error) {
  if (axios.isAxiosError(error) && error.response) {
    console.error("API error:", error.response.status, error.response.data);
  } else {
    throw error;
  }
}
```

### 处理验证错误

当缺少所需的参数时,SDK会抛出错误. 将 API 调用到尝试/ 抓取中, 处理验证和其他失败 .

### 重用配置实例

创建一个 `Configuration` 一次每个信使/密码,再用于多次API呼叫:

```typescript
import { Configuration, LinkApi, PaymentApi } from '@finverse/sdk-typescript';

const config = new Configuration({
  basePath: apiHost,
  accessToken: customerAccessToken,
});
const linkApi = new LinkApi(config);
const paymentApi = new PaymentApi(config);
const linkTokenResp = await linkApi.generateLinkToken({ ... });
const paymentResp = await paymentApi.createPayment(paymentRequest);
```

### 客户端秘密: 永远不会执行, 仅服务器侧

**永远不要把你的客户端秘密用于版本控制.** 客户端的秘密必须保密,只用于服务器上.

-   **只有服务器侧 :** 这个SDK是为后端使用而设计的. 永远不要暴露 `client_secret` 到浏览器、移动应用程序或任何客户端代码.
-   **使用环境变量或机密管理器 :** 从安全存储器在运行时装入证书 .
-   **添加为 `.gitignore`数字 :** 保证 `.env` 和任何包含秘密的文件 永远不会被执行.

```typescript
// ✅ Correct: Load from environment (server-side only)
const clientId = process.env.FINVERSE_CLIENT_ID;
const clientSecret = process.env.FINVERSE_CLIENT_SECRET;  // Never log, never send to client
const redirectUri = process.env.REDIRECT_URI;
```

### 支付能力

对于支付和任务操作,使用一能键安全地重试请求而无需产生重复支付. 如果请求因网络问题而失败, 您可以用相同的密钥重试—— API 将返回原始结果而不是创建重复 .

**支持一能键的方法:** `createPayment`, (中文(简体) ), `createMandate`, (中文(简体) ), `createMandateForExistingSender`,以及 `createScheduledPayout` 打开 `PaymentApi`。 。 。 .

```typescript
import { PaymentApi } from '@finverse/sdk-typescript';
import crypto from 'crypto';

// Generate a unique key per logical operation (e.g., per checkout or mandate setup)
const idempotencyKey = crypto.randomUUID();

// Safe to retry—same key returns same result
await new PaymentApi(config).createPayment(paymentRequest, idempotencyKey);
await new PaymentApi(config).createMandate(mandateRequest, idempotencyKey);
```

**最佳做法:**

-   每个独特的付款或任务使用一个独有能力键.
-   将密钥存储在您的命令/任务记录中, 以便在需要时您可以使用相同的密钥重试 .

* * *

## AI代理机构的资源

对于实施Finverse整合的AI代理人 [Finverse AI 存储器](https://github.com/finversetech/ai) 载有支付流动、数据检索和其他Finverse API模式的技能、执行指南和参考文件。 详细整合指示请遵循此链接: [https://github.com/finversetech/ai (中文(简体) )](https://github.com/finversetech/ai)

## 常见问题

### @finverse/sdk-typescript 是什么？

@ finvers/ sdk-typescript 的 OpenAPI 客户端

### 如何安装 @finverse/sdk-typescript？

在项目目录运行 npm install @finverse/sdk-typescript，或使用 pnpm add / yarn add / bun add。

### @finverse/sdk-typescript 支持 TypeScript 吗？

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

### @finverse/sdk-typescript 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @finverse/sdk-typescript 可以商用吗？

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

### @finverse/sdk-typescript 的下载量有多少？

根据 npm 官方下载统计，@finverse/sdk-typescript 在 2026/10/15 – 2026/11/13 这 30 天内被下载 6,689 次，日均约 223 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @finverse/sdk-typescript 还在维护吗？

最新版本 0\.0\.427 发布于 2026/11/13（1 天前）；至今共发布 419 个版本，其中过去 12 个月发布了 69 个；首次发布于 2022/03/01。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

