Stripe 是一个由 API 驱动的在线支付处理工具。supabase/wrappers 提供了以下端点。

准备

在开始之前,请确保您的数据库上安装了 wrappers 扩展:

  create extension if not exists wrappers with schema extensions;
  

然后创建外部数据封装器:

  create foreign data wrapper stripe_wrapper
  handler stripe_fdw_handler
  validator stripe_fdw_validator;
  

安全保护您的凭证(可选)

默认情况下,Postgres 将 FDW 凭证以明文形式存储在 pg_catalog.pg_foreign_server 中。任何有权访问此表的人都能够查看这些凭证。封装器设计为与 Vault 配合使用,Vault 提供了额外的安全级别来存储凭证。我们建议您使用 Vault 存储您的凭证。

  -- Save your Stripe API key in Vault and retrieve the `key_id`
insert into vault.secrets (name, secret)
values (
  'stripe',
  'YOUR_SECRET'
)
returning key_id;
  

连接到 Stripe

我们需要为 Postgres 提供连接到 Stripe 的凭证和任何额外的选项。我们可以使用 create server 命令来完成这个操作:

使用 Vault

      create server stripe_server
      foreign data wrapper stripe_wrapper
      options (
        api_key_id '<key_ID>', -- The Key ID from above, required.
        api_url 'https://api.stripe.com/v1/'  -- Stripe API base URL, optional. Default is 'https://api.stripe.com/v1/'
      );
  

不使用 Vault

      create server stripe_server
      foreign data wrapper stripe_wrapper
      options (
        api_key '<Stripe API Key>',  -- Stripe API key, required
        api_url 'https://api.stripe.com/v1/'  -- Stripe API base URL, optional. Default is 'https://api.stripe.com/v1/'
      );
  

创建外部表

Stripe 封装器支持从 Stripe API 读取和修改数据。.

Object Select Insert Update Delete Truncate
Accounts
Balance
Balance Transactions
Charges
Checkout Sessions
Customers
Disputes
Events
Files
File Links
Invoices
Mandates
PaymentIntents
Payouts
Prices
Products
Refunds
SetupAttempts
SetupIntents
Subscriptions
Tokens
Topups
Transfers

Stripe 外部表反映了 Stripe 的 API。我们可以创建一个模式来容纳所有 Stripe 表。

  create schema stripe;
  

然后创建外部表,例如:

  create foreign table stripe.accounts (
  id text,
  business_type text,
  country text,
  email text,
  type text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'accounts'
  );
  

attrs 是一个特殊列,它以 JSON 格式存储所有对象属性,您可以从中提取任何需要的属性或其关联的子对象。请参阅下面的更多示例。

Accounts

read only

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

參考: Stripe 文档

  create foreign table stripe.accounts (
  id text,
  business_type text,
  country text,
  email text,
  type text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'accounts'
  );
  

虽然在 where 子句中允许任何列,但按以下方式过滤最高效:

  • id

Balance

read only

显示您 Stripe 账户当前的余额。

參考: Stripe 文档

  create foreign table stripe.balance (
  balance_type text,
  amount bigint,
  currency text,
  attrs jsonb
)
  server stripe_server
  options (
    object 'balance'
  );
  

Balance Transactions

read only

余额交易代表通过您的 Stripe 账户的资金流动。它们为您的 Stripe 账户余额中进出的每种交易类型创建。

參考: Stripe 文档

  create foreign table stripe.balance_transactions (
  id text,
  amount bigint,
  currency text,
  description text,
  fee bigint,
  net bigint,
  status text,
  type text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'balance_transactions'
  );
  

虽然在 where 子句中允许任何列,但按以下方式过滤最高效:

  • id
  • type

Charges

read only

要对信用卡或借记卡进行收费,您需要创建一个 Charge 对象。您可以检索和退款个别收费,以及列出所有收费。收费由一个唯一的随机 ID 标识。

參考: Stripe 文档

  create foreign table stripe.charges (
  id text,
  amount bigint,
  currency text,
  customer text,
  description text,
  invoice text,
  payment_intent text,
  status text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'charges'
  );
  

虽然在 where 子句中允许任何列,但按以下方式过滤最高效:

  • id
  • customer

Checkout Sessions

read only

收银会话代表客户通过收银或支付链接进行一次性购买或订阅时的会话。我们建议每次客户尝试支付时都创建一个新的会话。

參考: Stripe 文档

  create foreign table stripe.checkout_sessions (
  id text,
  customer text,
  payment_intent text,
  subscription text,
  attrs jsonb
)
  server stripe_server
  options (
    object 'checkout/sessions',
    rowid_column 'id'
  );
  

虽然在 where 子句中允许任何列,但按以下方式过滤最高效:

  • id
  • customer
  • payment_intent
  • subscription

Customers

read and modify

包含 Stripe 已知的客户信息。

參考: Stripe 文档

  create foreign table stripe.customers (
  id text,
  email text,
  name text,
  description text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'customers',
    rowid_column 'id'
  );
  

虽然在 where 子句中允许任何列,但按以下方式过滤最高效:

  • id
  • email

Disputes

read only

客户向其信用卡发行机构质疑您的收费时,就会发生争议。

參考: Stripe 文档

  create foreign table stripe.disputes (
  id text,
  amount bigint,
  currency text,
  charge text,
  payment_intent text,
  reason text,
  status text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'disputes'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • charge
  • payment_intent

Events

read only

事件是我们通知您账户中发生有趣事情的方式。

參考: Stripe 文档

  create foreign table stripe.events (
  id text,
  type text,
  api_version text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'events'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • type

Files

read only

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

參考: Stripe 文档

  create foreign table stripe.files (
  id text,
  filename text,
  purpose text,
  title text,
  size bigint,
  type text,
  url text,
  created timestamp,
  expires_at timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'files'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • purpose

read only

要与非 Stripe 用户共享 File对象的内容,您可以创建一个 FileLink

參考: Stripe 文档

  create foreign table stripe.file_links (
  id text,
  file text,
  url text,
  created timestamp,
  expired bool,
  expires_at timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'file_links'
  );
  

Invoices#

read only

发票是客户所欠金额的报表,可以一次性生成,也可以通过订阅定期生成。

參考: Stripe 文档

  create foreign table stripe.invoices (
  id text,
  customer text,
  subscription text,
  status text,
  total bigint,
  currency text,
  period_start timestamp,
  period_end timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'invoices'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • customer
  • status
  • subscription

Mandates

read only

授权是记录客户授予您从其支付方式中扣款的权限的记录。

參考: Stripe 文档

  create foreign table stripe.mandates (
  id text,
  payment_method text,
  status text,
  type text,
  attrs jsonb
)
  server stripe_server
  options (
    object 'mandates'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id

Payment Intents

read only

付款意向可引导您完成向客户收款的过程。

參考: Stripe 文档

  create foreign table stripe.payment_intents (
  id text,
  customer text,
  amount bigint,
  currency text,
  payment_method text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'payment_intents'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • customer

Payouts

read only

当您从 Stripe 收到资金,或者当您启动向连接的 Stripe 账户的银行账户或借记卡进行提现时,会创建一个 Payout 对象。

參考: Stripe 文档

  create foreign table stripe.payouts (
  id text,
  amount bigint,
  currency text,
  arrival_date timestamp,
  description text,
  statement_descriptor text,
  status text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'payouts'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • status

Prices

read only

为了支持多种货币和定价选项,您的所有产品都需要一个Price 对象。

參考: Stripe 文档

  create foreign table stripe.prices (
  id text,
  active bool,
  currency text,
  product text,
  unit_amount bigint,
  type text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'prices'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • active

Products

read and modify

Stripe 上提供的所有产品。

參考: Stripe 文档

  create foreign table stripe.products (
  id text,
  name text,
  active bool,
  default_price text,
  description text,
  created timestamp,
  updated timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'products',
    rowid_column 'id'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • active

Refunds

read only

Refund对象允许您退还之前已创建但尚未退还的收费。

參考: Stripe 文档

  create foreign table stripe.refunds (
  id text,
  amount bigint,
  currency text,
  charge text,
  payment_intent text,
  reason text,
  status text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'refunds'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • charge
  • payment_intent

SetupAttempts

read only

一个 SetupAttempt 描述了对 SetupIntent 的一次尝试确认,无论这次确认是成功还是失败。

參考: Stripe 文档

  create foreign table stripe.setup_attempts (
  id text,
  application text,
  customer text,
  on_behalf_of text,
  payment_method text,
  setup_intent text,
  status text,
  usage text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'setup_attempts'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • setup_intent

SetupIntents

read only

SetupIntent 可引导您设置和保存客户支付凭证,以便将来付款。

參考: Stripe 文档

  create foreign table stripe.setup_intents (
  id text,
  client_secret text,
  customer text,
  description text,
  payment_method text,
  status text,
  usage text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'setup_intents'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • customer
  • payment_method

Subscriptions

read and modify

客户的定期支付计划。

參考: Stripe 文档

  create foreign table stripe.subscriptions (
  id text,
  customer text,
  currency text,
  current_period_start timestamp,
  current_period_end timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'subscriptions',
    rowid_column 'id'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • customer
  • price
  • status

Tokens

read only

令牌化是 Stripe 用来以安全方式直接从客户处收集敏感的银行卡或银行账户信息或个人身份信息 (PII) 的过程。

參考: Stripe 文档

  create foreign table stripe.tokens (
  id text,
  customer text,
  currency text,
  current_period_start timestamp,
  current_period_end timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'tokens'
  );
  

Top-ups

read only

要为 Stripe 余额充值,您需要创建一个充值对象。

參考: Stripe 文档

  create foreign table stripe.topups (
  id text,
  amount bigint,
  currency text,
  description text,
  status text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'topups'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • status

Transfers

read only

转账对象是在 Stripe 账户之间转移资金时创建的,是连接的一部分。

參考: Stripe 文档

  create foreign table stripe.transfers (
  id text,
  amount bigint,
  currency text,
  description text,
  destination text,
  created timestamp,
  attrs jsonb
)
  server stripe_server
  options (
    object 'transfers'
  );
  

虽然在 where 子句中允许使用任何列进行过滤,但以下方式的过滤最为高效:

  • id
  • destination

支持查询下推

FDW 支持 where 子句下推。您可以在 where 子句中指定过滤器,并将其传递给 Stripe API 调用。

例如,此查询:

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

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

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

示例

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

基本示例

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

查询 JSON 属性

  -- extract account name for an invoice
select id, attrs->>'account_name' as account_name
from stripe.invoices where id = 'in_xxx';

-- extract invoice line items for an invoice
select id, attrs#>'{lines,data}' as line_items
from stripe.invoices where id = 'in_xxx';

-- extract subscription items for a subscription
select id, attrs#>'{items,data}' as items
from stripe.subscriptions where id = 'sub_xxx';
  

数据修改

  insert into stripe.customers(email,name,description) values ('test@test.com', 'test name', null);
update stripe.customers set description='hello fdw' where id ='cus_xxx';
update stripe.customers set attrs='{"metadata[foo]": "bar"}' where id ='cus_xxx';
delete from stripe.customers where id ='cus_xxx';