From b03c71bbc31c0e7cdaf9f0fa07dd8c4fe8851c72 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:19:58 +0000 Subject: [PATCH 1/2] [fern-generated] Update SDK Generated by Fern CLI Version: unknown Generators: - fernapi/fern-python-sdk: 5.28.0 --- .fern/metadata.json | 2 +- reference.md | 488 +++++++++++++++++- src/whop_sdk/__init__.py | 91 +++- src/whop_sdk/accounts/client.py | 74 +++ src/whop_sdk/accounts/raw_client.py | 172 ++++++ src/whop_sdk/api_logs/__init__.py | 58 +++ src/whop_sdk/api_logs/client.py | 239 +++++++++ src/whop_sdk/api_logs/raw_client.py | 336 ++++++++++++ src/whop_sdk/api_logs/types/__init__.py | 56 ++ .../list_api_logs_request_http_method.py | 5 + .../types/list_api_logs_request_status.py | 5 + .../api_logs/types/list_api_logs_response.py | 22 + .../types/list_api_logs_response_data_item.py | 32 ++ ...api_logs_response_data_item_http_method.py | 7 + ...list_api_logs_response_data_item_status.py | 5 + .../types/list_api_logs_response_page_info.py | 22 + src/whop_sdk/apps/client.py | 4 +- src/whop_sdk/apps/raw_client.py | 4 +- src/whop_sdk/cards/client.py | 8 +- src/whop_sdk/cards/raw_client.py | 8 +- src/whop_sdk/client.py | 38 ++ src/whop_sdk/confirmation_tokens/__init__.py | 73 +++ src/whop_sdk/confirmation_tokens/client.py | 322 ++++++++++++ .../confirmation_tokens/raw_client.py | 431 ++++++++++++++++ .../confirmation_tokens/types/__init__.py | 87 ++++ ...irmation_tokens_request_billing_details.py | 25 + ...firmation_tokens_request_payment_method.py | 88 ++++ ...tokens_request_payment_method_apple_pay.py | 31 ++ ...n_tokens_request_payment_method_balance.py | 26 + ...okens_request_payment_method_bank_debit.py | 26 + ...tion_tokens_request_payment_method_card.py | 41 ++ ..._tokens_request_payment_method_category.py | 19 + ...okens_request_payment_method_google_pay.py | 26 + ...s_request_payment_method_payer_document.py | 34 ++ ...uest_payment_method_payer_document_type.py | 7 + ...ion_tokens_request_payment_method_saved.py | 26 + ...ation_tokens_request_setup_future_usage.py | 5 + .../types/create_events_request_context.py | 5 + src/whop_sdk/financial_activity/client.py | 10 + src/whop_sdk/financial_activity/raw_client.py | 10 + src/whop_sdk/members/client.py | 4 +- src/whop_sdk/members/raw_client.py | 4 +- src/whop_sdk/payments/client.py | 8 +- src/whop_sdk/payments/raw_client.py | 8 +- src/whop_sdk/payouts/methods/client.py | 42 +- src/whop_sdk/payouts/methods/raw_client.py | 34 +- src/whop_sdk/refunds/client.py | 12 +- src/whop_sdk/refunds/raw_client.py | 12 +- src/whop_sdk/social_accounts/client.py | 30 +- src/whop_sdk/social_accounts/raw_client.py | 24 +- src/whop_sdk/types/__init__.py | 24 +- src/whop_sdk/types/account.py | 4 +- src/whop_sdk/types/bounty.py | 5 + src/whop_sdk/types/bounty_list_item.py | 5 + src/whop_sdk/types/confirmation_token.py | 56 ++ .../types/confirmation_token_status.py | 5 + src/whop_sdk/types/membership.py | 4 +- src/whop_sdk/types/payment.py | 6 + .../types/payment_billing_details_preview.py | 37 ++ src/whop_sdk/types/payment_fees_item.py | 43 ++ src/whop_sdk/types/payment_method_display.py | 59 +++ .../types/payment_method_display_category.py | 19 + ...t.py => payment_method_display_preview.py} | 20 +- src/whop_sdk/types/payment_method_types.py | 2 + src/whop_sdk/types/payment_providers.py | 1 + src/whop_sdk/types/permission_action.py | 1 + src/whop_sdk/types/storefront_account.py | 5 + 67 files changed, 3319 insertions(+), 123 deletions(-) create mode 100644 src/whop_sdk/api_logs/__init__.py create mode 100644 src/whop_sdk/api_logs/client.py create mode 100644 src/whop_sdk/api_logs/raw_client.py create mode 100644 src/whop_sdk/api_logs/types/__init__.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_request_http_method.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_request_status.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_response.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_response_data_item.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_response_data_item_http_method.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_response_data_item_status.py create mode 100644 src/whop_sdk/api_logs/types/list_api_logs_response_page_info.py create mode 100644 src/whop_sdk/confirmation_tokens/__init__.py create mode 100644 src/whop_sdk/confirmation_tokens/client.py create mode 100644 src/whop_sdk/confirmation_tokens/raw_client.py create mode 100644 src/whop_sdk/confirmation_tokens/types/__init__.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_billing_details.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_apple_pay.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_balance.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_bank_debit.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_card.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_category.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_google_pay.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document_type.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_saved.py create mode 100644 src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_setup_future_usage.py create mode 100644 src/whop_sdk/types/confirmation_token.py create mode 100644 src/whop_sdk/types/confirmation_token_status.py create mode 100644 src/whop_sdk/types/payment_billing_details_preview.py create mode 100644 src/whop_sdk/types/payment_fees_item.py create mode 100644 src/whop_sdk/types/payment_method_display.py create mode 100644 src/whop_sdk/types/payment_method_display_category.py rename src/whop_sdk/types/{membership_account.py => payment_method_display_preview.py} (54%) diff --git a/.fern/metadata.json b/.fern/metadata.json index 0a957713..86a25147 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -15,7 +15,7 @@ "standardwebhooks": ">=1.0.1,<2" } }, - "originGitCommit": "b80eac0615e24d2cdfc26297d0bbd053c8e5cf35", + "originGitCommit": "5b8d46fb7a1e5cd06c30ccb87d0003a44c78f6cb", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "1.0.14", diff --git a/reference.md b/reference.md index 4085e653..dd9afd55 100644 --- a/reference.md +++ b/reference.md @@ -1216,6 +1216,79 @@ client.accounts.form_company( + + + + +
client.accounts.suspend(...) -> Account +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Suspends a connected account directly owned by the authenticated platform account. This cannot suspend the platform account itself or an account owned by another platform. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from whop_sdk import Whop +from whop_sdk.environment import WhopEnvironment + +client = Whop( + token="", + environment=WhopEnvironment.DEFAULT, +) + +client.accounts.suspend( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Connected account ID, prefixed `biz_`. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -6462,6 +6535,158 @@ client.api_keys.rotate( + + + + +## Api Logs +
client.api_logs.list(...) -> ListApiLogsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists the requests served by Whop's API with the account's API keys, newest first — every surface (GraphQL, REST, and native /api/v1), reads and failed requests included. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from whop_sdk import Whop +from whop_sdk.environment import WhopEnvironment + +client = Whop( + token="", + environment=WhopEnvironment.DEFAULT, +) + +client.api_logs.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**account_id:** `typing.Optional[str]` — The account (biz_*) whose API logs to list. Defaults to the authenticated account. + +
+
+ +
+
+ +**created_after:** `typing.Optional[str]` — Only return requests served at or after this ISO 8601 timestamp. Defaults to 7 days before created_before, or 7 days ago. + +
+
+ +
+
+ +**created_before:** `typing.Optional[str]` — Only return requests served before this ISO 8601 timestamp. + +
+
+ +
+
+ +**operation_name:** `typing.Optional[str]` — Only return requests for this operation, matched exactly against the operation_name shown on each log row (for example api/v1/products#create). + +
+
+ +
+
+ +**http_method:** `typing.Optional[ListApiLogsRequestHttpMethod]` — Only return requests made with this HTTP method. + +
+
+ +
+
+ +**status:** `typing.Optional[ListApiLogsRequestStatus]` — Only return requests that finished with this status. + +
+
+ +
+
+ +**api_key_id:** `typing.Optional[str]` — Only return requests made with this API key (apik_…). + +
+
+ +
+
+ +**min_duration_ms:** `typing.Optional[int]` — Only return requests that took at least this many milliseconds. + +
+
+ +
+
+ +**max_duration_ms:** `typing.Optional[int]` — Only return requests that took at most this many milliseconds. + +
+
+ +
+
+ +**first:** `typing.Optional[int]` — Number of logs to return. + +
+
+ +
+
+ +**after:** `typing.Optional[str]` — Cursor to fetch the page after (from page_info.end_cursor). + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -6982,7 +7207,7 @@ client.apps.list()
-**order:** `typing.Optional[ListAppsRequestOrder]` — The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then apps with a banner image, then by how many apps were created from each app as a template. +**order:** `typing.Optional[ListAppsRequestOrder]` — The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then by how many businesses created apps from each app as a template.
@@ -10354,7 +10579,7 @@ client.cards.list()
-Issue a virtual card, or apply for card issuing. +Issue a virtual card, or apply for card issuing. An account with no application files one here and gets back a `202`; call again to issue the card once it is approved.
@@ -10401,7 +10626,7 @@ client.cards.create()
-**assigned_user_id:** `typing.Optional[str]` — The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts. +**assigned_user_id:** `typing.Optional[str]` — The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts, and whenever a company API key files an account's first card application.
@@ -12358,6 +12583,223 @@ client.company_token_transactions.retrieve( + + + + +## Confirmation Tokens +
client.confirmation_tokens.create(...) -> ConfirmationToken +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Mints a single-use, short-lived confirmation token from what the buyer entered on your collection surface: the payment method payload, billing details, and attested save consent. Public and rate-limited — the account_id in the body scopes the token but does not authenticate. Confirm it with POST /payments from your server. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from whop_sdk import Whop +from whop_sdk.environment import WhopEnvironment +from whop_sdk.confirmation_tokens import CreateConfirmationTokensRequestBillingDetails, CreateConfirmationTokensRequestPaymentMethod, CreateConfirmationTokensRequestPaymentMethodCard + +client = Whop( + token="", + environment=WhopEnvironment.DEFAULT, +) + +client.confirmation_tokens.create( + account_id="biz_xxxxxxxxxxxxxx", + billing_details=CreateConfirmationTokensRequestBillingDetails( + address={ + "city": "Austin", + "country": "US", + "line1": "123 Main St", + "postal_code": "78701" + }, + email="buyer@example.com", + name="Buyer Name", + ), + payment_method=CreateConfirmationTokensRequestPaymentMethod( + card=CreateConfirmationTokensRequestPaymentMethodCard( + brand="visa", + last4="4242", + token_intent="bt_ti_123", + ), + category="card", + type="card", + ), + setup_future_usage="off_session", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**account_id:** `str` — The account (biz_) this token is scoped to — the publishable identity. + +
+
+ +
+
+ +**payment_method:** `CreateConfirmationTokensRequestPaymentMethod` — The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + +
+
+ +
+
+ +**billing_details:** `typing.Optional[CreateConfirmationTokensRequestBillingDetails]` — Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + +
+
+ +
+
+ +**browser_info:** `typing.Optional[typing.Dict[str, typing.Any]]` — Screen/runtime facts from the buyer's browser (platform, screen dimensions, language, ...) used for authentication ceremonies. Header-derived fields are captured server-side. + +
+
+ +
+
+ +**return_url:** `typing.Optional[str]` — Where redirect flows send the buyer, carried onto the confirm that consumes this token. + +
+
+ +
+
+ +**setup_future_usage:** `typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage]` — The save-consent state your surface displayed when the buyer confirmed. Confirm may vault only if attested here. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.confirmation_tokens.retrieve(...) -> ConfirmationToken +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a token's display-safe preview — never the underlying payment credential. Public and rate-limited: the account_id query param must match the account the token was minted for. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from whop_sdk import Whop +from whop_sdk.environment import WhopEnvironment + +client = Whop( + token="", + environment=WhopEnvironment.DEFAULT, +) + +client.confirmation_tokens.retrieve( + id="id", + account_id="account_id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Confirmation token ID, prefixed `ctok_`. + +
+
+ +
+
+ +**account_id:** `str` — The account (biz_) the token was minted for. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -19593,6 +20035,14 @@ client.financial_activity.list()
+**activity_id:** `typing.Optional[str]` — Optional ledger activity ID (for example `line_3`). Returns at most that one activity. + +
+
+ +
+
+ **currency:** `typing.Optional[str]` — Optional currency code filter, for example `usd`.
@@ -26166,7 +26616,7 @@ client.payments.list(
-**include_free:** `typing.Optional[bool]` — Whether to include payments with a zero amount. +**include_free:** `typing.Optional[bool]` — Whether to include payments with a zero amount. Defaults to false, so zero-amount payments are omitted unless you set this to true — a company whose sales are all free plans returns an empty list without it.
@@ -26246,7 +26696,7 @@ client.payments.list(
-Charge an existing member off-session using one of their stored payment methods. You can provide an existing plan, or create a new one in-line. This endpoint will respond with a payment object immediately, but the payment is processed asynchronously in the background. Use webhooks to be notified when the payment succeeds or fails. +Charge a buyer on-session with a `confirmation_token` for the method they selected, or charge an existing member off-session using a stored payment method. You can provide an existing plan or create one inline. The endpoint returns a payment immediately, but processing continues asynchronously. Use webhooks to learn whether it succeeds or fails, and poll the payment's status endpoint for any step the buyer must complete. Required permissions: - `payment:charge` @@ -31529,7 +31979,7 @@ client.refunds.list(
-**payment_id:** `typing.Optional[str]` — Filter refunds to only those associated with this specific payment. +**payment_id:** `typing.Optional[str]` — Filter refunds to those associated with this specific payment. Mutually exclusive with company_id and user_id: provide exactly one.
@@ -31537,7 +31987,7 @@ client.refunds.list(
-**company_id:** `typing.Optional[str]` — Filter refunds to only those belonging to this company. +**company_id:** `typing.Optional[str]` — Filter refunds to those belonging to this company. Mutually exclusive with payment_id and user_id: provide exactly one.
@@ -31545,7 +31995,7 @@ client.refunds.list(
-**user_id:** `typing.Optional[str]` — Filter refunds to only those associated with this specific user. +**user_id:** `typing.Optional[str]` — Filter refunds to those associated with this specific user. Mutually exclusive with payment_id and company_id: provide exactly one. Requires a credential belonging to that user; any other credential receives 'You are not authorized'.
@@ -34115,6 +34565,7 @@ client = Whop( client.social_accounts.connect( platform="meta_business", + redirect_url="https://example.com/settings/social-accounts", ) ``` @@ -34131,7 +34582,7 @@ client.social_accounts.connect(
-**platform:** `ConnectSocialAccountsRequestPlatform` — The platform to connect the social account on. Supported options are `meta_business` and `tiktok`. +**platform:** `ConnectSocialAccountsRequestPlatform` — The platform to connect the social account on. Use `meta_business` to connect Meta Business assets, which is how Facebook Pages and Instagram accounts are connected — there is no separate `instagram` value. Use `tiktok` for TikTok accounts.
@@ -34139,7 +34590,7 @@ client.social_accounts.connect(
-**account_id:** `typing.Optional[str]` — The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account. +**redirect_url:** `str` — Where to send the user once they finish connecting their accounts. Any `http` or `https` URL. If the connection fails, the user is redirected with a `social_account_error` query param.
@@ -34147,7 +34598,7 @@ client.social_accounts.connect(
-**redirect_url:** `typing.Optional[str]` — The Whop URL to redirect the user to after they finish connecting. +**account_id:** `typing.Optional[str]` — The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account.
@@ -34155,7 +34606,7 @@ client.social_accounts.connect(
-**scopes:** `typing.Optional[typing.List[ConnectSocialAccountsRequestScopesItem]]` — Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business or TikTok account for ads. +**scopes:** `typing.Optional[typing.List[ConnectSocialAccountsRequestScopesItem]]` — Capabilities to grant for the connected social account. `advertise` is required for both `meta_business` and `tiktok` connections — it is not conditional on whether you intend to run ads, and omitting it fails the request.
@@ -41135,7 +41586,7 @@ client.payouts.methods.delete(
-Changes the label used to identify a saved payout method. +Changes the label used to identify a saved payout method or makes it the account's default payout method.
@@ -41160,7 +41611,6 @@ client = Whop( client.payouts.methods.update( id="id", - nickname="Primary checking", ) ``` @@ -41185,7 +41635,15 @@ client.payouts.methods.update(
-**nickname:** `str` — New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters. +**is_default:** `typing.Optional[bool]` — Set to `true` to make this the account's default payout method. `false` is not accepted. + +
+
+ +
+
+ +**nickname:** `typing.Optional[str]` — New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters.
diff --git a/src/whop_sdk/__init__.py b/src/whop_sdk/__init__.py index 17ea9578..540831e9 100644 --- a/src/whop_sdk/__init__.py +++ b/src/whop_sdk/__init__.py @@ -324,6 +324,8 @@ CompanyTokenTransactionMember, CompanyTokenTransactionTypes, CompanyTokenTransactionUser, + ConfirmationToken, + ConfirmationTokenStatus, ConversionEvent, ConversionEventZero, Countries, @@ -600,7 +602,6 @@ MemberStatuses, MembersSortableColumns, Membership, - MembershipAccount, MembershipCancellationModes, MembershipListItem, MembershipListItemCompany, @@ -654,9 +655,11 @@ PaymentBankTransfer, PaymentBankTransferInstructions, PaymentBillingAddress, + PaymentBillingDetailsPreview, PaymentCompany, PaymentDeclineCodes, PaymentDisputesItem, + PaymentFeesItem, PaymentFinancingTransactionsItem, PaymentInstructions, PaymentInstructions_BankTransfer, @@ -718,6 +721,9 @@ PaymentMethodCashappPaymentMethodIconsSquare, PaymentMethodCashappPaymentMethodIconsSquareDark, PaymentMethodCashappPaymentMethodIconsSquareLight, + PaymentMethodDisplay, + PaymentMethodDisplayCategory, + PaymentMethodDisplayPreview, PaymentMethodDomain, PaymentMethodDomainProvider, PaymentMethodDomainStatus, @@ -1122,6 +1128,7 @@ affiliates, ai_chats, api_keys, + api_logs, app_builds, apps, audiences, @@ -1134,6 +1141,7 @@ checkout_configurations, companies, company_token_transactions, + confirmation_tokens, course_chapters, course_lesson_interactions, course_lessons, @@ -1369,6 +1377,15 @@ UpdateApiKeysRequestPermissionsStatementsItem, UpdateApiKeysRequestPermissionsSystemRole, ) + from .api_logs import ( + ListApiLogsRequestHttpMethod, + ListApiLogsRequestStatus, + ListApiLogsResponse, + ListApiLogsResponseDataItem, + ListApiLogsResponseDataItemHttpMethod, + ListApiLogsResponseDataItemStatus, + ListApiLogsResponsePageInfo, + ) from .app_builds import ( CreateAppBuildsRequestAttachment, CreateAppBuildsRequestPlatform, @@ -1636,6 +1653,20 @@ CreateCompanyTokenTransactionsRequest_Transfer, ListCompanyTokenTransactionsResponse, ) + from .confirmation_tokens import ( + CreateConfirmationTokensRequestBillingDetails, + CreateConfirmationTokensRequestPaymentMethod, + CreateConfirmationTokensRequestPaymentMethodApplePay, + CreateConfirmationTokensRequestPaymentMethodBalance, + CreateConfirmationTokensRequestPaymentMethodBankDebit, + CreateConfirmationTokensRequestPaymentMethodCard, + CreateConfirmationTokensRequestPaymentMethodCategory, + CreateConfirmationTokensRequestPaymentMethodGooglePay, + CreateConfirmationTokensRequestPaymentMethodPayerDocument, + CreateConfirmationTokensRequestPaymentMethodPayerDocumentType, + CreateConfirmationTokensRequestPaymentMethodSaved, + CreateConfirmationTokensRequestSetupFutureUsage, + ) from .course_chapters import ListCourseChaptersResponse from .course_lesson_interactions import ( ListCourseLessonInteractionsResponse, @@ -2949,6 +2980,8 @@ "CompanyTokenTransactionTypes": ".types", "CompanyTokenTransactionUser": ".types", "CompleteFilesRequestMultipartPartsItem": ".files", + "ConfirmationToken": ".types", + "ConfirmationTokenStatus": ".types", "ConflictError": ".errors", "ConnectSocialAccountsRequestPlatform": ".social_accounts", "ConnectSocialAccountsRequestScopesItem": ".social_accounts", @@ -3096,6 +3129,18 @@ "CreateCompanyTokenTransactionsRequest_Add": ".company_token_transactions", "CreateCompanyTokenTransactionsRequest_Subtract": ".company_token_transactions", "CreateCompanyTokenTransactionsRequest_Transfer": ".company_token_transactions", + "CreateConfirmationTokensRequestBillingDetails": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethod": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodApplePay": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodBalance": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodBankDebit": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodCard": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodCategory": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodGooglePay": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType": ".confirmation_tokens", + "CreateConfirmationTokensRequestPaymentMethodSaved": ".confirmation_tokens", + "CreateConfirmationTokensRequestSetupFutureUsage": ".confirmation_tokens", "CreateCourseLessonsRequestThumbnail": ".course_lessons", "CreateCoursesRequestThumbnail": ".courses", "CreateDepositsRequestDestination": ".deposits", @@ -3545,6 +3590,13 @@ "ListApiKeysRequestResourceType": ".api_keys", "ListApiKeysResponse": ".api_keys", "ListApiKeysResponsePageInfo": ".api_keys", + "ListApiLogsRequestHttpMethod": ".api_logs", + "ListApiLogsRequestStatus": ".api_logs", + "ListApiLogsResponse": ".api_logs", + "ListApiLogsResponseDataItem": ".api_logs", + "ListApiLogsResponseDataItemHttpMethod": ".api_logs", + "ListApiLogsResponseDataItemStatus": ".api_logs", + "ListApiLogsResponsePageInfo": ".api_logs", "ListAppBuildsRequestCreatedAfter": ".types", "ListAppBuildsRequestCreatedBefore": ".types", "ListAppBuildsRequestPlatform": ".app_builds", @@ -3840,7 +3892,6 @@ "MemberStatuses": ".types", "MembersSortableColumns": ".types", "Membership": ".types", - "MembershipAccount": ".types", "MembershipCancellationModes": ".types", "MembershipListItem": ".types", "MembershipListItemCompany": ".types", @@ -3899,9 +3950,11 @@ "PaymentBankTransfer": ".types", "PaymentBankTransferInstructions": ".types", "PaymentBillingAddress": ".types", + "PaymentBillingDetailsPreview": ".types", "PaymentCompany": ".types", "PaymentDeclineCodes": ".types", "PaymentDisputesItem": ".types", + "PaymentFeesItem": ".types", "PaymentFinancingTransactionsItem": ".types", "PaymentInstructions": ".types", "PaymentInstructions_BankTransfer": ".types", @@ -3963,6 +4016,9 @@ "PaymentMethodCashappPaymentMethodIconsSquare": ".types", "PaymentMethodCashappPaymentMethodIconsSquareDark": ".types", "PaymentMethodCashappPaymentMethodIconsSquareLight": ".types", + "PaymentMethodDisplay": ".types", + "PaymentMethodDisplayCategory": ".types", + "PaymentMethodDisplayPreview": ".types", "PaymentMethodDomain": ".types", "PaymentMethodDomainProvider": ".types", "PaymentMethodDomainStatus": ".types", @@ -5024,6 +5080,7 @@ "affiliates": ".affiliates", "ai_chats": ".ai_chats", "api_keys": ".api_keys", + "api_logs": ".api_logs", "app_builds": ".app_builds", "apps": ".apps", "audiences": ".audiences", @@ -5036,6 +5093,7 @@ "checkout_configurations": ".checkout_configurations", "companies": ".companies", "company_token_transactions": ".company_token_transactions", + "confirmation_tokens": ".confirmation_tokens", "course_chapters": ".course_chapters", "course_lesson_interactions": ".course_lesson_interactions", "course_lessons": ".course_lessons", @@ -5461,6 +5519,8 @@ def __dir__(): "CompanyTokenTransactionTypes", "CompanyTokenTransactionUser", "CompleteFilesRequestMultipartPartsItem", + "ConfirmationToken", + "ConfirmationTokenStatus", "ConflictError", "ConnectSocialAccountsRequestPlatform", "ConnectSocialAccountsRequestScopesItem", @@ -5608,6 +5668,18 @@ def __dir__(): "CreateCompanyTokenTransactionsRequest_Add", "CreateCompanyTokenTransactionsRequest_Subtract", "CreateCompanyTokenTransactionsRequest_Transfer", + "CreateConfirmationTokensRequestBillingDetails", + "CreateConfirmationTokensRequestPaymentMethod", + "CreateConfirmationTokensRequestPaymentMethodApplePay", + "CreateConfirmationTokensRequestPaymentMethodBalance", + "CreateConfirmationTokensRequestPaymentMethodBankDebit", + "CreateConfirmationTokensRequestPaymentMethodCard", + "CreateConfirmationTokensRequestPaymentMethodCategory", + "CreateConfirmationTokensRequestPaymentMethodGooglePay", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType", + "CreateConfirmationTokensRequestPaymentMethodSaved", + "CreateConfirmationTokensRequestSetupFutureUsage", "CreateCourseLessonsRequestThumbnail", "CreateCoursesRequestThumbnail", "CreateDepositsRequestDestination", @@ -6057,6 +6129,13 @@ def __dir__(): "ListApiKeysRequestResourceType", "ListApiKeysResponse", "ListApiKeysResponsePageInfo", + "ListApiLogsRequestHttpMethod", + "ListApiLogsRequestStatus", + "ListApiLogsResponse", + "ListApiLogsResponseDataItem", + "ListApiLogsResponseDataItemHttpMethod", + "ListApiLogsResponseDataItemStatus", + "ListApiLogsResponsePageInfo", "ListAppBuildsRequestCreatedAfter", "ListAppBuildsRequestCreatedBefore", "ListAppBuildsRequestPlatform", @@ -6352,7 +6431,6 @@ def __dir__(): "MemberStatuses", "MembersSortableColumns", "Membership", - "MembershipAccount", "MembershipCancellationModes", "MembershipListItem", "MembershipListItemCompany", @@ -6411,9 +6489,11 @@ def __dir__(): "PaymentBankTransfer", "PaymentBankTransferInstructions", "PaymentBillingAddress", + "PaymentBillingDetailsPreview", "PaymentCompany", "PaymentDeclineCodes", "PaymentDisputesItem", + "PaymentFeesItem", "PaymentFinancingTransactionsItem", "PaymentInstructions", "PaymentInstructions_BankTransfer", @@ -6475,6 +6555,9 @@ def __dir__(): "PaymentMethodCashappPaymentMethodIconsSquare", "PaymentMethodCashappPaymentMethodIconsSquareDark", "PaymentMethodCashappPaymentMethodIconsSquareLight", + "PaymentMethodDisplay", + "PaymentMethodDisplayCategory", + "PaymentMethodDisplayPreview", "PaymentMethodDomain", "PaymentMethodDomainProvider", "PaymentMethodDomainStatus", @@ -7536,6 +7619,7 @@ def __dir__(): "affiliates", "ai_chats", "api_keys", + "api_logs", "app_builds", "apps", "audiences", @@ -7548,6 +7632,7 @@ def __dir__(): "checkout_configurations", "companies", "company_token_transactions", + "confirmation_tokens", "course_chapters", "course_lesson_interactions", "course_lessons", diff --git a/src/whop_sdk/accounts/client.py b/src/whop_sdk/accounts/client.py index cfd1d054..0fa1c8a8 100644 --- a/src/whop_sdk/accounts/client.py +++ b/src/whop_sdk/accounts/client.py @@ -687,6 +687,39 @@ def form_company( ) return _response.data + def suspend(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Account: + """ + Suspends a connected account directly owned by the authenticated platform account. This cannot suspend the platform account itself or an account owned by another platform. + + Parameters + ---------- + id : str + Connected account ID, prefixed `biz_`. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Account + Connected account suspended. + + Examples + -------- + from whop_sdk import Whop + + client = Whop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + client.accounts.suspend( + id="id", + ) + """ + _response = self._raw_client.suspend(id, request_options=request_options) + return _response.data + def transfer_ownership( self, id: str, @@ -1446,6 +1479,47 @@ async def main() -> None: ) return _response.data + async def suspend(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Account: + """ + Suspends a connected account directly owned by the authenticated platform account. This cannot suspend the platform account itself or an account owned by another platform. + + Parameters + ---------- + id : str + Connected account ID, prefixed `biz_`. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Account + Connected account suspended. + + Examples + -------- + import asyncio + + from whop_sdk import AsyncWhop + + client = AsyncWhop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.accounts.suspend( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.suspend(id, request_options=request_options) + return _response.data + async def transfer_ownership( self, id: str, diff --git a/src/whop_sdk/accounts/raw_client.py b/src/whop_sdk/accounts/raw_client.py index 3f5b25be..167af66e 100644 --- a/src/whop_sdk/accounts/raw_client.py +++ b/src/whop_sdk/accounts/raw_client.py @@ -973,6 +973,91 @@ def form_company( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def suspend(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Account]: + """ + Suspends a connected account directly owned by the authenticated platform account. This cannot suspend the platform account itself or an account owned by another platform. + + Parameters + ---------- + id : str + Connected account ID, prefixed `biz_`. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Account] + Connected account suspended. + """ + _response = self._client_wrapper.httpx_client.request( + f"accounts/{encode_path_param(id)}/suspend", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Account, + parse_obj_as( + type_=Account, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + V1ErrorResponse, + parse_obj_as( + type_=V1ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def transfer_ownership( self, id: str, @@ -1985,6 +2070,93 @@ async def form_company( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def suspend( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Account]: + """ + Suspends a connected account directly owned by the authenticated platform account. This cannot suspend the platform account itself or an account owned by another platform. + + Parameters + ---------- + id : str + Connected account ID, prefixed `biz_`. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Account] + Connected account suspended. + """ + _response = await self._client_wrapper.httpx_client.request( + f"accounts/{encode_path_param(id)}/suspend", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Account, + parse_obj_as( + type_=Account, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + V1ErrorResponse, + parse_obj_as( + type_=V1ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def transfer_ownership( self, id: str, diff --git a/src/whop_sdk/api_logs/__init__.py b/src/whop_sdk/api_logs/__init__.py new file mode 100644 index 00000000..875ed5b0 --- /dev/null +++ b/src/whop_sdk/api_logs/__init__.py @@ -0,0 +1,58 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import ( + ListApiLogsRequestHttpMethod, + ListApiLogsRequestStatus, + ListApiLogsResponse, + ListApiLogsResponseDataItem, + ListApiLogsResponseDataItemHttpMethod, + ListApiLogsResponseDataItemStatus, + ListApiLogsResponsePageInfo, + ) +_dynamic_imports: typing.Dict[str, str] = { + "ListApiLogsRequestHttpMethod": ".types", + "ListApiLogsRequestStatus": ".types", + "ListApiLogsResponse": ".types", + "ListApiLogsResponseDataItem": ".types", + "ListApiLogsResponseDataItemHttpMethod": ".types", + "ListApiLogsResponseDataItemStatus": ".types", + "ListApiLogsResponsePageInfo": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "ListApiLogsRequestHttpMethod", + "ListApiLogsRequestStatus", + "ListApiLogsResponse", + "ListApiLogsResponseDataItem", + "ListApiLogsResponseDataItemHttpMethod", + "ListApiLogsResponseDataItemStatus", + "ListApiLogsResponsePageInfo", +] diff --git a/src/whop_sdk/api_logs/client.py b/src/whop_sdk/api_logs/client.py new file mode 100644 index 00000000..1be92500 --- /dev/null +++ b/src/whop_sdk/api_logs/client.py @@ -0,0 +1,239 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from .raw_client import AsyncRawApiLogsClient, RawApiLogsClient +from .types.list_api_logs_request_http_method import ListApiLogsRequestHttpMethod +from .types.list_api_logs_request_status import ListApiLogsRequestStatus +from .types.list_api_logs_response import ListApiLogsResponse +from .types.list_api_logs_response_data_item import ListApiLogsResponseDataItem + + +class ApiLogsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawApiLogsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawApiLogsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawApiLogsClient + """ + return self._raw_client + + def list( + self, + *, + account_id: typing.Optional[str] = None, + created_after: typing.Optional[str] = None, + created_before: typing.Optional[str] = None, + operation_name: typing.Optional[str] = None, + http_method: typing.Optional[ListApiLogsRequestHttpMethod] = None, + status: typing.Optional[ListApiLogsRequestStatus] = None, + api_key_id: typing.Optional[str] = None, + min_duration_ms: typing.Optional[int] = None, + max_duration_ms: typing.Optional[int] = None, + first: typing.Optional[int] = None, + after: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse]: + """ + Lists the requests served by Whop's API with the account's API keys, newest first — every surface (GraphQL, REST, and native /api/v1), reads and failed requests included. + + Parameters + ---------- + account_id : typing.Optional[str] + The account (biz_*) whose API logs to list. Defaults to the authenticated account. + + created_after : typing.Optional[str] + Only return requests served at or after this ISO 8601 timestamp. Defaults to 7 days before created_before, or 7 days ago. + + created_before : typing.Optional[str] + Only return requests served before this ISO 8601 timestamp. + + operation_name : typing.Optional[str] + Only return requests for this operation, matched exactly against the operation_name shown on each log row (for example api/v1/products#create). + + http_method : typing.Optional[ListApiLogsRequestHttpMethod] + Only return requests made with this HTTP method. + + status : typing.Optional[ListApiLogsRequestStatus] + Only return requests that finished with this status. + + api_key_id : typing.Optional[str] + Only return requests made with this API key (apik_…). + + min_duration_ms : typing.Optional[int] + Only return requests that took at least this many milliseconds. + + max_duration_ms : typing.Optional[int] + Only return requests that took at most this many milliseconds. + + first : typing.Optional[int] + Number of logs to return. + + after : typing.Optional[str] + Cursor to fetch the page after (from page_info.end_cursor). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse] + api logs listed + + Examples + -------- + from whop_sdk import Whop + + client = Whop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + response = client.api_logs.list() + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + account_id=account_id, + created_after=created_after, + created_before=created_before, + operation_name=operation_name, + http_method=http_method, + status=status, + api_key_id=api_key_id, + min_duration_ms=min_duration_ms, + max_duration_ms=max_duration_ms, + first=first, + after=after, + request_options=request_options, + ) + + +class AsyncApiLogsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawApiLogsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawApiLogsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawApiLogsClient + """ + return self._raw_client + + async def list( + self, + *, + account_id: typing.Optional[str] = None, + created_after: typing.Optional[str] = None, + created_before: typing.Optional[str] = None, + operation_name: typing.Optional[str] = None, + http_method: typing.Optional[ListApiLogsRequestHttpMethod] = None, + status: typing.Optional[ListApiLogsRequestStatus] = None, + api_key_id: typing.Optional[str] = None, + min_duration_ms: typing.Optional[int] = None, + max_duration_ms: typing.Optional[int] = None, + first: typing.Optional[int] = None, + after: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse]: + """ + Lists the requests served by Whop's API with the account's API keys, newest first — every surface (GraphQL, REST, and native /api/v1), reads and failed requests included. + + Parameters + ---------- + account_id : typing.Optional[str] + The account (biz_*) whose API logs to list. Defaults to the authenticated account. + + created_after : typing.Optional[str] + Only return requests served at or after this ISO 8601 timestamp. Defaults to 7 days before created_before, or 7 days ago. + + created_before : typing.Optional[str] + Only return requests served before this ISO 8601 timestamp. + + operation_name : typing.Optional[str] + Only return requests for this operation, matched exactly against the operation_name shown on each log row (for example api/v1/products#create). + + http_method : typing.Optional[ListApiLogsRequestHttpMethod] + Only return requests made with this HTTP method. + + status : typing.Optional[ListApiLogsRequestStatus] + Only return requests that finished with this status. + + api_key_id : typing.Optional[str] + Only return requests made with this API key (apik_…). + + min_duration_ms : typing.Optional[int] + Only return requests that took at least this many milliseconds. + + max_duration_ms : typing.Optional[int] + Only return requests that took at most this many milliseconds. + + first : typing.Optional[int] + Number of logs to return. + + after : typing.Optional[str] + Cursor to fetch the page after (from page_info.end_cursor). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse] + api logs listed + + Examples + -------- + import asyncio + + from whop_sdk import AsyncWhop + + client = AsyncWhop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + + + async def main() -> None: + response = await client.api_logs.list() + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + account_id=account_id, + created_after=created_after, + created_before=created_before, + operation_name=operation_name, + http_method=http_method, + status=status, + api_key_id=api_key_id, + min_duration_ms=min_duration_ms, + max_duration_ms=max_duration_ms, + first=first, + after=after, + request_options=request_options, + ) diff --git a/src/whop_sdk/api_logs/raw_client.py b/src/whop_sdk/api_logs/raw_client.py new file mode 100644 index 00000000..38f366d7 --- /dev/null +++ b/src/whop_sdk/api_logs/raw_client.py @@ -0,0 +1,336 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.forbidden_error import ForbiddenError +from ..errors.too_many_requests_error import TooManyRequestsError +from ..errors.unauthorized_error import UnauthorizedError +from .types.list_api_logs_request_http_method import ListApiLogsRequestHttpMethod +from .types.list_api_logs_request_status import ListApiLogsRequestStatus +from .types.list_api_logs_response import ListApiLogsResponse +from .types.list_api_logs_response_data_item import ListApiLogsResponseDataItem +from pydantic import ValidationError + + +class RawApiLogsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + *, + account_id: typing.Optional[str] = None, + created_after: typing.Optional[str] = None, + created_before: typing.Optional[str] = None, + operation_name: typing.Optional[str] = None, + http_method: typing.Optional[ListApiLogsRequestHttpMethod] = None, + status: typing.Optional[ListApiLogsRequestStatus] = None, + api_key_id: typing.Optional[str] = None, + min_duration_ms: typing.Optional[int] = None, + max_duration_ms: typing.Optional[int] = None, + first: typing.Optional[int] = None, + after: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse]: + """ + Lists the requests served by Whop's API with the account's API keys, newest first — every surface (GraphQL, REST, and native /api/v1), reads and failed requests included. + + Parameters + ---------- + account_id : typing.Optional[str] + The account (biz_*) whose API logs to list. Defaults to the authenticated account. + + created_after : typing.Optional[str] + Only return requests served at or after this ISO 8601 timestamp. Defaults to 7 days before created_before, or 7 days ago. + + created_before : typing.Optional[str] + Only return requests served before this ISO 8601 timestamp. + + operation_name : typing.Optional[str] + Only return requests for this operation, matched exactly against the operation_name shown on each log row (for example api/v1/products#create). + + http_method : typing.Optional[ListApiLogsRequestHttpMethod] + Only return requests made with this HTTP method. + + status : typing.Optional[ListApiLogsRequestStatus] + Only return requests that finished with this status. + + api_key_id : typing.Optional[str] + Only return requests made with this API key (apik_…). + + min_duration_ms : typing.Optional[int] + Only return requests that took at least this many milliseconds. + + max_duration_ms : typing.Optional[int] + Only return requests that took at most this many milliseconds. + + first : typing.Optional[int] + Number of logs to return. + + after : typing.Optional[str] + Cursor to fetch the page after (from page_info.end_cursor). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse] + api logs listed + """ + _response = self._client_wrapper.httpx_client.request( + "api_logs", + method="GET", + params={ + "account_id": account_id, + "created_after": created_after, + "created_before": created_before, + "operation_name": operation_name, + "http_method": http_method, + "status": status, + "api_key_id": api_key_id, + "min_duration_ms": min_duration_ms, + "max_duration_ms": max_duration_ms, + "first": first, + "after": after, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListApiLogsResponse, + parse_obj_as( + type_=ListApiLogsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = False + _get_next = None + if _parsed_response.page_info is not None: + _parsed_next = _parsed_response.page_info.end_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + _get_next = lambda: self.list( + account_id=account_id, + created_after=created_after, + created_before=created_before, + operation_name=operation_name, + http_method=http_method, + status=status, + api_key_id=api_key_id, + min_duration_ms=min_duration_ms, + max_duration_ms=max_duration_ms, + first=first, + after=_parsed_next, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawApiLogsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + *, + account_id: typing.Optional[str] = None, + created_after: typing.Optional[str] = None, + created_before: typing.Optional[str] = None, + operation_name: typing.Optional[str] = None, + http_method: typing.Optional[ListApiLogsRequestHttpMethod] = None, + status: typing.Optional[ListApiLogsRequestStatus] = None, + api_key_id: typing.Optional[str] = None, + min_duration_ms: typing.Optional[int] = None, + max_duration_ms: typing.Optional[int] = None, + first: typing.Optional[int] = None, + after: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse]: + """ + Lists the requests served by Whop's API with the account's API keys, newest first — every surface (GraphQL, REST, and native /api/v1), reads and failed requests included. + + Parameters + ---------- + account_id : typing.Optional[str] + The account (biz_*) whose API logs to list. Defaults to the authenticated account. + + created_after : typing.Optional[str] + Only return requests served at or after this ISO 8601 timestamp. Defaults to 7 days before created_before, or 7 days ago. + + created_before : typing.Optional[str] + Only return requests served before this ISO 8601 timestamp. + + operation_name : typing.Optional[str] + Only return requests for this operation, matched exactly against the operation_name shown on each log row (for example api/v1/products#create). + + http_method : typing.Optional[ListApiLogsRequestHttpMethod] + Only return requests made with this HTTP method. + + status : typing.Optional[ListApiLogsRequestStatus] + Only return requests that finished with this status. + + api_key_id : typing.Optional[str] + Only return requests made with this API key (apik_…). + + min_duration_ms : typing.Optional[int] + Only return requests that took at least this many milliseconds. + + max_duration_ms : typing.Optional[int] + Only return requests that took at most this many milliseconds. + + first : typing.Optional[int] + Number of logs to return. + + after : typing.Optional[str] + Cursor to fetch the page after (from page_info.end_cursor). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[ListApiLogsResponseDataItem, ListApiLogsResponse] + api logs listed + """ + _response = await self._client_wrapper.httpx_client.request( + "api_logs", + method="GET", + params={ + "account_id": account_id, + "created_after": created_after, + "created_before": created_before, + "operation_name": operation_name, + "http_method": http_method, + "status": status, + "api_key_id": api_key_id, + "min_duration_ms": min_duration_ms, + "max_duration_ms": max_duration_ms, + "first": first, + "after": after, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListApiLogsResponse, + parse_obj_as( + type_=ListApiLogsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = False + _get_next = None + if _parsed_response.page_info is not None: + _parsed_next = _parsed_response.page_info.end_cursor + _has_next = _parsed_next is not None and _parsed_next != "" + + async def _get_next(): + return await self.list( + account_id=account_id, + created_after=created_after, + created_before=created_before, + operation_name=operation_name, + http_method=http_method, + status=status, + api_key_id=api_key_id, + min_duration_ms=min_duration_ms, + max_duration_ms=max_duration_ms, + first=first, + after=_parsed_next, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/whop_sdk/api_logs/types/__init__.py b/src/whop_sdk/api_logs/types/__init__.py new file mode 100644 index 00000000..4a318958 --- /dev/null +++ b/src/whop_sdk/api_logs/types/__init__.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .list_api_logs_request_http_method import ListApiLogsRequestHttpMethod + from .list_api_logs_request_status import ListApiLogsRequestStatus + from .list_api_logs_response import ListApiLogsResponse + from .list_api_logs_response_data_item import ListApiLogsResponseDataItem + from .list_api_logs_response_data_item_http_method import ListApiLogsResponseDataItemHttpMethod + from .list_api_logs_response_data_item_status import ListApiLogsResponseDataItemStatus + from .list_api_logs_response_page_info import ListApiLogsResponsePageInfo +_dynamic_imports: typing.Dict[str, str] = { + "ListApiLogsRequestHttpMethod": ".list_api_logs_request_http_method", + "ListApiLogsRequestStatus": ".list_api_logs_request_status", + "ListApiLogsResponse": ".list_api_logs_response", + "ListApiLogsResponseDataItem": ".list_api_logs_response_data_item", + "ListApiLogsResponseDataItemHttpMethod": ".list_api_logs_response_data_item_http_method", + "ListApiLogsResponseDataItemStatus": ".list_api_logs_response_data_item_status", + "ListApiLogsResponsePageInfo": ".list_api_logs_response_page_info", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "ListApiLogsRequestHttpMethod", + "ListApiLogsRequestStatus", + "ListApiLogsResponse", + "ListApiLogsResponseDataItem", + "ListApiLogsResponseDataItemHttpMethod", + "ListApiLogsResponseDataItemStatus", + "ListApiLogsResponsePageInfo", +] diff --git a/src/whop_sdk/api_logs/types/list_api_logs_request_http_method.py b/src/whop_sdk/api_logs/types/list_api_logs_request_http_method.py new file mode 100644 index 00000000..7f4c19f3 --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_request_http_method.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListApiLogsRequestHttpMethod = typing.Union[typing.Literal["GET", "POST", "PUT", "PATCH", "DELETE"], typing.Any] diff --git a/src/whop_sdk/api_logs/types/list_api_logs_request_status.py b/src/whop_sdk/api_logs/types/list_api_logs_request_status.py new file mode 100644 index 00000000..a0f8074f --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_request_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListApiLogsRequestStatus = typing.Union[typing.Literal["success", "error"], typing.Any] diff --git a/src/whop_sdk/api_logs/types/list_api_logs_response.py b/src/whop_sdk/api_logs/types/list_api_logs_response.py new file mode 100644 index 00000000..2817fab1 --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .list_api_logs_response_data_item import ListApiLogsResponseDataItem +from .list_api_logs_response_page_info import ListApiLogsResponsePageInfo + + +class ListApiLogsResponse(UniversalBaseModel): + data: typing.List[ListApiLogsResponseDataItem] + page_info: ListApiLogsResponsePageInfo + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/api_logs/types/list_api_logs_response_data_item.py b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item.py new file mode 100644 index 00000000..e12be241 --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .list_api_logs_response_data_item_http_method import ListApiLogsResponseDataItemHttpMethod +from .list_api_logs_response_data_item_status import ListApiLogsResponseDataItemStatus + + +class ListApiLogsResponseDataItem(UniversalBaseModel): + api_key_id: typing.Optional[str] = None + created_at: str + duration_ms: typing.Optional[int] = None + http_method: typing.Optional[ListApiLogsResponseDataItemHttpMethod] = None + http_path: typing.Optional[str] = None + id: str + ip_address: typing.Optional[str] = None + operation_name: typing.Optional[str] = None + resource_id: typing.Optional[str] = None + status: typing.Optional[ListApiLogsResponseDataItemStatus] = None + status_code: typing.Optional[int] = None + user_agent: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_http_method.py b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_http_method.py new file mode 100644 index 00000000..0c94e2cb --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_http_method.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListApiLogsResponseDataItemHttpMethod = typing.Union[ + typing.Literal["GET", "POST", "PUT", "PATCH", "DELETE"], typing.Any +] diff --git a/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_status.py b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_status.py new file mode 100644 index 00000000..18d9d18a --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_response_data_item_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ListApiLogsResponseDataItemStatus = typing.Union[typing.Literal["success", "error"], typing.Any] diff --git a/src/whop_sdk/api_logs/types/list_api_logs_response_page_info.py b/src/whop_sdk/api_logs/types/list_api_logs_response_page_info.py new file mode 100644 index 00000000..4ae0e3a0 --- /dev/null +++ b/src/whop_sdk/api_logs/types/list_api_logs_response_page_info.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class ListApiLogsResponsePageInfo(UniversalBaseModel): + end_cursor: typing.Optional[str] = None + has_next_page: bool + has_previous_page: bool + start_cursor: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/apps/client.py b/src/whop_sdk/apps/client.py index ce1a9da9..782aa9b7 100644 --- a/src/whop_sdk/apps/client.py +++ b/src/whop_sdk/apps/client.py @@ -96,7 +96,7 @@ def list( A search string matched against app names. order : typing.Optional[ListAppsRequestOrder] - The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then apps with a banner image, then by how many apps were created from each app as a template. + The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then by how many businesses created apps from each app as a template. direction : typing.Optional[ListAppsRequestDirection] Sort direction. @@ -723,7 +723,7 @@ async def list( A search string matched against app names. order : typing.Optional[ListAppsRequestOrder] - The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then apps with a banner image, then by how many apps were created from each app as a template. + The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then by how many businesses created apps from each app as a template. direction : typing.Optional[ListAppsRequestDirection] Sort direction. diff --git a/src/whop_sdk/apps/raw_client.py b/src/whop_sdk/apps/raw_client.py index ae4036f4..a470c56b 100644 --- a/src/whop_sdk/apps/raw_client.py +++ b/src/whop_sdk/apps/raw_client.py @@ -102,7 +102,7 @@ def list( A search string matched against app names. order : typing.Optional[ListAppsRequestOrder] - The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then apps with a banner image, then by how many apps were created from each app as a template. + The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then by how many businesses created apps from each app as a template. direction : typing.Optional[ListAppsRequestDirection] Sort direction. @@ -1186,7 +1186,7 @@ async def list( A search string matched against app names. order : typing.Optional[ListAppsRequestOrder] - The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then apps with a banner image, then by how many apps were created from each app as a template. + The field to sort apps by. Defaults to discoverable_at, showing the most recently published apps first. `template_usage` ranks Whop-verified apps first, then by how many businesses created apps from each app as a template. direction : typing.Optional[ListAppsRequestDirection] Sort direction. diff --git a/src/whop_sdk/cards/client.py b/src/whop_sdk/cards/client.py index c606cc0c..50218498 100644 --- a/src/whop_sdk/cards/client.py +++ b/src/whop_sdk/cards/client.py @@ -85,7 +85,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> CreateCardsResponse: """ - Issue a virtual card, or apply for card issuing. + Issue a virtual card, or apply for card issuing. An account with no application files one here and gets back a `202`; call again to issue the card once it is approved. Parameters ---------- @@ -93,7 +93,7 @@ def create( The owning account ID (a biz_ identifier). Provide this or user_id. assigned_user_id : typing.Optional[str] - The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts. + The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts, and whenever a company API key files an account's first card application. name : typing.Optional[str] A display name for the card. @@ -362,7 +362,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> CreateCardsResponse: """ - Issue a virtual card, or apply for card issuing. + Issue a virtual card, or apply for card issuing. An account with no application files one here and gets back a `202`; call again to issue the card once it is approved. Parameters ---------- @@ -370,7 +370,7 @@ async def create( The owning account ID (a biz_ identifier). Provide this or user_id. assigned_user_id : typing.Optional[str] - The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts. + The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts, and whenever a company API key files an account's first card application. name : typing.Optional[str] A display name for the card. diff --git a/src/whop_sdk/cards/raw_client.py b/src/whop_sdk/cards/raw_client.py index 099c88eb..4f146d76 100644 --- a/src/whop_sdk/cards/raw_client.py +++ b/src/whop_sdk/cards/raw_client.py @@ -145,7 +145,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[CreateCardsResponse]: """ - Issue a virtual card, or apply for card issuing. + Issue a virtual card, or apply for card issuing. An account with no application files one here and gets back a `202`; call again to issue the card once it is approved. Parameters ---------- @@ -153,7 +153,7 @@ def create( The owning account ID (a biz_ identifier). Provide this or user_id. assigned_user_id : typing.Optional[str] - The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts. + The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts, and whenever a company API key files an account's first card application. name : typing.Optional[str] A display name for the card. @@ -608,7 +608,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[CreateCardsResponse]: """ - Issue a virtual card, or apply for card issuing. + Issue a virtual card, or apply for card issuing. An account with no application files one here and gets back a `202`; call again to issue the card once it is approved. Parameters ---------- @@ -616,7 +616,7 @@ async def create( The owning account ID (a biz_ identifier). Provide this or user_id. assigned_user_id : typing.Optional[str] - The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts. + The account member (a user_ identifier) to assign the card to. Required for business card issuing accounts, and whenever a company API key files an account's first card application. name : typing.Optional[str] A display name for the card. diff --git a/src/whop_sdk/client.py b/src/whop_sdk/client.py index f06163ce..bfb4bb79 100644 --- a/src/whop_sdk/client.py +++ b/src/whop_sdk/client.py @@ -20,6 +20,7 @@ from .affiliates.client import AffiliatesClient, AsyncAffiliatesClient from .ai_chats.client import AiChatsClient, AsyncAiChatsClient from .api_keys.client import ApiKeysClient, AsyncApiKeysClient + from .api_logs.client import ApiLogsClient, AsyncApiLogsClient from .app_builds.client import AppBuildsClient, AsyncAppBuildsClient from .apps.client import AppsClient, AsyncAppsClient from .audiences.client import AsyncAudiencesClient, AudiencesClient @@ -32,6 +33,7 @@ from .checkout_configurations.client import AsyncCheckoutConfigurationsClient, CheckoutConfigurationsClient from .companies.client import AsyncCompaniesClient, CompaniesClient from .company_token_transactions.client import AsyncCompanyTokenTransactionsClient, CompanyTokenTransactionsClient + from .confirmation_tokens.client import AsyncConfirmationTokensClient, ConfirmationTokensClient from .course_chapters.client import AsyncCourseChaptersClient, CourseChaptersClient from .course_lesson_interactions.client import AsyncCourseLessonInteractionsClient, CourseLessonInteractionsClient from .course_lessons.client import AsyncCourseLessonsClient, CourseLessonsClient @@ -194,6 +196,7 @@ def __init__( self._affiliates: typing.Optional[AffiliatesClient] = None self._ai_chats: typing.Optional[AiChatsClient] = None self._api_keys: typing.Optional[ApiKeysClient] = None + self._api_logs: typing.Optional[ApiLogsClient] = None self._app_builds: typing.Optional[AppBuildsClient] = None self._apps: typing.Optional[AppsClient] = None self._audiences: typing.Optional[AudiencesClient] = None @@ -206,6 +209,7 @@ def __init__( self._checkout_configurations: typing.Optional[CheckoutConfigurationsClient] = None self._companies: typing.Optional[CompaniesClient] = None self._company_token_transactions: typing.Optional[CompanyTokenTransactionsClient] = None + self._confirmation_tokens: typing.Optional[ConfirmationTokensClient] = None self._course_chapters: typing.Optional[CourseChaptersClient] = None self._course_lesson_interactions: typing.Optional[CourseLessonInteractionsClient] = None self._course_lessons: typing.Optional[CourseLessonsClient] = None @@ -345,6 +349,14 @@ def api_keys(self): self._api_keys = ApiKeysClient(client_wrapper=self._client_wrapper) return self._api_keys + @property + def api_logs(self): + if self._api_logs is None: + from .api_logs.client import ApiLogsClient # noqa: E402 + + self._api_logs = ApiLogsClient(client_wrapper=self._client_wrapper) + return self._api_logs + @property def app_builds(self): if self._app_builds is None: @@ -441,6 +453,14 @@ def company_token_transactions(self): self._company_token_transactions = CompanyTokenTransactionsClient(client_wrapper=self._client_wrapper) return self._company_token_transactions + @property + def confirmation_tokens(self): + if self._confirmation_tokens is None: + from .confirmation_tokens.client import ConfirmationTokensClient # noqa: E402 + + self._confirmation_tokens = ConfirmationTokensClient(client_wrapper=self._client_wrapper) + return self._confirmation_tokens + @property def course_chapters(self): if self._course_chapters is None: @@ -1029,6 +1049,7 @@ def __init__( self._affiliates: typing.Optional[AsyncAffiliatesClient] = None self._ai_chats: typing.Optional[AsyncAiChatsClient] = None self._api_keys: typing.Optional[AsyncApiKeysClient] = None + self._api_logs: typing.Optional[AsyncApiLogsClient] = None self._app_builds: typing.Optional[AsyncAppBuildsClient] = None self._apps: typing.Optional[AsyncAppsClient] = None self._audiences: typing.Optional[AsyncAudiencesClient] = None @@ -1041,6 +1062,7 @@ def __init__( self._checkout_configurations: typing.Optional[AsyncCheckoutConfigurationsClient] = None self._companies: typing.Optional[AsyncCompaniesClient] = None self._company_token_transactions: typing.Optional[AsyncCompanyTokenTransactionsClient] = None + self._confirmation_tokens: typing.Optional[AsyncConfirmationTokensClient] = None self._course_chapters: typing.Optional[AsyncCourseChaptersClient] = None self._course_lesson_interactions: typing.Optional[AsyncCourseLessonInteractionsClient] = None self._course_lessons: typing.Optional[AsyncCourseLessonsClient] = None @@ -1180,6 +1202,14 @@ def api_keys(self): self._api_keys = AsyncApiKeysClient(client_wrapper=self._client_wrapper) return self._api_keys + @property + def api_logs(self): + if self._api_logs is None: + from .api_logs.client import AsyncApiLogsClient # noqa: E402 + + self._api_logs = AsyncApiLogsClient(client_wrapper=self._client_wrapper) + return self._api_logs + @property def app_builds(self): if self._app_builds is None: @@ -1276,6 +1306,14 @@ def company_token_transactions(self): self._company_token_transactions = AsyncCompanyTokenTransactionsClient(client_wrapper=self._client_wrapper) return self._company_token_transactions + @property + def confirmation_tokens(self): + if self._confirmation_tokens is None: + from .confirmation_tokens.client import AsyncConfirmationTokensClient # noqa: E402 + + self._confirmation_tokens = AsyncConfirmationTokensClient(client_wrapper=self._client_wrapper) + return self._confirmation_tokens + @property def course_chapters(self): if self._course_chapters is None: diff --git a/src/whop_sdk/confirmation_tokens/__init__.py b/src/whop_sdk/confirmation_tokens/__init__.py new file mode 100644 index 00000000..6a931269 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/__init__.py @@ -0,0 +1,73 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import ( + CreateConfirmationTokensRequestBillingDetails, + CreateConfirmationTokensRequestPaymentMethod, + CreateConfirmationTokensRequestPaymentMethodApplePay, + CreateConfirmationTokensRequestPaymentMethodBalance, + CreateConfirmationTokensRequestPaymentMethodBankDebit, + CreateConfirmationTokensRequestPaymentMethodCard, + CreateConfirmationTokensRequestPaymentMethodCategory, + CreateConfirmationTokensRequestPaymentMethodGooglePay, + CreateConfirmationTokensRequestPaymentMethodPayerDocument, + CreateConfirmationTokensRequestPaymentMethodPayerDocumentType, + CreateConfirmationTokensRequestPaymentMethodSaved, + CreateConfirmationTokensRequestSetupFutureUsage, + ) +_dynamic_imports: typing.Dict[str, str] = { + "CreateConfirmationTokensRequestBillingDetails": ".types", + "CreateConfirmationTokensRequestPaymentMethod": ".types", + "CreateConfirmationTokensRequestPaymentMethodApplePay": ".types", + "CreateConfirmationTokensRequestPaymentMethodBalance": ".types", + "CreateConfirmationTokensRequestPaymentMethodBankDebit": ".types", + "CreateConfirmationTokensRequestPaymentMethodCard": ".types", + "CreateConfirmationTokensRequestPaymentMethodCategory": ".types", + "CreateConfirmationTokensRequestPaymentMethodGooglePay": ".types", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument": ".types", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType": ".types", + "CreateConfirmationTokensRequestPaymentMethodSaved": ".types", + "CreateConfirmationTokensRequestSetupFutureUsage": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "CreateConfirmationTokensRequestBillingDetails", + "CreateConfirmationTokensRequestPaymentMethod", + "CreateConfirmationTokensRequestPaymentMethodApplePay", + "CreateConfirmationTokensRequestPaymentMethodBalance", + "CreateConfirmationTokensRequestPaymentMethodBankDebit", + "CreateConfirmationTokensRequestPaymentMethodCard", + "CreateConfirmationTokensRequestPaymentMethodCategory", + "CreateConfirmationTokensRequestPaymentMethodGooglePay", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType", + "CreateConfirmationTokensRequestPaymentMethodSaved", + "CreateConfirmationTokensRequestSetupFutureUsage", +] diff --git a/src/whop_sdk/confirmation_tokens/client.py b/src/whop_sdk/confirmation_tokens/client.py new file mode 100644 index 00000000..b9f7caae --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/client.py @@ -0,0 +1,322 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.confirmation_token import ConfirmationToken +from .raw_client import AsyncRawConfirmationTokensClient, RawConfirmationTokensClient +from .types.create_confirmation_tokens_request_billing_details import CreateConfirmationTokensRequestBillingDetails +from .types.create_confirmation_tokens_request_payment_method import CreateConfirmationTokensRequestPaymentMethod +from .types.create_confirmation_tokens_request_setup_future_usage import CreateConfirmationTokensRequestSetupFutureUsage + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class ConfirmationTokensClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawConfirmationTokensClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawConfirmationTokensClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawConfirmationTokensClient + """ + return self._raw_client + + def create( + self, + *, + account_id: str, + payment_method: CreateConfirmationTokensRequestPaymentMethod, + billing_details: typing.Optional[CreateConfirmationTokensRequestBillingDetails] = OMIT, + browser_info: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + return_url: typing.Optional[str] = OMIT, + setup_future_usage: typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ConfirmationToken: + """ + Mints a single-use, short-lived confirmation token from what the buyer entered on your collection surface: the payment method payload, billing details, and attested save consent. Public and rate-limited — the account_id in the body scopes the token but does not authenticate. Confirm it with POST /payments from your server. + + Parameters + ---------- + account_id : str + The account (biz_) this token is scoped to — the publishable identity. + + payment_method : CreateConfirmationTokensRequestPaymentMethod + The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + + billing_details : typing.Optional[CreateConfirmationTokensRequestBillingDetails] + Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + + browser_info : typing.Optional[typing.Dict[str, typing.Any]] + Screen/runtime facts from the buyer's browser (platform, screen dimensions, language, ...) used for authentication ceremonies. Header-derived fields are captured server-side. + + return_url : typing.Optional[str] + Where redirect flows send the buyer, carried onto the confirm that consumes this token. + + setup_future_usage : typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] + The save-consent state your surface displayed when the buyer confirmed. Confirm may vault only if attested here. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConfirmationToken + confirmation token created from a card token intent + + Examples + -------- + from whop_sdk import Whop + from whop_sdk.confirmation_tokens import ( + CreateConfirmationTokensRequestBillingDetails, + CreateConfirmationTokensRequestPaymentMethod, + CreateConfirmationTokensRequestPaymentMethodCard, + ) + + client = Whop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + client.confirmation_tokens.create( + account_id="biz_xxxxxxxxxxxxxx", + billing_details=CreateConfirmationTokensRequestBillingDetails( + address={ + "city": "Austin", + "country": "US", + "line1": "123 Main St", + "postal_code": "78701", + }, + email="buyer@example.com", + name="Buyer Name", + ), + payment_method=CreateConfirmationTokensRequestPaymentMethod( + card=CreateConfirmationTokensRequestPaymentMethodCard( + brand="visa", + last4="4242", + token_intent="bt_ti_123", + ), + category="card", + type="card", + ), + setup_future_usage="off_session", + ) + """ + _response = self._raw_client.create( + account_id=account_id, + payment_method=payment_method, + billing_details=billing_details, + browser_info=browser_info, + return_url=return_url, + setup_future_usage=setup_future_usage, + request_options=request_options, + ) + return _response.data + + def retrieve( + self, id: str, *, account_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> ConfirmationToken: + """ + Retrieves a token's display-safe preview — never the underlying payment credential. Public and rate-limited: the account_id query param must match the account the token was minted for. + + Parameters + ---------- + id : str + Confirmation token ID, prefixed `ctok_`. + + account_id : str + The account (biz_) the token was minted for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConfirmationToken + confirmation token retrieved + + Examples + -------- + from whop_sdk import Whop + + client = Whop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + client.confirmation_tokens.retrieve( + id="id", + account_id="account_id", + ) + """ + _response = self._raw_client.retrieve(id, account_id=account_id, request_options=request_options) + return _response.data + + +class AsyncConfirmationTokensClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawConfirmationTokensClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawConfirmationTokensClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawConfirmationTokensClient + """ + return self._raw_client + + async def create( + self, + *, + account_id: str, + payment_method: CreateConfirmationTokensRequestPaymentMethod, + billing_details: typing.Optional[CreateConfirmationTokensRequestBillingDetails] = OMIT, + browser_info: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + return_url: typing.Optional[str] = OMIT, + setup_future_usage: typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ConfirmationToken: + """ + Mints a single-use, short-lived confirmation token from what the buyer entered on your collection surface: the payment method payload, billing details, and attested save consent. Public and rate-limited — the account_id in the body scopes the token but does not authenticate. Confirm it with POST /payments from your server. + + Parameters + ---------- + account_id : str + The account (biz_) this token is scoped to — the publishable identity. + + payment_method : CreateConfirmationTokensRequestPaymentMethod + The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + + billing_details : typing.Optional[CreateConfirmationTokensRequestBillingDetails] + Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + + browser_info : typing.Optional[typing.Dict[str, typing.Any]] + Screen/runtime facts from the buyer's browser (platform, screen dimensions, language, ...) used for authentication ceremonies. Header-derived fields are captured server-side. + + return_url : typing.Optional[str] + Where redirect flows send the buyer, carried onto the confirm that consumes this token. + + setup_future_usage : typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] + The save-consent state your surface displayed when the buyer confirmed. Confirm may vault only if attested here. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConfirmationToken + confirmation token created from a card token intent + + Examples + -------- + import asyncio + + from whop_sdk import AsyncWhop + from whop_sdk.confirmation_tokens import ( + CreateConfirmationTokensRequestBillingDetails, + CreateConfirmationTokensRequestPaymentMethod, + CreateConfirmationTokensRequestPaymentMethodCard, + ) + + client = AsyncWhop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.confirmation_tokens.create( + account_id="biz_xxxxxxxxxxxxxx", + billing_details=CreateConfirmationTokensRequestBillingDetails( + address={ + "city": "Austin", + "country": "US", + "line1": "123 Main St", + "postal_code": "78701", + }, + email="buyer@example.com", + name="Buyer Name", + ), + payment_method=CreateConfirmationTokensRequestPaymentMethod( + card=CreateConfirmationTokensRequestPaymentMethodCard( + brand="visa", + last4="4242", + token_intent="bt_ti_123", + ), + category="card", + type="card", + ), + setup_future_usage="off_session", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create( + account_id=account_id, + payment_method=payment_method, + billing_details=billing_details, + browser_info=browser_info, + return_url=return_url, + setup_future_usage=setup_future_usage, + request_options=request_options, + ) + return _response.data + + async def retrieve( + self, id: str, *, account_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> ConfirmationToken: + """ + Retrieves a token's display-safe preview — never the underlying payment credential. Public and rate-limited: the account_id query param must match the account the token was minted for. + + Parameters + ---------- + id : str + Confirmation token ID, prefixed `ctok_`. + + account_id : str + The account (biz_) the token was minted for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConfirmationToken + confirmation token retrieved + + Examples + -------- + import asyncio + + from whop_sdk import AsyncWhop + + client = AsyncWhop( + "2026-08-25-2", + idempotency_key="YOUR_IDEMPOTENCY_KEY", + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.confirmation_tokens.retrieve( + id="id", + account_id="account_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retrieve(id, account_id=account_id, request_options=request_options) + return _response.data diff --git a/src/whop_sdk/confirmation_tokens/raw_client.py b/src/whop_sdk/confirmation_tokens/raw_client.py new file mode 100644 index 00000000..f568f8b1 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/raw_client.py @@ -0,0 +1,431 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import encode_path_param +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.confirmation_token import ConfirmationToken +from ..types.v1error_response import V1ErrorResponse +from .types.create_confirmation_tokens_request_billing_details import CreateConfirmationTokensRequestBillingDetails +from .types.create_confirmation_tokens_request_payment_method import CreateConfirmationTokensRequestPaymentMethod +from .types.create_confirmation_tokens_request_setup_future_usage import CreateConfirmationTokensRequestSetupFutureUsage +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawConfirmationTokensClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def create( + self, + *, + account_id: str, + payment_method: CreateConfirmationTokensRequestPaymentMethod, + billing_details: typing.Optional[CreateConfirmationTokensRequestBillingDetails] = OMIT, + browser_info: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + return_url: typing.Optional[str] = OMIT, + setup_future_usage: typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ConfirmationToken]: + """ + Mints a single-use, short-lived confirmation token from what the buyer entered on your collection surface: the payment method payload, billing details, and attested save consent. Public and rate-limited — the account_id in the body scopes the token but does not authenticate. Confirm it with POST /payments from your server. + + Parameters + ---------- + account_id : str + The account (biz_) this token is scoped to — the publishable identity. + + payment_method : CreateConfirmationTokensRequestPaymentMethod + The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + + billing_details : typing.Optional[CreateConfirmationTokensRequestBillingDetails] + Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + + browser_info : typing.Optional[typing.Dict[str, typing.Any]] + Screen/runtime facts from the buyer's browser (platform, screen dimensions, language, ...) used for authentication ceremonies. Header-derived fields are captured server-side. + + return_url : typing.Optional[str] + Where redirect flows send the buyer, carried onto the confirm that consumes this token. + + setup_future_usage : typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] + The save-consent state your surface displayed when the buyer confirmed. Confirm may vault only if attested here. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ConfirmationToken] + confirmation token created from a card token intent + """ + _response = self._client_wrapper.httpx_client.request( + "confirmation_tokens", + method="POST", + json={ + "account_id": account_id, + "billing_details": convert_and_respect_annotation_metadata( + object_=billing_details, annotation=CreateConfirmationTokensRequestBillingDetails, direction="write" + ), + "browser_info": browser_info, + "payment_method": convert_and_respect_annotation_metadata( + object_=payment_method, annotation=CreateConfirmationTokensRequestPaymentMethod, direction="write" + ), + "return_url": return_url, + "setup_future_usage": setup_future_usage, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConfirmationToken, + parse_obj_as( + type_=ConfirmationToken, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + V1ErrorResponse, + parse_obj_as( + type_=V1ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retrieve( + self, id: str, *, account_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ConfirmationToken]: + """ + Retrieves a token's display-safe preview — never the underlying payment credential. Public and rate-limited: the account_id query param must match the account the token was minted for. + + Parameters + ---------- + id : str + Confirmation token ID, prefixed `ctok_`. + + account_id : str + The account (biz_) the token was minted for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ConfirmationToken] + confirmation token retrieved + """ + _response = self._client_wrapper.httpx_client.request( + f"confirmation_tokens/{encode_path_param(id)}", + method="GET", + params={ + "account_id": account_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConfirmationToken, + parse_obj_as( + type_=ConfirmationToken, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawConfirmationTokensClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def create( + self, + *, + account_id: str, + payment_method: CreateConfirmationTokensRequestPaymentMethod, + billing_details: typing.Optional[CreateConfirmationTokensRequestBillingDetails] = OMIT, + browser_info: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, + return_url: typing.Optional[str] = OMIT, + setup_future_usage: typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ConfirmationToken]: + """ + Mints a single-use, short-lived confirmation token from what the buyer entered on your collection surface: the payment method payload, billing details, and attested save consent. Public and rate-limited — the account_id in the body scopes the token but does not authenticate. Confirm it with POST /payments from your server. + + Parameters + ---------- + account_id : str + The account (biz_) this token is scoped to — the publishable identity. + + payment_method : CreateConfirmationTokensRequestPaymentMethod + The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + + billing_details : typing.Optional[CreateConfirmationTokensRequestBillingDetails] + Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + + browser_info : typing.Optional[typing.Dict[str, typing.Any]] + Screen/runtime facts from the buyer's browser (platform, screen dimensions, language, ...) used for authentication ceremonies. Header-derived fields are captured server-side. + + return_url : typing.Optional[str] + Where redirect flows send the buyer, carried onto the confirm that consumes this token. + + setup_future_usage : typing.Optional[CreateConfirmationTokensRequestSetupFutureUsage] + The save-consent state your surface displayed when the buyer confirmed. Confirm may vault only if attested here. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ConfirmationToken] + confirmation token created from a card token intent + """ + _response = await self._client_wrapper.httpx_client.request( + "confirmation_tokens", + method="POST", + json={ + "account_id": account_id, + "billing_details": convert_and_respect_annotation_metadata( + object_=billing_details, annotation=CreateConfirmationTokensRequestBillingDetails, direction="write" + ), + "browser_info": browser_info, + "payment_method": convert_and_respect_annotation_metadata( + object_=payment_method, annotation=CreateConfirmationTokensRequestPaymentMethod, direction="write" + ), + "return_url": return_url, + "setup_future_usage": setup_future_usage, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConfirmationToken, + parse_obj_as( + type_=ConfirmationToken, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + V1ErrorResponse, + parse_obj_as( + type_=V1ErrorResponse, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retrieve( + self, id: str, *, account_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ConfirmationToken]: + """ + Retrieves a token's display-safe preview — never the underlying payment credential. Public and rate-limited: the account_id query param must match the account the token was minted for. + + Parameters + ---------- + id : str + Confirmation token ID, prefixed `ctok_`. + + account_id : str + The account (biz_) the token was minted for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ConfirmationToken] + confirmation token retrieved + """ + _response = await self._client_wrapper.httpx_client.request( + f"confirmation_tokens/{encode_path_param(id)}", + method="GET", + params={ + "account_id": account_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConfirmationToken, + parse_obj_as( + type_=ConfirmationToken, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/whop_sdk/confirmation_tokens/types/__init__.py b/src/whop_sdk/confirmation_tokens/types/__init__.py new file mode 100644 index 00000000..d435487d --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/__init__.py @@ -0,0 +1,87 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .create_confirmation_tokens_request_billing_details import CreateConfirmationTokensRequestBillingDetails + from .create_confirmation_tokens_request_payment_method import CreateConfirmationTokensRequestPaymentMethod + from .create_confirmation_tokens_request_payment_method_apple_pay import ( + CreateConfirmationTokensRequestPaymentMethodApplePay, + ) + from .create_confirmation_tokens_request_payment_method_balance import ( + CreateConfirmationTokensRequestPaymentMethodBalance, + ) + from .create_confirmation_tokens_request_payment_method_bank_debit import ( + CreateConfirmationTokensRequestPaymentMethodBankDebit, + ) + from .create_confirmation_tokens_request_payment_method_card import CreateConfirmationTokensRequestPaymentMethodCard + from .create_confirmation_tokens_request_payment_method_category import ( + CreateConfirmationTokensRequestPaymentMethodCategory, + ) + from .create_confirmation_tokens_request_payment_method_google_pay import ( + CreateConfirmationTokensRequestPaymentMethodGooglePay, + ) + from .create_confirmation_tokens_request_payment_method_payer_document import ( + CreateConfirmationTokensRequestPaymentMethodPayerDocument, + ) + from .create_confirmation_tokens_request_payment_method_payer_document_type import ( + CreateConfirmationTokensRequestPaymentMethodPayerDocumentType, + ) + from .create_confirmation_tokens_request_payment_method_saved import ( + CreateConfirmationTokensRequestPaymentMethodSaved, + ) + from .create_confirmation_tokens_request_setup_future_usage import CreateConfirmationTokensRequestSetupFutureUsage +_dynamic_imports: typing.Dict[str, str] = { + "CreateConfirmationTokensRequestBillingDetails": ".create_confirmation_tokens_request_billing_details", + "CreateConfirmationTokensRequestPaymentMethod": ".create_confirmation_tokens_request_payment_method", + "CreateConfirmationTokensRequestPaymentMethodApplePay": ".create_confirmation_tokens_request_payment_method_apple_pay", + "CreateConfirmationTokensRequestPaymentMethodBalance": ".create_confirmation_tokens_request_payment_method_balance", + "CreateConfirmationTokensRequestPaymentMethodBankDebit": ".create_confirmation_tokens_request_payment_method_bank_debit", + "CreateConfirmationTokensRequestPaymentMethodCard": ".create_confirmation_tokens_request_payment_method_card", + "CreateConfirmationTokensRequestPaymentMethodCategory": ".create_confirmation_tokens_request_payment_method_category", + "CreateConfirmationTokensRequestPaymentMethodGooglePay": ".create_confirmation_tokens_request_payment_method_google_pay", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument": ".create_confirmation_tokens_request_payment_method_payer_document", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType": ".create_confirmation_tokens_request_payment_method_payer_document_type", + "CreateConfirmationTokensRequestPaymentMethodSaved": ".create_confirmation_tokens_request_payment_method_saved", + "CreateConfirmationTokensRequestSetupFutureUsage": ".create_confirmation_tokens_request_setup_future_usage", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = [ + "CreateConfirmationTokensRequestBillingDetails", + "CreateConfirmationTokensRequestPaymentMethod", + "CreateConfirmationTokensRequestPaymentMethodApplePay", + "CreateConfirmationTokensRequestPaymentMethodBalance", + "CreateConfirmationTokensRequestPaymentMethodBankDebit", + "CreateConfirmationTokensRequestPaymentMethodCard", + "CreateConfirmationTokensRequestPaymentMethodCategory", + "CreateConfirmationTokensRequestPaymentMethodGooglePay", + "CreateConfirmationTokensRequestPaymentMethodPayerDocument", + "CreateConfirmationTokensRequestPaymentMethodPayerDocumentType", + "CreateConfirmationTokensRequestPaymentMethodSaved", + "CreateConfirmationTokensRequestSetupFutureUsage", +] diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_billing_details.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_billing_details.py new file mode 100644 index 00000000..61823b4a --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_billing_details.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestBillingDetails(UniversalBaseModel): + """ + Billing details collected with the method. `email` is always required; cards additionally require `name` and an address with `line1` and `country`. + """ + + address: typing.Optional[typing.Dict[str, typing.Any]] = None + email: str + name: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method.py new file mode 100644 index 00000000..0b26dca8 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method.py @@ -0,0 +1,88 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .create_confirmation_tokens_request_payment_method_apple_pay import ( + CreateConfirmationTokensRequestPaymentMethodApplePay, +) +from .create_confirmation_tokens_request_payment_method_balance import ( + CreateConfirmationTokensRequestPaymentMethodBalance, +) +from .create_confirmation_tokens_request_payment_method_bank_debit import ( + CreateConfirmationTokensRequestPaymentMethodBankDebit, +) +from .create_confirmation_tokens_request_payment_method_card import CreateConfirmationTokensRequestPaymentMethodCard +from .create_confirmation_tokens_request_payment_method_category import ( + CreateConfirmationTokensRequestPaymentMethodCategory, +) +from .create_confirmation_tokens_request_payment_method_google_pay import ( + CreateConfirmationTokensRequestPaymentMethodGooglePay, +) +from .create_confirmation_tokens_request_payment_method_payer_document import ( + CreateConfirmationTokensRequestPaymentMethodPayerDocument, +) +from .create_confirmation_tokens_request_payment_method_saved import CreateConfirmationTokensRequestPaymentMethodSaved + + +class CreateConfirmationTokensRequestPaymentMethod(UniversalBaseModel): + """ + The collected method: `type` names the payment method, `category` names the payload shape, and the category-keyed object carries the payload. Wallets are the exception: their payload rides the type key (`apple_pay` / `google_pay`). Send exactly the one payload arm the category selects — extra arms are rejected. Redirect-flow methods (category `redirect`, `bank_transfer`, `voucher`, and redirect wallets like `cashapp`) collect nothing and send no payload arm. + """ + + apple_pay: typing.Optional[CreateConfirmationTokensRequestPaymentMethodApplePay] = pydantic.Field(default=None) + """ + Type `apple_pay` (category `wallet`) only. + """ + + balance: typing.Optional[CreateConfirmationTokensRequestPaymentMethodBalance] = pydantic.Field(default=None) + """ + Category `balance` only. Names one of the buyer's spendable platform balances. Requires a buyer credential — whether the caller may spend the wallet is checked against their own grants, so another user's id reads as not found. + """ + + bank_debit: typing.Optional[CreateConfirmationTokensRequestPaymentMethodBankDebit] = pydantic.Field(default=None) + """ + Category `bank_debit` only. A type that declares a secure field (`sepa_debit`) sends the element's tokenized credential as `token`. `us_bank_account` sends nothing here — the buyer links the account after confirm, through the hosted bank-connection flow the payment parks behind. + """ + + card: typing.Optional[CreateConfirmationTokensRequestPaymentMethodCard] = pydantic.Field(default=None) + """ + Category `card` only. Exactly one of `token` or `token_intent`; display fields ride alongside. + """ + + category: CreateConfirmationTokensRequestPaymentMethodCategory = pydantic.Field() + """ + The payload shape the surface collected. Must be the category the type resolves to — it is derived server-side and a mismatch is rejected. `saved` and `balance` are the exceptions: they name a method already on file or a spendable balance rather than one collected here. + """ + + google_pay: typing.Optional[CreateConfirmationTokensRequestPaymentMethodGooglePay] = pydantic.Field(default=None) + """ + Type `google_pay` (category `wallet`) only. + """ + + payer_document: typing.Optional[CreateConfirmationTokensRequestPaymentMethodPayerDocument] = pydantic.Field( + default=None + ) + """ + The buyer's identity document when the charge currency has a payer_document_requirements entry for this method, such as ARS card, MODO, or Rapipago. This is independent of the method category. + """ + + saved: typing.Optional[CreateConfirmationTokensRequestPaymentMethodSaved] = pydantic.Field(default=None) + """ + Category `saved` only. Names one of the buyer's own stored payment methods. Requires a buyer credential — the wallet read is scoped to that account, so another user's id reads as not found. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The payment method type, for example `card` or `ideal`. Required for every category except `saved` and `balance`, where it is read from the referenced method. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_apple_pay.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_apple_pay.py new file mode 100644 index 00000000..c71ccc53 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_apple_pay.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodApplePay(UniversalBaseModel): + """ + Type `apple_pay` (category `wallet`) only. + """ + + merchant_identifier: typing.Optional[str] = pydantic.Field(default=None) + """ + The merchant identifier the Apple Pay sheet validated with — the same hostname-matched value from the type's `merchants` list the session ceremony used. Apple encrypts the wallet token for the certificate attached to this exact identifier, so the charge needs it to decrypt. Omit it when the ceremony omitted it; must be one the account has registered. + """ + + token_intent: str = pydantic.Field() + """ + The Basis Theory token intent the Apple Pay sheet flow vaulted the raw wallet token into. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_balance.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_balance.py new file mode 100644 index 00000000..54d10709 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_balance.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodBalance(UniversalBaseModel): + """ + Category `balance` only. Names one of the buyer's spendable platform balances. Requires a buyer credential — whether the caller may spend the wallet is checked against their own grants, so another user's id reads as not found. + """ + + id: str = pydantic.Field() + """ + The balance to spend — a balance id (ldgr_) from GET /balances. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_bank_debit.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_bank_debit.py new file mode 100644 index 00000000..1883f1a7 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_bank_debit.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodBankDebit(UniversalBaseModel): + """ + Category `bank_debit` only. A type that declares a secure field (`sepa_debit`) sends the element's tokenized credential as `token`. `us_bank_account` sends nothing here — the buyer links the account after confirm, through the hosted bank-connection flow the payment parks behind. + """ + + token: typing.Optional[str] = pydantic.Field(default=None) + """ + The Basis Theory token the element vaulted the account details into. Required for types declaring a secure field; rejected for types that collect after confirm. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_card.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_card.py new file mode 100644 index 00000000..7b28ca2f --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_card.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodCard(UniversalBaseModel): + """ + Category `card` only. Exactly one of `token` or `token_intent`; display fields ride alongside. + """ + + brand: typing.Optional[str] = pydantic.Field(default=None) + """ + Display-safe card brand from the collection surface, e.g. `visa`. + """ + + last4: typing.Optional[str] = pydantic.Field(default=None) + """ + Display-safe last four digits from the collection surface. + """ + + token: typing.Optional[str] = pydantic.Field(default=None) + """ + An element-assembled, expiring Basis Theory token. Provide this or token_intent. + """ + + token_intent: typing.Optional[str] = pydantic.Field(default=None) + """ + A Basis Theory token intent. Provide this or token. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_category.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_category.py new file mode 100644 index 00000000..e2b3fad4 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_category.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateConfirmationTokensRequestPaymentMethodCategory = typing.Union[ + typing.Literal[ + "card", + "wallet", + "bank_debit", + "bank_transfer", + "voucher", + "redirect", + "crypto", + "balance", + "in_app_purchase", + "saved", + ], + typing.Any, +] diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_google_pay.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_google_pay.py new file mode 100644 index 00000000..bf2d706f --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_google_pay.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodGooglePay(UniversalBaseModel): + """ + Type `google_pay` (category `wallet`) only. + """ + + token_intent: str = pydantic.Field() + """ + The Basis Theory token intent the Google Pay sheet flow vaulted the raw wallet token into. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document.py new file mode 100644 index 00000000..a23636b1 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .create_confirmation_tokens_request_payment_method_payer_document_type import ( + CreateConfirmationTokensRequestPaymentMethodPayerDocumentType, +) + + +class CreateConfirmationTokensRequestPaymentMethodPayerDocument(UniversalBaseModel): + """ + The buyer's identity document when the charge currency has a payer_document_requirements entry for this method, such as ARS card, MODO, or Rapipago. This is independent of the method category. + """ + + token: str = pydantic.Field() + """ + The Basis Theory token containing the identity-document number. + """ + + type: CreateConfirmationTokensRequestPaymentMethodPayerDocumentType = pydantic.Field() + """ + The selected identity-document type from the method's payer_document_requirements entry. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document_type.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document_type.py new file mode 100644 index 00000000..177d2c59 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_payer_document_type.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateConfirmationTokensRequestPaymentMethodPayerDocumentType = typing.Union[ + typing.Literal["dni", "cuil", "cuit", "passport", "cc", "ci", "rut", "curp", "rfc"], typing.Any +] diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_saved.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_saved.py new file mode 100644 index 00000000..06a0fcb0 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_payment_method_saved.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CreateConfirmationTokensRequestPaymentMethodSaved(UniversalBaseModel): + """ + Category `saved` only. Names one of the buyer's own stored payment methods. Requires a buyer credential — the wallet read is scoped to that account, so another user's id reads as not found. + """ + + payment_method: str = pydantic.Field() + """ + The stored payment method to charge — a payment method id from GET /payment_methods. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_setup_future_usage.py b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_setup_future_usage.py new file mode 100644 index 00000000..19a32175 --- /dev/null +++ b/src/whop_sdk/confirmation_tokens/types/create_confirmation_tokens_request_setup_future_usage.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateConfirmationTokensRequestSetupFutureUsage = typing.Union[typing.Literal["off_session", "on_session"], typing.Any] diff --git a/src/whop_sdk/events/types/create_events_request_context.py b/src/whop_sdk/events/types/create_events_request_context.py index 69bb6196..762a90cf 100644 --- a/src/whop_sdk/events/types/create_events_request_context.py +++ b/src/whop_sdk/events/types/create_events_request_context.py @@ -96,6 +96,11 @@ class CreateEventsRequestContext(UniversalBaseModel): Reddit click ID. """ + sc: typing.Optional[str] = pydantic.Field(default=None) + """ + Whop SC identifier. + """ + sccid: typing.Optional[str] = pydantic.Field(default=None) """ Snapchat click ID. diff --git a/src/whop_sdk/financial_activity/client.py b/src/whop_sdk/financial_activity/client.py index c8ee66d8..caae0d8c 100644 --- a/src/whop_sdk/financial_activity/client.py +++ b/src/whop_sdk/financial_activity/client.py @@ -40,6 +40,7 @@ def list( ] = None, direction: typing.Optional[ListFinancialActivityRequestDirection] = None, resource_id: typing.Optional[str] = None, + activity_id: typing.Optional[str] = None, currency: typing.Optional[str] = None, posted_after: typing.Optional[dt.datetime] = None, posted_before: typing.Optional[dt.datetime] = None, @@ -75,6 +76,9 @@ def list( resource_id : typing.Optional[str] Optional prefixed resource ID. Returns activity associated with that resource. + activity_id : typing.Optional[str] + Optional ledger activity ID (for example `line_3`). Returns at most that one activity. + currency : typing.Optional[str] Optional currency code filter, for example `usd`. @@ -123,6 +127,7 @@ def list( line_types=line_types, direction=direction, resource_id=resource_id, + activity_id=activity_id, currency=currency, posted_after=posted_after, posted_before=posted_before, @@ -164,6 +169,7 @@ async def list( ] = None, direction: typing.Optional[ListFinancialActivityRequestDirection] = None, resource_id: typing.Optional[str] = None, + activity_id: typing.Optional[str] = None, currency: typing.Optional[str] = None, posted_after: typing.Optional[dt.datetime] = None, posted_before: typing.Optional[dt.datetime] = None, @@ -199,6 +205,9 @@ async def list( resource_id : typing.Optional[str] Optional prefixed resource ID. Returns activity associated with that resource. + activity_id : typing.Optional[str] + Optional ledger activity ID (for example `line_3`). Returns at most that one activity. + currency : typing.Optional[str] Optional currency code filter, for example `usd`. @@ -255,6 +264,7 @@ async def main() -> None: line_types=line_types, direction=direction, resource_id=resource_id, + activity_id=activity_id, currency=currency, posted_after=posted_after, posted_before=posted_before, diff --git a/src/whop_sdk/financial_activity/raw_client.py b/src/whop_sdk/financial_activity/raw_client.py index c5bf5710..4c325ef9 100644 --- a/src/whop_sdk/financial_activity/raw_client.py +++ b/src/whop_sdk/financial_activity/raw_client.py @@ -39,6 +39,7 @@ def list( ] = None, direction: typing.Optional[ListFinancialActivityRequestDirection] = None, resource_id: typing.Optional[str] = None, + activity_id: typing.Optional[str] = None, currency: typing.Optional[str] = None, posted_after: typing.Optional[dt.datetime] = None, posted_before: typing.Optional[dt.datetime] = None, @@ -74,6 +75,9 @@ def list( resource_id : typing.Optional[str] Optional prefixed resource ID. Returns activity associated with that resource. + activity_id : typing.Optional[str] + Optional ledger activity ID (for example `line_3`). Returns at most that one activity. + currency : typing.Optional[str] Optional currency code filter, for example `usd`. @@ -114,6 +118,7 @@ def list( "line_types": line_types, "direction": direction, "resource_id": resource_id, + "activity_id": activity_id, "currency": currency, "posted_after": serialize_datetime(posted_after) if posted_after is not None else None, "posted_before": serialize_datetime(posted_before) if posted_before is not None else None, @@ -206,6 +211,7 @@ async def list( ] = None, direction: typing.Optional[ListFinancialActivityRequestDirection] = None, resource_id: typing.Optional[str] = None, + activity_id: typing.Optional[str] = None, currency: typing.Optional[str] = None, posted_after: typing.Optional[dt.datetime] = None, posted_before: typing.Optional[dt.datetime] = None, @@ -241,6 +247,9 @@ async def list( resource_id : typing.Optional[str] Optional prefixed resource ID. Returns activity associated with that resource. + activity_id : typing.Optional[str] + Optional ledger activity ID (for example `line_3`). Returns at most that one activity. + currency : typing.Optional[str] Optional currency code filter, for example `usd`. @@ -281,6 +290,7 @@ async def list( "line_types": line_types, "direction": direction, "resource_id": resource_id, + "activity_id": activity_id, "currency": currency, "posted_after": serialize_datetime(posted_after) if posted_after is not None else None, "posted_before": serialize_datetime(posted_before) if posted_before is not None else None, diff --git a/src/whop_sdk/members/client.py b/src/whop_sdk/members/client.py index 39fd0287..63b1b091 100644 --- a/src/whop_sdk/members/client.py +++ b/src/whop_sdk/members/client.py @@ -149,7 +149,7 @@ def retrieve(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- Member - member phone falls back to the stamped checkout-collected number + the stamped number outranks the consented account read Examples -------- @@ -315,7 +315,7 @@ async def retrieve(self, id: str, *, request_options: typing.Optional[RequestOpt Returns ------- Member - member phone falls back to the stamped checkout-collected number + the stamped number outranks the consented account read Examples -------- diff --git a/src/whop_sdk/members/raw_client.py b/src/whop_sdk/members/raw_client.py index dfe4d6c9..cef79b02 100644 --- a/src/whop_sdk/members/raw_client.py +++ b/src/whop_sdk/members/raw_client.py @@ -201,7 +201,7 @@ def retrieve(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- HttpResponse[Member] - member phone falls back to the stamped checkout-collected number + the stamped number outranks the consented account read """ _response = self._client_wrapper.httpx_client.request( f"members/{encode_path_param(id)}", @@ -432,7 +432,7 @@ async def retrieve( Returns ------- AsyncHttpResponse[Member] - member phone falls back to the stamped checkout-collected number + the stamped number outranks the consented account read """ _response = await self._client_wrapper.httpx_client.request( f"members/{encode_path_param(id)}", diff --git a/src/whop_sdk/payments/client.py b/src/whop_sdk/payments/client.py index d615f590..3361b7b4 100644 --- a/src/whop_sdk/payments/client.py +++ b/src/whop_sdk/payments/client.py @@ -122,7 +122,7 @@ def list( Filter payments by their current substatus for more granular filtering. include_free : typing.Optional[bool] - Whether to include payments with a zero amount. + Whether to include payments with a zero amount. Defaults to false, so zero-amount payments are omitted unless you set this to true — a company whose sales are all free plans returns an empty list without it. created_before : typing.Optional[dt.datetime] Only return payments created before this timestamp. @@ -212,7 +212,7 @@ def create( self, *, request: CreatePaymentsRequest, request_options: typing.Optional[RequestOptions] = None ) -> CreatePaymentsResponse: """ - Charge an existing member off-session using one of their stored payment methods. You can provide an existing plan, or create a new one in-line. This endpoint will respond with a payment object immediately, but the payment is processed asynchronously in the background. Use webhooks to be notified when the payment succeeds or fails. + Charge a buyer on-session with a `confirmation_token` for the method they selected, or charge an existing member off-session using a stored payment method. You can provide an existing plan or create one inline. The endpoint returns a payment immediately, but processing continues asynchronously. Use webhooks to learn whether it succeeds or fails, and poll the payment's status endpoint for any step the buyer must complete. Required permissions: - `payment:charge` @@ -726,7 +726,7 @@ async def list( Filter payments by their current substatus for more granular filtering. include_free : typing.Optional[bool] - Whether to include payments with a zero amount. + Whether to include payments with a zero amount. Defaults to false, so zero-amount payments are omitted unless you set this to true — a company whose sales are all free plans returns an empty list without it. created_before : typing.Optional[dt.datetime] Only return payments created before this timestamp. @@ -824,7 +824,7 @@ async def create( self, *, request: CreatePaymentsRequest, request_options: typing.Optional[RequestOptions] = None ) -> CreatePaymentsResponse: """ - Charge an existing member off-session using one of their stored payment methods. You can provide an existing plan, or create a new one in-line. This endpoint will respond with a payment object immediately, but the payment is processed asynchronously in the background. Use webhooks to be notified when the payment succeeds or fails. + Charge a buyer on-session with a `confirmation_token` for the method they selected, or charge an existing member off-session using a stored payment method. You can provide an existing plan or create one inline. The endpoint returns a payment immediately, but processing continues asynchronously. Use webhooks to learn whether it succeeds or fails, and poll the payment's status endpoint for any step the buyer must complete. Required permissions: - `payment:charge` diff --git a/src/whop_sdk/payments/raw_client.py b/src/whop_sdk/payments/raw_client.py index eda4e37b..2fb007b8 100644 --- a/src/whop_sdk/payments/raw_client.py +++ b/src/whop_sdk/payments/raw_client.py @@ -128,7 +128,7 @@ def list( Filter payments by their current substatus for more granular filtering. include_free : typing.Optional[bool] - Whether to include payments with a zero amount. + Whether to include payments with a zero amount. Defaults to false, so zero-amount payments are omitted unless you set this to true — a company whose sales are all free plans returns an empty list without it. created_before : typing.Optional[dt.datetime] Only return payments created before this timestamp. @@ -312,7 +312,7 @@ def create( self, *, request: CreatePaymentsRequest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[CreatePaymentsResponse]: """ - Charge an existing member off-session using one of their stored payment methods. You can provide an existing plan, or create a new one in-line. This endpoint will respond with a payment object immediately, but the payment is processed asynchronously in the background. Use webhooks to be notified when the payment succeeds or fails. + Charge a buyer on-session with a `confirmation_token` for the method they selected, or charge an existing member off-session using a stored payment method. You can provide an existing plan or create one inline. The endpoint returns a payment immediately, but processing continues asynchronously. Use webhooks to learn whether it succeeds or fails, and poll the payment's status endpoint for any step the buyer must complete. Required permissions: - `payment:charge` @@ -1472,7 +1472,7 @@ async def list( Filter payments by their current substatus for more granular filtering. include_free : typing.Optional[bool] - Whether to include payments with a zero amount. + Whether to include payments with a zero amount. Defaults to false, so zero-amount payments are omitted unless you set this to true — a company whose sales are all free plans returns an empty list without it. created_before : typing.Optional[dt.datetime] Only return payments created before this timestamp. @@ -1659,7 +1659,7 @@ async def create( self, *, request: CreatePaymentsRequest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[CreatePaymentsResponse]: """ - Charge an existing member off-session using one of their stored payment methods. You can provide an existing plan, or create a new one in-line. This endpoint will respond with a payment object immediately, but the payment is processed asynchronously in the background. Use webhooks to be notified when the payment succeeds or fails. + Charge a buyer on-session with a `confirmation_token` for the method they selected, or charge an existing member off-session using a stored payment method. You can provide an existing plan or create one inline. The endpoint returns a payment immediately, but processing continues asynchronously. Use webhooks to learn whether it succeeds or fails, and poll the payment's status endpoint for any step the buyer must complete. Required permissions: - `payment:charge` diff --git a/src/whop_sdk/payouts/methods/client.py b/src/whop_sdk/payouts/methods/client.py index 3d975d77..e7af187e 100644 --- a/src/whop_sdk/payouts/methods/client.py +++ b/src/whop_sdk/payouts/methods/client.py @@ -225,17 +225,25 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = return _response.data def update( - self, id: str, *, nickname: str, request_options: typing.Optional[RequestOptions] = None + self, + id: str, + *, + is_default: typing.Optional[bool] = OMIT, + nickname: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> UpdateMethodsResponse: """ - Changes the label used to identify a saved payout method. + Changes the label used to identify a saved payout method or makes it the account's default payout method. Parameters ---------- id : str Payout method ID, prefixed `potk_`. - nickname : str + is_default : typing.Optional[bool] + Set to `true` to make this the account's default payout method. `false` is not accepted. + + nickname : typing.Optional[str] New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters. request_options : typing.Optional[RequestOptions] @@ -244,7 +252,7 @@ def update( Returns ------- UpdateMethodsResponse - payout method renamed + payout method updated Examples -------- @@ -257,10 +265,11 @@ def update( ) client.payouts.methods.update( id="id", - nickname="Primary checking", ) """ - _response = self._raw_client.update(id, nickname=nickname, request_options=request_options) + _response = self._raw_client.update( + id, is_default=is_default, nickname=nickname, request_options=request_options + ) return _response.data @@ -499,17 +508,25 @@ async def main() -> None: return _response.data async def update( - self, id: str, *, nickname: str, request_options: typing.Optional[RequestOptions] = None + self, + id: str, + *, + is_default: typing.Optional[bool] = OMIT, + nickname: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> UpdateMethodsResponse: """ - Changes the label used to identify a saved payout method. + Changes the label used to identify a saved payout method or makes it the account's default payout method. Parameters ---------- id : str Payout method ID, prefixed `potk_`. - nickname : str + is_default : typing.Optional[bool] + Set to `true` to make this the account's default payout method. `false` is not accepted. + + nickname : typing.Optional[str] New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters. request_options : typing.Optional[RequestOptions] @@ -518,7 +535,7 @@ async def update( Returns ------- UpdateMethodsResponse - payout method renamed + payout method updated Examples -------- @@ -536,11 +553,12 @@ async def update( async def main() -> None: await client.payouts.methods.update( id="id", - nickname="Primary checking", ) asyncio.run(main()) """ - _response = await self._raw_client.update(id, nickname=nickname, request_options=request_options) + _response = await self._raw_client.update( + id, is_default=is_default, nickname=nickname, request_options=request_options + ) return _response.data diff --git a/src/whop_sdk/payouts/methods/raw_client.py b/src/whop_sdk/payouts/methods/raw_client.py index c2c1040f..98b44677 100644 --- a/src/whop_sdk/payouts/methods/raw_client.py +++ b/src/whop_sdk/payouts/methods/raw_client.py @@ -405,17 +405,25 @@ def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def update( - self, id: str, *, nickname: str, request_options: typing.Optional[RequestOptions] = None + self, + id: str, + *, + is_default: typing.Optional[bool] = OMIT, + nickname: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[UpdateMethodsResponse]: """ - Changes the label used to identify a saved payout method. + Changes the label used to identify a saved payout method or makes it the account's default payout method. Parameters ---------- id : str Payout method ID, prefixed `potk_`. - nickname : str + is_default : typing.Optional[bool] + Set to `true` to make this the account's default payout method. `false` is not accepted. + + nickname : typing.Optional[str] New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters. request_options : typing.Optional[RequestOptions] @@ -424,12 +432,13 @@ def update( Returns ------- HttpResponse[UpdateMethodsResponse] - payout method renamed + payout method updated """ _response = self._client_wrapper.httpx_client.request( f"payouts/methods/{encode_path_param(id)}", method="PATCH", json={ + "is_default": is_default, "nickname": nickname, }, headers={ @@ -881,17 +890,25 @@ async def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def update( - self, id: str, *, nickname: str, request_options: typing.Optional[RequestOptions] = None + self, + id: str, + *, + is_default: typing.Optional[bool] = OMIT, + nickname: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[UpdateMethodsResponse]: """ - Changes the label used to identify a saved payout method. + Changes the label used to identify a saved payout method or makes it the account's default payout method. Parameters ---------- id : str Payout method ID, prefixed `potk_`. - nickname : str + is_default : typing.Optional[bool] + Set to `true` to make this the account's default payout method. `false` is not accepted. + + nickname : typing.Optional[str] New label for the payout method, with at least one non-whitespace character and a maximum of 100 characters. request_options : typing.Optional[RequestOptions] @@ -900,12 +917,13 @@ async def update( Returns ------- AsyncHttpResponse[UpdateMethodsResponse] - payout method renamed + payout method updated """ _response = await self._client_wrapper.httpx_client.request( f"payouts/methods/{encode_path_param(id)}", method="PATCH", json={ + "is_default": is_default, "nickname": nickname, }, headers={ diff --git a/src/whop_sdk/refunds/client.py b/src/whop_sdk/refunds/client.py index 23eb6e47..9b33dc96 100644 --- a/src/whop_sdk/refunds/client.py +++ b/src/whop_sdk/refunds/client.py @@ -64,13 +64,13 @@ def list( Returns the last _n_ elements from the list. payment_id : typing.Optional[str] - Filter refunds to only those associated with this specific payment. + Filter refunds to those associated with this specific payment. Mutually exclusive with company_id and user_id: provide exactly one. company_id : typing.Optional[str] - Filter refunds to only those belonging to this company. + Filter refunds to those belonging to this company. Mutually exclusive with payment_id and user_id: provide exactly one. user_id : typing.Optional[str] - Filter refunds to only those associated with this specific user. + Filter refunds to those associated with this specific user. Mutually exclusive with payment_id and company_id: provide exactly one. Requires a credential belonging to that user; any other credential receives 'You are not authorized'. direction : typing.Optional[Direction] @@ -225,13 +225,13 @@ async def list( Returns the last _n_ elements from the list. payment_id : typing.Optional[str] - Filter refunds to only those associated with this specific payment. + Filter refunds to those associated with this specific payment. Mutually exclusive with company_id and user_id: provide exactly one. company_id : typing.Optional[str] - Filter refunds to only those belonging to this company. + Filter refunds to those belonging to this company. Mutually exclusive with payment_id and user_id: provide exactly one. user_id : typing.Optional[str] - Filter refunds to only those associated with this specific user. + Filter refunds to those associated with this specific user. Mutually exclusive with payment_id and company_id: provide exactly one. Requires a credential belonging to that user; any other credential receives 'You are not authorized'. direction : typing.Optional[Direction] diff --git a/src/whop_sdk/refunds/raw_client.py b/src/whop_sdk/refunds/raw_client.py index 635ad1ee..5c65aea3 100644 --- a/src/whop_sdk/refunds/raw_client.py +++ b/src/whop_sdk/refunds/raw_client.py @@ -67,13 +67,13 @@ def list( Returns the last _n_ elements from the list. payment_id : typing.Optional[str] - Filter refunds to only those associated with this specific payment. + Filter refunds to those associated with this specific payment. Mutually exclusive with company_id and user_id: provide exactly one. company_id : typing.Optional[str] - Filter refunds to only those belonging to this company. + Filter refunds to those belonging to this company. Mutually exclusive with payment_id and user_id: provide exactly one. user_id : typing.Optional[str] - Filter refunds to only those associated with this specific user. + Filter refunds to those associated with this specific user. Mutually exclusive with payment_id and company_id: provide exactly one. Requires a credential belonging to that user; any other credential receives 'You are not authorized'. direction : typing.Optional[Direction] @@ -390,13 +390,13 @@ async def list( Returns the last _n_ elements from the list. payment_id : typing.Optional[str] - Filter refunds to only those associated with this specific payment. + Filter refunds to those associated with this specific payment. Mutually exclusive with company_id and user_id: provide exactly one. company_id : typing.Optional[str] - Filter refunds to only those belonging to this company. + Filter refunds to those belonging to this company. Mutually exclusive with payment_id and user_id: provide exactly one. user_id : typing.Optional[str] - Filter refunds to only those associated with this specific user. + Filter refunds to those associated with this specific user. Mutually exclusive with payment_id and company_id: provide exactly one. Requires a credential belonging to that user; any other credential receives 'You are not authorized'. direction : typing.Optional[Direction] diff --git a/src/whop_sdk/social_accounts/client.py b/src/whop_sdk/social_accounts/client.py index 18cea196..238991bf 100644 --- a/src/whop_sdk/social_accounts/client.py +++ b/src/whop_sdk/social_accounts/client.py @@ -181,8 +181,8 @@ def connect( self, *, platform: ConnectSocialAccountsRequestPlatform, + redirect_url: str, account_id: typing.Optional[str] = OMIT, - redirect_url: typing.Optional[str] = OMIT, scopes: typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ConnectSocialAccountsResponse: @@ -192,16 +192,16 @@ def connect( Parameters ---------- platform : ConnectSocialAccountsRequestPlatform - The platform to connect the social account on. Supported options are `meta_business` and `tiktok`. + The platform to connect the social account on. Use `meta_business` to connect Meta Business assets, which is how Facebook Pages and Instagram accounts are connected — there is no separate `instagram` value. Use `tiktok` for TikTok accounts. + + redirect_url : str + Where to send the user once they finish connecting their accounts. Any `http` or `https` URL. If the connection fails, the user is redirected with a `social_account_error` query param. account_id : typing.Optional[str] The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account. - redirect_url : typing.Optional[str] - The Whop URL to redirect the user to after they finish connecting. - scopes : typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] - Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business or TikTok account for ads. + Capabilities to grant for the connected social account. `advertise` is required for both `meta_business` and `tiktok` connections — it is not conditional on whether you intend to run ads, and omitting it fails the request. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -222,12 +222,13 @@ def connect( ) client.social_accounts.connect( platform="meta_business", + redirect_url="https://example.com/settings/social-accounts", ) """ _response = self._raw_client.connect( platform=platform, - account_id=account_id, redirect_url=redirect_url, + account_id=account_id, scopes=scopes, request_options=request_options, ) @@ -555,8 +556,8 @@ async def connect( self, *, platform: ConnectSocialAccountsRequestPlatform, + redirect_url: str, account_id: typing.Optional[str] = OMIT, - redirect_url: typing.Optional[str] = OMIT, scopes: typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> ConnectSocialAccountsResponse: @@ -566,16 +567,16 @@ async def connect( Parameters ---------- platform : ConnectSocialAccountsRequestPlatform - The platform to connect the social account on. Supported options are `meta_business` and `tiktok`. + The platform to connect the social account on. Use `meta_business` to connect Meta Business assets, which is how Facebook Pages and Instagram accounts are connected — there is no separate `instagram` value. Use `tiktok` for TikTok accounts. + + redirect_url : str + Where to send the user once they finish connecting their accounts. Any `http` or `https` URL. If the connection fails, the user is redirected with a `social_account_error` query param. account_id : typing.Optional[str] The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account. - redirect_url : typing.Optional[str] - The Whop URL to redirect the user to after they finish connecting. - scopes : typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] - Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business or TikTok account for ads. + Capabilities to grant for the connected social account. `advertise` is required for both `meta_business` and `tiktok` connections — it is not conditional on whether you intend to run ads, and omitting it fails the request. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -601,6 +602,7 @@ async def connect( async def main() -> None: await client.social_accounts.connect( platform="meta_business", + redirect_url="https://example.com/settings/social-accounts", ) @@ -608,8 +610,8 @@ async def main() -> None: """ _response = await self._raw_client.connect( platform=platform, - account_id=account_id, redirect_url=redirect_url, + account_id=account_id, scopes=scopes, request_options=request_options, ) diff --git a/src/whop_sdk/social_accounts/raw_client.py b/src/whop_sdk/social_accounts/raw_client.py index b32e2e2f..de7d3415 100644 --- a/src/whop_sdk/social_accounts/raw_client.py +++ b/src/whop_sdk/social_accounts/raw_client.py @@ -279,8 +279,8 @@ def connect( self, *, platform: ConnectSocialAccountsRequestPlatform, + redirect_url: str, account_id: typing.Optional[str] = OMIT, - redirect_url: typing.Optional[str] = OMIT, scopes: typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ConnectSocialAccountsResponse]: @@ -290,16 +290,16 @@ def connect( Parameters ---------- platform : ConnectSocialAccountsRequestPlatform - The platform to connect the social account on. Supported options are `meta_business` and `tiktok`. + The platform to connect the social account on. Use `meta_business` to connect Meta Business assets, which is how Facebook Pages and Instagram accounts are connected — there is no separate `instagram` value. Use `tiktok` for TikTok accounts. + + redirect_url : str + Where to send the user once they finish connecting their accounts. Any `http` or `https` URL. If the connection fails, the user is redirected with a `social_account_error` query param. account_id : typing.Optional[str] The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account. - redirect_url : typing.Optional[str] - The Whop URL to redirect the user to after they finish connecting. - scopes : typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] - Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business or TikTok account for ads. + Capabilities to grant for the connected social account. `advertise` is required for both `meta_business` and `tiktok` connections — it is not conditional on whether you intend to run ads, and omitting it fails the request. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -932,8 +932,8 @@ async def connect( self, *, platform: ConnectSocialAccountsRequestPlatform, + redirect_url: str, account_id: typing.Optional[str] = OMIT, - redirect_url: typing.Optional[str] = OMIT, scopes: typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ConnectSocialAccountsResponse]: @@ -943,16 +943,16 @@ async def connect( Parameters ---------- platform : ConnectSocialAccountsRequestPlatform - The platform to connect the social account on. Supported options are `meta_business` and `tiktok`. + The platform to connect the social account on. Use `meta_business` to connect Meta Business assets, which is how Facebook Pages and Instagram accounts are connected — there is no separate `instagram` value. Use `tiktok` for TikTok accounts. + + redirect_url : str + Where to send the user once they finish connecting their accounts. Any `http` or `https` URL. If the connection fails, the user is redirected with a `social_account_error` query param. account_id : typing.Optional[str] The Account (biz_ identifier) to connect the social account for. An account-scoped API key may omit this to default to its own account. - redirect_url : typing.Optional[str] - The Whop URL to redirect the user to after they finish connecting. - scopes : typing.Optional[typing.Sequence[ConnectSocialAccountsRequestScopesItem]] - Capabilities to grant for the connected social account. Use `advertise` when connecting a Meta Business or TikTok account for ads. + Capabilities to grant for the connected social account. `advertise` is required for both `meta_business` and `tiktok` connections — it is not conditional on whether you intend to run ads, and omitting it fails the request. request_options : typing.Optional[RequestOptions] Request-specific configuration. diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py index cac4d660..6d1906f7 100644 --- a/src/whop_sdk/types/__init__.py +++ b/src/whop_sdk/types/__init__.py @@ -333,6 +333,8 @@ from .company_token_transaction_member import CompanyTokenTransactionMember from .company_token_transaction_types import CompanyTokenTransactionTypes from .company_token_transaction_user import CompanyTokenTransactionUser + from .confirmation_token import ConfirmationToken + from .confirmation_token_status import ConfirmationTokenStatus from .conversion_event import ConversionEvent from .conversion_event_zero import ConversionEventZero from .countries import Countries @@ -623,7 +625,6 @@ from .member_statuses import MemberStatuses from .members_sortable_columns import MembersSortableColumns from .membership import Membership - from .membership_account import MembershipAccount from .membership_cancellation_modes import MembershipCancellationModes from .membership_list_item import MembershipListItem from .membership_list_item_company import MembershipListItemCompany @@ -677,9 +678,11 @@ from .payment_bank_transfer import PaymentBankTransfer from .payment_bank_transfer_instructions import PaymentBankTransferInstructions from .payment_billing_address import PaymentBillingAddress + from .payment_billing_details_preview import PaymentBillingDetailsPreview from .payment_company import PaymentCompany from .payment_decline_codes import PaymentDeclineCodes from .payment_disputes_item import PaymentDisputesItem + from .payment_fees_item import PaymentFeesItem from .payment_financing_transactions_item import PaymentFinancingTransactionsItem from .payment_instructions import ( PaymentInstructions, @@ -757,6 +760,9 @@ from .payment_method_cashapp_payment_method_icons_square_light import ( PaymentMethodCashappPaymentMethodIconsSquareLight, ) + from .payment_method_display import PaymentMethodDisplay + from .payment_method_display_category import PaymentMethodDisplayCategory + from .payment_method_display_preview import PaymentMethodDisplayPreview from .payment_method_domain import PaymentMethodDomain from .payment_method_domain_provider import PaymentMethodDomainProvider from .payment_method_domain_status import PaymentMethodDomainStatus @@ -1555,6 +1561,8 @@ "CompanyTokenTransactionMember": ".company_token_transaction_member", "CompanyTokenTransactionTypes": ".company_token_transaction_types", "CompanyTokenTransactionUser": ".company_token_transaction_user", + "ConfirmationToken": ".confirmation_token", + "ConfirmationTokenStatus": ".confirmation_token_status", "ConversionEvent": ".conversion_event", "ConversionEventZero": ".conversion_event_zero", "Countries": ".countries", @@ -1831,7 +1839,6 @@ "MemberStatuses": ".member_statuses", "MembersSortableColumns": ".members_sortable_columns", "Membership": ".membership", - "MembershipAccount": ".membership_account", "MembershipCancellationModes": ".membership_cancellation_modes", "MembershipListItem": ".membership_list_item", "MembershipListItemCompany": ".membership_list_item_company", @@ -1885,9 +1892,11 @@ "PaymentBankTransfer": ".payment_bank_transfer", "PaymentBankTransferInstructions": ".payment_bank_transfer_instructions", "PaymentBillingAddress": ".payment_billing_address", + "PaymentBillingDetailsPreview": ".payment_billing_details_preview", "PaymentCompany": ".payment_company", "PaymentDeclineCodes": ".payment_decline_codes", "PaymentDisputesItem": ".payment_disputes_item", + "PaymentFeesItem": ".payment_fees_item", "PaymentFinancingTransactionsItem": ".payment_financing_transactions_item", "PaymentInstructions": ".payment_instructions", "PaymentInstructions_BankTransfer": ".payment_instructions", @@ -1949,6 +1958,9 @@ "PaymentMethodCashappPaymentMethodIconsSquare": ".payment_method_cashapp_payment_method_icons_square", "PaymentMethodCashappPaymentMethodIconsSquareDark": ".payment_method_cashapp_payment_method_icons_square_dark", "PaymentMethodCashappPaymentMethodIconsSquareLight": ".payment_method_cashapp_payment_method_icons_square_light", + "PaymentMethodDisplay": ".payment_method_display", + "PaymentMethodDisplayCategory": ".payment_method_display_category", + "PaymentMethodDisplayPreview": ".payment_method_display_preview", "PaymentMethodDomain": ".payment_method_domain", "PaymentMethodDomainProvider": ".payment_method_domain_provider", "PaymentMethodDomainStatus": ".payment_method_domain_status", @@ -2671,6 +2683,8 @@ def __dir__(): "CompanyTokenTransactionMember", "CompanyTokenTransactionTypes", "CompanyTokenTransactionUser", + "ConfirmationToken", + "ConfirmationTokenStatus", "ConversionEvent", "ConversionEventZero", "Countries", @@ -2947,7 +2961,6 @@ def __dir__(): "MemberStatuses", "MembersSortableColumns", "Membership", - "MembershipAccount", "MembershipCancellationModes", "MembershipListItem", "MembershipListItemCompany", @@ -3001,9 +3014,11 @@ def __dir__(): "PaymentBankTransfer", "PaymentBankTransferInstructions", "PaymentBillingAddress", + "PaymentBillingDetailsPreview", "PaymentCompany", "PaymentDeclineCodes", "PaymentDisputesItem", + "PaymentFeesItem", "PaymentFinancingTransactionsItem", "PaymentInstructions", "PaymentInstructions_BankTransfer", @@ -3065,6 +3080,9 @@ def __dir__(): "PaymentMethodCashappPaymentMethodIconsSquare", "PaymentMethodCashappPaymentMethodIconsSquareDark", "PaymentMethodCashappPaymentMethodIconsSquareLight", + "PaymentMethodDisplay", + "PaymentMethodDisplayCategory", + "PaymentMethodDisplayPreview", "PaymentMethodDomain", "PaymentMethodDomainProvider", "PaymentMethodDomainStatus", diff --git a/src/whop_sdk/types/account.py b/src/whop_sdk/types/account.py index 31b0c9f2..41e90b04 100644 --- a/src/whop_sdk/types/account.py +++ b/src/whop_sdk/types/account.py @@ -238,12 +238,12 @@ class Account(UniversalBaseModel): status: typing.Optional[str] = pydantic.Field(default=None) """ - Whether the account can operate on Whop: `active` or `suspended`. Computed on `list`, `retrieve`, and `me`; `null` otherwise. + Whether the account can operate on Whop: `active` or `suspended`. Computed on `list`, `retrieve`, `me`, and `suspend`; `null` otherwise. """ status_reason: typing.Optional[str] = pydantic.Field(default=None) """ - Why the account was suspended, in language safe to show the account owner. Computed only on `retrieve` and `me`; `null` otherwise, when `status` is not `suspended`, and when the suspension was recorded without a reason. + Why the account was suspended, in language safe to show the account owner. Computed on `retrieve`, `me`, and `suspend`; `null` otherwise, when `status` is not `suspended`, and when the suspension was recorded without a reason. """ store_page_config: AccountStorePageConfig = pydantic.Field() diff --git a/src/whop_sdk/types/bounty.py b/src/whop_sdk/types/bounty.py index 790a1b67..de55e5f1 100644 --- a/src/whop_sdk/types/bounty.py +++ b/src/whop_sdk/types/bounty.py @@ -130,6 +130,11 @@ class Bounty(UniversalBaseModel): Bounty ID, prefixed `bnty_`. """ + min_total_verified_duration_seconds: typing.Optional[int] = pydantic.Field(default=None) + """ + Total verified footage a submission must accumulate before it can be submitted, in seconds. Always a whole number of hours. Present only on `data_capture` bounties — it is what `net_reward_amount` pays for, so rate displays divide by it. `null` for every other goal type. + """ + net_reward_amount: float = pydantic.Field() """ What a worker is quoted per accepted submission after the platform fee, in whole currency units. The exact post-fee figure, at the standard platform fee rate — a worker who locked a different rate, or who arrived through an affiliate link, is paid a different amount. diff --git a/src/whop_sdk/types/bounty_list_item.py b/src/whop_sdk/types/bounty_list_item.py index efed7661..fdcb0c78 100644 --- a/src/whop_sdk/types/bounty_list_item.py +++ b/src/whop_sdk/types/bounty_list_item.py @@ -111,6 +111,11 @@ class BountyListItem(UniversalBaseModel): Bounty ID, prefixed `bnty_`. """ + min_total_verified_duration_seconds: typing.Optional[int] = pydantic.Field(default=None) + """ + Total verified footage a submission must accumulate before it can be submitted, in seconds. Always a whole number of hours. Present only on `data_capture` bounties — it is what `net_reward_amount` pays for, so rate displays divide by it. `null` for every other goal type. + """ + net_reward_amount: float = pydantic.Field() """ What a worker is quoted per accepted submission after the platform fee, in whole currency units. The exact post-fee figure, at the standard platform fee rate — a worker who locked a different rate, or who arrived through an affiliate link, is paid a different amount. diff --git a/src/whop_sdk/types/confirmation_token.py b/src/whop_sdk/types/confirmation_token.py new file mode 100644 index 00000000..c77386e3 --- /dev/null +++ b/src/whop_sdk/types/confirmation_token.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .confirmation_token_status import ConfirmationTokenStatus +from .payment_billing_details_preview import PaymentBillingDetailsPreview +from .payment_method_display import PaymentMethodDisplay + + +class ConfirmationToken(UniversalBaseModel): + billing_details: typing.Optional[PaymentBillingDetailsPreview] = pydantic.Field(default=None) + """ + Enough of the billing details to raise a customer record and recognise the method — email, name, country and postal code. The street address is collected for the charge but never returned; this endpoint is a display-safe preview. + """ + + created_at: str = pydantic.Field() + """ + When the token was created, as an ISO 8601 timestamp. + """ + + expires_at: str = pydantic.Field() + """ + When the token expires, as an ISO 8601 timestamp. Tokens are single-use and short-lived. + """ + + id: str + object: str = pydantic.Field() + """ + Always `confirmation_token`. + """ + + payment_method_preview: PaymentMethodDisplay = pydantic.Field() + """ + Display-only preview of the collected method — never the underlying token. + """ + + setup_future_usage: typing.Optional[str] = pydantic.Field(default=None) + """ + Save-consent state the element displayed at collection: `off_session`, `on_session`, or `null`. Confirm may vault only if attested here. + """ + + status: ConfirmationTokenStatus = pydantic.Field() + """ + `pending` until it is used, then `consumed`; `expired` once its short lifetime elapses. Only a `pending` token can be charged. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/types/confirmation_token_status.py b/src/whop_sdk/types/confirmation_token_status.py new file mode 100644 index 00000000..5872dd54 --- /dev/null +++ b/src/whop_sdk/types/confirmation_token_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ConfirmationTokenStatus = typing.Union[typing.Literal["pending", "consumed", "expired"], typing.Any] diff --git a/src/whop_sdk/types/membership.py b/src/whop_sdk/types/membership.py index 41986bae..2143bf29 100644 --- a/src/whop_sdk/types/membership.py +++ b/src/whop_sdk/types/membership.py @@ -4,13 +4,13 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .membership_account import MembershipAccount from .membership_member import MembershipMember from .membership_status import MembershipStatus +from .storefront_account import StorefrontAccount class Membership(UniversalBaseModel): - account: MembershipAccount = pydantic.Field() + account: StorefrontAccount = pydantic.Field() """ The account (seller) this membership belongs to. """ diff --git a/src/whop_sdk/types/payment.py b/src/whop_sdk/types/payment.py index 545d8c65..2b2f4978 100644 --- a/src/whop_sdk/types/payment.py +++ b/src/whop_sdk/types/payment.py @@ -14,6 +14,7 @@ from .payment_company import PaymentCompany from .payment_decline_codes import PaymentDeclineCodes from .payment_disputes_item import PaymentDisputesItem +from .payment_fees_item import PaymentFeesItem from .payment_financing_transactions_item import PaymentFinancingTransactionsItem from .payment_member import PaymentMember from .payment_membership import PaymentMembership @@ -128,6 +129,11 @@ class Payment(UniversalBaseModel): If the payment failed, the reason for the failure. """ + fees: typing.List[PaymentFeesItem] = pydantic.Field() + """ + The fees associated with this specific payment. + """ + financing_installments_count: typing.Optional[int] = pydantic.Field(default=None) """ The number of financing installments for the payment. Present if the payment is a financing payment (e.g. Splitit, Klarna, etc.). diff --git a/src/whop_sdk/types/payment_billing_details_preview.py b/src/whop_sdk/types/payment_billing_details_preview.py new file mode 100644 index 00000000..7b160313 --- /dev/null +++ b/src/whop_sdk/types/payment_billing_details_preview.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class PaymentBillingDetailsPreview(UniversalBaseModel): + country: typing.Optional[str] = pydantic.Field(default=None) + """ + ISO 3166-1 alpha-2 country code. + """ + + email: typing.Optional[str] = pydantic.Field(default=None) + """ + Email supplied when the method was collected. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name on the payment method. + """ + + postal_code: typing.Optional[str] = pydantic.Field(default=None) + """ + Postal or ZIP code. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/types/payment_fees_item.py b/src/whop_sdk/types/payment_fees_item.py new file mode 100644 index 00000000..becb0a82 --- /dev/null +++ b/src/whop_sdk/types/payment_fees_item.py @@ -0,0 +1,43 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .currencies import Currencies +from .specific_fee_origins import SpecificFeeOrigins + + +class PaymentFeesItem(UniversalBaseModel): + """ + Represents a fee related to a payment + """ + + amount: float = pydantic.Field() + """ + The value or amount to display for the fee. + """ + + currency: Currencies = pydantic.Field() + """ + The currency of the fee. + """ + + name: str = pydantic.Field() + """ + The label to display for the fee. + """ + + type: SpecificFeeOrigins = pydantic.Field() + """ + The specific origin of the fee, if applicable. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/types/payment_method_display.py b/src/whop_sdk/types/payment_method_display.py new file mode 100644 index 00000000..103610e3 --- /dev/null +++ b/src/whop_sdk/types/payment_method_display.py @@ -0,0 +1,59 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .payment_method_display_category import PaymentMethodDisplayCategory +from .payment_method_display_preview import PaymentMethodDisplayPreview + + +class PaymentMethodDisplay(UniversalBaseModel): + bank_debit: typing.Optional[PaymentMethodDisplayPreview] = pydantic.Field(default=None) + """ + Present when the category is `bank_debit`. Carries the account's last four when the linking provider surfaced it. + """ + + card: typing.Optional[PaymentMethodDisplayPreview] = pydantic.Field(default=None) + """ + Present when the category is `card`. What the collection surface displayed — the token has not been charged, so this is the buyer's claim, not the vault's record. + """ + + category: PaymentMethodDisplayCategory = pydantic.Field() + """ + The family the type belongs to. + """ + + display_name: str = pydantic.Field() + """ + Human-readable label for the method, e.g. `Visa •••• 4242`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The saved payment method this preview came from, or `null` when the buyer supplied a new one. + """ + + saved: typing.Optional[PaymentMethodDisplayPreview] = pydantic.Field(default=None) + """ + Present when the category is `saved` and the stored method is a card. Unlike the other previews this is the vault's own record, not a claim from the collection surface. Absent for a balance, which has no instrument. + """ + + type: str = pydantic.Field() + """ + The payment method type, e.g. `card`, `apple_pay`, `klarna`. + """ + + wallet: typing.Optional[PaymentMethodDisplayPreview] = pydantic.Field(default=None) + """ + Present when the category is `wallet`. Carries the backing card's brand and last four when the wallet surfaced them. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/whop_sdk/types/payment_method_display_category.py b/src/whop_sdk/types/payment_method_display_category.py new file mode 100644 index 00000000..a14d5f12 --- /dev/null +++ b/src/whop_sdk/types/payment_method_display_category.py @@ -0,0 +1,19 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PaymentMethodDisplayCategory = typing.Union[ + typing.Literal[ + "card", + "wallet", + "bank_debit", + "bank_transfer", + "voucher", + "redirect", + "crypto", + "balance", + "in_app_purchase", + "saved", + ], + typing.Any, +] diff --git a/src/whop_sdk/types/membership_account.py b/src/whop_sdk/types/payment_method_display_preview.py similarity index 54% rename from src/whop_sdk/types/membership_account.py rename to src/whop_sdk/types/payment_method_display_preview.py index af668155..8704e1ea 100644 --- a/src/whop_sdk/types/membership_account.py +++ b/src/whop_sdk/types/payment_method_display_preview.py @@ -6,25 +6,15 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class MembershipAccount(UniversalBaseModel): - id: str = pydantic.Field() +class PaymentMethodDisplayPreview(UniversalBaseModel): + brand: typing.Optional[str] = pydantic.Field(default=None) """ - Account ID, prefixed `biz_`. + Lowercase card brand, e.g. `visa`. Absent when the method carries no brand. """ - logo_url: typing.Optional[str] = pydantic.Field(default=None) + last4: typing.Optional[str] = pydantic.Field(default=None) """ - Account logo image URL. - """ - - route: str = pydantic.Field() - """ - Account public route identifier — the `whop.com/{route}` storefront path. - """ - - title: str = pydantic.Field() - """ - Account display name. + Last four digits of the instrument. Absent when the method carries none. """ if IS_PYDANTIC_V2: diff --git a/src/whop_sdk/types/payment_method_types.py b/src/whop_sdk/types/payment_method_types.py index 74e65b6d..c221741b 100644 --- a/src/whop_sdk/types/payment_method_types.py +++ b/src/whop_sdk/types/payment_method_types.py @@ -41,7 +41,9 @@ "eps", "eu_bank_transfer", "fpx", + "flex_pay", "gb_bank_transfer", + "gcash", "giropay", "google_pay", "gopay", diff --git a/src/whop_sdk/types/payment_providers.py b/src/whop_sdk/types/payment_providers.py index 206d009b..213b86ed 100644 --- a/src/whop_sdk/types/payment_providers.py +++ b/src/whop_sdk/types/payment_providers.py @@ -14,6 +14,7 @@ "multi_psp", "adyen", "claritypay", + "flex_pay", "checkout_dot_com", "airwallex", "coinflow", diff --git a/src/whop_sdk/types/permission_action.py b/src/whop_sdk/types/permission_action.py index 2adcf3a6..0d77c25c 100644 --- a/src/whop_sdk/types/permission_action.py +++ b/src/whop_sdk/types/permission_action.py @@ -73,6 +73,7 @@ "company:transfer_ownership", "company:create", "company:create_child", + "company:suspend_child", "company:delete", "company:delete_child", "company:update_child_fees", diff --git a/src/whop_sdk/types/storefront_account.py b/src/whop_sdk/types/storefront_account.py index b1acb65a..088b3bd1 100644 --- a/src/whop_sdk/types/storefront_account.py +++ b/src/whop_sdk/types/storefront_account.py @@ -12,6 +12,11 @@ class StorefrontAccount(UniversalBaseModel): Account ID, prefixed `biz_`. """ + logo_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Account logo image URL. `null` when the account has not set one. + """ + route: str = pydantic.Field() """ Account public route identifier — the `whop.com/{route}` storefront path. From 010c812b9881aca16a6aba5fe022793f2256146a Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 18:19:58 +0000 Subject: [PATCH 2/2] [fern-replay] advance lockfile --- .fern/replay.lock | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.fern/replay.lock b/.fern/replay.lock index 78d5b701..b6f137b7 100644 --- a/.fern/replay.lock +++ b/.fern/replay.lock @@ -54,5 +54,11 @@ generations: cli_version: unknown generator_versions: fernapi/fern-python-sdk: 5.28.0 -current_generation: 615e77c5e680abbf32599eb1dbd5d1f7c2cccbb1 + - commit_sha: 7455c12e8e11b1d9a1ff89ba52cb2015c637979e + tree_hash: 3904631a2930f5d65c46bfecc12968ed5beb6cc0 + timestamp: 2026-08-31T18:19:55.092Z + cli_version: unknown + generator_versions: + fernapi/fern-python-sdk: 5.28.0 +current_generation: 7455c12e8e11b1d9a1ff89ba52cb2015c637979e patches: []