Supabase Stripe Wrapper:用 Postgres FDW 直接读写 Stripe 数据的技术详解
【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase
本文以 Supabase 仓库中 Stripe Wrapper 集成概览 为起点,深入解析这个 Foreign Data Wrapper(外部数据包装器)的完整技术定义:它的扩展、处理器与校验器命名、服务器级连接参数(如api_key_id、api_url)、Studio 中"按表创建"与"外部 Schema"两种使用模式、全部 27 个可映射的 Stripe 对象及其列结构,以及它依赖的wrappers、supabase_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: true且secureEntry: 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.ts 的getWrapperCreationFormSchema会遍历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(源码):
- Tables 模式(
mode: 'tables'):逐表映射。用户从预定义的 Stripe 对象列表中选择要映射的对象,每张外表需要table_name、所属schema(可选custom+ 自定义schema_name)、列集合columns,以及该对象的object选项;要求"至少一张表"。 - 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 | 转账 |
列结构上有两点值得注意的设计:
- 固定列 +
attrsjsonb 列:每张表都暴露少量强类型列(id/text、金额类bigint、created/timestamp、状态类text、布尔bool等),并统一附加一个attrs(jsonb)列承载 Stripe API 返回的完整 JSON。例如 Balance Transactions 表暴露id、amount、currency、fee、net、status、type、created之外,其余字段全部收进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 specifier。loadIntegrationOverview(integrationId)对没有概览的集成(如 marketplace 应用)返回null。配套的 overviews.test.ts 会断言这张映射表与磁盘上的overview.md文件保持同步——新增集成时,overview.md与overviews.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.ts 与 Wrappers.utils.ts 中查证,测试文件 Wrappers.utils.test.ts 则锁定了这些校验行为。
【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考