# @flopay/node 中文文档

规范地址：https://npmcn.com/package/%40flopay/node/

版本：1\.14\.11
npm 元数据更新时间：2026-11-14T08:09:52.704Z
中文译文更新时间：2026-11-14T23:51:18.276Z
软件包许可：未声明

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

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

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

- 包体积（解压后）：32.6 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-03-30T16:07:25.403Z
- 最新版本发布：2026-11-14T08:09:52.511Z
- 近 30 天下载量：4003（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：174（近 12 个月 174 个）

## 中文简介

为Node.js服务的服务器端 FloPay SDK. 通过 FloPay 计费API 创建取出会话,检索并过期 Strede 取出会话,管理 Strede 客户端,并验证 Strede webhooks.

## 安装

```sh
npm install @flopay/node
```

也可以使用：`pnpm add @flopay/node`、`yarn add @flopay/node`、`bun add @flopay/node`

## README

# @ flopay/ 节点

为Node.js服务的服务器端 FloPay SDK. 通过 FloPay 计费API 创建取出会话,检索并过期 Strede 取出会话,管理 Strede 客户端,并验证 Strede webhooks.

## 安装

```bash
pnpm add @flopay/node
```

`stripe` 财务报告和审定财务报表 `@flopay/shared` 作为依赖性自动安装。 只从信任的服务器代码使用它: 构造器取出一个花纹密钥, 它绝不能到达浏览器 .

### 节点.js 版本

运行 `@flopay/node` 在为CVE-2026-111497 ("Node2Shell")所修补的Node.js发布上,在Node.js本身的Brotli解码器中写出出出界. 2026年10月21日的Node.js安全发布将其固定在22.23.4,24.22.1和26.12.1上,因此运行22.23.4+在22x上,24.22.1+在24x上,或26.12.1+在26x上.

20.x(生命末期)和 25.x 得不到固定:将其移到补丁 22.x, 24.x 或 26.x 释放. 所支持的范围,Node.js 20.19+, 22.13+和24+,仍然包括了两行,因此包中没有任何东西会阻止你运行在它们上.

## 使用量

### 初始化

使用您的花纹密钥创建一个客户端 。 直接条纹操作使用 API 版本在 `STRIPE_API_VERSION` 除非你通过 `apiVersion`; 通过 `stripeSecretKey` 用来为他们使用不同的密钥.

```ts
import { FloPay } from '@flopay/node';

const flopay = new FloPay('sk_test_...'); // load the real key from your secret store
```

### 创建退出会话

`flopay.checkout.sessions.create()` 发帖给API `POST /v1/checkouts/sessions` 并决心 `CheckoutSessionResult`数字 :

-   `{ status: 201, redirectUrl, nonce }`: 将买方送往 `redirectUrl`,主机退出页面(`checkoutBaseUrl` + 键 `/secure`,带有会话编号和您的 `redirectParams`) (中文(简体) ). `nonce` 是会话绑定的退出符号;转发为 `x-checkout-session-token` 接续同一届会的每次呼吁都以标题标出.
-   `{ status: 204 }`:买方已经有一个付款方法存档,不需要显示.

需要会议货币。 过 `currency` 或关于第一个项目、订阅或产品. `checkoutMode` 默认为 `'confirm'` 这个方法,和 `timeoutMs` 至12秒钟.

`checkoutMetadata` 接受 `Record<string, string> | null` 且发送未变 : 省略后, 请求机构未变 , 明确 `null` 保存下来 `{}` 保留空地图。 计费API是元数据限制的唯一权威.

### 用一等钥匙安全重试

传出同样的 `idempotencyKey` 当您在未知结果后重试一个逻辑会话创建时。 最多为 255 个字符的非空白密钥的发送方式与 `Idempotency-Key` 头曰. 空的, 仅白空的, 超长的, 和头- 不安全的值会被忽略而不丢出, 省略选项时不会生成密钥 . `@flopay/node` 没有内部重试循环, 因此您的服务器拥有重试时间和重用密钥 .

### 现在授权,稍后抓取

要授权一个合格的一次性卡车 不抓取,通过 `captureMethod: 'manual'`。手动抓取不能与订阅合并使用,省略选项可以让直接抓取。 之后的捕捉是故意的,不是 `@flopay/node` 方法: 从可信任的服务器代码中调用商号认证的 REST 端点, 并使用稳定 `Idempotency-Key`如本报告所述 [付款和授权](https://flopay.com/docs/technical-reference/rest/payments)。 。 。 .

### 已保存的牌

保存卡管理也不属于 `@flopay/node` 认证表面。 从信任的服务器代码中,使用经认证的 REST API 列出仅显示的支付方法,创建设置会话,并删除符合条件的方法,然后只通过设置会话 `sessionId` 财务报告和审定财务报表 `nonce` 改为 `FloPayCardSetup` 内 `@flopay/react`。先替换一个卡片设置,然后删除,所以一个失败或取消的设置会让现有的卡片保持完整. 见 [支付方法参考](https://flopay.com/docs/technical-reference/rest/payment-methods)。 。 。 .

输入设置请求正文 `CreateCardSetupSessionRequest` 从 `@flopay/shared`. 除所需外 `userId` 选项 `successUrl` 财务报告和审定财务报表 `cancelUrl`中,它接受您服务器可能已经知道的交易上下文,该上帐的 API 路由卡的校验。 每个字段都是可选的,独立于其他字段,没有这些字段的要求仍然有效,保持不变:

-   `country`: ISO 3166-1 alpha-2国道卡将使用入.
-   `currency`:后期付款的三字母货币将记入. 提供 `currency` 成为设置会话的货币.
-   `futureUse`数字 : **已贬值** (单位:千美元)`CardSetupFutureUse`, (中文(简体) ), `'on_session'` 或者说 `'off_session'`) (中文(简体) ). 未来使用是平台政策:计费API设置了所有节省的方法 `'off_session'` 并忽略此值。 它仍然被接受,所以现有的请求继续工作;把它排除在新的代码之外.

上下文需要计费API v1.9.48 或以后. 年长的API悄悄地忽略了它,并如出一辙地设置了卡. 发送您持有的值: 计费 API 修饰和大写 `country` 财务报告和审定财务报表 `currency`中,验证所有三个字段,并拒绝一个带有 `400`。上下文描述了交易,从不选择网关;单靠收费API决定哪个网关验证卡.

### 节省的支付方法

客户可以保留任何类型的被保存的支付方法,不仅仅是卡,服务器侧流与被保存的卡相同. 商家证书留在商家服务器上:您的服务器通过自己认证的计费API客户端创建了设置会话,没有FloPay软件包发送设置请求. 输入身体 `CreateCardSetupSessionRequest` 从 `@flopay/shared` 就是一张牌 保存另一个方法类型不需要额外的字段,请求中没有网关提示,提供者允许列表,或者资格表. 计费API的广告是哪些设置会话可以保存,而SDK从未决定哪个网关或方法有资格.

`@flopay/shared` 键入列表和删除的混合方法类型:

-   `SavedPaymentMethodFamily` 实值 `'card'`, (中文(简体) ), `'wallet'`, (中文(简体) ), `'paypal'`,或 `'apm'`:一个保存的方法属于家庭,用于分组. `SAVED_PAYMENT_METHOD_FAMILIES` 列出用于详尽处理的每个值. `SavedPaymentMethodType` 财务报告和审定财务报表 `SAVED_PAYMENT_METHOD_TYPES` 具有相同价值的被贬值的别名.
-   `SavedPaymentMethodDisplay` 一种只保存显示的 任何类型的方法, 受到家庭的歧视 `type`每个变体都有 `id` 和生命周期 `status`,并可能携带计费API行的 `methodType` 财务报告和审定财务报表 `displayLabel`。 。 。 . `methodType` 告诉一个家庭的不同方法:苹果支付行和谷歌支付行都是 `type: 'wallet'`,与 `methodType` `apple_pay` 财务报告和审定财务报表 `google_pay`。钱包、 PayPal 或 APM 方法总是有安全的显示 `label`,以有利于 `displayLabel`,其价值相同。 一张牌 `brand`, (中文(简体) ), `lastFour`, (中文(简体) ), `expiryMonth`,以及 `expiryYear`页:1 `methodType` 实值 `card`,以及 `label` 可选及其 `displayLabel` 实值 `null`: 从 `brand` 财务报告和审定财务报表 `lastFour` 相反,正如下文的例子所示。 没有任何变体带有可再使用的证书,令牌或卡号. 现有 `SavedCardDisplay` 是一个有效的 `SavedPaymentMethodDisplay` 无 `type`,所以只用卡的代码在不断编译.
-   `ListSavedPaymentMethodsQuery` 是列表请求的可选 `type` 过滤器, a `SavedPaymentMethodListType`。不要列出每个保存的方法,就像今天只使用卡片的集成一样.
-   `SavedPaymentMethodListType` 用于此过滤器的计费 API 接受的方法 : `card`, (中文(简体) ), `paypal`, (中文(简体) ), `apple_pay`, (中文(简体) ), `google_pay`, (中文(简体) ), `sepa_debit`,或 `us_bank_account`,以及 `SAVED_PAYMENT_METHOD_LIST_TYPES` 列出每个值。 它按照方法类型过滤,从不通过家庭过滤,所以没有 `wallet` 或者说 `apm` 过滤器: 请求 `apple_pay` 或者说 `google_pay` 换句话说 PayPal为 `paypal`,不是设置流 `paypal_vaulted`。 。 。 .
-   `isSetupCheckoutSession` 实值 `true` 无收费设置会议`checkoutMode: 'setup'`,零数量,没有产品),无论方法 `advertisedPaymentMethods` 列表中选择一个选项. `isCardSetupCheckoutSession` 不变.

删除被保存的方法对每种类型都一样,同样 `PaymentMethodRemovalError` 回应.

### 列条取出会话和客户

`checkout.sessions.retrieve()`, (中文(简体) ), `expire()`,以及 `listLineItems()` 直接调用条纹并规范结果. `customers.create()`, (中文(简体) ), `retrieve()`,以及 `update()` 管理条纹客户并返回一个正常的 `Customer`。 。 。 .

### 校验网约车

`webhooks.constructEvent()` 核查 `Stripe-Signature` 标注在您的 webhook 签名后返回一个正常的 `WebhookEvent` (单位:千美元)`id`, (中文(简体) ), `type`, (中文(简体) ), `data`, (中文(简体) ), `created`) (中文(简体) ). 传出原始的,未分解的请求体.

## 实例

创建退出会话并重定向购买者:

```ts
import { FloPay } from '@flopay/node';

function requiredEnv(name: string): string {
  const value = process.env[name];
  if (!value) throw new Error(`${name} is not set`);
  return value;
}

const flopay = new FloPay(requiredEnv('STRIPE_SECRET_KEY'));

const result = await flopay.checkout.sessions.create({
  billingApiUrl: 'https://billing.example.com',
  checkoutBaseUrl: 'https://checkout.example.com',
  clientId: 'client_123',
  currency: 'USD',
  items: [
    {
      providerItemId: 'prod_abc',
      providerItemName: 'Pro Plan',
      totalAmount: 49.99,
      overrideAmount: 24.99,
    },
  ],
  subscriptions: [{ providerPlanId: 'plan_xyz', providerPlanName: 'Monthly Plan', totalAmount: 9.99 }],
  account: { userId: 'user_1', email: 'user@example.com', firstName: 'Jane', lastName: 'Doe' },
  successUrl: 'https://shop.example.com/success',
  cancelUrl: 'https://shop.example.com/cancel',
  checkoutMode: 'full',
  checkoutMetadata: { merchantOrderId: 'order-123', campaign: 'summer' },
  couponCodes: ['SAVE10'],
  tagsData: { googleContainerId: 'GTM-XXXX' },
  redirectParams: { email: 'user@example.com' },
  timeoutMs: 12_000,
  idempotencyKey: 'checkout:order-123',
});

if (result.status === 201 && 'redirectUrl' in result) {
  console.log('Redirect the buyer to', result.redirectUrl);
} else if (result.status === 204) {
  console.log('A payment method is already on file.');
}
```

输入带有可选交易上下文的卡片设置请求, 随计费API客户端发送, 您的服务器已经认证, 只返回会话控件 `FloPayCardSetup`数字 :

```ts
import type { CreateCardSetupSessionRequest } from '@flopay/shared';

// Your server's existing billing API client; it adds your merchant authentication.
type AuthenticatedPost = (
  path: string,
  body: CreateCardSetupSessionRequest,
) => Promise<{ data: { uuid: string; nonce: string } }>;

export async function createCardSetupSession(post: AuthenticatedPost, userId: string) {
  const request: CreateCardSetupSessionRequest = {
    userId,
    country: 'GB',
    currency: 'GBP',
  };
  const { data } = await post('/v1/checkouts/sessions/setup', request);

  return { sessionId: data.uuid, nonce: data.nonce };
}
```

列出任何类型的保存的支付方法, 可选择通过方法过滤 `type`,并在网关上不分枝贴出每个标签:

```ts
import type { ListSavedPaymentMethodsQuery, SavedPaymentMethodDisplay } from '@flopay/shared';

// Your server's existing billing API client; it adds your merchant authentication.
type AuthenticatedList = (query: ListSavedPaymentMethodsQuery) => Promise<SavedPaymentMethodDisplay[]>;

export function describeSavedMethod(method: SavedPaymentMethodDisplay): string {
  switch (method.type) {
    case 'wallet':
    case 'paypal':
    case 'apm':
      return method.displayLabel ?? method.label;
    default:
      // A card; card-only responses may omit `type`, and a card's `displayLabel` is null.
      return method.displayLabel ?? method.label ?? `${method.brand} ending ${method.lastFour}`;
  }
}

export async function listSavedApplePay(list: AuthenticatedList): Promise<string[]> {
  // Filter by method type: the billing API accepts `apple_pay`, never the `wallet` family.
  const methods = await list({ type: 'apple_pay' });
  return methods.map(describeSavedMethod);
}
```

校验平原节点. js HTTP 服务器中的 Strepe webhook :

```ts
import { createServer } from 'node:http';
import { FloPay } from '@flopay/node';

const flopay = new FloPay(process.env.STRIPE_SECRET_KEY ?? 'sk_test_...');
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET ?? 'whsec_...';
const MAX_BODY_BYTES = 64 * 1024; // Pick a limit that fits your largest expected event.

createServer((request, response) => {
  const chunks: Buffer[] = [];
  let received = 0;
  request.on('data', (chunk: Buffer) => {
    received += chunk.length;
    if (received > MAX_BODY_BYTES) {
      response.writeHead(413, { Connection: 'close' }).end('Payload too large');
      request.destroy();
      return;
    }
    chunks.push(chunk);
  });
  request.on('end', () => {
    try {
      const event = flopay.webhooks.constructEvent(
        Buffer.concat(chunks),
        String(request.headers['stripe-signature']),
        webhookSecret,
      );
      console.log(event.type, event.created);
      response.writeHead(200).end();
    } catch {
      response.writeHead(400).end('Invalid signature');
    }
  });
}).listen(3000);
```

管理花纹客户 :

```ts
import { FloPay } from '@flopay/node';

const flopay = new FloPay(process.env.STRIPE_SECRET_KEY ?? 'sk_test_...');

const customer = await flopay.customers.create({
  email: 'user@example.com',
  name: 'Jane Doe',
  metadata: { plan: 'pro' },
});

const updated = await flopay.customers.update(customer.id, { metadata: { plan: 'enterprise' } });
const session = await flopay.checkout.sessions.retrieve('cs_test_...');
console.log(updated.email, session.status, session.amount);
```

## 公共 API

### 出口

| 导出 | 说明 |
| --- | --- |
| `FloPay` | 服务器端客户端 : `new FloPay(secretKey, options?)` 带有条纹密钥的 (`sk_test_...` 或者说 `sk_live_...`(中文(简体) ) |
| `FloPayNodeOptions` | 构造选项 |
| `STRIPE_API_VERSION` | `'2026-04-22.dahlia'`,用于直接 Strape 操作的默认 Strape API 版本 |

### FloPay 节点选项

| 选项 | 类型 | 说明 |
| --- | --- | --- |
| `apiVersion` | `string?` | 用于直接 Strape 操作的 Strape API 版本覆盖 |
| `stripeSecretKey` | `string?` | 直接花纹操作的花纹密钥, 而不是构造键 |

### FloPay 方法

| 方法 | 回返 | 说明 |
| --- | --- | --- |
| `checkout.sessions.create(params)` | `Promise<CheckoutSessionResult>` | 通过计费API创建会话( C)`POST /v1/checkouts/sessions`) (中文(简体) ). 接受 `CreateSessionParams`。 。 。 . |
| `checkout.sessions.retrieve(id)` | `Promise<CheckoutSession>` | 获取并规范条纹检查退出会话 |
| `checkout.sessions.expire(id)` | `Promise<CheckoutSession>` | 已过期的条形取出会话 |
| `checkout.sessions.listLineItems(id)` | `Promise<LineItem[]>` | 列出条形断面的行项目 |
| `customers.create(params)` | `Promise<Customer>` | 创建条纹客户端 |
| `customers.retrieve(id)` | `Promise<Customer>` | 获取条纹客户 |
| `customers.update(id, params)` | `Promise<Customer>` | 更新条纹客户端 |
| `webhooks.constructEvent(payload, signature, secret)` | `WebhookEvent` | 校验并解析花旗网游事件 |

参数和结果类型(`CreateSessionParams`, (中文(简体) ), `CheckoutSessionResult`, (中文(简体) ), `CheckoutSession`, (中文(简体) ), `Customer`, (中文(简体) ), `LineItem`, (中文(简体) ), `WebhookEvent`)导出于 `@flopay/shared`。 。 。 .

`@flopay/node` 没有卡片设置方法 也没有商人证书. `CreateCardSetupSessionRequest` 财务报告和审定财务报表 `CardSetupFutureUse`,并导出 `@flopay/shared`,键入您服务器发送给认证对象的正文 `POST /v1/checkouts/sessions/setup` 路由与自己的计费API客户端.

类型保存的支付方法由 `@flopay/shared` 还有: `SavedPaymentMethodDisplay`, (中文(简体) ), `SavedPaymentMethodFamily` (有被贬值的别名) `SavedPaymentMethodType`, (中文(简体) ), `ListSavedPaymentMethodsQuery` 联 合 国 `SavedPaymentMethodListType` 过滤值, `AdvertisedPaymentMethod`,则 `isSetupCheckoutSession` 警卫. `@flopay/node` 不为它们添加列表或删除方法.

## 错误

SDK验证和计费API故障 `FloPayError`从 `@flopay/shared`; 分支打开 `type` 财务报告和审定财务报表 `code`。 。 。 .

| 代码 | 类型 | 何时 |
| --- | --- | --- |
| `CurrencyRequired` | `validation_error` | `checkout.sessions.create()` 无法解析会话货币。 在任何请求之前丢弃 `param: 'currency'`。 。 。 . |
| `CaptureMethodUnsupportedForSubscription` | `validation_error` | `captureMethod: 'manual'` 请求购买一辆有订阅费的推车。 在任何请求之前就扔了. |
| API的账单 `code`,或 `http_<status>` | `api_error` | 计费API拒绝了会话创建. 错误保留了计费API的信息和代码, HTTP 状态在 `statusCode`。 。 。 . |
| `MissingCheckoutSessionToken` | `api_error` | 计费 API 创建了会话, 但返回否 `nonce`也就是说这个SDK太老了. |
| `resource_missing` | `api_error` | `customers.retrieve()` 找到一个删除的客户. |

构造 `FloPay` 没有密钥 扔出一个 `authentication_error`创建请求超过 `timeoutMs` 被中止,网络失败以隐藏的获取错误拒绝,而不是一个 `FloPayError`。包括Webhook签名验证在内的条纹操作以条纹本身的错误拒绝。 处理失败 `constructEvent()` 作为不信任的要求.

## 常见问题

### @flopay/node 是什么？

为Node\.js服务的服务器端 FloPay SDK\. 通过 FloPay 计费API 创建取出会话,检索并过期 Strede 取出会话,管理 Strede 客户端,并验证 Strede webhooks\.

### 如何安装 @flopay/node？

在项目目录运行 npm install @flopay/node，或使用 pnpm add / yarn add / bun add。

### @flopay/node 支持 TypeScript 吗？

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

### @flopay/node 支持 ESM 还是 CommonJS？

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

### @flopay/node 可以商用吗？

@flopay/node 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @flopay/node 的下载量有多少？

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

### @flopay/node 还在维护吗？

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

