From c424527d792f18a9e42df3c83f7de8f809b90aa4 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Sun, 7 May 2023 21:50:45 +0200 Subject: [PATCH 01/10] new formatting for docs --- docs/stripe.md | 315 ++++++++++++---------- wrappers/src/fdw/stripe_fdw/README.md | 1 + wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 2 +- 3 files changed, 168 insertions(+), 150 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index 1dd12179..186ae232 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -1,27 +1,36 @@ -[Stripe](https://stripe.com) is an API driven online payment processing utility. `supabase/wrappers` exposes below endpoints. - -1. [Accounts](https://stripe.com/docs/api/accounts/list) (*read only*) -2. [Balance](https://stripe.com/docs/api/balance) (*read only*) -3. [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) (*read only*) -4. [Charges](https://stripe.com/docs/api/charges/list) (*read only*) -5. [Customers](https://stripe.com/docs/api/customers/list) (*read and modify*) -6. [Disputes](https://stripe.com/docs/api/disputes/list) (*read only*) -7. [Events](https://stripe.com/docs/api/events/list) (*read only*) -8. [Files](https://stripe.com/docs/api/files/list) (*read only*) -9. [File Links](https://stripe.com/docs/api/file_links/list) (*read only*) -10. [Invoices](https://stripe.com/docs/api/invoices/list) (*read only*) -11. [Mandates](https://stripe.com/docs/api/mandates) (*read only*) -12. [PaymentIntents](https://stripe.com/docs/api/payment_intents/list) (*read only*) -13. [Payouts](https://stripe.com/docs/api/payouts/list) (*read only*) -14. [Prices](https://stripe.com/docs/api/prices/list) (*read only*) -15. [Products](https://stripe.com/docs/api/products/list) (*read and modify*) -16. [Refunds](https://stripe.com/docs/api/refunds/list) (*read only*) -17. [SetupAttempts](https://stripe.com/docs/api/setup_attempts/list) (*read only*) -18. [SetupIntents](https://stripe.com/docs/api/setup_intents/list) (*read only*) -19. [Subscriptions](https://stripe.com/docs/api/subscriptions/list) (*read and modify*) -20. [Tokens](https://stripe.com/docs/api/tokens) (*read only*) -21. [Topups](https://stripe.com/docs/api/topups/list) (*read only*) -22. [Transfers](https://stripe.com/docs/api/transfers/list) (*read only*) +[Stripe](https://stripe.com) is an API driven online payment processing utility. `supabase/wrappers` exposes below endpoints. If you are missing an endpoint feel free to open an issue or even add it yourself. + +**Core resources**: + - [Balance](https://stripe.com/docs/api/balance) (*read only*) + - [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) (*read only*) + - [Charges](https://stripe.com/docs/api/charges/list) (*read only*) + - [Customers](https://stripe.com/docs/api/customers/list) (*read and modify*) + - [Disputes](https://stripe.com/docs/api/disputes/list) (*read only*) + - [Events](https://stripe.com/docs/api/events/list) (*read only*) + - [Files](https://stripe.com/docs/api/files/list) (*read only*) + - [File Links](https://stripe.com/docs/api/file_links/list) (*read only*) + - [Mandates](https://stripe.com/docs/api/mandates) (*read only*) + - [PaymentIntents](https://stripe.com/docs/api/payment_intents/list) (*read only*) + - [SetupAttempts](https://stripe.com/docs/api/setup_attempts/list) (*read only*) + - [SetupIntents](https://stripe.com/docs/api/setup_intents/list) (*read only*) + - [Payouts](https://stripe.com/docs/api/payouts/list) (*read only*) + - [Refunds](https://stripe.com/docs/api/refunds/list) (*read only*) + - [Tokens](https://stripe.com/docs/api/tokens) (*read only*) + +**Products**: + - [Products](https://stripe.com/docs/api/products/list) (*read and modify*) + - [Prices](https://stripe.com/docs/api/prices/list) (*read only*) + +**Billing**: + - [Invoices](https://stripe.com/docs/api/invoices/list) (*read only*) + - [Subscriptions](https://stripe.com/docs/api/subscriptions/list) (*read and modify*) + +**Connect**: + - [Accounts](https://stripe.com/docs/api/accounts/list) (*read only*) + - [Top-ups](https://stripe.com/docs/api/topups/list) (*read only*) + - [Transfers](https://stripe.com/docs/api/transfers/list) (*read only*) + + ### Wrapper To get started with the Stripe wrapper, create a foreign data wrapper specifying `handler` and `validator` as below. @@ -93,32 +102,7 @@ The Stripe tables mirror Stripe's API. create schema stripe; ``` -##### Accounts -*read only* - -This is an object representing a Stripe account. - -Ref: [Stripe docs](https://stripe.com/docs/api/accounts/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id +#### Core resources ##### Balance *read only* @@ -341,85 +325,113 @@ create foreign table stripe.file_links ( ); ``` -##### Invoices +##### Mandates *read only* -Invoices are statements of amounts owed by a customer, and are either generated one-off, or generated periodically from a subscription. +A Mandate is a record of the permission a customer has given you to debit their payment method. -Ref: [Stripe docs](https://stripe.com/docs/api/invoices/list) +Ref: [Stripe docs](https://stripe.com/docs/api/mandates) ```sql -create foreign table stripe.invoices ( +create foreign table stripe.mandates ( id text, - customer text, - subscription text, + payment_method text, status text, - total bigint, - currency text, - period_start timestamp, - period_end timestamp, + type text, attrs jsonb ) server stripe_server options ( - object 'invoices' + object 'mandates' ); +``` + +While any column is allowed in a where clause, it is most efficient to filter by: + +- id + + +##### PaymentIntents +*read only* + +A payment intent guides you through the process of collecting a payment from your customer. +Ref: [Stripe docs](https://stripe.com/docs/api/payment_intents/list) + +```sql +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' + ); ``` While any column is allowed in a where clause, it is most efficient to filter by: - id - customer -- status -- subscription -##### Mandates +##### SetupAttempts *read only* -A Mandate is a record of the permission a customer has given you to debit their payment method. +A `SetupAttempt` describes one attempted confirmation of a SetupIntent, whether that confirmation was successful or unsuccessful. -Ref: [Stripe docs](https://stripe.com/docs/api/mandates) +Ref: [Stripe docs](https://stripe.com/docs/api/setup_attempts/list) ```sql -create foreign table stripe.mandates ( +create foreign table stripe.setup_attempts ( id text, + application text, + customer text, + on_behalf_of text, payment_method text, + setup_intent text, status text, - type text, + usage text, + created timestamp, attrs jsonb ) server stripe_server options ( - object 'mandates' + object 'setup_attempts' ); ``` While any column is allowed in a where clause, it is most efficient to filter by: - id +- setup_intent - -##### Payment Intents +##### SetupIntents *read only* -A payment intent guides you through the process of collecting a payment from your customer. +A `SetupIntent` guides you through the process of setting up and saving a customer's payment credentials for future payments. -Ref: [Stripe docs](https://stripe.com/docs/api/payment_intents/list) +Ref: [Stripe docs](https://stripe.com/docs/api/setup_intents/list) ```sql -create foreign table stripe.payment_intents ( +create foreign table stripe.setup_intents ( id text, + client_secret text, customer text, - amount bigint, - currency text, + description text, payment_method text, + status text, + usage text, created timestamp, attrs jsonb ) server stripe_server options ( - object 'payment_intents' + object 'setup_intents' ); ``` @@ -427,6 +439,7 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - customer +- payment_method ##### Payouts *read only* @@ -458,34 +471,60 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - status -##### Prices +##### Refunds *read only* -A `Price` object is needed for all of your products to facilitate multiple currencies and pricing options. +`Refund` objects allow you to refund a charge that has previously been created but not yet refunded. -Ref: [Stripe docs](https://stripe.com/docs/api/prices/list) +Ref: [Stripe docs](https://stripe.com/docs/api/refunds/list) ```sql -create foreign table stripe.prices ( +create foreign table stripe.refunds ( id text, - active bool, + amount bigint, currency text, - product text, - unit_amount bigint, - type text, + charge text, + payment_intent text, + reason text, + status text, created timestamp, attrs jsonb ) server stripe_server options ( - object 'pricing' + object 'refunds' ); ``` While any column is allowed in a where clause, it is most efficient to filter by: - id -- active +- charge +- payment_intent + +##### Tokens +*read only* + +Tokenization is the process Stripe uses to collect sensitive card or bank account details, or personally identifiable information (PII), directly from your customers in a secure manner. + +Ref: [Stripe docs](https://stripe.com/docs/api/tokens) + +```sql +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' + ); +``` + +#### Products ##### Products *read and modify* @@ -517,98 +556,69 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - active -##### Refunds +##### Prices *read only* -`Refund` objects allow you to refund a charge that has previously been created but not yet refunded. +A `Price` object is needed for all of your products to facilitate multiple currencies and pricing options. -Ref: [Stripe docs](https://stripe.com/docs/api/refunds/list) +Ref: [Stripe docs](https://stripe.com/docs/api/prices/list) ```sql -create foreign table stripe.refunds ( +create foreign table stripe.prices ( id text, - amount bigint, + active bool, currency text, - charge text, - payment_intent text, - reason text, - status text, + product text, + unit_amount bigint, + type text, created timestamp, attrs jsonb ) server stripe_server options ( - object 'refunds' + object 'pricing' ); ``` While any column is allowed in a where clause, it is most efficient to filter by: - id -- charge -- payment_intent - -##### SetupAttempts -*read only* - -A `SetupAttempt` describes one attempted confirmation of a SetupIntent, whether that confirmation was successful or unsuccessful. - -Ref: [Stripe docs](https://stripe.com/docs/api/setup_attempts/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: +- active -- id -- setup_intent +#### Billing -##### SetupIntents +##### Invoices *read only* -A `SetupIntent` guides you through the process of setting up and saving a customer's payment credentials for future payments. +Invoices are statements of amounts owed by a customer, and are either generated one-off, or generated periodically from a subscription. -Ref: [Stripe docs](https://stripe.com/docs/api/setup_intents/list) +Ref: [Stripe docs](https://stripe.com/docs/api/invoices/list) ```sql -create foreign table stripe.setup_intents ( +create foreign table stripe.invoices ( id text, - client_secret text, customer text, - description text, - payment_method text, + subscription text, status text, - usage text, - created timestamp, + total bigint, + currency text, + period_start timestamp, + period_end timestamp, attrs jsonb ) server stripe_server options ( - object 'setup_intents' + object 'invoices' ); + ``` While any column is allowed in a where clause, it is most efficient to filter by: - id - customer -- payment_method +- status +- subscription ##### Subscriptions *read and modify* @@ -641,28 +651,35 @@ While any column is allowed in a where clause, it is most efficient to filter by - price - status -##### Tokens +#### Connect + +##### Accounts *read only* -Tokenization is the process Stripe uses to collect sensitive card or bank account details, or personally identifiable information (PII), directly from your customers in a secure manner. +This is an object representing a Stripe account. -Ref: [Stripe docs](https://stripe.com/docs/api/tokens) +Ref: [Stripe docs](https://stripe.com/docs/api/accounts/list) ```sql -create foreign table stripe.tokens ( +create foreign table stripe.accounts ( id text, - customer text, - currency text, - current_period_start timestamp, - current_period_end timestamp, + business_type text, + country text, + email text, + type text, + created timestamp, attrs jsonb ) server stripe_server options ( - object 'tokens' + object 'accounts' ); ``` +While any column is allowed in a where clause, it is most efficient to filter by: + +- id + ##### Top-ups *read only* diff --git a/wrappers/src/fdw/stripe_fdw/README.md b/wrappers/src/fdw/stripe_fdw/README.md index 30ecb2a3..36042f52 100644 --- a/wrappers/src/fdw/stripe_fdw/README.md +++ b/wrappers/src/fdw/stripe_fdw/README.md @@ -10,6 +10,7 @@ This is a foreign data wrapper for [Stripe](https://stripe.com/) developed using | Version | Date | Notes | | ------- | ---------- | ---------------------------------------------------- | +| 0.1.7 | 2023-05-06 | Added more Stripe object | | 0.1.5 | 2023-05-01 | Added 'prices' object | | 0.1.4 | 2023-02-21 | Added Connect objects | | 0.1.3 | 2022-12-21 | Added more core objects | diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index 2af6b60c..5a084fef 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -234,7 +234,7 @@ macro_rules! report_request_error { } #[wrappers_fdw( - version = "0.1.5", + version = "0.1.7", author = "Supabase", website = "https://github.com/supabase/wrappers/tree/main/wrappers/src/fdw/stripe_fdw" )] From 6165fa1400b538f09e49a460f73770ff75b820e9 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Tue, 9 May 2023 20:08:43 +0200 Subject: [PATCH 02/10] small docs bugs fix --- docs/stripe.md | 9 ++++++++- wrappers/src/fdw/stripe_fdw/README.md | 2 +- wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index 186ae232..f9bf6ba4 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -576,7 +576,7 @@ create foreign table stripe.prices ( ) server stripe_server options ( - object 'pricing' + object 'prices' ); ``` @@ -778,3 +778,10 @@ update stripe.customers set attrs='{"metadata[foo]": "bar"}' where id ='cus_xxx' delete from stripe.customers where id ='cus_xxx'; ``` +##### Removing foreign tables + +If you would like to remove a foreign table because you do not use it anymore this can be done easily with the following command + +```sql +drop foreign table stripe.customers, stripe.invoices, stripe.subscriptions; +``` \ No newline at end of file diff --git a/wrappers/src/fdw/stripe_fdw/README.md b/wrappers/src/fdw/stripe_fdw/README.md index 36042f52..809855e6 100644 --- a/wrappers/src/fdw/stripe_fdw/README.md +++ b/wrappers/src/fdw/stripe_fdw/README.md @@ -10,7 +10,7 @@ This is a foreign data wrapper for [Stripe](https://stripe.com/) developed using | Version | Date | Notes | | ------- | ---------- | ---------------------------------------------------- | -| 0.1.7 | 2023-05-06 | Added more Stripe object | +| 0.1.6 | 2023-05-06 | Updated docs and added more objects | | 0.1.5 | 2023-05-01 | Added 'prices' object | | 0.1.4 | 2023-02-21 | Added Connect objects | | 0.1.3 | 2022-12-21 | Added more core objects | diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index 5a084fef..f98210ae 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -234,7 +234,7 @@ macro_rules! report_request_error { } #[wrappers_fdw( - version = "0.1.7", + version = "0.1.6", author = "Supabase", website = "https://github.com/supabase/wrappers/tree/main/wrappers/src/fdw/stripe_fdw" )] From dcd92b4261206a94e03c165b01b185dc0928adef Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Fri, 2 Jun 2023 16:34:19 +0200 Subject: [PATCH 03/10] Fixed merge conflicts --- docs/stripe.md | 8 +- wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 233 +++++++++++++++------- wrappers/src/fdw/stripe_fdw/tests.rs | 175 +++++++++------- 3 files changed, 264 insertions(+), 152 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index 463ed454..05d7f870 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -1,6 +1,6 @@ [Stripe](https://stripe.com) is an API driven online payment processing utility. `supabase/wrappers` exposes below endpoints. If you are missing an endpoint feel free to open an issue or even add it yourself. -**Core resources**: +**Core resources (Complete)**: - [Balance](https://stripe.com/docs/api/balance) (*read only*) - [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) (*read only*) - [Charges](https://stripe.com/docs/api/charges/list) (*read only*) @@ -17,18 +17,18 @@ - [Refunds](https://stripe.com/docs/api/refunds/list) (*read only*) - [Tokens](https://stripe.com/docs/api/tokens) (*read only*) -**Products**: +**Products (Incomplete)**: - [Products](https://stripe.com/docs/api/products/list) (*read and modify*) - [Prices](https://stripe.com/docs/api/prices/list) (*read only*) **Checkout**: - [Checkout Sessions](https://stripe.com/docs/api/checkout/sessions/list) (*read only*) -**Billing**: +**Billing (Incomplete)**: - [Invoices](https://stripe.com/docs/api/invoices/list) (*read only*) - [Subscriptions](https://stripe.com/docs/api/subscriptions/list) (*read and modify*) -**Connect**: +**Connect (Incomplete)**: - [Accounts](https://stripe.com/docs/api/accounts/list) (*read only*) - [Top-ups](https://stripe.com/docs/api/topups/list) (*read only*) - [Transfers](https://stripe.com/docs/api/transfers/list) (*read only*) diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index 92239a11..378c4df6 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -97,6 +97,8 @@ fn body_to_rows( .and_then(|v| match *col_type { "bool" => v.as_bool().map(Cell::Bool), "i64" => v.as_i64().map(Cell::I64), + "f64" => v.as_f64().map(Cell::F64), + "json" => v.as_i64().map(Cell::Json), "string" => v.as_str().map(|a| Cell::String(a.to_owned())), "timestamp" => v.as_i64().map(|a| { let dt = OffsetDateTime::from_unix_timestamp(a).unwrap(); @@ -148,6 +150,9 @@ fn row_to_body(row: &Row) -> JsonValue { Cell::I64(v) => { map.insert(col_name, JsonValue::Number(Number::from(*v))); } + Cell::F64(v) => { + map.insert(col_name, JsonValue::Number(Decimal::from(*v))); + } Cell::String(v) => { map.insert(col_name, JsonValue::String(v.to_string())); } @@ -156,6 +161,8 @@ fn row_to_body(row: &Row) -> JsonValue { if let Some(m) = v.0.clone().as_object_mut() { map.append(m) } + } else { + map.insert(col_name, v); } } _ => { @@ -260,7 +267,7 @@ impl StripeFdw { // pushdown quals other than id // ref: https://stripe.com/docs/api/[object]/list let fields = match obj { - "accounts" => vec![], + // Core resources "balance" => vec![], "balance_transactions" => vec!["type"], "charges" => vec!["customer"], @@ -269,20 +276,34 @@ impl StripeFdw { "events" => vec!["type"], "files" => vec!["purpose"], "file_links" => vec![], - "invoices" => vec!["customer", "status", "subscription"], "mandates" => vec![], "payment_intents" => vec!["customer"], - "payouts" => vec!["status"], - "prices" => vec!["active", "currency", "product", "type"], - "products" => vec!["active"], - "refunds" => vec!["charge", "payment_intent"], "setup_attempts" => vec!["setup_intent"], "setup_intents" => vec!["customer", "payment_method"], - "subscriptions" => vec!["customer", "price", "status"], + "payouts" => vec!["status"], + "refunds" => vec!["charge", "payment_intent"], "tokens" => vec![], + + // Products + "products" => vec!["active"], + "prices" => vec!["active", "currency", "product", "type"], + "coupons" => vec![], + "promotion_codes" => vec![], + "tax_codes" => vec![], + "tax_rates" => vec!["active"], + "shipping_rates" => vec!["active", "created", "currency"], + + // Checkout + "checkout/sessions" => vec!["customer", "payment_intent", "subscription"], + + // Billing + "invoices" => vec!["customer", "status", "subscription"], + "subscriptions" => vec!["customer", "price", "status"], + + // Connect + "accounts" => vec![], "topups" => vec!["status"], "transfers" => vec!["destination"], - "checkout/sessions" => vec!["customer", "payment_intent", "subscription"], _ => { report_error( PgSqlErrorCode::ERRCODE_FDW_TABLE_NOT_FOUND, @@ -304,18 +325,7 @@ impl StripeFdw { tgt_cols: &[Column], ) -> (Vec, Option, Option) { match obj { - "accounts" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("business_type", "string"), - ("country", "string"), - ("email", "string"), - ("type", "string"), - ("created", "timestamp"), - ], - tgt_cols, - ), + // Core resources "balance" => body_to_rows( resp_body, vec![ @@ -417,20 +427,6 @@ impl StripeFdw { ], tgt_cols, ), - "invoices" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("customer", "string"), - ("subscription", "string"), - ("status", "string"), - ("total", "i64"), - ("currency", "string"), - ("period_start", "timestamp"), - ("period_end", "timestamp"), - ], - tgt_cols, - ), "mandates" => body_to_rows( resp_body, vec![ @@ -467,19 +463,62 @@ impl StripeFdw { ], tgt_cols, ), - "prices" => body_to_rows( + "refunds" => body_to_rows( resp_body, vec![ ("id", "string"), - ("active", "bool"), + ("amount", "i64"), ("currency", "string"), - ("product", "string"), - ("unit_amount", "i64"), + ("charge", "string"), + ("payment_intent", "string"), + ("reason", "string"), + ("status", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "setup_attempts" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("application", "string"), + ("customer", "string"), + ("on_behalf_of", "string"), + ("payment_method", "string"), + ("setup_intent", "string"), + ("status", "string"), + ("usage", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "setup_intents" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("client_secret", "string"), + ("customer", "string"), + ("description", "string"), + ("payment_method", "string"), + ("status", "string"), + ("usage", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "tokens" => body_to_rows( + resp_body, + vec![ + ("id", "string"), ("type", "string"), + ("client_ip", "string"), + ("used", "bool"), ("created", "timestamp"), ], tgt_cols, ), + + // Products "products" => body_to_rows( resp_body, vec![ @@ -493,46 +532,106 @@ impl StripeFdw { ], tgt_cols, ), - "refunds" => body_to_rows( + "prices" => body_to_rows( resp_body, vec![ ("id", "string"), - ("amount", "i64"), + ("active", "bool"), ("currency", "string"), - ("charge", "string"), - ("payment_intent", "string"), - ("reason", "string"), - ("status", "string"), + ("product", "string"), + ("unit_amount", "i64"), + ("type", "string"), ("created", "timestamp"), ], tgt_cols, ), - "setup_attempts" => body_to_rows( + "coupons" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("amount_off", "i64"), + ("currency", "string"), + ("duration", "string"), + ("duration_in_months", "i64"), + ("max_redemptions", "i64"), + ("name", "string"), + ("percent_off", "f64"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "promotion_codes" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("code", "string"), + ("coupon", "string"), + ("active", "bool"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "tax_codes" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("description", "string"), + ("name", "string"), + ], + tgt_cols, + ), + "tax_rates" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("active", "bool"), + ("country", "string"), + ("description", "string"), + ("display_name", "string"), + ("inclusive", "bool"), + ("percentage", "f64"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "shipping_rates" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("active", "bool"), + ("display_name", "string"), + ("amount", "string"), + ("type", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), + + // Checkout + "checkout/sessions" => body_to_rows( resp_body, vec![ ("id", "string"), - ("application", "string"), ("customer", "string"), - ("on_behalf_of", "string"), - ("payment_method", "string"), - ("setup_intent", "string"), - ("status", "string"), - ("usage", "string"), + ("payment_intent", "string"), + ("subscription", "string"), ("created", "timestamp"), ], tgt_cols, ), - "setup_intents" => body_to_rows( + + // Billing + "invoices" => body_to_rows( resp_body, vec![ ("id", "string"), - ("client_secret", "string"), ("customer", "string"), - ("description", "string"), - ("payment_method", "string"), + ("subscription", "string"), ("status", "string"), - ("usage", "string"), - ("created", "timestamp"), + ("total", "i64"), + ("currency", "string"), + ("period_start", "timestamp"), + ("period_end", "timestamp"), ], tgt_cols, ), @@ -547,13 +646,16 @@ impl StripeFdw { ], tgt_cols, ), - "tokens" => body_to_rows( + + // Connect + "accounts" => body_to_rows( resp_body, vec![ ("id", "string"), + ("business_type", "string"), + ("country", "string"), + ("email", "string"), ("type", "string"), - ("client_ip", "string"), - ("used", "bool"), ("created", "timestamp"), ], tgt_cols, @@ -582,17 +684,6 @@ impl StripeFdw { ], tgt_cols, ), - "checkout/sessions" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("customer", "string"), - ("payment_intent", "string"), - ("subscription", "string"), - ("created", "timestamp"), - ], - tgt_cols, - ), _ => { report_error( PgSqlErrorCode::ERRCODE_FDW_TABLE_NOT_FOUND, diff --git a/wrappers/src/fdw/stripe_fdw/tests.rs b/wrappers/src/fdw/stripe_fdw/tests.rs index bed205b2..4ea601ac 100644 --- a/wrappers/src/fdw/stripe_fdw/tests.rs +++ b/wrappers/src/fdw/stripe_fdw/tests.rs @@ -22,29 +22,10 @@ mod tests { )"#, None, None, - ).unwrap(); - - c.update( - r#" - CREATE FOREIGN TABLE stripe_accounts ( - id text, - business_type text, - country text, - email text, - type text, - created timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'accounts' -- source object in stripe, required - ) - "#, - None, - None, ) .unwrap(); + // Core resources c.update( r#" CREATE FOREIGN TABLE stripe_balance ( @@ -219,22 +200,22 @@ mod tests { ) .unwrap(); + // TODO: Add mandates test + c.update( r#" - CREATE FOREIGN TABLE stripe_invoices ( + CREATE FOREIGN TABLE stripe_payment_intents ( id text, customer text, - subscription text, - status text, - total bigint, + amount bigint, currency text, - period_start timestamp, - period_end timestamp, + payment_method text, + created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'invoices' -- source object in stripe, required + object 'payment_intents' -- source object in stripe, required ) "#, None, @@ -244,18 +225,44 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_payment_intents ( + CREATE FOREIGN TABLE stripe_setup_attempts ( id text, + application text, customer text, - amount bigint, - currency text, + on_behalf_of text, + payment_method text, + setup_intent text, + status text, + usage text, + created timestamp, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'setup_attempts' -- source object in stripe, required + ) + "#, + None, + None, + ) + .unwrap(); + + c.update( + r#" + 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 my_stripe_server OPTIONS ( - object 'payment_intents' -- source object in stripe, required + object 'setup_intents' -- source object in stripe, required ) "#, None, @@ -288,19 +295,20 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_prices ( + CREATE FOREIGN TABLE stripe_refunds ( id text, - active bool, + amount bigint, currency text, - product text, - unit_amount bigint, - type text, + charge text, + payment_intent text, + reason text, + status text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'prices' -- source object in stripe, required + object 'refunds' -- source object in stripe, required ) "#, None, @@ -308,6 +316,9 @@ mod tests { ) .unwrap(); + // TODO: Add tokens tests + + // Products c.update( r#" CREATE FOREIGN TABLE stripe_products ( @@ -333,20 +344,19 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_refunds ( + CREATE FOREIGN TABLE stripe_prices ( id text, - amount bigint, + active bool, currency text, - charge text, - payment_intent text, - reason text, - status text, + product text, + unit_amount bigint, + type text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'refunds' -- source object in stripe, required + object 'prices' -- source object in stripe, required ) "#, None, @@ -354,46 +364,55 @@ mod tests { ) .unwrap(); + // TODO: Add coupons tests + + // TODO: Add promotion_codes tests + + // TODO: Add tax_codes tests + + // TODO: Add tax_rates tests + + // TODO: Add shipping_rates tests + + // Checkout c.update( r#" - CREATE FOREIGN TABLE stripe_setup_attempts ( + CREATE FOREIGN TABLE checkout_sessions ( id text, - application text, customer text, - on_behalf_of text, - payment_method text, - setup_intent text, - status text, - usage text, - created timestamp, + payment_intent text, + subscription text, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'setup_attempts' -- source object in stripe, required - ) + object 'checkout/sessions', + rowid_column 'id' + ) "#, None, None, ) .unwrap(); + + // Billing c.update( r#" - CREATE FOREIGN TABLE stripe_setup_intents ( + CREATE FOREIGN TABLE stripe_invoices ( id text, - client_secret text, customer text, - description text, - payment_method text, + subscription text, status text, - usage text, - created timestamp, + total bigint, + currency text, + period_start timestamp, + period_end timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'setup_intents' -- source object in stripe, required + object 'invoices' -- source object in stripe, required ) "#, None, @@ -422,21 +441,22 @@ mod tests { ) .unwrap(); + // Connect c.update( r#" - CREATE FOREIGN TABLE stripe_topups ( + CREATE FOREIGN TABLE stripe_accounts ( id text, - amount bigint, - currency text, - description text, - status text, + business_type text, + country text, + email text, + type text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'topups' -- source object in stripe, required - ) + object 'accounts' -- source object in stripe, required + ) "#, None, None, @@ -445,18 +465,18 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_transfers ( + CREATE FOREIGN TABLE stripe_topups ( id text, amount bigint, currency text, description text, - destination text, + status text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'transfers' -- source object in stripe, required + object 'topups' -- source object in stripe, required ) "#, None, @@ -466,17 +486,18 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE checkout_sessions ( + CREATE FOREIGN TABLE stripe_transfers ( id text, - customer text, - payment_intent text, - subscription text, + amount bigint, + currency text, + description text, + destination text, + created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'checkout/sessions', - rowid_column 'id' + object 'transfers' -- source object in stripe, required ) "#, None, From 24c5febb6bf32e0e9822f18a53f87040564d6548 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Fri, 2 Jun 2023 17:00:50 +0200 Subject: [PATCH 04/10] working on tests --- wrappers/src/fdw/stripe_fdw/tests.rs | 127 +++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/wrappers/src/fdw/stripe_fdw/tests.rs b/wrappers/src/fdw/stripe_fdw/tests.rs index 4ea601ac..6cbeb8f8 100644 --- a/wrappers/src/fdw/stripe_fdw/tests.rs +++ b/wrappers/src/fdw/stripe_fdw/tests.rs @@ -396,6 +396,111 @@ mod tests { .unwrap(); + // Billing + c.update( + r#" + 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 my_stripe_server + OPTIONS ( + object 'invoices' -- source object in stripe, required + ) + "#, + None, + None, + ) + .unwrap(); + + c.update( + r#" + 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 my_stripe_server + OPTIONS ( + object 'refunds' -- source object in stripe, required + ) + "#, + None, + None, + ) + .unwrap(); + + // TODO: Add tokens tests + + // Products + c.update( + r#" + CREATE FOREIGN TABLE stripe_products ( + id text, + name text, + active bool, + default_price text, + description text, + created timestamp, + updated timestamp, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'products', -- source object in stripe, required + rowid_column 'id' + ) + "#, + None, + None, + ) + .unwrap(); + + c.update( + r#" + CREATE FOREIGN TABLE stripe_prices ( + id text, + active bool, + currency text, + product text, + unit_amount bigint, + type text, + created timestamp, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'prices' -- source object in stripe, required + ) + "#, + None, + None, + ) + .unwrap(); + + // TODO: Add coupons tests + + // TODO: Add promotion_codes tests + + // TODO: Add tax_codes tests + + // TODO: Add tax_rates tests + + // TODO: Add shipping_rates tests + // Billing c.update( r#" @@ -463,6 +568,28 @@ mod tests { ) .unwrap(); + // Connect + c.update( + r#" + CREATE FOREIGN TABLE stripe_accounts ( + id text, + business_type text, + country text, + email text, + type text, + created timestamp, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'accounts' -- source object in stripe, required + ) + "#, + None, + None, + ) + .unwrap(); + c.update( r#" CREATE FOREIGN TABLE stripe_topups ( From f73d0eaefc05101883798c0eddd7d23424bf1079 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 20:16:12 +0200 Subject: [PATCH 05/10] Updated version --- wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index e4a28a61..02885d49 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -260,7 +260,7 @@ macro_rules! report_request_error { } #[wrappers_fdw( - version = "0.1.7", + version = "0.1.8", author = "Supabase", website = "https://github.com/supabase/wrappers/tree/main/wrappers/src/fdw/stripe_fdw" )] From 7a351fe191f0ceaf7b837f9311d11e7445097458 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 20:27:24 +0200 Subject: [PATCH 06/10] add small section how to remove table --- docs/stripe.md | 315 ++++++++++++------------------------------------- 1 file changed, 78 insertions(+), 237 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index f042d229..35589b80 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -1,4 +1,4 @@ -[Stripe](https://stripe.com) is an API driven online payment processing utility. `supabase/wrappers` exposes below endpoints. If you are missing an endpoint feel free to open an issue or even add it yourself. +[Stripe](https://stripe.com) is an API driven online payment processing utility. `supabase/wrappers` exposes below endpoints. ## Preparation @@ -90,7 +90,27 @@ The Stripe foreign tables mirror Stripe's API. We can create a schema to hold al create schema stripe; ``` -##### Accounts +Then create the foreign table, for example: + +```sql +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` is a special column which stores all the object attributes in JSON format, you can extract any attributes needed or its associated sub objects from it. See more examples below. + +### Accounts *read only* This is an object representing a Stripe account. @@ -199,7 +219,7 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - customer -##### Checkout Sessions +### Checkout Sessions *read only* @@ -368,7 +388,40 @@ create foreign table stripe.file_links ( ); ``` -##### Invoices +### Invoices +*read only* + +Invoices are statements of amounts owed by a customer, and are either generated one-off, or generated periodically from a subscription. + +Ref: [Stripe docs](https://stripe.com/docs/api/invoices/list) + +```sql +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' + ); + +``` + +While any column is allowed in a where clause, it is most efficient to filter by: + +- id +- customer +- status +- subscription + +### Mandates *read only* A Mandate is a record of the permission a customer has given you to debit their payment method. @@ -394,7 +447,7 @@ While any column is allowed in a where clause, it is most efficient to filter by - id -##### PaymentIntents +### Payment Intents *read only* A payment intent guides you through the process of collecting a payment from your customer. @@ -573,8 +626,7 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - setup_intent - -##### Payment Intents +### SetupIntents *read only* A `SetupIntent` guides you through the process of setting up and saving a customer's payment credentials for future payments. @@ -605,213 +657,7 @@ While any column is allowed in a where clause, it is most efficient to filter by - customer - payment_method -### Payouts -*read only* - -A `Payout` object is created when you receive funds from Stripe, or when you initiate a payout to either a bank account or debit card of a connected Stripe account. - -Ref: [Stripe docs](https://stripe.com/docs/api/payouts/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- status - -##### Prices -*read only* - -`Refund` objects allow you to refund a charge that has previously been created but not yet refunded. - -Ref: [Stripe docs](https://stripe.com/docs/api/refunds/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- charge -- payment_intent - -##### Tokens -*read only* - -Tokenization is the process Stripe uses to collect sensitive card or bank account details, or personally identifiable information (PII), directly from your customers in a secure manner. - -Ref: [Stripe docs](https://stripe.com/docs/api/tokens) - -```sql -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' - ); -``` - -#### Products - -### Products -*read and modify* - -All products available in Stripe. - -Ref: [Stripe docs](https://stripe.com/docs/api/products/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- active - -##### Refunds -*read only* - -A `Price` object is needed for all of your products to facilitate multiple currencies and pricing options. - -Ref: [Stripe docs](https://stripe.com/docs/api/prices/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- active - -##### SetupAttempts -*read only* - -A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout or Payment Links. We recommend creating a new Session each time your customer attempts to pay. - -Ref: [Stripe docs](https://stripe.com/docs/api/checkout/sessions/list) - -```sql -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' - ); -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- customer -- payment_intent -- subscription - -##### SetupIntents -*read only* - -Invoices are statements of amounts owed by a customer, and are either generated one-off, or generated periodically from a subscription. - -Ref: [Stripe docs](https://stripe.com/docs/api/invoices/list) - -```sql -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' - ); - -``` - -While any column is allowed in a where clause, it is most efficient to filter by: - -- id -- customer -- status -- subscription - -##### Subscriptions +### Subscriptions *read and modify* Customer recurring payment schedules. @@ -842,33 +688,28 @@ While any column is allowed in a where clause, it is most efficient to filter by - price - status -##### Tokens +### Tokens *read only* -This is an object representing a Stripe account. +Tokenization is the process Stripe uses to collect sensitive card or bank account details, or personally identifiable information (PII), directly from your customers in a secure manner. -Ref: [Stripe docs](https://stripe.com/docs/api/accounts/list) +Ref: [Stripe docs](https://stripe.com/docs/api/tokens) ```sql -create foreign table stripe.accounts ( +create foreign table stripe.tokens ( id text, - business_type text, - country text, - email text, - type text, - created timestamp, + customer text, + currency text, + current_period_start timestamp, + current_period_end timestamp, attrs jsonb ) server stripe_server options ( - object 'accounts' + object 'tokens' ); ``` -While any column is allowed in a where clause, it is most efficient to filter by: - -- id - ### Top-ups *read only* @@ -925,6 +766,14 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - destination +## Removing foreign tables + +If you would like to remove a foreign table because you do not use it anymore this can be done easily with the following command + +```sql +drop foreign table stripe.customers, stripe.invoices, stripe.subscriptions; +``` + ## Examples Some examples on how to use Stripe foreign tables. @@ -961,12 +810,4 @@ insert into stripe.customers(email,name,description) values ('test@test.com', 't 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'; -``` - -##### Removing foreign tables - -If you would like to remove a foreign table because you do not use it anymore this can be done easily with the following command - -```sql -drop foreign table stripe.customers, stripe.invoices, stripe.subscriptions; -``` +``` \ No newline at end of file From c12f729bd590f1a3b66b6fda5e2f6e2a6bb3e1fe Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 21:27:16 +0200 Subject: [PATCH 07/10] Working on adding more objects --- docs/stripe.md | 2 +- wrappers/src/fdw/stripe_fdw/README.md | 22 +- wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 253 ++++++++-------- wrappers/src/fdw/stripe_fdw/tests.rs | 342 +++++++--------------- 4 files changed, 241 insertions(+), 378 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index 35589b80..74055746 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -810,4 +810,4 @@ insert into stripe.customers(email,name,description) values ('test@test.com', 't 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'; -``` \ No newline at end of file +``` diff --git a/wrappers/src/fdw/stripe_fdw/README.md b/wrappers/src/fdw/stripe_fdw/README.md index e13780f9..8b9e0127 100644 --- a/wrappers/src/fdw/stripe_fdw/README.md +++ b/wrappers/src/fdw/stripe_fdw/README.md @@ -8,14 +8,14 @@ This is a foreign data wrapper for [Stripe](https://stripe.com/) developed using ## Changelog -| Version | Date | Notes | -| ------- | ---------- | ---------------------------------------------------- | -| 0.1.8 | 2023-08-11 | Updated docs and added more objects | -| 0.1.7 | 2023-07-13 | Added fdw stats collection | -| 0.1.6 | 2023-05-30 | Added Checkout Session object | -| 0.1.5 | 2023-05-01 | Added 'prices' object and empty result improvement | -| 0.1.4 | 2023-02-21 | Added Connect objects | -| 0.1.3 | 2022-12-21 | Added more core objects | -| 0.1.2 | 2022-12-04 | Added 'products' objects support | -| 0.1.1 | 2022-12-03 | Added quals pushdown support | -| 0.1.0 | 2022-12-01 | Initial version | +| Version | Date | Notes | +| ------- | ---------- | ---------------------------------------------------------------------------------------------------- | +| 0.1.8 | 2023-09-13 | Added objects for coupons, promotion_codes, tax_codes, tax_rates and shipping rates | +| 0.1.7 | 2023-07-13 | Added fdw stats collection | +| 0.1.6 | 2023-05-30 | Added Checkout Session object | +| 0.1.5 | 2023-05-01 | Added 'prices' object and empty result improvement | +| 0.1.4 | 2023-02-21 | Added Connect objects | +| 0.1.3 | 2022-12-21 | Added more core objects | +| 0.1.2 | 2022-12-04 | Added 'products' objects support | +| 0.1.1 | 2022-12-03 | Added quals pushdown support | +| 0.1.0 | 2022-12-01 | Initial version | diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index fb870466..d0223f9d 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -8,6 +8,7 @@ use serde_json::{json, Map as JsonMap, Number, Value as JsonValue}; use std::collections::HashMap; use supabase_wrappers::prelude::*; +use thiserror::Error; fn create_client(api_key: &str) -> ClientWithMiddleware { let mut headers = header::HeaderMap::new(); @@ -289,41 +290,32 @@ impl StripeFdw { // pushdown quals other than id // ref: https://stripe.com/docs/api/[object]/list let fields = match obj { - // Core resources + "accounts" => vec![], "balance" => vec![], "balance_transactions" => vec!["type"], "charges" => vec!["customer"], + "checkout/sessions" => vec!["customer", "payment_intent", "subscription"], + "coupons" => vec![], "customers" => vec!["email"], "disputes" => vec!["charge", "payment_intent"], "events" => vec!["type"], "files" => vec!["purpose"], "file_links" => vec![], + "invoices" => vec!["customer", "status", "subscription"], "mandates" => vec![], "payment_intents" => vec!["customer"], - "setup_attempts" => vec!["setup_intent"], - "setup_intents" => vec!["customer", "payment_method"], "payouts" => vec!["status"], - "refunds" => vec!["charge", "payment_intent"], - "tokens" => vec![], - - // Products - "products" => vec!["active"], "prices" => vec!["active", "currency", "product", "type"], - "coupons" => vec![], + "products" => vec!["active"], "promotion_codes" => vec![], - "tax_codes" => vec![], - "tax_rates" => vec!["active"], + "refunds" => vec!["charge", "payment_intent"], + "setup_attempts" => vec!["setup_intent"], + "setup_intents" => vec!["customer", "payment_method"], "shipping_rates" => vec!["active", "created", "currency"], - - // Checkout - "checkout/sessions" => vec!["customer", "payment_intent", "subscription"], - - // Billing - "invoices" => vec!["customer", "status", "subscription"], "subscriptions" => vec!["customer", "price", "status"], - - // Connect - "accounts" => vec![], + "tax_codes" => vec![], + "tax_rates" => vec!["active"], + "tokens" => vec![], "topups" => vec!["status"], "transfers" => vec!["destination"], _ => { @@ -347,7 +339,18 @@ impl StripeFdw { tgt_cols: &[Column], ) -> (Vec, Option, Option) { match obj { - // Core resources + "accounts" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("business_type", "string"), + ("country", "string"), + ("email", "string"), + ("type", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), "balance" => body_to_rows( resp_body, vec![ @@ -387,6 +390,32 @@ impl StripeFdw { ], tgt_cols, ), + "checkout/sessions" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("customer", "string"), + ("payment_intent", "string"), + ("subscription", "string"), + ("created", "timestamp"), + ], + tgt_cols, + ), + "coupons" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("amount_off", "i64"), + ("currency", "string"), + ("duration", "string"), + ("duration_in_months", "i64"), + ("max_redemptions", "i64"), + ("name", "string"), + ("percent_off", "f64"), + ("created", "timestamp"), + ], + tgt_cols, + ), "customers" => body_to_rows( resp_body, vec![ @@ -449,6 +478,20 @@ impl StripeFdw { ], tgt_cols, ), + "invoices" => body_to_rows( + resp_body, + vec![ + ("id", "string"), + ("customer", "string"), + ("subscription", "string"), + ("status", "string"), + ("total", "i64"), + ("currency", "string"), + ("period_start", "timestamp"), + ("period_end", "timestamp"), + ], + tgt_cols, + ), "mandates" => body_to_rows( resp_body, vec![ @@ -485,62 +528,19 @@ impl StripeFdw { ], tgt_cols, ), - "refunds" => body_to_rows( + "prices" => body_to_rows( resp_body, vec![ ("id", "string"), - ("amount", "i64"), + ("active", "bool"), ("currency", "string"), - ("charge", "string"), - ("payment_intent", "string"), - ("reason", "string"), - ("status", "string"), - ("created", "timestamp"), - ], - tgt_cols, - ), - "setup_attempts" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("application", "string"), - ("customer", "string"), - ("on_behalf_of", "string"), - ("payment_method", "string"), - ("setup_intent", "string"), - ("status", "string"), - ("usage", "string"), - ("created", "timestamp"), - ], - tgt_cols, - ), - "setup_intents" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("client_secret", "string"), - ("customer", "string"), - ("description", "string"), - ("payment_method", "string"), - ("status", "string"), - ("usage", "string"), - ("created", "timestamp"), - ], - tgt_cols, - ), - "tokens" => body_to_rows( - resp_body, - vec![ - ("id", "string"), + ("product", "string"), + ("unit_amount", "i64"), ("type", "string"), - ("client_ip", "string"), - ("used", "bool"), ("created", "timestamp"), ], tgt_cols, ), - - // Products "products" => body_to_rows( resp_body, vec![ @@ -554,64 +554,56 @@ impl StripeFdw { ], tgt_cols, ), - "prices" => body_to_rows( + "promotion_codes" => body_to_rows( resp_body, vec![ ("id", "string"), + ("code", "string"), + ("coupon", "string"), ("active", "bool"), - ("currency", "string"), - ("product", "string"), - ("unit_amount", "i64"), - ("type", "string"), ("created", "timestamp"), ], tgt_cols, ), - "coupons" => body_to_rows( + "refunds" => body_to_rows( resp_body, vec![ ("id", "string"), - ("amount_off", "i64"), + ("amount", "i64"), ("currency", "string"), - ("duration", "string"), - ("duration_in_months", "i64"), - ("max_redemptions", "i64"), - ("name", "string"), - ("percent_off", "f64"), + ("charge", "string"), + ("payment_intent", "string"), + ("reason", "string"), + ("status", "string"), ("created", "timestamp"), ], tgt_cols, ), - "promotion_codes" => body_to_rows( + "setup_attempts" => body_to_rows( resp_body, vec![ ("id", "string"), - ("code", "string"), - ("coupon", "string"), - ("active", "bool"), + ("application", "string"), + ("customer", "string"), + ("on_behalf_of", "string"), + ("payment_method", "string"), + ("setup_intent", "string"), + ("status", "string"), + ("usage", "string"), ("created", "timestamp"), ], tgt_cols, ), - "tax_codes" => body_to_rows( - resp_body, - vec![ - ("id", "string"), - ("description", "string"), - ("name", "string"), - ], - tgt_cols, - ), - "tax_rates" => body_to_rows( + "setup_intents" => body_to_rows( resp_body, vec![ ("id", "string"), - ("active", "bool"), - ("country", "string"), + ("client_secret", "string"), + ("customer", "string"), ("description", "string"), - ("display_name", "string"), - ("inclusive", "bool"), - ("percentage", "f64"), + ("payment_method", "string"), + ("status", "string"), + ("usage", "string"), ("created", "timestamp"), ], tgt_cols, @@ -628,56 +620,45 @@ impl StripeFdw { ], tgt_cols, ), - - // Checkout - "checkout/sessions" => body_to_rows( + "subscriptions" => body_to_rows( resp_body, vec![ ("id", "string"), ("customer", "string"), - ("payment_intent", "string"), - ("subscription", "string"), - ("created", "timestamp"), + ("currency", "string"), + ("current_period_start", "timestamp"), + ("current_period_end", "timestamp"), ], tgt_cols, ), - - // Billing - "invoices" => body_to_rows( + "tax_codes" => body_to_rows( resp_body, vec![ ("id", "string"), - ("customer", "string"), - ("subscription", "string"), - ("status", "string"), - ("total", "i64"), - ("currency", "string"), - ("period_start", "timestamp"), - ("period_end", "timestamp"), + ("description", "string"), + ("name", "string"), ], tgt_cols, ), - "subscriptions" => body_to_rows( + "tax_rates" => body_to_rows( resp_body, vec![ ("id", "string"), - ("customer", "string"), - ("currency", "string"), - ("current_period_start", "timestamp"), - ("current_period_end", "timestamp"), - ], - tgt_cols, + ("active", "bool"), + ("country", "string"), + ("description", "string"), + ("display_name", "string"), + ("inclusive", "bool"), + ("percentage", "f64"), + ("created", "timestamp"), ), - - // Connect - "accounts" => body_to_rows( + "tokens" => body_to_rows( resp_body, vec![ ("id", "string"), - ("business_type", "string"), - ("country", "string"), - ("email", "string"), ("type", "string"), + ("client_ip", "string"), + ("used", "bool"), ("created", "timestamp"), ], tgt_cols, @@ -717,11 +698,17 @@ impl StripeFdw { } } -enum StripeFdwError {} +#[derive(Error, Debug)] +enum StripeFdwError { + #[error("{0}")] + CreateRuntimeError(#[from] CreateRuntimeError), +} impl From for ErrorReport { - fn from(_value: StripeFdwError) -> Self { - ErrorReport::new(PgSqlErrorCode::ERRCODE_FDW_ERROR, "", "") + fn from(value: StripeFdwError) -> Self { + match value { + StripeFdwError::CreateRuntimeError(e) => e.into(), + } } } @@ -750,7 +737,7 @@ impl ForeignDataWrapper for StripeFdw { stats::inc_stats(Self::FDW_NAME, stats::Metric::CreateTimes, 1); Ok(StripeFdw { - rt: create_async_runtime(), + rt: create_async_runtime()?, base_url: Url::parse(&base_url).unwrap(), client, scan_result: None, @@ -1035,4 +1022,4 @@ impl ForeignDataWrapper for StripeFdw { Ok(()) } -} +} \ No newline at end of file diff --git a/wrappers/src/fdw/stripe_fdw/tests.rs b/wrappers/src/fdw/stripe_fdw/tests.rs index 6cbeb8f8..de51d4c6 100644 --- a/wrappers/src/fdw/stripe_fdw/tests.rs +++ b/wrappers/src/fdw/stripe_fdw/tests.rs @@ -22,10 +22,29 @@ mod tests { )"#, None, None, + ).unwrap(); + + c.update( + r#" + CREATE FOREIGN TABLE stripe_accounts ( + id text, + business_type text, + country text, + email text, + type text, + created timestamp, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'accounts' -- source object in stripe, required + ) + "#, + None, + None, ) .unwrap(); - // Core resources c.update( r#" CREATE FOREIGN TABLE stripe_balance ( @@ -92,6 +111,28 @@ mod tests { ) .unwrap(); + c.update( + r#" + CREATE FOREIGN TABLE checkout_sessions ( + id text, + customer text, + payment_intent text, + subscription text, + attrs jsonb + ) + SERVER my_stripe_server + OPTIONS ( + object 'checkout/sessions', + rowid_column 'id' + ) + "#, + None, + None, + ) + .unwrap(); + + // TODO: Add coupons test setup + c.update( r#" CREATE FOREIGN TABLE stripe_customers ( @@ -200,46 +241,22 @@ mod tests { ) .unwrap(); - // TODO: Add mandates test - - c.update( - r#" - CREATE FOREIGN TABLE stripe_payment_intents ( - id text, - customer text, - amount bigint, - currency text, - payment_method text, - created timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'payment_intents' -- source object in stripe, required - ) - "#, - None, - None, - ) - .unwrap(); - c.update( r#" - CREATE FOREIGN TABLE stripe_setup_attempts ( + CREATE FOREIGN TABLE stripe_invoices ( id text, - application text, customer text, - on_behalf_of text, - payment_method text, - setup_intent text, + subscription text, status text, - usage text, - created timestamp, + total bigint, + currency text, + period_start timestamp, + period_end timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'setup_attempts' -- source object in stripe, required + object 'invoices' -- source object in stripe, required ) "#, None, @@ -249,20 +266,18 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_setup_intents ( + CREATE FOREIGN TABLE stripe_payment_intents ( id text, - client_secret text, customer text, - description text, + amount bigint, + currency text, payment_method text, - status text, - usage text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'setup_intents' -- source object in stripe, required + object 'payment_intents' -- source object in stripe, required ) "#, None, @@ -295,20 +310,19 @@ mod tests { c.update( r#" - CREATE FOREIGN TABLE stripe_refunds ( + CREATE FOREIGN TABLE stripe_prices ( id text, - amount bigint, + active bool, currency text, - charge text, - payment_intent text, - reason text, - status text, + product text, + unit_amount bigint, + type text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'refunds' -- source object in stripe, required + object 'prices' -- source object in stripe, required ) "#, None, @@ -316,9 +330,6 @@ mod tests { ) .unwrap(); - // TODO: Add tokens tests - - // Products c.update( r#" CREATE FOREIGN TABLE stripe_products ( @@ -342,83 +353,7 @@ mod tests { ) .unwrap(); - c.update( - r#" - CREATE FOREIGN TABLE stripe_prices ( - id text, - active bool, - currency text, - product text, - unit_amount bigint, - type text, - created timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'prices' -- source object in stripe, required - ) - "#, - None, - None, - ) - .unwrap(); - - // TODO: Add coupons tests - - // TODO: Add promotion_codes tests - - // TODO: Add tax_codes tests - - // TODO: Add tax_rates tests - - // TODO: Add shipping_rates tests - - // Checkout - c.update( - r#" - CREATE FOREIGN TABLE checkout_sessions ( - id text, - customer text, - payment_intent text, - subscription text, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'checkout/sessions', - rowid_column 'id' - ) - "#, - None, - None, - ) - .unwrap(); - - - // Billing - c.update( - r#" - 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 my_stripe_server - OPTIONS ( - object 'invoices' -- source object in stripe, required - ) - "#, - None, - None, - ) - .unwrap(); + // TODO: Add promotion_codes test setup c.update( r#" @@ -443,47 +378,23 @@ mod tests { ) .unwrap(); - // TODO: Add tokens tests - - // Products - c.update( - r#" - CREATE FOREIGN TABLE stripe_products ( - id text, - name text, - active bool, - default_price text, - description text, - created timestamp, - updated timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'products', -- source object in stripe, required - rowid_column 'id' - ) - "#, - None, - None, - ) - .unwrap(); - c.update( r#" - CREATE FOREIGN TABLE stripe_prices ( + CREATE FOREIGN TABLE stripe_setup_attempts ( id text, - active bool, - currency text, - product text, - unit_amount bigint, - type text, + application text, + customer text, + on_behalf_of text, + payment_method text, + setup_intent text, + status text, + usage text, created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'prices' -- source object in stripe, required + object 'setup_attempts' -- source object in stripe, required ) "#, None, @@ -491,33 +402,22 @@ mod tests { ) .unwrap(); - // TODO: Add coupons tests - - // TODO: Add promotion_codes tests - - // TODO: Add tax_codes tests - - // TODO: Add tax_rates tests - - // TODO: Add shipping_rates tests - - // Billing c.update( r#" - CREATE FOREIGN TABLE stripe_invoices ( + CREATE FOREIGN TABLE stripe_setup_intents ( id text, + client_secret text, customer text, - subscription text, + description text, + payment_method text, status text, - total bigint, - currency text, - period_start timestamp, - period_end timestamp, + usage text, + created timestamp, attrs jsonb ) SERVER my_stripe_server OPTIONS ( - object 'invoices' -- source object in stripe, required + object 'setup_intents' -- source object in stripe, required ) "#, None, @@ -525,6 +425,8 @@ mod tests { ) .unwrap(); + // TODO: Add shipping_rates test setup + c.update( r#" CREATE FOREIGN TABLE stripe_subscriptions ( @@ -546,49 +448,11 @@ mod tests { ) .unwrap(); - // Connect - c.update( - r#" - CREATE FOREIGN TABLE stripe_accounts ( - id text, - business_type text, - country text, - email text, - type text, - created timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'accounts' -- source object in stripe, required - ) - "#, - None, - None, - ) - .unwrap(); + // TODO: Add tax_codes test setup - // Connect - c.update( - r#" - CREATE FOREIGN TABLE stripe_accounts ( - id text, - business_type text, - country text, - email text, - type text, - created timestamp, - attrs jsonb - ) - SERVER my_stripe_server - OPTIONS ( - object 'accounts' -- source object in stripe, required - ) - "#, - None, - None, - ) - .unwrap(); + // TODO: Add tax_rates test setup + + // TODO: Check why there is no tokens test setup c.update( r#" @@ -692,6 +556,22 @@ mod tests { .collect::>(); assert_eq!(results, vec![(((100, "usd"), "succeeded"))]); + // TODO: Add coupons test + + let results = c + .select( + "SELECT attrs->>'id' as id FROM checkout_sessions", + None, + None, + ) + .unwrap() + .filter_map(|r| r.get_by_name::<&str, _>("id").unwrap()) + .collect::>(); + assert_eq!( + results, + vec!["cs_test_a1DmlfbOPqmbKHfpwpFQ0RM3pVXmKoESZbJxnKrPdMsLDPPMGYtEBcHGPR"] + ); + let results = c .select("SELECT * FROM stripe_customers", None, None) .unwrap() @@ -720,20 +600,6 @@ mod tests { .collect::>(); assert_eq!(results, vec!["cus_MJiBgSUgeWFN0z"]); - let results = c - .select( - "SELECT attrs->>'id' as id FROM checkout_sessions", - None, - None, - ) - .unwrap() - .filter_map(|r| r.get_by_name::<&str, _>("id").unwrap()) - .collect::>(); - assert_eq!( - results, - vec!["cs_test_a1DmlfbOPqmbKHfpwpFQ0RM3pVXmKoESZbJxnKrPdMsLDPPMGYtEBcHGPR"] - ); - // Stripe mock service cannot return 404 error code correctly for // non-exists customer, so we have to disable this test case. // @@ -903,6 +769,8 @@ mod tests { vec![(("T-shirt", true), "Comfortable gray cotton t-shirt")] ); + // TODO: Add promotion_codes test + let results = c .select("SELECT * FROM stripe_refunds", None, None) .unwrap() @@ -954,6 +822,8 @@ mod tests { )] ); + // TODO: Add shipping_rates test + let results = c .select("SELECT * FROM stripe_subscriptions", None, None) .unwrap() @@ -979,6 +849,12 @@ mod tests { )] ); + // TODO: Add tax_codes test + + // TODO: Add tax_rates test + + // TODO: Check why there is no tokens test + let results = c .select("SELECT * FROM stripe_topups", None, None) .unwrap() @@ -1102,4 +978,4 @@ mod tests { */ }); } -} +} \ No newline at end of file From efed1de437aa090732bbe6c27336c239e858dfa8 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 21:49:35 +0200 Subject: [PATCH 08/10] added more todo's --- docs/stripe.md | 15 +++++++++++++++ wrappers/src/fdw/stripe_fdw/README.md | 2 +- wrappers/src/fdw/stripe_fdw/stripe_fdw.rs | 2 +- wrappers/src/fdw/stripe_fdw/tests.rs | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index 74055746..bc4b4df6 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -65,6 +65,7 @@ The Stripe Wrapper supports data read and modify from Stripe API. | [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Charges](https://stripe.com/docs/api/charges/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Checkout Sessions](https://stripe.com/docs/api/checkout/sessions/list) | :white_check_mark:| :x: | :x: | :x: | :x: | +| [Coupons](https://stripe.com/docs/api/coupons/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Customers](https://stripe.com/docs/api/customers/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | | [Disputes](https://stripe.com/docs/api/disputes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Events](https://stripe.com/docs/api/events/list) | :white_check_mark:| :x: | :x: | :x: | :x: | @@ -76,10 +77,14 @@ The Stripe Wrapper supports data read and modify from Stripe API. | [Payouts](https://stripe.com/docs/api/payouts/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Prices](https://stripe.com/docs/api/prices/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Products](https://stripe.com/docs/api/products/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | +| [Promotion Codes](https://stripe.com/docs/api/promotion_codes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Refunds](https://stripe.com/docs/api/refunds/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [SetupAttempts](https://stripe.com/docs/api/setup_attempts/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [SetupIntents](https://stripe.com/docs/api/setup_intents/list) | :white_check_mark:| :x: | :x: | :x: | :x: | +| [Shipping Rates](https://stripe.com/docs/api/shipping_rates/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Subscriptions](https://stripe.com/docs/api/subscriptions/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | +| [Tax Codes](https://stripe.com/docs/api/tax_codes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | +| [Tax Rates](https://stripe.com/docs/api/tax_rates/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Tokens](https://stripe.com/docs/api/tokens) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Topups](https://stripe.com/docs/api/topups/list) | :white_check_mark:| :x: | :x: | :x: | :x: | | [Transfers](https://stripe.com/docs/api/transfers/list) | :white_check_mark:| :x: | :x: | :x: | :x: | @@ -249,6 +254,8 @@ While any column is allowed in a where clause, it is most efficient to filter by - payment_intent - subscription +// TODO: Add coupons docs + ### Customers *read and modify* @@ -564,6 +571,8 @@ While any column is allowed in a where clause, it is most efficient to filter by - id - active +// TODO: Add promotion_codes docs + ### Refunds *read only* @@ -657,6 +666,8 @@ While any column is allowed in a where clause, it is most efficient to filter by - customer - payment_method +// TODO: Add shipping_rates docs + ### Subscriptions *read and modify* @@ -688,6 +699,10 @@ While any column is allowed in a where clause, it is most efficient to filter by - price - status +// TODO: Add tax_codes docs + +// TODO: Add tax_rates docs + ### Tokens *read only* diff --git a/wrappers/src/fdw/stripe_fdw/README.md b/wrappers/src/fdw/stripe_fdw/README.md index 8b9e0127..5d4bf486 100644 --- a/wrappers/src/fdw/stripe_fdw/README.md +++ b/wrappers/src/fdw/stripe_fdw/README.md @@ -10,7 +10,7 @@ This is a foreign data wrapper for [Stripe](https://stripe.com/) developed using | Version | Date | Notes | | ------- | ---------- | ---------------------------------------------------------------------------------------------------- | -| 0.1.8 | 2023-09-13 | Added objects for coupons, promotion_codes, tax_codes, tax_rates and shipping rates | +| 0.1.8 | 2023-09-13 | Added objects for Coupons, Promotion Codes, Tax codes, Tax rates and Shipping rates | | 0.1.7 | 2023-07-13 | Added fdw stats collection | | 0.1.6 | 2023-05-30 | Added Checkout Session object | | 0.1.5 | 2023-05-01 | Added 'prices' object and empty result improvement | diff --git a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs index d0223f9d..e189b8f2 100644 --- a/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs +++ b/wrappers/src/fdw/stripe_fdw/stripe_fdw.rs @@ -1022,4 +1022,4 @@ impl ForeignDataWrapper for StripeFdw { Ok(()) } -} \ No newline at end of file +} diff --git a/wrappers/src/fdw/stripe_fdw/tests.rs b/wrappers/src/fdw/stripe_fdw/tests.rs index de51d4c6..321bd173 100644 --- a/wrappers/src/fdw/stripe_fdw/tests.rs +++ b/wrappers/src/fdw/stripe_fdw/tests.rs @@ -978,4 +978,4 @@ mod tests { */ }); } -} \ No newline at end of file +} From c770df215c2ba52ff6c8bf08e3eff27a8b8da095 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 21:53:21 +0200 Subject: [PATCH 09/10] formatted table for better readability --- docs/stripe.md | 61 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/docs/stripe.md b/docs/stripe.md index bc4b4df6..b5a74f20 100644 --- a/docs/stripe.md +++ b/docs/stripe.md @@ -58,36 +58,37 @@ We need to provide Postgres with the credentials to connect to Stripe, and any a The Stripe Wrapper supports data read and modify from Stripe API. -| Object | Select | Insert | Update | Delete | Truncate | -| ----------- | :----: | :----: | :----: | :----: | :----: | -| [Accounts](https://stripe.com/docs/api/accounts/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Balance](https://stripe.com/docs/api/balance) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Charges](https://stripe.com/docs/api/charges/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Checkout Sessions](https://stripe.com/docs/api/checkout/sessions/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Coupons](https://stripe.com/docs/api/coupons/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Customers](https://stripe.com/docs/api/customers/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | -| [Disputes](https://stripe.com/docs/api/disputes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Events](https://stripe.com/docs/api/events/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Files](https://stripe.com/docs/api/files/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [File Links](https://stripe.com/docs/api/file_links/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Invoices](https://stripe.com/docs/api/invoices/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Mandates](https://stripe.com/docs/api/mandates) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [PaymentIntents](https://stripe.com/docs/api/payment_intents/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Payouts](https://stripe.com/docs/api/payouts/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Prices](https://stripe.com/docs/api/prices/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Products](https://stripe.com/docs/api/products/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | -| [Promotion Codes](https://stripe.com/docs/api/promotion_codes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Refunds](https://stripe.com/docs/api/refunds/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [SetupAttempts](https://stripe.com/docs/api/setup_attempts/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [SetupIntents](https://stripe.com/docs/api/setup_intents/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Shipping Rates](https://stripe.com/docs/api/shipping_rates/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Subscriptions](https://stripe.com/docs/api/subscriptions/list) | :white_check_mark:| :white_check_mark:| :white_check_mark:| :white_check_mark:| :x: | -| [Tax Codes](https://stripe.com/docs/api/tax_codes/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Tax Rates](https://stripe.com/docs/api/tax_rates/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Tokens](https://stripe.com/docs/api/tokens) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Topups](https://stripe.com/docs/api/topups/list) | :white_check_mark:| :x: | :x: | :x: | :x: | -| [Transfers](https://stripe.com/docs/api/transfers/list) | :white_check_mark:| :x: | :x: | :x: | :x: | +| Object | Select | Insert | Update | Delete | Truncate | +|-------------------------------------------------------------------------------|-:-:----------------|-:-:----------------|-:-:----------------|-:-:----------------|-:-:------| +| [Accounts](https://stripe.com/docs/api/accounts/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Balance](https://stripe.com/docs/api/balance) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Balance Transactions](https://stripe.com/docs/api/balance_transactions/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Charges](https://stripe.com/docs/api/charges/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Checkout Sessions](https://stripe.com/docs/api/checkout/sessions/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Coupons](https://stripe.com/docs/api/coupons/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Customers](https://stripe.com/docs/api/customers/list) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | +| [Disputes](https://stripe.com/docs/api/disputes/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Events](https://stripe.com/docs/api/events/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Files](https://stripe.com/docs/api/files/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [File Links](https://stripe.com/docs/api/file_links/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Invoices](https://stripe.com/docs/api/invoices/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Mandates](https://stripe.com/docs/api/mandates) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [PaymentIntents](https://stripe.com/docs/api/payment_intents/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Payouts](https://stripe.com/docs/api/payouts/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Prices](https://stripe.com/docs/api/prices/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Products](https://stripe.com/docs/api/products/list) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | +| [Promotion Codes](https://stripe.com/docs/api/promotion_codes/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Refunds](https://stripe.com/docs/api/refunds/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [SetupAttempts](https://stripe.com/docs/api/setup_attempts/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [SetupIntents](https://stripe.com/docs/api/setup_intents/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Shipping Rates](https://stripe.com/docs/api/shipping_rates/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Subscriptions](https://stripe.com/docs/api/subscriptions/list) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | +| [Tax Codes](https://stripe.com/docs/api/tax_codes/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Tax Rates](https://stripe.com/docs/api/tax_rates/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Tokens](https://stripe.com/docs/api/tokens) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Topups](https://stripe.com/docs/api/topups/list) | :white_check_mark: | :x: | :x: | :x: | :x: | +| [Transfers](https://stripe.com/docs/api/transfers/list) | :white_check_mark: | :x: | :x: | :x: | :x: | + The Stripe foreign tables mirror Stripe's API. We can create a schema to hold all the Stripe tables. From 3f871e020aaf71970ebc1f7df7aba2aea91fdb03 Mon Sep 17 00:00:00 2001 From: Niels van Brakel Date: Wed, 13 Sep 2023 21:57:45 +0200 Subject: [PATCH 10/10] added todo's for missing mandates tests --- wrappers/src/fdw/stripe_fdw/tests.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrappers/src/fdw/stripe_fdw/tests.rs b/wrappers/src/fdw/stripe_fdw/tests.rs index 321bd173..2823b808 100644 --- a/wrappers/src/fdw/stripe_fdw/tests.rs +++ b/wrappers/src/fdw/stripe_fdw/tests.rs @@ -264,6 +264,8 @@ mod tests { ) .unwrap(); + // TODO: Add mandates test setup + c.update( r#" CREATE FOREIGN TABLE stripe_payment_intents ( @@ -704,6 +706,8 @@ mod tests { vec![((("cus_MJiBgSUgeWFN0z", 1000), "usd"), "draft")] ); + // TODO: Add mandates test + let results = c .select("SELECT * FROM stripe_payment_intents", None, None) .unwrap()