From 41ae5a72a99cb754736eab3a1e97b52772a1ca87 Mon Sep 17 00:00:00 2001 From: "stripe-openapi[bot]" <105521251+stripe-openapi[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:00:06 +0000 Subject: [PATCH 1/2] Update generated code (#972) * Update generated code for v358 * Update generated code for v376 * Update generated code for v379 * Update generated code for v384 * Update generated code for v385 --------- Co-authored-by: Stripe OpenAPI <105521251+stripe-openapi[bot]@users.noreply.github.com> Co-authored-by: pakrym-stripe <99349468+pakrym-stripe@users.noreply.github.com> --- OPENAPI_VERSION | 2 +- stripe/api_resources/account.py | 8 +- stripe/api_resources/charge.py | 9 +- stripe/api_resources/credit_note.py | 18 + stripe/api_resources/credit_note_line_item.py | 4 +- stripe/api_resources/customer.py | 8 +- stripe/api_resources/invoice.py | 2 +- stripe/api_resources/login_link.py | 4 + stripe/api_resources/token.py | 2 - tests/test_generated_examples.py | 400 ++++++++++++++++++ 10 files changed, 438 insertions(+), 19 deletions(-) diff --git a/OPENAPI_VERSION b/OPENAPI_VERSION index d646e1409..86e861958 100644 --- a/OPENAPI_VERSION +++ b/OPENAPI_VERSION @@ -1 +1 @@ -v353 \ No newline at end of file +v385 \ No newline at end of file diff --git a/stripe/api_resources/account.py b/stripe/api_resources/account.py index 08bf8458e..09d0659f5 100644 --- a/stripe/api_resources/account.py +++ b/stripe/api_resources/account.py @@ -13,15 +13,15 @@ from stripe.six.moves.urllib.parse import quote_plus -@nested_resource_class_methods( - "external_account", - operations=["create", "retrieve", "update", "delete", "list"], -) @nested_resource_class_methods( "capability", operations=["retrieve", "update", "list"], resource_plural="capabilities", ) +@nested_resource_class_methods( + "external_account", + operations=["create", "retrieve", "update", "delete", "list"], +) @nested_resource_class_methods( "login_link", operations=["create"], diff --git a/stripe/api_resources/charge.py b/stripe/api_resources/charge.py index e82b0d446..d817b703d 100644 --- a/stripe/api_resources/charge.py +++ b/stripe/api_resources/charge.py @@ -16,11 +16,10 @@ class Charge( UpdateableAPIResource, ): """ - To charge a credit or a debit card, you create a `Charge` object. You can - retrieve and refund individual charges as well as list all charges. Charges - are identified by a unique, random ID. - - Related guide: [Accept a payment with the Charges API](https://stripe.com/docs/payments/accept-a-payment-charges) + The `Charge` object represents a single attempt to move money into your Stripe account. + PaymentIntent confirmation is the most common way to create Charges, but transferring + money to a different Stripe account through Connect also creates Charges. + Some legacy payment flows create Charges directly, which is not recommended for new integrations. """ OBJECT_NAME = "charge" diff --git a/stripe/api_resources/credit_note.py b/stripe/api_resources/credit_note.py index f4ea69384..37f5603cd 100644 --- a/stripe/api_resources/credit_note.py +++ b/stripe/api_resources/credit_note.py @@ -6,8 +6,13 @@ from stripe.api_resources.abstract import CreateableAPIResource from stripe.api_resources.abstract import ListableAPIResource from stripe.api_resources.abstract import UpdateableAPIResource +from stripe.api_resources.abstract import nested_resource_class_methods +@nested_resource_class_methods( + "line", + operations=["list"], +) class CreditNote( CreateableAPIResource, ListableAPIResource, @@ -34,6 +39,19 @@ def preview( params=params, ) + @classmethod + def preview_lines( + cls, api_key=None, stripe_version=None, stripe_account=None, **params + ): + return cls._static_request( + "get", + "/v1/credit_notes/preview/lines", + api_key=api_key, + stripe_version=stripe_version, + stripe_account=stripe_account, + params=params, + ) + @classmethod def _cls_void_credit_note( cls, diff --git a/stripe/api_resources/credit_note_line_item.py b/stripe/api_resources/credit_note_line_item.py index 6e5eab599..1bd4b9910 100644 --- a/stripe/api_resources/credit_note_line_item.py +++ b/stripe/api_resources/credit_note_line_item.py @@ -2,8 +2,8 @@ # File generated from our OpenAPI spec from __future__ import absolute_import, division, print_function -from stripe.stripe_object import StripeObject +from stripe.api_resources.abstract import ListableAPIResource -class CreditNoteLineItem(StripeObject): +class CreditNoteLineItem(ListableAPIResource): OBJECT_NAME = "credit_note_line_item" diff --git a/stripe/api_resources/customer.py b/stripe/api_resources/customer.py index 629dd1e10..e23f0f19d 100644 --- a/stripe/api_resources/customer.py +++ b/stripe/api_resources/customer.py @@ -14,10 +14,6 @@ @test_helpers -@nested_resource_class_methods( - "source", - operations=["create", "retrieve", "update", "delete", "list"], -) @nested_resource_class_methods( "balance_transaction", operations=["create", "retrieve", "update", "list"], @@ -26,6 +22,10 @@ "cash_balance_transaction", operations=["retrieve", "list"], ) +@nested_resource_class_methods( + "source", + operations=["create", "retrieve", "update", "delete", "list"], +) @nested_resource_class_methods( "tax_id", operations=["create", "retrieve", "delete", "list"], diff --git a/stripe/api_resources/invoice.py b/stripe/api_resources/invoice.py index 2f8c4cf58..c4a04e6b0 100644 --- a/stripe/api_resources/invoice.py +++ b/stripe/api_resources/invoice.py @@ -27,7 +27,7 @@ class Invoice( If your invoice is configured to be billed through automatic charges, Stripe automatically finalizes your invoice and attempts payment. Note that finalizing the invoice, - [when automatic](https://stripe.com/docs/billing/invoices/workflow/#auto_advance), does + [when automatic](https://stripe.com/docs/invoicing/integration/automatic-advancement-collection), does not happen immediately as the invoice is created. Stripe waits until one hour after the last webhook was successfully sent (or the last webhook timed out after failing). If you (and the platforms you may have diff --git a/stripe/api_resources/login_link.py b/stripe/api_resources/login_link.py index ec152fd09..20bae9a3f 100644 --- a/stripe/api_resources/login_link.py +++ b/stripe/api_resources/login_link.py @@ -6,4 +6,8 @@ class LoginLink(StripeObject): + """ + Login Links are single-use login link for an Express account to access their Stripe dashboard. + """ + OBJECT_NAME = "login_link" diff --git a/stripe/api_resources/token.py b/stripe/api_resources/token.py index 719355d7e..cb2554065 100644 --- a/stripe/api_resources/token.py +++ b/stripe/api_resources/token.py @@ -27,8 +27,6 @@ class Token(CreateableAPIResource): objects or [Custom accounts](https://stripe.com/docs/api#external_accounts). Note that [Radar](https://stripe.com/docs/radar), our integrated solution for automatic fraud protection, performs best with integrations that use client-side tokenization. - - Related guide: [Accept a payment with Charges and Tokens](https://stripe.com/docs/payments/accept-a-payment-charges#web-create-token) """ OBJECT_NAME = "token" diff --git a/tests/test_generated_examples.py b/tests/test_generated_examples.py index f680974f7..e191ef8c8 100644 --- a/tests/test_generated_examples.py +++ b/tests/test_generated_examples.py @@ -4,6 +4,16 @@ class TestGeneratedExamples(object): + def test_account_externalaccount_list(self, request_mock): + stripe.Account.list_external_accounts( + "acct_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts", + ) + def test_apps_secret_list(self, request_mock): stripe.apps.Secret.list( scope={"type": "account"}, @@ -124,6 +134,17 @@ def test_customer_list_payment_methods(self, request_mock): "/v1/customers/cus_xyz/payment_methods", ) + def test_customer_paymentsource_update(self, request_mock): + stripe.Customer.modify_source( + "cus_123", + "card_123", + account_holder_name="Kamil", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_123/sources/card_123", + ) + def test_financial_connections_account_list(self, request_mock): stripe.financial_connections.Account.list() request_mock.assert_requested( @@ -566,6 +587,13 @@ def test_account_reject(self, request_mock): "/v1/accounts/acct_xxxxxxxxxxxxx/reject", ) + def test_account_capability_list(self, request_mock): + stripe.Account.list_capabilities("acct_xxxxxxxxxxxxx") + request_mock.assert_requested( + "get", + "/v1/accounts/acct_xxxxxxxxxxxxx/capabilities", + ) + def test_account_capability_retrieve(self, request_mock): stripe.Account.retrieve_capability( "acct_xxxxxxxxxxxxx", @@ -587,6 +615,126 @@ def test_account_capability_update(self, request_mock): "/v1/accounts/acct_xxxxxxxxxxxxx/capabilities/card_payments", ) + def test_account_externalaccount_create(self, request_mock): + stripe.Account.create_external_account( + "acct_xxxxxxxxxxxxx", + external_account="btok_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts", + ) + + def test_account_externalaccount_create2(self, request_mock): + stripe.Account.create_external_account( + "acct_xxxxxxxxxxxxx", + external_account="tok_xxxx_debit", + ) + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts", + ) + + def test_account_externalaccount_delete(self, request_mock): + stripe.Account.delete_external_account( + "acct_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/ba_xxxxxxxxxxxxx", + ) + + def test_account_externalaccount_delete2(self, request_mock): + stripe.Account.delete_external_account( + "acct_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/card_xxxxxxxxxxxxx", + ) + + def test_account_externalaccount_retrieve(self, request_mock): + stripe.Account.retrieve_external_account( + "acct_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "get", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/ba_xxxxxxxxxxxxx", + ) + + def test_account_externalaccount_retrieve2(self, request_mock): + stripe.Account.retrieve_external_account( + "acct_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "get", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/card_xxxxxxxxxxxxx", + ) + + def test_account_externalaccount_update(self, request_mock): + stripe.Account.modify_external_account( + "acct_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + metadata={"order_id": "6735"}, + ) + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/ba_xxxxxxxxxxxxx", + ) + + def test_account_externalaccount_update2(self, request_mock): + stripe.Account.modify_external_account( + "acct_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + metadata={"order_id": "6735"}, + ) + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/external_accounts/card_xxxxxxxxxxxxx", + ) + + def test_account_loginlink_create(self, request_mock): + stripe.Account.create_login_link("acct_xxxxxxxxxxxxx") + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/login_links", + ) + + def test_account_persons(self, request_mock): + stripe.Account.persons( + "acct_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/accounts/acct_xxxxxxxxxxxxx/persons", + ) + + def test_account_person_create(self, request_mock): + stripe.Account.create_person( + "acct_xxxxxxxxxxxxx", + first_name="Jane", + last_name="Diaz", + ) + request_mock.assert_requested( + "post", + "/v1/accounts/acct_xxxxxxxxxxxxx/persons", + ) + + def test_account_person_delete(self, request_mock): + stripe.Account.delete_person( + "acct_xxxxxxxxxxxxx", + "person_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/accounts/acct_xxxxxxxxxxxxx/persons/person_xxxxxxxxxxxxx", + ) + def test_account_person_retrieve(self, request_mock): stripe.Account.retrieve_person( "acct_xxxxxxxxxxxxx", @@ -622,6 +770,23 @@ def test_applicationfee_retrieve(self, request_mock): "/v1/application_fees/fee_xxxxxxxxxxxxx", ) + def test_applicationfee_feerefund_list(self, request_mock): + stripe.ApplicationFee.list_refunds( + "fee_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/application_fees/fee_xxxxxxxxxxxxx/refunds", + ) + + def test_applicationfee_refund(self, request_mock): + stripe.ApplicationFee.refund("fee_xxxxxxxxxxxxx") + request_mock.assert_requested( + "post", + "/v1/application_fees/fee_xxxxxxxxxxxxx/refunds", + ) + def test_applicationfee_feerefund_retrieve(self, request_mock): stripe.ApplicationFee.retrieve_refund( "fee_xxxxxxxxxxxxx", @@ -904,6 +1069,16 @@ def test_creditnote_void_credit_note(self, request_mock): "/v1/credit_notes/cn_xxxxxxxxxxxxx/void", ) + def test_creditnote_creditnotelineitem_list(self, request_mock): + stripe.CreditNote.list_lines( + "cn_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/credit_notes/cn_xxxxxxxxxxxxx/lines", + ) + def test_creditnote_preview(self, request_mock): stripe.CreditNote.preview( invoice="in_xxxxxxxxxxxxx", @@ -967,6 +1142,27 @@ def test_customer_update(self, request_mock): "/v1/customers/cus_xxxxxxxxxxxxx", ) + def test_customer_customerbalancetransaction_list(self, request_mock): + stripe.Customer.list_balance_transactions( + "cus_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/balance_transactions", + ) + + def test_customer_customerbalancetransaction_create(self, request_mock): + stripe.Customer.create_balance_transaction( + "cus_xxxxxxxxxxxxx", + amount=-500, + currency="usd", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/balance_transactions", + ) + def test_customer_customerbalancetransaction_retrieve(self, request_mock): stripe.Customer.retrieve_balance_transaction( "cus_xxxxxxxxxxxxx", @@ -977,6 +1173,17 @@ def test_customer_customerbalancetransaction_retrieve(self, request_mock): "/v1/customers/cus_xxxxxxxxxxxxx/balance_transactions/cbtxn_xxxxxxxxxxxxx", ) + def test_customer_customerbalancetransaction_update(self, request_mock): + stripe.Customer.modify_balance_transaction( + "cus_xxxxxxxxxxxxx", + "cbtxn_xxxxxxxxxxxxx", + metadata={"order_id": "6735"}, + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/balance_transactions/cbtxn_xxxxxxxxxxxxx", + ) + def test_customer_list_payment_methods2(self, request_mock): stripe.Customer.list_payment_methods( "cus_xxxxxxxxxxxxx", @@ -987,6 +1194,141 @@ def test_customer_list_payment_methods2(self, request_mock): "/v1/customers/cus_xxxxxxxxxxxxx/payment_methods", ) + def test_customer_paymentsource_list(self, request_mock): + stripe.Customer.list_sources( + "cus_xxxxxxxxxxxxx", + object="bank_account", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/sources", + ) + + def test_customer_paymentsource_list2(self, request_mock): + stripe.Customer.list_sources( + "cus_xxxxxxxxxxxxx", + object="card", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/sources", + ) + + def test_customer_paymentsource_create(self, request_mock): + stripe.Customer.create_source( + "cus_xxxxxxxxxxxxx", + source="btok_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/sources", + ) + + def test_customer_paymentsource_create2(self, request_mock): + stripe.Customer.create_source( + "cus_xxxxxxxxxxxxx", + source="tok_xxxx", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/sources", + ) + + def test_customer_paymentsource_delete(self, request_mock): + stripe.Customer.delete_source( + "cus_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/ba_xxxxxxxxxxxxx", + ) + + def test_customer_paymentsource_delete2(self, request_mock): + stripe.Customer.delete_source( + "cus_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/card_xxxxxxxxxxxxx", + ) + + def test_customer_paymentsource_retrieve(self, request_mock): + stripe.Customer.retrieve_source( + "cus_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/ba_xxxxxxxxxxxxx", + ) + + def test_customer_paymentsource_retrieve2(self, request_mock): + stripe.Customer.retrieve_source( + "cus_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/card_xxxxxxxxxxxxx", + ) + + def test_customer_paymentsource_update2(self, request_mock): + stripe.Customer.modify_source( + "cus_xxxxxxxxxxxxx", + "ba_xxxxxxxxxxxxx", + metadata={"order_id": "6735"}, + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/ba_xxxxxxxxxxxxx", + ) + + def test_customer_paymentsource_update3(self, request_mock): + stripe.Customer.modify_source( + "cus_xxxxxxxxxxxxx", + "card_xxxxxxxxxxxxx", + name="Jenny Rosen", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/sources/card_xxxxxxxxxxxxx", + ) + + def test_customer_taxid_list(self, request_mock): + stripe.Customer.list_tax_ids( + "cus_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/customers/cus_xxxxxxxxxxxxx/tax_ids", + ) + + def test_customer_taxid_create(self, request_mock): + stripe.Customer.create_tax_id( + "cus_xxxxxxxxxxxxx", + type="eu_vat", + value="DE123456789", + ) + request_mock.assert_requested( + "post", + "/v1/customers/cus_xxxxxxxxxxxxx/tax_ids", + ) + + def test_customer_taxid_delete(self, request_mock): + stripe.Customer.delete_tax_id( + "cus_xxxxxxxxxxxxx", + "txi_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "delete", + "/v1/customers/cus_xxxxxxxxxxxxx/tax_ids/txi_xxxxxxxxxxxxx", + ) + def test_customer_taxid_retrieve(self, request_mock): stripe.Customer.retrieve_tax_id( "cus_xxxxxxxxxxxxx", @@ -2366,6 +2708,27 @@ def test_subscriptionitem_update(self, request_mock): "/v1/subscription_items/si_xxxxxxxxxxxxx", ) + def test_subscriptionitem_usagerecordsummary_list(self, request_mock): + stripe.SubscriptionItem.list_usage_record_summaries( + "si_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/subscription_items/si_xxxxxxxxxxxxx/usage_record_summaries", + ) + + def test_subscriptionitem_usagerecord_create(self, request_mock): + stripe.SubscriptionItem.create_usage_record( + "si_xxxxxxxxxxxxx", + quantity=100, + timestamp=1571252444, + ) + request_mock.assert_requested( + "post", + "/v1/subscription_items/si_xxxxxxxxxxxxx/usage_records", + ) + def test_subscriptionschedule_list(self, request_mock): stripe.SubscriptionSchedule.list(limit=3) request_mock.assert_requested( @@ -2438,6 +2801,13 @@ def test_subscription_create(self, request_mock): "/v1/subscriptions", ) + def test_subscription_cancel(self, request_mock): + stripe.Subscription.cancel("sub_xxxxxxxxxxxxx") + request_mock.assert_requested( + "delete", + "/v1/subscriptions/sub_xxxxxxxxxxxxx", + ) + def test_subscription_retrieve(self, request_mock): stripe.Subscription.retrieve("sub_xxxxxxxxxxxxx") request_mock.assert_requested( @@ -2858,6 +3228,26 @@ def test_transfer_update(self, request_mock): "/v1/transfers/tr_xxxxxxxxxxxxx", ) + def test_transfer_transferreversal_list(self, request_mock): + stripe.Transfer.list_reversals( + "tr_xxxxxxxxxxxxx", + limit=3, + ) + request_mock.assert_requested( + "get", + "/v1/transfers/tr_xxxxxxxxxxxxx/reversals", + ) + + def test_transfer_transferreversal_create(self, request_mock): + stripe.Transfer.create_reversal( + "tr_xxxxxxxxxxxxx", + amount=100, + ) + request_mock.assert_requested( + "post", + "/v1/transfers/tr_xxxxxxxxxxxxx/reversals", + ) + def test_transfer_transferreversal_retrieve(self, request_mock): stripe.Transfer.retrieve_reversal( "tr_xxxxxxxxxxxxx", @@ -3245,3 +3635,13 @@ def test_tax_calculation_create(self, request_mock): "post", "/v1/tax/calculations", ) + + def test_creditnote_preview_lines(self, request_mock): + stripe.CreditNote.preview_lines( + limit=3, + invoice="in_xxxxxxxxxxxxx", + ) + request_mock.assert_requested( + "get", + "/v1/credit_notes/preview/lines", + ) From 1d1372bb760676a329034b504d3e5cfc9cea6d0f Mon Sep 17 00:00:00 2001 From: pakrym-stripe <99349468+pakrym-stripe@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:28:21 -0700 Subject: [PATCH 2/2] Add information about accessing response headers (#977) --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index c61423a35..036b1e2ac 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,19 @@ There are a few options for enabling it: logging.getLogger('stripe').setLevel(logging.DEBUG) ``` +### Accessing response code and headers + +You can access the HTTP response code and headers using the `last_response` property of the returned resource. + +```python +customer = stripe.Customer.retrieve( + "cus_123456789" +) + +print(customer.last_response.code) +print(customer.last_response.headers) +``` + ### Writing a Plugin If you're writing a plugin that uses the library, we'd appreciate it if you