# @flopay/js 中文文档

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

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

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

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

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

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

## 中文简介

浏览器- side FloPay SDK. `loadFloPay()` 初始化 a `FloPay` 例如,主机卡捕获和会话访问, `PaymentAPI` 是收费的 API 客户端,并且 `createCheckoutSession()` 创建退出会话并重定向到主机退出页面.

## 安装

```sh
npm install @flopay/js
```

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

## README

# @ flopay/js (英语)

浏览器- side FloPay SDK. `loadFloPay()` 初始化 a `FloPay` 例如,主机卡捕获和会话访问, `PaymentAPI` 是收费的 API 客户端,并且 `createCheckoutSession()` 创建退出会话并重定向到主机退出页面.

供应商坐在后面 `PaymentProviderAdapter` 接口(今天由 `StripeAdapter`),所以当一个会话被路由到另一个网关时,退出代码不会改变.

## 安装

```bash
pnpm add @flopay/js
```

`@stripe/stripe-js` 财务报告和审定财务报表 `@flopay/shared` 自动安装为依赖;您不需要添加。 启动时选择计费 API 环境 `configureFlopay()` 从 `@flopay/shared`,或 `NEXT_PUBLIC_FLOPAY_ENV` 环境变量.

对于反应应用程序, `@flopay/react` 以此软件包为基础, 并进行完整的检出 .

### 选择和升级发行

读取 [SDK 更改日志](https://changelog.sdk.flopay.com/) 对于目标释放的修改和 升级前的整合指导. 当安装多个时 `@flopay/*` 直接包装, 为每个版本选择相同的发布版本,并输入所产生的锁文件。 你没必要 安装已作为依赖性提供的软件包.

确认您正在更新的每个软件包可在 npm 上获取所选版本 。 合并 光是GitHub拉取请求并不意味着出版物已经完成。 如果准确版本尚未确定 ,等待出版,而不是混合版本或安装寄存处分支.

## 使用量

### 初始化 SDK

```ts
import { loadFloPay } from '@flopay/js';

const flopay = await loadFloPay('pk_test_...', {
  billingApiUrl: 'https://billing.example.com', // enables retrieveSession() and retrieveUnifiedSession()
});
```

可选第二个参数接受每 `FloPayConfig` 字段除外 `publishableKey`数字 : `billingApiUrl`, (中文(简体) ), `locale`, (中文(简体) ), `appearance`,以及 `telemetry`。 。 。 . `loadFloPay` 通过可公布的密钥和行为影响选项进行缓存:使用相同密钥的并行呼叫和选项共享一个飞行中初始化并解决相同问题 `FloPay` 举个例子 一个失败的初始化被赶出去,所以以后的调用可以重试.

### 获取会话

`flopay.retrieveSession(sessionId)` 返回已规范的 `CheckoutSession` (货币、货币、状况、客户). `flopay.retrieveUnifiedSession(sessionId)` 返回 a `NormalizedCheckoutSession`: 会话广告的每个网关都在 `providers`,而网关数据,例如Frede客户端秘密在下面 `data`两者均使用 `billingApiUrl` 从 `loadFloPay`,或者通过一个URL作为第二个参数.

`retrieveUnifiedSession()` 曝光特定提供者的会话数据而不包含 安装提供者 UI 。 使用 `FloPayCheckout` 或者说 `SplitCardForm` 从 `@flopay/react` 用于主机故障卡,钱包和APM渲染.

### 直接拨打帐单 API

`PaymentAPI` 将计费的 API 路由包起来。 会议宣读,继续开会 **无**当会话创建时返回并发送为 `x-checkout-session-token`。 。 。 .

-   `getUnifiedCheckoutSession(sessionId, nonce)` 读取并规范会话.
-   `createSessionIntent(sessionId, nonce, request)` 创建花脸钱包/APM或直接-PayPal意图。 申请是由提供者、付款方法类别、类型、身份和意向组成的歧视联盟;直接卡申请不能代表。 如果会话仍在处理更早的付款(例如正在审查的 PayPal 捕获),开具账单的API 回答 `202 checkout_processing`SDK然后在同一时限内对会话状态进行投票 `processPayment` 用户。 它决心达成一个既定的结果, `{ settled: true, response }`而不是意图. `response` 这是 `Response` `processPayment` 为此,将: `204` 已经成功, `200` 核定数, `400` 拒绝。 检查一下 `isSettledSessionIntent` 从 `@flopay/shared`如果时限提前到期,则以 `checkout_processing_timeout`, (中文(简体) ), `statusCode: 202` 编辑 `sessionId`。 。 。 .
-   `reportSessionIntentDecline(sessionId, nonce, request)` 仅使用分类代码报告客户端观察到的非卡率下降。 信件,标识符,卡片数据,证书,以及个人数据在发送前被拒绝.
-   `processPayment(userId, params)` 向届会提交已保存或核准的无卡付款 `/process` 路线。 当计费API回答时 `202`,SDK遵循其经认证的状态终点,直到最近的交易尝试成功,授权,下降,需要买方行动,失败或出盘.
-   `getPaymentsByEmail(email)` 检查前期付款的储蓄经验 .

### 创建主机退出会话

`createCheckoutSession(options)` 员额 `POST /v1/checkouts/sessions` 并重定向浏览器 :

-   打开 `201`,浏览器进入主机的取出页面,结果为 `{ status: 201, redirectUrl, nonce }`匹配 `flopay_checkout_token` cookie 写入了相同的父域 `checkout_data`,所以主机页面可以在不将其放入URL,历史,或 `Referer`。 。 。 .
-   打开 `204`,一个支付方法已经在文件中了,浏览器会前往 `successUrl`。 。 。 .

`createCheckoutSessionWithRetries(options)` 在瞬态运输、超时和偶效性在建故障上增加自动重试:最多两次重试(三次尝试),全部在12秒总限期内,您可以更改 `timeoutMs`。 。 。 .

### 检出元数据

过 `checkoutMetadata?: Record<string, string> | null` 以重定向、重试、一发内线或离子创建。 一张地图,一张明确的 `null`,以及 `{}` 发送不变;省略字段后,请求正文保持不变。 会话读取显示返回的快照为 `normalized.checkoutMetadata` 财务报告和审定财务报表 `normalized.data.session.checkoutMetadata`; 省略或 `null` 在读取时没有创建值,而 `{}` 返回为 `{}`。SDK不执行重复大小验证:计费API拒绝保留其 `code`、消息和 HTTP `statusCode`。 。 。 .

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

对于只检查项的卡片,如果该卡片应放置一个控件,而不是立即抓取,请添加 `captureMethod: 'manual'` 改为 `createCheckoutSession`, (中文(简体) ), `createCheckoutSessionWithRetries`, (中文(简体) ), `PaymentAPI.createAndFetchSession`,或 `PaymentAPI.createDetachedSession`。被接受的控件表面为 `status: 'authorized'` 和支付结果,以及 `paymentId`, (中文(简体) ), `sessionId`,以及 `authorizationExpiresAt`将它视为结账时间,但没有付款。 抓取是商家认证的 REST 操作, 浏览器代码从不可用; 见 [付款和授权](https://flopay.com/docs/technical-reference/rest/payments)。 。 。 .

### 同上,表1

每次检查会话创建都会发送一个稳定 `Idempotency-Key` 当安全随机源可用时, 头条, 所以一个超时或丢失的响应不能薄荷第二个会话 。 现有的一体化不需要改变.

-   **自动( 默认) :** sDK 每个逻辑生成一个密码随机键 `createCheckoutSession` 调用并重用它 用于操作的每一次重试。 独立通话即使身体完全相同也会得到不同的键. 该密钥从未从客户数据中获取,也从未被登录或返回. 无 `crypto.randomUUID` 或者说 `crypto.getRandomValues` 标题被省略; 提供您自己的密钥, 以便留在那里.
-   **销售:** 通过 `idempotencyKey` 以在重载、 SDK 实例或自己的服务器重试中保持密钥的稳定。 它精确地确定了一个逻辑核对结果,绝不能用于新的采购.

`createCheckoutSessionWithRetries` 在重试循环之前解决一次密钥, 因此超时、 丢失的响应, 进行中的答复都重放相同的密钥 ; a `409` 有效载荷冲突不经过重试就浮出水面. `PaymentAPI.createAndFetchSession` (使用时间: `@flopay/react`)遵循同样的规则,在网络故障和在建工程答复中共享一个三试预算.

### 已取消会话创建( 默认)

内置会话创建默认脱去 。 SDK没有一项要求解决买方的身份和目录,而是发布了两项:

1.  `POST /v1/checkouts/sessions` 与 `deferDataAttachment: true` 返回轻量级 **外壳**它不进行目录验证,也不使用串接同一客户同时报到的买方身份锁,但已经载有 `gateways` 和东道主 `vault` 块 : **纸牌表可以挂起.** 在此请求下发送出账元数据 .
2.  `PATCH /v1/checkouts/sessions/{id}/claim` 在背景中附加产品和优惠券。 当草案有电子邮件时,它也附有买方;无电子邮件的草稿省略了买方,而返回的会话有其完整的目录、总数和方法,同时 `buyerIdentified` 留下来 `false`。 。 。 .

`PaymentAPI.createDetachedSession(params)` 将这两个阶段暴露为: `{ shell, sessionId, nonce, claimed, claim }`。 。 。 . `claimed` 当目录附载的时候; `claim(account)` 稍后附上买方身份。 两者都是独立的重放安全:重复有效 `claim(account)` 而本地无效的电子邮件拒绝不会消耗操作. `createAndFetchSession` 还接受一个没有电子邮件的草稿,并与目录附载的匿名会话解决.

之前不得起诉 `claimed` 和解:向 API 计费拒绝进程、意图和拒绝要求未声称的会话 `409 checkout_session_data_attachment_required`,并持有无名主机卡充值,可重试 `503`。 。 。 . `@flopay/react` 为这个窗口打开卡片表的提交按钮.

对于分离的创造, `timeoutMs` 是每个阶段的新预算 : 外壳 POST 得到全部值, 在它成功后, PATCH 得到完整的值 `AbortSignal` (默认为12秒),所以花费的时间创造出一个可用的外壳永远不会饿死它的目录主张. 拆分创建需要向API v1.7.12 或更新或 `checkoutMode: 'full'`,当 `tokenizedData` 提供。 独发创作没有退后之处;通过 `deferDataAttachment: false` 强迫它。 由于目录验证移到索赔,一个无效的产品或券表面是相同的 `422`,在流动的后期。 SDK重播一个字节相同的有效载荷 重播一个已声明的会话回覆 `409` 不重试.

### 服务器侧卡网关( Worldpay)

计费API可以通过一个经批准的Worldpay Corporation Gateway完全通过服务器端处理主机故障和符合条件的被保存卡. 一个会话是否可以使用,是由从商家的活出网关和被保存方法的资格来计费API的决定. `PaymentAPI` 不发送网关提示, 提供者选择, 资格断言, 商号, 或方案引用 。 一切都保持提供者中立,所以现有的整合没有改变:

-   纸牌仍然通过主机卡表,从嵌入式 `vault` 块或 `getVaultCapture()`。没有Worldpay浏览器 SDK、密钥或证书: `gateways.worldpayCorporateGateway` 有一个 `null` 可公布的密钥且没有启用的方法,它从未出现在已规范的 `providers` 列表中选择一个选项.
-   结果也一样 `complete`, (中文(简体) ), `decline`,以及 `error` 事件。 衰减使用FloPay的衰减分类法,从不使用生处理器代码. 一份模棱两可的呈文将一直等待到向API开具帐单时进行核对为止;主机表格报告说 `error`,从来就没有成功过,以后的会话读回和解状态.
-   持卡人认证(3DS)通过与其他卡网关相同的提供者中性续作恢复. 主办表格报告 `action_required` 使用 Flo 托管的挑战 URL,适配器会让 URL 以自己的模式覆盖,结果在主机格式报告终端前解决服务器侧 `complete`, (中文(简体) ), `decline`,或 `error`。没有Worldpay或提供认证的脚本、商号、ACS URL或指使符到达浏览器.
-   合格保存卡自动、确认、回购和订阅的结账均使用同一供应商的中性 `/process` 无路径 `tokenizedData`立即成功并授权使用现有的Flo形状;a `202 checkout_processing` 响应通过非ce保护状态 URL 调节,包括衰减,购买者动作和终端出错状态.
-   当无法使用保存的方法时, `stored_payment_method_unsupported` 保留为可操作的 Flo 错误,用于选择另一种支付方法。 SDK从不默不作声地转换为不同的充电行为. 预定的订阅回单、复签、停签和存储的合格资格仍然是计费-API的责任.

`PaymentAPI` 自动只创建通用广告 `async-auto-checkout-v1` 响应能力使得计费API可以返回同步状态信封. 它不是一个世界支付能力或路由请求; 确认和完全创建不发送任何能力标题。 不要在创建请求中添加网关选择或提供者专用分支, 无论是通过此 SDK 还是您自己构建的请求: 计费API 拥有此决定 .

### 主机卡捕捉

`flopay.cardCapture()` 返回 a `CardCaptureAdapter` 输入 API 自成一体的主机卡表。 该表单拥有PCI卡片字段,它自己的提交按钮,符号化,充值(创建和确认的服务器侧),3DS,以及结果,所以 **没有花脸.js在卡片路径上运行** 和牌号从不进入 SDK 运行时间。 SDK注入表单并转发其终端结果.

-   使用会话嵌入 `vault` 屏蔽当存在。 否则拿一个 `PaymentAPI.getVaultCapture(sessionId, nonce)` 届会的条纹 `enabledPaymentMethods` 明确包括 `card`或者广告 `gateways.worldpayCorporateGateway`。 。 。 . `getVaultCapture()` 在同时呼叫者之间共享一个主动请求, 在十秒后中止一个已停顿的尝试, 并重试在位元器件上的瞬态网络故障 `POST /v1/checkouts/sessions/{id}/vault/capture` 路线.
-   结果活动是: `ready`, (中文(简体) ), `complete`, (中文(简体) ), `decline`,以及 `error`· ; `challenge_dismissed` 是买方终止认证质疑的非通知。 窗体是注入同窗的,因此适配器拒绝与挂载会话无关的终端结果,即不匹配块的 `messageToken`,或者从不同的 `expectedOrigin`从金库区传到 `mount()`。 。 。 .
-   当买方的银行要求认证时,寄存表将质疑交给适配器,这使得供应商以一整页模式覆盖URL(`role="dialog"`, (中文(简体) ), `aria-modal`,焦点转移到挑战中,并在任何处理背景之上恢复倒闭状态。 挑战不是一个结果:它没有到达任何听众,挑战URL在事件或遥测中从未出现. 主机表格能解决结果,并照常报告 `complete`, (中文(简体) ), `decline`,或 `error`; 如果没有任何结果, 覆盖在主机表单的认证窗口之后关闭并报告一个 `error`. 关闭重叠部分放弃挑战,并报告非永久性 `challenge_dismissed` 事件,使主机能够降低其处理状态,并让表单可以直接重试;它不是结果,而是迟到 `complete`, (中文(简体) ), `decline`,或 `error` 你们的听众,仍可享受主打表的款待.
-   A 类 `complete` 事件 `intentId` 是处理网关本身的参考。 它是一种花纹支付intent(或SetupIntentent)id,只在花纹取出卡时才会使用;对于服务器侧卡网关,它可能是一个不透明的订单参考. 调和 `paymentId` 和会议.
-   对于商务服务器创建的无收费设置会话,使用 `operation: 'card_setup'`A级 `complete` 事件然后可能只包含一个显示 `paymentMethod` (FloPay id,品牌,后四,到期,及地位.
-   `capture.applyTheme(theme)` (a) 不装入而重新为挂载形式作外皮; `applyTheme(null)` 是明确的经典重置。 明是化妆品 从来不阻碍捕捉.
-   `capture.setSubmitLabel(label)` 设置主机提交按钮的活字(billing API v1.9.35+),而不重载或清除输入的卡片数据。 通过最终的,已经本地化的纯文本;主机窗体显示其会话默认值( C)`CONFIRM PAYMENT`,或 `ADD CARD` 空白或无效文本. `capture.setSubmitLabel(null)` 是该默认的清晰重置,并且 a `submitLabel` 挂载选项设置了初始措辞.

适配器保留最新的标签并重放 每次部件报告一个认证 `ready`,所以延迟或重载 表格仍然收到它。 因为指令 带有商贸文本,它是 只有在金库区供应时才公布 `messageToken` 财务报告和审定财务报表 `expectedOrigin`,绑入挂载 `sessionId`,与准确 `expectedOrigin` 作为 `postMessage` 目标——从未 `'*'`数字 :

```ts
{ source: 'flopay-vault-host', type: 'submitLabel', sessionId, messageToken, label }
```

未安装这些字段的表格( 较旧的帐单 API) 保留默认值 。 标签从未被添加到遥测中. 其他东道主指令(主题、提交大门和外地秩序)也针对准确的 `expectedOrigin` 当一个被提供,回到 `'*'` 仅用于挂载的部件。 认证没有主机指令:主机格式不接受页面的补全信号,因为挑战的结果是解决了服务器侧.

### 隐私安全操作遥测

浏览器遥测在默认和最佳效果上. 它只向FloPay拥有的API报告已关闭的SDK错误、寿命周期和性能分类;它从未将Sentry捆绑起来,读取资源计时,坚持排队,或发送付款,客户,或形成数据,证书,URL,提供者有效载荷,任意信息,或堆栈. 选择退出 `telemetry: false` 打开 `loadFloPay`, (中文(简体) ), `PaymentAPI`, (中文(简体) ), `PciVaultCardCapture`, (中文(简体) ), `createCheckoutSession`,以及 `createCheckoutSessionWithRetries`. 商机召回程序保留其论点和引用命令;它们提出的例外只限制在您的控制台上.

真正的技术故障包含一个限定的类别: `server_error` 对API 5xx的答复, `transport_error` 当没有可用的反应到达时, `invalid_response` 反应不当,以及 `provider_runtime` 用于供应商 SDK 或主机形式的运行时间失败。 付款减少和请求验证失败作为非错误报告 `payment_declined` 财务报告和审定财务报表 `validation_rejected` 结果.

启用遥测时, 仅报告带宽加载器的拒绝 `provider_runtime` 类别,而无条纹加载器结果则使用不同的 `invalid_response` 类别。 既不改变抛出的错误,也不改变失败的负载重试行为,也不传输可公布的密钥,拒绝,提供者消息,堆栈,URL,或提供者的有效载荷.

`FloPayCheckout` 内 `@flopay/react` 还将会话和提供者边界周围的故障分类,而不暴露原始错误。 现有的会话读取运输失败用途 `transport_error`; JSON 使用不当 `invalid_response`。 。 。 .

### 过滤您自己的 Sentry 客户端中的第三方错误

```ts
import * as Sentry from '@sentry/browser';
import { dropThirdPartyOnlyError } from '@flopay/js';

Sentry.init({ beforeSend: dropThirdPartyOnlyError });
```

此纯上游投放只包含完全例外堆栈, 没有应用程序或 `@flopay/*` 框架和至少一个浏览器扩展 URL 或条纹 `dahlia/stripe.js` 控制帧 。 混合的,无关的,不完整的,和匿名的误差 返回不变,和哨兵的 `in_app` 旗被忽略.

## 实例

初始化 SDK 并读取会话的网关 :

```ts
import { loadFloPay } from '@flopay/js';

const flopay = await loadFloPay('pk_test_...', { billingApiUrl: 'https://billing.example.com' });

const session = await flopay.retrieveSession('session_uuid');
console.log(session.amount, session.currency, session.status);

const unified = await flopay.retrieveUnifiedSession('session_uuid');
if (unified.providers.includes('stripe')) {
  console.log('Stripe publishable key:', unified.data.stripe?.publishableKey);
}
```

创建一个包含元数据以及商家控制的一能键的挂出会话:

```ts
import { createCheckoutSessionWithRetries } from '@flopay/js';
import { FloPayError } from '@flopay/shared';

try {
  const result = await createCheckoutSessionWithRetries({
    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 }],
    account: { userId: 'user_1', email: 'user@example.com' },
    successUrl: '/success',
    cancelUrl: '/cancel',
    couponCodes: ['SAVE10'],
    checkoutMetadata: { merchantOrderId: 'order-123', campaign: 'summer' },
    idempotencyKey: 'checkout:order-123',
  });
  console.log('Checkout session created with status', result.status);
} catch (error) {
  if (error instanceof FloPayError && error.code === 'CouponLimitExceeded') {
    console.warn('Too many coupon codes.');
  } else if (error instanceof FloPayError && error.code === 'CouponCurrencyUnsupported') {
    console.warn('A coupon is not valid for this currency.');
  } else {
    throw error;
  }
}
```

创建分离会话,从外壳上挂出卡表,并稍后识别出购买者:

```ts
import { PaymentAPI } from '@flopay/js';

const api = new PaymentAPI('https://billing.example.com');

const detached = await api.createDetachedSession({
  clientId: 'client_123',
  currency: 'EUR',
  items: [{ providerItemId: 'prod_abc', providerItemName: 'Widget', totalAmount: 29.99 }],
  account: { userId: 'buyer_123' },
  successUrl: '/success',
  cancelUrl: '/cancel',
});

console.log('Card form can mount from', detached.shell.data.session?.vault);
const anonymous = await detached.claimed; // catalog, totals, and methods; buyerIdentified is false
const identified = await detached.claim({ email: 'buyer@example.com', firstName: 'Jane', lastName: 'Doe' });
console.log(anonymous.data.session?.buyerIdentified, identified.data.session?.buyerIdentified);
```

挂起主机卡表并转发其结果 :

```ts
import { loadFloPay, PaymentAPI } from '@flopay/js';
import type { PaymentResult } from '@flopay/shared';

const billingApiUrl = 'https://billing.example.com';
const sessionId = 'session_uuid';
const nonce = 'session_nonce';

function onComplete(result: PaymentResult) {
  console.log('Checkout finished:', result.status, result.paymentId);
}

const flopay = await loadFloPay('pk_test_...', { billingApiUrl });
const session = await flopay.retrieveSession(sessionId);
const vault = session.vault ?? (await new PaymentAPI(billingApiUrl).getVaultCapture(sessionId, nonce));

const capture = flopay.cardCapture({ sessionId, captureMethod: session.captureMethod });
capture.on('complete', (e) => {
  if (e.outcome === 'authorized' || session.captureMethod === 'manual') {
    onComplete({
      status: 'authorized',
      paymentId: e.paymentId,
      sessionId: e.sessionId,
      authorizationExpiresAt: e.authorizationExpiresAt,
    });
    return;
  }
  onComplete({ status: 'succeeded', paymentId: e.paymentId, sessionId: e.sessionId });
});
capture.on('decline', (e) => console.warn('Card declined:', e.declineReason));
capture.on('error', (e) => console.error('Card form failed:', e.message));

const container = document.getElementById('card-form');
if (container && vault.html) {
  await capture.mount(container, {
    html: vault.html,
    messageToken: vault.messageToken,
    expectedOrigin: vault.expectedOrigin,
    submitLabel: 'Pay €29.99',
  });
}
```

创建钱包意图并报告客户端可观察到的下降 :

```ts
import { PaymentAPI } from '@flopay/js';
import { isSettledSessionIntent } from '@flopay/shared';

const api = new PaymentAPI('https://billing.example.com', { telemetry: false });

const intent = await api.createSessionIntent('session_uuid', 'session_nonce', {
  provider: 'stripe',
  paymentMethodCategory: 'wallet',
  paymentMethodType: 'apple_pay',
  paymentMethodId: null,
  intentKind: 'payment',
});
if (isSettledSessionIntent(intent)) {
  // An earlier payment on this session already reached its outcome: there is nothing to confirm.
  console.log('Session settled with', intent.response.status);
} else if (intent.provider === 'stripe') {
  console.log('Confirm the wallet payment with', intent.clientSecret);
}

await api.reportSessionIntentDecline('session_uuid', 'session_nonce', {
  provider: 'stripe',
  paymentMethodCategory: 'wallet',
  paymentMethodType: 'apple_pay',
  providerDeclineReason: 'payment_failed',
});
```

## 公共 API

### 出口

| 导出 | 说明 |
| --- | --- |
| `loadFloPay(publishableKey, options?)` | 初始化 SDK 并解决 a `FloPay`。按密钥和选项分享成功和飞行中的工作;失败的工作仍然可以重试. |
| `FloPay` | 主 SDK 类,由 `loadFloPay()` |
| `PaymentAPI` | 计费API 客户端 : `new PaymentAPI(billingApiUrl, { telemetry })` |
| `createCheckoutSession(options)` | 创建退出会话并重定向。 决定a `CheckoutSessionResult`。 。 。 . |
| `createCheckoutSessionWithRetries(options)` | 喜欢 `createCheckoutSession`,在一个总期限内最多重复两次(三次尝试),使用紧张的指数倒置 |
| `PciVaultCardCapture` | `CardCaptureAdapter` 使用 API 主机卡表 |
| `CardCaptureOperation` | `'checkout'` 编号 : `'card_setup'` |
| `PciVaultCardCaptureConfig` | 适配器配置 : `sessionId?`, (中文(简体) ), `captureMethod?`, (中文(简体) ), `operation?`, (中文(简体) ), `expectedOrigin?`, (中文(简体) ), `telemetry?` |
| `StripeAdapter` | `PaymentProviderAdapter` 执行 |
| `toStripeAppearance(appearance)` | 转换 a `FloPayAppearance` 改为 a `StripeSafeAppearance`,绘制 FloPay 的地图 `theme` 符号( r)`'default'`, (中文(简体) ), `'flat'`, (中文(简体) ), `'night'`, (中文(简体) ), `'none'`在史崔克接受的设定。 随便你把外表给Freace元素自己用. |
| `toStripeAppearanceTheme(theme)` | 绘制单个 FloPay 地图的下级助手 `theme` 给条纹的符号 |
| `StripeSafeAppearance` | 一个外观花纹元素接受 |
| `cacheSessionDisplayData(sessionId, data, options?)` | Stashes 仅显示会话数据客户端侧面, 这样它就可以在重定向到取出页面后幸存 |
| `getSessionDisplayData(sessionId)` | 读取已缓存的显示数据,或 `null` 当没有缓存或过期时 |
| `clearSessionDisplayData(sessionId)` | 丢弃缓存的显示数据, 例如在成功页面 |
| `SessionDisplayCacheData` | 仅显示存储的数据 `cacheSessionDisplayData()` |
| `dropThirdPartyOnlyError(event)` | 哨兵 `beforeSend` 跳出已识别的第三方例外堆栈, 否则返回原始事件 |

### FloPay 方法

| 方法 | 回返 | 说明 |
| --- | --- | --- |
| `cardCapture(options?)` | `CardCaptureAdapter` | 创建寄存卡窗体适配器 `sessionId` 财务报告和审定财务报表 `captureMethod` |
| `retrieveSession(sessionId, billingApiUrl?)` | `Promise<CheckoutSession>` | 读取会话通过 `GET /v1/checkouts/sessions/{id}` |
| `retrieveUnifiedSession(sessionId, billingApiUrl?)` | `Promise<NormalizedCheckoutSession>` | 读取并规范会话,包括网关数据 |
| `getRawProvider()` | `unknown` | 基础提供者实例, 如 Friede 对象 |
| `destroy()` | `void` | 撕下遥测和提供者 |

### 付款API方法

| 方法 | 回返 | 说明 |
| --- | --- | --- |
| `getUnifiedCheckoutSession(sessionId, nonce?)` | `Promise<NormalizedCheckoutSession>` | 读取并规范会话 |
| `getVaultCapture(sessionId, nonce?)` | `Promise<VaultCaptureBlock>` | 当会话没有嵌入时获取主机卡表 `vault` 块 |
| `createAndFetchSession(params)` | `Promise<NormalizedCheckoutSession>` | 创建内置会话, 一旦其目录( 以及任何供应的购买者) 被附后即解决 |
| `createDetachedSession(params)` | `Promise<DetachedCheckoutSession>` | 分两个阶段创建内置会话并同时曝光 |
| `claimCheckoutSession(sessionId, nonce, payload)` | `Promise<NormalizedCheckoutSession>` | 发送一个 `PATCH /v1/checkouts/sessions/{id}/claim` |
| `createSessionIntent(sessionId, nonce, request, options?)` | `Promise<SessionIntentResult>` | 创建花脸钱包/ APM 或直接 PayPal 意图 。 如果会议仍在处理提前付款,则决定 `{ settled: true, response }` 与支付的结果. |
| `reportSessionIntentDecline(sessionId, nonce, request, options?)` | `Promise<void>` | 报告非卡率下降分类 |
| `processPayment(userId, params, options?)` | `Promise<Response>` | 向 `/process`页:1 `202` 遵循已公布的经认证状态终点,并将终端尝试结果回溯到现有流程响应形状 |
| `waitForCheckoutSessionCompletion(sessionId, options?)` | `Promise<NormalizedCheckoutSession>` | 等待终端状态; 通过会话 `nonce` 和处理回复 `statusUrl` 协调尝试一级的成功、授权、下降、买方行为和失败. `timeoutMs` (默认时为15秒)停止正常投票. 在飞行中读取的读取器在15多秒的宽限期内仍可能着陆;如果返回终端状态,SDK可能会启动一个后续会话来读取结果正常化. 整个行动都受此恩宠所限 |
| `reportThreeDsAbandoned(sessionId)` | `void` | 在Flo的隐私安全遥测中记录一张被保存的卡片3DS对买方提出挑战,从未作为买方放弃的结果完成,而不是技术故障。 遥测关闭时不开放 自动付款按钮给你打电话 |
| `getPaymentsByEmail(email, options?)` | `Promise<{ data, total, page, limit }>` | 列出电子邮件的先前付款 |
| `destroy()` | `void` | 撕下客户端的遥测 |

### PciVaultCard 能力方法

| 方法 | 说明 |
| --- | --- |
| `mount(container, { html, messageToken?, expectedOrigin?, submitLabel? })` | 输入主机卡表 |
| `on(event, handler)` | 订阅 `ready`, (中文(简体) ), `complete`, (中文(简体) ), `decline`,或 `error` |
| `unmount()` | 删除窗体及其听众 |
| `applyTheme(theme)` | 重新剥下挂起式; `null` 是经典重置 |
| `setSubmitGate(blocked)` | 虽然 `blocked`,则主机表格取消其下次提交并发送 `blocked` 因此主机可以先验证自己的字段( 如 AVS) |
| `setCardFieldOrder(order, autoFocus)` | 重排主机卡行( E)`name`, (中文(简体) ), `number`, (中文(简体) ), `expiry`);第一行集中,除非 `autoFocus` 错误 |
| `setSubmitLabel(label)` | 设置主机提交措辞为活; `null` 默认恢复会话 |

## 错误

失败者拒绝 `FloPayError` 从 `@flopay/shared`部门 `type` 财务报告和审定财务报表 `code`永远不要 `message`。当计费的 API 返回结构化错误正文时, SDK 将保持其安全 `message`, (中文(简体) ), `code`,和 HTTP 软件 `statusCode`;无体反应回落到 `code: 'http_<status>'`。 。 。 .

| 代码 | 类型 | 何时 |
| --- | --- | --- |
| `CurrencyRequired` | `validation_error` | 会话的创建无法从会话、项目、订阅或产品中解决货币问题。 在任何请求之前就扔了. |
| `CouponLimitExceeded` | `validation_error` 或者说 `api_error` | 提供了5个以上的优惠券编码:a `validation_error` 在提出请求之前,或 `api_error` 从账单API. |
| `CouponCurrencyUnsupported` | `api_error` | 基于金额的优惠券在车币上没有出价. |
| `CaptureMethodUnsupportedForSubscription` | `validation_error` | 要求手动抓取一辆有订阅的手推车. |
| `InvalidIdempotencyKey` | `validation_error` | 提供 `idempotencyKey` 空白或超过255个字符。 在任何请求之前就扔了. |
| `IdempotencyKeyInProgress` | `api_error` | 同样的密钥仍在处理中. 在截止日期内用相同的密钥自动重审. |
| `MissingCheckoutSessionToken` | `validation_error` 或者说 `api_error` | 在没有会话非会话的情况下继续呼叫,或者计费API创建会话而不返回会话. |
| `BuyerEmailCollectionRequired` | `validation_error` | 为创建或逾期索赔而提供的买方电子邮件不是有效的电子邮件地址. |
| `checkout_session_data_attachment_required` | `api_error` | 在分立的会议的目录债权(HTTP 409)得到解决之前,提出了程序、意图或拒绝要求。 等着 `claimed`。 。 。 . |
| `InvalidSessionIntentRequest` | `validation_error` | 意图请求不是支持的非卡或PayPal请求. |
| `InvalidAuthorizationAttemptId` | `validation_error` | 意向请求的授权尝试ID不是有效的UUID. |
| `InvalidSessionIntentDeclineRequest` | `validation_error` | 一份下降报告除了安全分类代码之外 还有其他东西. |
| `InvalidSessionIntentResponse` | `api_error` | 计费API返回了不符合请求的意向. |
| `InvalidCheckoutSessionResponse` | `api_error` | 计费的 API 返回了错误的会话或没有会话 ID . |
| `session_auto_completed` | `api_error` | Inline Creature 找到一个已经在文件中的支付方法, 并完成了会话, 无需检出 . |
| `checkout_processing_timeout` | `api_error` | SDK无法及时得到终端解答,所以还不知道付款结果,可能仍然完整. 不重新提交或向买方提供复试:与 `payment.*` 或再次读取会话。 买方发来的消息说,付款仍在确认之中。 何时 `createSessionIntent` 提出它,因为会议仍在处理 较早的付款,它也携带 `statusCode: 202` 编辑 `sessionId`。 。 。 . |
| `stored_payment_method_unsupported` | `api_error` | 此交易不能使用后端选择的保存方法 。 要求买方选择另一种支付方法;SDK不会默默地改变支付行为. |
| `vault_capture_timeout` | `api_error` | `getVaultCapture()` 未在10秒内返回主机卡表. |
| `card_capture_no_window` | `api_error` | `PciVaultCardCapture.mount()` 运行在浏览器外. |
| `card_capture_no_widget_html` | `api_error` | `PciVaultCardCapture.mount()` 在不使用 HTML 格式的情况下调用. |

纸牌下降不是扔出,而是按纸牌形式运出 `decline` 包含一个事件 `declineReason`技术故障是造成 `error` 活动。 在拆分目录索赔中被拒绝的产品或优惠券作为API的账单出现 `422` 错误来自 `claimed`。 。 。 .

## 常见问题

### @flopay/js 是什么？

浏览器- side FloPay SDK\. loadFloPay\(\) 初始化 a FloPay 例如,主机卡捕获和会话访问, PaymentAPI 是收费的 API 客户端,并且 createCheckoutSession\(\) 创建退出会话并重定向到主机退出页面\.

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

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

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

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

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

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

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

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

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

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

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

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

