首页
/ Supabase Stripe Wrapper:用 Postgres FDW 直接读写 Stripe 数据的技术详解

Supabase Stripe Wrapper:用 Postgres FDW 直接读写 Stripe 数据的技术详解

2026-09-06 15:47:15作者:姚月梅Lane

本文以 Supabase 仓库中 Stripe Wrapper 集成概览 为起点,深入解析这个 Foreign Data Wrapper(外部数据包装器)的完整技术定义:它的扩展、处理器与校验器命名、服务器级连接参数(如 api_key_idapi_url)、Studio 中"按表创建"与"外部 Schema"两种使用模式、全部 27 个可映射的 Stripe 对象及其列结构,以及它依赖的 wrapperssupabase_vault 前置扩展。读完后,你将能够基于仓库中的真实元数据,在自己的 Postgres 数据库中正确配置并查询 Stripe 的客户、订阅、发票与支付数据。

什么是 Stripe Wrapper

官方概览文档 给出的核心定义只有两句,但信息密度很高:

Stripe 是一个 API 驱动的支付处理和订阅管理平台。Stripe Wrapper 是一个 Foreign Data Wrapper,允许你在 Postgres 数据库内部直接从 Stripe 读取和写入数据。

这意味着 Stripe 的账户数据不需要经过 ETL 管道或 Webhook 搬运,就能以 Postgres 外表(foreign table)的形式出现在你的数据库里,直接用 SQL 完成 JOIN、聚合和 BI 查询。"读写"两个方向都要注意:既支持 SELECT 拉取 Stripe API 的对象列表,也支持通过 INSERT/UPDATE 回写到 Stripe。

在 Supabase Studio 的集成市场中,该集成的标识为 stripe_wrapper,其展示描述为"Payment processing and subscription management",归类于 billing 分类。

技术身份:扩展、Handler 与 Validator

从源码定义 Wrappers.constants.ts 可以看到,每个 Wrapper 在 Postgres 侧都由三元组标识:

属性 stripe_wrapper 的取值 作用
extensionName StripeFdw 需要安装的 Postgres 扩展
handlerName stripe_fdw_handler CREATE SERVER ... HANDLER 时指定的 FDW 处理函数
validatorName stripe_fdw_validator 校验服务器/外表选项合法性的函数
name stripe_wrapper Studio 内部集成标识
docsUrl /guides/database/extensions/wrappers/stripe 官方文档页

WRAPPER_HANDLERS 映射表 中,Stripe 与 Firebase、S3、ClickHouse、BigQuery、Airtable 等属于原生(非 WASM)FDW 处理器一列;而 Paddle、Snowflake、Slack、Notion 等则统一走 wasm_fdw_handler。这种区分说明 Stripe 使用的是针对其 REST API 专门实现的 C 层 FDW,而非通用 WASM 封装。

服务器级连接参数

stripe_wrapper 的 server.options 定义 中,连接 Stripe 需要配置以下三个服务器选项:

选项名 表单标签 必填 说明
api_key_id Stripe Secret Key Stripe 密钥;encrypted: truesecureEntry: true,表示 Studio 会以密文形式存入 Vault,输入框为安全输入
api_url Stripe API URL 默认值 https://api.stripe.com/v1,可覆盖以指向其他 API 端点
supabase_target_schema Target Schema 隐藏且只读 的框架选项(hidden: true, readOnly: true),由 Studio 在后台自动写入,用于指定外表落位的 target schema

密钥通过 encrypted 标记说明其不直接落在 CREATE SERVER 的明文中,而是经由 Supabase Vault 扩展托管——这也是下面"前置扩展"一节中 supabase_vault 成为必需项的原因。

表单层面对这些选项做了强制校验:Wrappers.utils.tsgetWrapperCreationFormSchema 会遍历 server.options,把所有 required: true 的选项(即 api_key_id)编译为 Zod 必填字段,可选项(api_url)编译为 z.string().optional()。对应的单测 Wrappers.utils.test.ts 断言了:缺少 api_key_id 时校验失败并定位到该字段,而缺少 api_url 时不产生错误——与上面的参数表一一对应。

两种使用模式:Tables 模式与 Schema 模式

创建 Wrapper 表单是一个以 mode 为判别字段的 discriminated union(源码):

  1. Tables 模式(mode: 'tables':逐表映射。用户从预定义的 Stripe 对象列表中选择要映射的对象,每张外表需要 table_name、所属 schema(可选 custom + 自定义 schema_name)、列集合 columns,以及该对象的 object 选项;要求"至少一张表"。
  2. Schema 模式(mode: 'schema':整 Schema 映射。只需提供 source_schema(Stripe 侧源 schema)与 target_schema(Postgres 侧唯一目标 schema)。stripe_wrapper 的 source_schema 选项 默认值为 stripe

单测 Wrappers.utils.test.ts 明确验证了两个分支:tables 模式缺 tables 字段会报错,schema 模式缺 source_schema/target_schema 会报错。

支持的 27 个 Stripe 对象

stripe_wrapper 的 tables 数组 完整枚举了可映射的 Stripe API 对象,每个对象由一个不可编辑、必填object 选项指向对应的 API 端点:

对象 object 默认值 说明(原文描述摘要)
Accounts accounts Stripe 账户下的账户列表
Balance balance 账户当前余额
Balance Transactions balance_transactions 构成账户余额的交易
Charges charges 已发生的扣款
Checkout Sessions checkout/sessions Checkout/Payment Links 支付会话
Customers customers 客户
Disputes disputes 客户向发卡机构发起的争议
Events events Stripe 账户内发生的事件
Files files 托管在 Stripe 服务器上的文件
File Links file_links 与非 Stripe 用户共享文件的链接
Invoices invoices 发票
Mandates mandates 客户授权扣款的凭证记录
Meters billing/meters 计费中的用量计量事件
Payment Intents payment_intents 支付意向
Payouts payouts 提现/打款到银行账户或借记卡
Prices prices 产品价格对象
Products products 产品
Refunds refunds 退款
Setup Attempts setup_attempts SetupIntent 的确认尝试
Setup Intents setup_intents 保存支付凭证的意向
Subscriptions subscriptions 订阅
Tokens tokens 令牌
Top-ups topups 充值
Transfers transfers 转账

列结构上有两点值得注意的设计:

  • 固定列 + attrs jsonb 列:每张表都暴露少量强类型列(id/text、金额类 bigintcreated/timestamp、状态类 text、布尔 bool 等),并统一附加一个 attrsjsonb)列承载 Stripe API 返回的完整 JSON。例如 Balance Transactions 表暴露 idamountcurrencyfeenetstatustypecreated 之外,其余字段全部收进 attrs。这保证了常用字段有类型、有性能,长尾字段又不丢失。
  • rowid_column 选项:Accounts、Checkout Sessions、Customers、Products、Subscriptions 等对象额外提供可编辑的 rowid_column(默认 id),用于标识行身份,支撑对 Stripe 的写回操作(UPDATE/DELETE 依赖它定位远端对象)。

前置扩展与版本约束

Stripe Wrapper 并非开箱即用,它依赖两个扩展,这一点在 getRequiredExtensionsToInstall 及其测试中有明确定义:

  • wrappers:FDW 框架核心扩展;
  • supabase_vault:用于安全托管 api_key_id 等加密选项。

Wrappers.utils.test.ts 验证了"缺哪个补哪个"的安装逻辑:两个都已安装时返回空数组,只装了 supabase_vault 时返回 ['wrappers']

另外,hasForeignSchemaSupport 的单测界定了版本能力边界:wrappers 扩展 >= 0.5.0 才支持外部 Schema(foreign schema)模式,0.4.9 及以下返回 false。因此如果你要使用上文的 Schema 模式(source_schema/target_schema),应确认数据库中安装的 wrappers 版本满足该前提。

与 Stripe Sync Engine 的分工

同目录下还有一个近亲集成 stripe_sync_engine,其官方描述是:"将 Stripe 账户中的 customers、subscriptions、invoices、payments 数据同步(sync)到 Supabase 账户的 Postgres 表"。两者定位不同:

  • stripe_wrapper(本文主题):FDW,数据实时代理,查询时按需读写 Stripe,适合交互式 SQL 分析、联表查询;
  • stripe_sync_engine:同步引擎,把数据物化到本地 Postgres 表,适合需要本地持久副本的场景。

在 Studio 集成市场里二者并列出现,选择依据取决于"实时代理"还是"物化副本"。

概览文档在 Studio 中的加载机制

最后交代一下这份 overview.md 本身如何进入产品。overviews.ts 维护了一个以集成为键的惰性加载表,stripe_wrapper 的条目动态 import 本概览 Markdown;文件头部注释解释了为什么必须写成字符串字面量:webpack/turbopack 与 Vite/Rolldown 的 md-as-string 加载器(next.config.ts 的 raw-loader 规则、vite.config.ts 的 mdRawLoader 插件)只能静态分析字面量导入,模板字符串写法会在 TanStack 构建中抛出 TypeError: Failed to resolve module specifierloadIntegrationOverview(integrationId) 对没有概览的集成(如 marketplace 应用)返回 null。配套的 overviews.test.ts 会断言这张映射表与磁盘上的 overview.md 文件保持同步——新增集成时,overview.mdoverviews.ts 条目需要同时添加。

小结

Stripe Wrapper 让 Stripe 数据以标准 Postgres 外表的形式进入你的数据库:由 StripeFdw 扩展、stripe_fdw_handler 处理器与 stripe_fdw_validator 校验器构成技术底座,通过 api_key_id(Vault 加密托管)与可选的 api_url 建立连接,支持 27 个 Stripe 对象的逐表映射(Tables 模式)或整体 Schema 映射(要求 wrappers >= 0.5.0)。所有参数、列与默认值均可在上述 Wrappers.constants.tsWrappers.utils.ts 中查证,测试文件 Wrappers.utils.test.ts 则锁定了这些校验行为。

登录后查看全文
热门项目推荐
相关项目推荐