数据库

Stripe


Stripe 是一种基于 API 的在线支付处理工具。

Stripe Wrapper 允许您在 Postgres 数据库中读取 Stripe 的数据。

准备#

在查询 Stripe 之前,您需要启用 Wrappers 扩展并在 Postgres 中存储您的凭据。

启用 Wrappers#

确保 wrappers 扩展已安装在您的数据库上

1
create extension if not exists wrappers with schema extensions;

启用 Stripe Wrapper#

启用 stripe_wrapper FDW

1
create foreign data wrapper stripe_wrapper
2
handler stripe_fdw_handler
3
validator stripe_fdw_validator;

存储您的凭据(可选)#

默认情况下,Postgres 将 FDW 凭据以明文形式存储在 pg_catalog.pg_foreign_server 中。任何访问此表的人都可以查看这些凭据。Wrappers 旨在与 Vault 配合使用,Vault 为存储凭据提供额外的安全级别。我们建议使用 Vault 存储您的凭据。

1
-- Save your Stripe API key in Vault and retrieve the created `key_id`
2
select vault.create_secret(
3
'<Stripe API key>',
4
'stripe',
5
'Stripe API key for Wrappers'
6
);

连接到 Stripe#

我们需要向 Postgres 提供连接到 Stripe 的凭据以及任何其他选项。我们可以使用 create server 命令来执行此操作

1
create server stripe_server
2
foreign data wrapper stripe_wrapper
3
options (
4
api_key_id '<key_ID>', -- The Key ID from above, required if api_key_name is not specified.
5
api_key_name '<key_Name>', -- The Key Name from above, required if api_key_id is not specified.
6
api_url 'https://api.stripe.com/v1/', -- Stripe API base URL, optional. Default is 'https://api.stripe.com/v1/'
7
api_version '2024-06-20' -- Stripe API version, optional. Default is your Stripe account’s default API version.
8
);

创建模式#

我们建议创建一个模式来保存所有外部表

1
create schema if not exists stripe;

实体#

Stripe Wrapper 支持从 Stripe API 读取和修改数据。

对象选择插入更新删除截断
账户
余额
余额交易
收费
结账会话
客户
争议
事件
文件
文件链接
发票
授权
计量
PaymentIntents
支付
价格
产品
退款
SetupAttempts
SetupIntents
订阅
令牌
充值
转账

我们可以使用 SQL import foreign schema 来从 Stripe 导入外部表定义。

例如,使用下面的 SQL 可以自动在 stripe schema 中创建外部表。

1
-- create all the foreign tables
2
import foreign schema stripe from server stripe_server into stripe;
3
4
-- or, create "checkout_sessions", "customers" and "balance" tables only
5
import foreign schema stripe
6
limit to ("checkout_sessions", "customers", "balance")
7
from server stripe_server into stripe;
8
9
-- or, create all foreign tables except "checkout_sessions" and "billing_meters"
10
import foreign schema stripe
11
except ("checkout_sessions", "billing_meters")
12
from server stripe_server into stripe;

完整的外部表列表如下

账户#

这是一个代表 Stripe 账户的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
账户

用法#

1
create foreign table stripe.accounts (
2
id text,
3
business_type text,
4
country text,
5
email text,
6
type text,
7
created timestamp,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'accounts'
13
);

说明#

  • 虽然 where 子句中允许任何列,但按 id 过滤效率最高
  • 使用 attrs jsonb 列访问其他账户详细信息

余额#

这是一个代表 Stripe 账户当前余额的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
余额

用法#

1
create foreign table stripe.balance (
2
balance_type text,
3
amount bigint,
4
currency text,
5
attrs jsonb
6
)
7
server stripe_server
8
options (
9
object 'balance'
10
);

说明#

  • 余额是一个只读对象,显示 Stripe 账户中的当前资金
  • 余额按来源类型(例如,卡、银行账户)和货币细分
  • 使用 attrs jsonb 列访问其他余额详细信息,例如待处理金额
  • 虽然 where 子句中允许任何列,但由于这是一个单例对象,过滤选项有限

余额交易#

这是一个代表资金流经 Stripe 账户的对象。每当资金进入或流出 Stripe 账户余额时,都会创建余额交易。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
余额交易

用法#

1
create foreign table stripe.balance_transactions (
2
id text,
3
amount bigint,
4
currency text,
5
description text,
6
fee bigint,
7
net bigint,
8
status text,
9
type text,
10
created timestamp,
11
attrs jsonb
12
)
13
server stripe_server
14
options (
15
object 'balance_transactions'
16
);

说明#

  • 余额交易是 Stripe 账户中所有资金流动的只读记录
  • 每笔交易包括金额、货币、费用和净额信息
  • 使用 attrs jsonb 列访问其他交易详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • type

收费#

这是一个代表信用卡或借记卡上的收费的对象。您可以检索和退还单个收费,以及列出所有收费。收费由唯一的随机 ID 标识。

参考:Stripe 文档

Operations#

对象选择插入更新删除截断
收费

Usage#

1
create foreign table stripe.charges (
2
id text,
3
amount bigint,
4
currency text,
5
customer text,
6
description text,
7
invoice text,
8
payment_intent text,
9
status text,
10
created timestamp,
11
attrs jsonb
12
)
13
server stripe_server
14
options (
15
object 'charges'
16
);

Notes#

  • 收费是 Stripe 账户中支付交易的只读记录
  • 每笔收费包括金额、货币、客户和付款状态信息
  • 使用 attrs jsonb 列访问其他收费详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户

结账会话#

这是一个代表您的客户通过 Checkout 或 Payment Links 支付一次性购买或订阅时的会话的对象。我们建议每次客户尝试付款时创建一个新的会话。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
结账会话

用法#

1
create foreign table stripe.checkout_sessions (
2
id text,
3
customer text,
4
payment_intent text,
5
subscription text,
6
attrs jsonb
7
)
8
server stripe_server
9
options (
10
object 'checkout/sessions',
11
rowid_column 'id'
12
);

说明#

  • 结账会话是 Stripe 账户中客户支付会话的只读记录
  • 每个会话包括客户、付款意图和订阅信息
  • 使用 attrs jsonb 列访问其他会话详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户
    • 付款意图
    • 订阅

客户#

这是一个代表您的 Stripe 客户的对象。您可以创建、检索、更新和删除客户。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
客户

用法#

1
create foreign table stripe.customers (
2
id text,
3
email text,
4
name text,
5
description text,
6
created timestamp,
7
attrs jsonb
8
)
9
server stripe_server
10
options (
11
object 'customers',
12
rowid_column 'id'
13
);

示例操作

1
-- create a new customer
2
insert into stripe.customers(email, name, description)
3
values ('jane@example.com', 'Jane Smith', 'Premium customer');
4
5
-- update a customer
6
update stripe.customers
7
set name = 'Jane Doe'
8
where email = 'jane@example.com';
9
10
-- delete a customer
11
delete from stripe.customers
12
where id = 'cus_xxx';

说明#

  • 客户可以通过 SQL 操作创建、检索、更新和删除
  • 每个客户可以拥有电子邮件、姓名和描述
  • 使用 attrs jsonb 列访问其他客户详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • email

争议#

这是一个代表客户对他们的卡发卡行质疑您的收费时发生的争议的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
争议

用法#

1
create foreign table stripe.disputes (
2
id text,
3
amount bigint,
4
currency text,
5
charge text,
6
payment_intent text,
7
reason text,
8
status text,
9
created timestamp,
10
attrs jsonb
11
)
12
server stripe_server
13
options (
14
object 'disputes'
15
);

备注#

  • 争议是 Stripe 账户中客户支付争议的只读记录
  • 每个争议包括金额、货币、收费和付款意图信息
  • 使用 attrs jsonb 列访问其他争议详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 收费
    • 付款意图

事件#

这是一个代表在 Stripe 账户中发生的事件的对象,让您知道何时发生了一些有趣的事情。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
事件

用法#

1
create foreign table stripe.events (
2
id text,
3
type text,
4
api_version text,
5
created timestamp,
6
attrs jsonb
7
)
8
server stripe_server
9
options (
10
object 'events'
11
);

备注#

  • 事件是 Stripe 账户中活动的只读记录
  • 每个事件包括类型、API 版本和时间戳信息
  • 使用 attrs jsonb 列访问其他事件详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • type

文件#

这是一个代表托管在 Stripe 服务器上的文件的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
文件

用法#

1
create foreign table stripe.files (
2
id text,
3
filename text,
4
purpose text,
5
title text,
6
size bigint,
7
type text,
8
url text,
9
created timestamp,
10
expires_at timestamp,
11
attrs jsonb
12
)
13
server stripe_server
14
options (
15
object 'files'
16
);

备注#

  • 文件是托管在 Stripe 服务器上的文件的只读记录
  • 每个文件包括文件名、用途、大小、类型和 URL 信息
  • 文件可能在 expires_at 中指定到期日期
  • 使用 attrs jsonb 列访问其他文件详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 用途

这是一个代表可用于与非 Stripe 用户共享 File 对象内容的链接的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
文件链接

用法#

1
create foreign table stripe.file_links (
2
id text,
3
file text,
4
url text,
5
created timestamp,
6
expired bool,
7
expires_at timestamp,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'file_links'
13
);

备注#

  • 文件链接是提供对 Stripe 文件共享访问权限的只读记录
  • 每个链接包括对文件的引用和公共 URL
  • 链接可以配置为在特定时间过期
  • 使用 expired 布尔值检查链接是否已过期
  • 使用 attrs jsonb 列访问其他链接详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • file

发票#

这是一个代表客户欠款的报表的对象,这些报表要么一次性生成,要么定期从订阅中生成。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
发票

用法#

1
create foreign table stripe.invoices (
2
id text,
3
customer text,
4
subscription text,
5
status text,
6
total bigint,
7
currency text,
8
period_start timestamp,
9
period_end timestamp,
10
attrs jsonb
11
)
12
server stripe_server
13
options (
14
object 'invoices'
15
);

备注#

  • 发票是客户欠款的只读记录
  • 每张发票包括客户、订阅、状态和金额信息
  • 发票跟踪带有 period_start 和 period_end 时间戳的计费周期
  • 使用 attrs jsonb 列访问其他发票详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户
    • 状态
    • 订阅

授权#

这是一个代表客户授予您扣款其付款方式的权限的记录的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
授权

用法#

1
create foreign table stripe.mandates (
2
id text,
3
payment_method text,
4
status text,
5
type text,
6
attrs jsonb
7
)
8
server stripe_server
9
options (
10
object 'mandates'
11
);

备注#

  • 授权是客户付款权限的只读记录
  • 每个授权包括付款方式、状态和类型信息
  • 使用 attrs jsonb 列访问其他授权详细信息
  • 虽然 where 子句中允许任何列,但按
    • id

计量#

这是一个代表允许您跟踪特定事件使用情况的计费计量仪的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
计量

用法#

1
create foreign table stripe.billing_meter (
2
id text,
3
display_name text,
4
event_name text,
5
event_time_window text,
6
status text,
7
attrs jsonb
8
)
9
server stripe_server
10
options (
11
object 'billing/meters'
12
);

备注#

  • 计量是用于跟踪计费中事件使用情况的只读记录
  • 每个计量仪包括显示名称、事件名称和时间窗口信息
  • 状态字段指示计量仪是否处于活动状态
  • 使用 attrs jsonb 列访问其他计量仪详细信息
  • 虽然 where 子句中允许任何列,但按
    • id

付款意图#

这是一个代表指导您从客户处收款过程的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
付款意图

用法#

1
create foreign table stripe.payment_intents (
2
id text,
3
customer text,
4
amount bigint,
5
currency text,
6
payment_method text,
7
created timestamp,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'payment_intents'
13
);

备注#

  • 付款意图是指导付款收款过程的只读记录
  • 每个意图包括客户、金额、货币和付款方式信息
  • 创建时间戳跟踪付款意图的启动时间
  • 使用 attrs jsonb 列访问其他付款意图详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户

Payouts#

这是代表从 Stripe 收到的资金或发起的支付到连接的 Stripe 账户的银行账户或借记卡的对象的。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
支付

用法#

1
create foreign table stripe.payouts (
2
id text,
3
amount bigint,
4
currency text,
5
arrival_date timestamp,
6
description text,
7
statement_descriptor text,
8
status text,
9
created timestamp,
10
attrs jsonb
11
)
12
server stripe_server
13
options (
14
object 'payouts'
15
);

说明#

  • Payouts 是资金转移的只读记录
  • 每个 Payout 都包含金额、货币和状态信息
  • arrival_date 指示资金何时可用
  • statement_descriptor 出现在您的银行对账单上
  • 使用 attrs jsonb 列访问其他 Payout 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 状态

Prices#

这是代表产品定价配置的对象,以便支持多种货币和定价选项。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
价格

用法#

1
create foreign table stripe.prices (
2
id text,
3
active bool,
4
currency text,
5
product text,
6
unit_amount bigint,
7
type text,
8
created timestamp,
9
attrs jsonb
10
)
11
server stripe_server
12
options (
13
object 'prices'
14
);

说明#

  • Prices 是定义产品定价配置的只读记录
  • 每个 Price 都包含货币、单价和产品引用
  • active 布尔值指示 Price 是否可用
  • type 字段指定定价模式(例如,一次性、定期)
  • 使用 attrs jsonb 列访问其他 Price 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • active

Products#

这是代表 Stripe 中所有可用产品的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
产品

用法#

1
create foreign table stripe.products (
2
id text,
3
name text,
4
active bool,
5
default_price text,
6
description text,
7
created timestamp,
8
updated timestamp,
9
attrs jsonb
10
)
11
server stripe_server
12
options (
13
object 'products',
14
rowid_column 'id'
15
);

说明#

  • Products 可以创建、读取、更新和删除
  • 每个 Product 都包含名称、描述和活动状态
  • default_price 链接到 Product 的默认 Price 对象
  • updated 时间戳跟踪上次修改时间
  • 使用 attrs jsonb 列访问其他 Product 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • active

Refunds#

这是代表先前创建但尚未退款的费用的退款对象的。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
退款

用法#

1
create foreign table stripe.refunds (
2
id text,
3
amount bigint,
4
currency text,
5
charge text,
6
payment_intent text,
7
reason text,
8
status text,
9
created timestamp,
10
attrs jsonb
11
)
12
server stripe_server
13
options (
14
object 'refunds'
15
);

说明#

  • Refunds 是费用冲销的只读记录
  • 每个 Refund 都包含金额、货币和状态信息
  • charge 和 payment_intent 字段链接到原始交易
  • reason 字段提供退款的上下文
  • 使用 attrs jsonb 列访问其他 Refund 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 收费
    • 付款意图

SetupAttempts#

这是代表 SetupIntents 的确认尝试的对象,跟踪成功和不成功的尝试。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
SetupAttempts

用法#

1
create foreign table stripe.setup_attempts (
2
id text,
3
application text,
4
customer text,
5
on_behalf_of text,
6
payment_method text,
7
setup_intent text,
8
status text,
9
usage text,
10
created timestamp,
11
attrs jsonb
12
)
13
server stripe_server
14
options (
15
object 'setup_attempts'
16
);

说明#

  • SetupAttempts 是支付设置确认尝试的只读记录
  • 每次尝试都包含客户、支付方式和状态信息
  • setup_intent 字段链接到关联的 SetupIntent
  • usage 字段指示预期的支付方式用途
  • 使用 attrs jsonb 列访问其他尝试详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • setup_intent

SetupIntents#

这是代表引导客户支付凭据设置和保存以供未来支付的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
SetupIntents

用法#

1
create foreign table stripe.setup_intents (
2
id text,
3
client_secret text,
4
customer text,
5
description text,
6
payment_method text,
7
status text,
8
usage text,
9
created timestamp,
10
attrs jsonb
11
)
12
server stripe_server
13
options (
14
object 'setup_intents'
15
);

说明#

  • SetupIntents 是用于保存客户支付凭据的只读记录
  • 每个 Intent 都包含客户、支付方式和状态信息
  • client_secret 用于客户端确认
  • usage 字段指示将如何使用支付方式
  • 使用 attrs jsonb 列访问其他 Intent 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户
    • payment_method

Subscriptions#

这是代表客户定期支付计划的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
订阅

用法#

1
create foreign table stripe.subscriptions (
2
id text,
3
customer text,
4
currency text,
5
current_period_start timestamp,
6
current_period_end timestamp,
7
attrs jsonb
8
)
9
server stripe_server
10
options (
11
object 'subscriptions',
12
rowid_column 'id'
13
);

说明#

  • Subscriptions 可以创建、读取、更新和删除
  • 每个 Subscription 都包含客户和货币信息
  • current_period_start 和 current_period_end 跟踪计费周期
  • rowid_column 选项启用修改操作
  • 使用 attrs jsonb 列访问其他 Subscription 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 客户
    • price
    • 状态

Tokens#

这是代表安全地收集客户敏感卡、银行账户或个人身份信息 (PII) 的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
令牌

用法#

1
create foreign table stripe.tokens (
2
id text,
3
type text,
4
client_ip text,
5
created timestamp,
6
livemode boolean,
7
used boolean,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'tokens'
13
);

说明#

  • Tokens 是只读的、一次性使用的对象,用于安全的数据收集
  • 每个 Token 都包含类型信息(卡、银行账户、PII 等)
  • client_ip 字段记录创建 Token 的位置
  • used 字段指示 Token 是否已使用
  • 使用 attrs jsonb 列访问 Token 详细信息,例如卡或银行信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • type
    • used

Top-ups#

这是代表向您的 Stripe 余额添加资金的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
Top-ups

用法#

1
create foreign table stripe.topups (
2
id text,
3
amount bigint,
4
currency text,
5
description text,
6
status text,
7
created timestamp,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'topups'
13
);

说明#

  • Top-ups 是余额添加的只读记录
  • 每个 Top-up 都包含金额和货币信息
  • status 字段跟踪 Top-up 状态(例如,成功、失败)
  • 使用 attrs jsonb 列访问其他 Top-up 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • 状态

Transfers#

这是代表作为 Connect 的一部分在 Stripe 账户之间移动资金的对象。

参考:Stripe 文档

操作#

对象选择插入更新删除截断
转账

用法#

1
create foreign table stripe.transfers (
2
id text,
3
amount bigint,
4
currency text,
5
description text,
6
destination text,
7
created timestamp,
8
attrs jsonb
9
)
10
server stripe_server
11
options (
12
object 'transfers'
13
);

说明#

  • Transfers 是账户之间资金移动的只读记录
  • 每个 Transfer 都包含金额、货币和目的地信息
  • destination 字段标识接收 Stripe 账户
  • 使用 attrs jsonb 列访问其他 Transfer 详细信息
  • 虽然 where 子句中允许任何列,但按
    • id
    • destination

查询下推支持#

此 FDW 支持 where 子句下推。您可以在 where 子句中指定一个过滤器,它将被传递到 Stripe API 调用。

例如,此查询

1
select * from stripe.customers where id = 'cus_xxx';

将被转换为 Stripe API 调用:https://api.stripe.com/v1/customers/cus_xxx

有关每个对象支持的过滤器列,请查看上面的外表文档。

限制#

本节描述了在使用此 FDW 时需要注意的重要限制和注意事项

  • 由于需要完全的数据传输,大型结果集可能会遇到较慢的性能
  • 不支持 Webhook 事件和实时更新
  • API 版本不匹配可能导致意外的数据格式问题
  • 使用这些外部表的物化视图在逻辑备份期间可能会失败

示例#

一些关于如何使用 Stripe 外表的示例。

基本示例#

1
-- always limit records to reduce API calls to Stripe
2
select * from stripe.customers limit 10;
3
select * from stripe.invoices limit 10;
4
select * from stripe.subscriptions limit 10;

查询 JSON 属性#

1
-- extract account name for an invoice
2
select id, attrs->>'account_name' as account_name
3
from stripe.invoices where id = 'in_xxx';
4
5
-- extract invoice line items for an invoice
6
select id, attrs#>'{lines,data}' as line_items
7
from stripe.invoices where id = 'in_xxx';
8
9
-- extract subscription items for a subscription
10
select id, attrs#>'{items,data}' as items
11
from stripe.subscriptions where id = 'sub_xxx';

数据修改#

1
-- insert
2
insert into stripe.customers(email,name,description)
3
values ('test@test.com', 'test name', null);
4
5
-- update
6
update stripe.customers
7
set description='hello fdw'
8
where id = 'cus_xxx';
9
10
update stripe.customers
11
set attrs='{"metadata[foo]": "bar"}'
12
where id = 'cus_xxx';
13
14
-- delete
15
delete from stripe.customers
16
where id = 'cus_xxx';

要插入具有子字段的对象,我们需要使用与 API 要求的完全相同的列名创建外表。例如,要插入 subscription 对象,我们可以按照 Stripe API 文档 定义外表

1
-- create the subscription table for data insertion, the 'customer'
2
-- and 'items[0][price]' fields are required.
3
create foreign table stripe.subscriptions (
4
id text,
5
customer text,
6
"items[0][price]" text -- column name will be used in API Post request
7
)
8
server stripe_server
9
options (
10
object 'subscriptions',
11
rowid_column 'id'
12
);

然后我们可以像下面这样插入一个 Subscription

1
insert into stripe.subscriptions(customer, "items[0][price]")
2
values ('cus_Na6dX7aXxi11N4', 'price_1MowQULkdIwHu7ixraBm864M');

请注意,此外表仅用于数据插入,不能在 select 语句中使用。