diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7234cce..ba9deff 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,7 +19,7 @@ jobs:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/whopsdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
@@ -38,7 +38,7 @@ jobs:
run: ./scripts/lint
build:
- if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
+ if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
timeout-minutes: 10
name: build
permissions:
diff --git a/.gitignore b/.gitignore
index 95ceb18..3824f4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.prism.log
+.stdy.log
_dev
__pycache__
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 9682ed8..cacb3a0 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.0.35"
+ ".": "0.0.36"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index c2e464b..32314d6 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 191
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-97e920db587b07c064bef1bf31de5e110a3750ddfddc8fca26642e79e6b827f8.yml
-openapi_spec_hash: 97ca16cc55271602443a4329d1e02895
-config_hash: 1a836d20bb988f001cc66d1526f71306
+configured_endpoints: 193
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/frostedinc%2Fwhopsdk-876b65a7e83beed2ddf0d639f3df62f98d4da76d26724730d8ae49ba87855b0e.yml
+openapi_spec_hash: 0512773c97cda918c1017f3b972bff0c
+config_hash: fee5c8b2e5f00cef705ad48c3f3b5b5a
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c02743..7cb411b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,44 @@
# Changelog
+## 0.0.36 (2026-04-07)
+
+Full Changelog: [v0.0.35...v0.0.36](https://github.com/whopio/whopsdk-python/compare/v0.0.35...v0.0.36)
+
+### Features
+
+* **api:** api update ([dfd2e5b](https://github.com/whopio/whopsdk-python/commit/dfd2e5b1fde74bf5d93fa8195e3aa7610c8349e6))
+* **api:** api update ([c2694e3](https://github.com/whopio/whopsdk-python/commit/c2694e3e189f52f64006c5b2503b901f31fcfe71))
+* **api:** api update ([82f0234](https://github.com/whopio/whopsdk-python/commit/82f02347c686891b5ffaeacd7cd84b9bc0a314d8))
+* **api:** api update ([6aa464e](https://github.com/whopio/whopsdk-python/commit/6aa464e34ab3d27134a66157a4ca0ef4d20b810a))
+* **api:** api update ([c7b5425](https://github.com/whopio/whopsdk-python/commit/c7b5425e8257162625fd6db79079953247a05d90))
+* **api:** api update ([6ac4297](https://github.com/whopio/whopsdk-python/commit/6ac4297d8b69e3f8209c69786f7017dd10913053))
+* **api:** api update ([e733ac9](https://github.com/whopio/whopsdk-python/commit/e733ac94f3c0f71876b46145c325e597c9569541))
+* **api:** api update ([82ba7a3](https://github.com/whopio/whopsdk-python/commit/82ba7a3c12417e18a6408a32eb2c4bf160e94768))
+* **api:** api update ([10c00d9](https://github.com/whopio/whopsdk-python/commit/10c00d9e1c45709469a36ea63c624b04fa312e58))
+* **api:** api update ([91ad304](https://github.com/whopio/whopsdk-python/commit/91ad304ea92ca8916afd9e6abb17d463b1b81b58))
+* **api:** api update ([881d399](https://github.com/whopio/whopsdk-python/commit/881d399d3b01938fd43252b435935798bd3171f7))
+* **api:** api update ([cea4dc2](https://github.com/whopio/whopsdk-python/commit/cea4dc2006ad8a1819e93fa2632edc511ab9731c))
+* **api:** api update ([349533c](https://github.com/whopio/whopsdk-python/commit/349533cc0cdb665e00d6ca104292b8cf9ae4d0d0))
+* **api:** api update ([a6443ea](https://github.com/whopio/whopsdk-python/commit/a6443ea4697c674dc80a9877fd9c531a6b688d73))
+* **api:** api update ([8f4b022](https://github.com/whopio/whopsdk-python/commit/8f4b022372bee1a75d74e83334431e030ee02496))
+* **api:** api update ([f4459b0](https://github.com/whopio/whopsdk-python/commit/f4459b0d9fa3d7e4e01db71c29611d98099dfadf))
+* **api:** api update ([a391cfc](https://github.com/whopio/whopsdk-python/commit/a391cfca3a11e21d4ac80518369b44f8f6f9ee2f))
+* **api:** api update ([021294e](https://github.com/whopio/whopsdk-python/commit/021294ecc577e24f56839d852bc978b839feb7fe))
+* **api:** manual updates ([014b6bb](https://github.com/whopio/whopsdk-python/commit/014b6bba88788acb14ce8240388b8712209f66fa))
+* **internal:** implement indices array format for query and form serialization ([e8bc1d6](https://github.com/whopio/whopsdk-python/commit/e8bc1d6948d253c722be8ea0802e8187165f4a0d))
+
+
+### Bug Fixes
+
+* add missing import and response wrappers for add_free_days method ([6f857b2](https://github.com/whopio/whopsdk-python/commit/6f857b22e4db5b371779e0759ddbd82752a0acc9))
+* sanitize endpoint path params ([ca495f7](https://github.com/whopio/whopsdk-python/commit/ca495f7081478f0056efbad9c75eea30af62f9fe))
+
+
+### Chores
+
+* **ci:** skip lint on metadata-only changes ([5428231](https://github.com/whopio/whopsdk-python/commit/542823145fee2ead9f920efd00278464d8601513))
+* **internal:** update gitignore ([e409b46](https://github.com/whopio/whopsdk-python/commit/e409b46665a918b487c9e10c25dd48819398f2bc))
+
## 0.0.35 (2026-03-18)
Full Changelog: [v0.0.34...v0.0.35](https://github.com/whopio/whopsdk-python/compare/v0.0.34...v0.0.35)
diff --git a/api.md b/api.md
index 60f2181..1d4b939 100644
--- a/api.md
+++ b/api.md
@@ -83,7 +83,12 @@ Methods:
Types:
```python
-from whop_sdk.types import InvoiceVoidResponse
+from whop_sdk.types import (
+ TaxIdentifierType,
+ InvoiceMarkPaidResponse,
+ InvoiceMarkUncollectibleResponse,
+ InvoiceVoidResponse,
+)
```
Methods:
@@ -91,6 +96,8 @@ Methods:
- client.invoices.create(\*\*params) -> Invoice
- client.invoices.retrieve(id) -> Invoice
- client.invoices.list(\*\*params) -> SyncCursorPage[InvoiceListItem]
+- client.invoices.mark_paid(id) -> InvoiceMarkPaidResponse
+- client.invoices.mark_uncollectible(id) -> InvoiceMarkUncollectibleResponse
- client.invoices.void(id) -> InvoiceVoidResponse
# CourseLessonInteractions
@@ -144,6 +151,7 @@ from whop_sdk.types import (
WebhookListResponse,
WebhookDeleteResponse,
InvoiceCreatedWebhookEvent,
+ InvoiceMarkedUncollectibleWebhookEvent,
InvoicePaidWebhookEvent,
InvoicePastDueWebhookEvent,
InvoiceVoidedWebhookEvent,
@@ -162,6 +170,9 @@ from whop_sdk.types import (
PayoutMethodCreatedWebhookEvent,
VerificationSucceededWebhookEvent,
PayoutAccountStatusUpdatedWebhookEvent,
+ ResolutionCenterCaseCreatedWebhookEvent,
+ ResolutionCenterCaseUpdatedWebhookEvent,
+ ResolutionCenterCaseDecidedWebhookEvent,
PaymentCreatedWebhookEvent,
PaymentSucceededWebhookEvent,
PaymentFailedWebhookEvent,
diff --git a/pyproject.toml b/pyproject.toml
index 062c3d4..9056f9e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "whop-sdk"
-version = "0.0.35"
+version = "0.0.36"
description = "The official Python library for the Whop API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/whop_sdk/_qs.py b/src/whop_sdk/_qs.py
index ada6fd3..de8c99b 100644
--- a/src/whop_sdk/_qs.py
+++ b/src/whop_sdk/_qs.py
@@ -101,7 +101,10 @@ def _stringify_item(
items.extend(self._stringify_item(key, item, opts))
return items
elif array_format == "indices":
- raise NotImplementedError("The array indices format is not supported yet")
+ items = []
+ for i, item in enumerate(value):
+ items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
+ return items
elif array_format == "brackets":
items = []
key = key + "[]"
diff --git a/src/whop_sdk/_utils/__init__.py b/src/whop_sdk/_utils/__init__.py
index dc64e29..10cb66d 100644
--- a/src/whop_sdk/_utils/__init__.py
+++ b/src/whop_sdk/_utils/__init__.py
@@ -1,3 +1,4 @@
+from ._path import path_template as path_template
from ._sync import asyncify as asyncify
from ._proxy import LazyProxy as LazyProxy
from ._utils import (
diff --git a/src/whop_sdk/_utils/_path.py b/src/whop_sdk/_utils/_path.py
new file mode 100644
index 0000000..4d6e1e4
--- /dev/null
+++ b/src/whop_sdk/_utils/_path.py
@@ -0,0 +1,127 @@
+from __future__ import annotations
+
+import re
+from typing import (
+ Any,
+ Mapping,
+ Callable,
+)
+from urllib.parse import quote
+
+# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
+_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
+
+_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
+
+
+def _quote_path_segment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI path segment.
+
+ Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
+ """
+ # quote() already treats unreserved characters (letters, digits, and -._~)
+ # as safe, so we only need to add sub-delims, ':', and '@'.
+ # Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
+ return quote(value, safe="!$&'()*+,;=:@")
+
+
+def _quote_query_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI query string.
+
+ Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
+ """
+ return quote(value, safe="!$'()*+,;:@/?")
+
+
+def _quote_fragment_part(value: str) -> str:
+ """Percent-encode `value` for use in a URI fragment.
+
+ Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
+ https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
+ """
+ return quote(value, safe="!$&'()*+,;=:@/?")
+
+
+def _interpolate(
+ template: str,
+ values: Mapping[str, Any],
+ quoter: Callable[[str], str],
+) -> str:
+ """Replace {name} placeholders in `template`, quoting each value with `quoter`.
+
+ Placeholder names are looked up in `values`.
+
+ Raises:
+ KeyError: If a placeholder is not found in `values`.
+ """
+ # re.split with a capturing group returns alternating
+ # [text, name, text, name, ..., text] elements.
+ parts = _PLACEHOLDER_RE.split(template)
+
+ for i in range(1, len(parts), 2):
+ name = parts[i]
+ if name not in values:
+ raise KeyError(f"a value for placeholder {{{name}}} was not provided")
+ val = values[name]
+ if val is None:
+ parts[i] = "null"
+ elif isinstance(val, bool):
+ parts[i] = "true" if val else "false"
+ else:
+ parts[i] = quoter(str(values[name]))
+
+ return "".join(parts)
+
+
+def path_template(template: str, /, **kwargs: Any) -> str:
+ """Interpolate {name} placeholders in `template` from keyword arguments.
+
+ Args:
+ template: The template string containing {name} placeholders.
+ **kwargs: Keyword arguments to interpolate into the template.
+
+ Returns:
+ The template with placeholders interpolated and percent-encoded.
+
+ Safe characters for percent-encoding are dependent on the URI component.
+ Placeholders in path and fragment portions are percent-encoded where the `segment`
+ and `fragment` sets from RFC 3986 respectively are considered safe.
+ Placeholders in the query portion are percent-encoded where the `query` set from
+ RFC 3986 §3.3 is considered safe except for = and & characters.
+
+ Raises:
+ KeyError: If a placeholder is not found in `kwargs`.
+ ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
+ """
+ # Split the template into path, query, and fragment portions.
+ fragment_template: str | None = None
+ query_template: str | None = None
+
+ rest = template
+ if "#" in rest:
+ rest, fragment_template = rest.split("#", 1)
+ if "?" in rest:
+ rest, query_template = rest.split("?", 1)
+ path_template = rest
+
+ # Interpolate each portion with the appropriate quoting rules.
+ path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
+
+ # Reject dot-segments (. and ..) in the final assembled path. The check
+ # runs after interpolation so that adjacent placeholders or a mix of static
+ # text and placeholders that together form a dot-segment are caught.
+ # Also reject percent-encoded dot-segments to protect against incorrectly
+ # implemented normalization in servers/proxies.
+ for segment in path_result.split("/"):
+ if _DOT_SEGMENT_RE.match(segment):
+ raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
+
+ result = path_result
+ if query_template is not None:
+ result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
+ if fragment_template is not None:
+ result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
+
+ return result
diff --git a/src/whop_sdk/_version.py b/src/whop_sdk/_version.py
index 057036e..75c4782 100644
--- a/src/whop_sdk/_version.py
+++ b/src/whop_sdk/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "whop_sdk"
-__version__ = "0.0.35" # x-release-please-version
+__version__ = "0.0.36" # x-release-please-version
diff --git a/src/whop_sdk/resources/affiliates/affiliates.py b/src/whop_sdk/resources/affiliates/affiliates.py
index 2c184de..75b951e 100644
--- a/src/whop_sdk/resources/affiliates/affiliates.py
+++ b/src/whop_sdk/resources/affiliates/affiliates.py
@@ -9,7 +9,7 @@
from ...types import Status, affiliate_list_params, affiliate_create_params
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, async_maybe_transform
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .overrides import (
OverridesResource,
@@ -142,7 +142,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/affiliates/{id}",
+ path_template("/affiliates/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -259,7 +259,7 @@ def archive(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/affiliates/{id}/archive",
+ path_template("/affiliates/{id}/archive", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -296,7 +296,7 @@ def unarchive(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/affiliates/{id}/unarchive",
+ path_template("/affiliates/{id}/unarchive", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -408,7 +408,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/affiliates/{id}",
+ path_template("/affiliates/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -525,7 +525,7 @@ async def archive(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/affiliates/{id}/archive",
+ path_template("/affiliates/{id}/archive", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -562,7 +562,7 @@ async def unarchive(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/affiliates/{id}/unarchive",
+ path_template("/affiliates/{id}/unarchive", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/affiliates/overrides.py b/src/whop_sdk/resources/affiliates/overrides.py
index a3158a1..351eab6 100644
--- a/src/whop_sdk/resources/affiliates/overrides.py
+++ b/src/whop_sdk/resources/affiliates/overrides.py
@@ -8,7 +8,7 @@
import httpx
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import required_args, maybe_transform, async_maybe_transform
+from ..._utils import path_template, required_args, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -180,7 +180,7 @@ def create(
if not path_id:
raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}")
return self._post(
- f"/affiliates/{path_id}/overrides",
+ path_template("/affiliates/{path_id}/overrides", path_id=path_id),
body=maybe_transform(
{
"body_id": body_id,
@@ -233,7 +233,7 @@ def retrieve(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return self._get(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -285,7 +285,7 @@ def update(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return self._patch(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
body=maybe_transform(
{
"applies_to_payments": applies_to_payments,
@@ -346,7 +346,7 @@ def list(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get_api_list(
- f"/affiliates/{id}/overrides",
+ path_template("/affiliates/{id}/overrides", id=id),
page=SyncCursorPage[OverrideListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -400,7 +400,7 @@ def delete(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return self._delete(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -547,7 +547,7 @@ async def create(
if not path_id:
raise ValueError(f"Expected a non-empty value for `path_id` but received {path_id!r}")
return await self._post(
- f"/affiliates/{path_id}/overrides",
+ path_template("/affiliates/{path_id}/overrides", path_id=path_id),
body=await async_maybe_transform(
{
"body_id": body_id,
@@ -600,7 +600,7 @@ async def retrieve(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return await self._get(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -652,7 +652,7 @@ async def update(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return await self._patch(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
body=await async_maybe_transform(
{
"applies_to_payments": applies_to_payments,
@@ -713,7 +713,7 @@ def list(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get_api_list(
- f"/affiliates/{id}/overrides",
+ path_template("/affiliates/{id}/overrides", id=id),
page=AsyncCursorPage[OverrideListResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -767,7 +767,7 @@ async def delete(
if not override_id:
raise ValueError(f"Expected a non-empty value for `override_id` but received {override_id!r}")
return await self._delete(
- f"/affiliates/{id}/overrides/{override_id}",
+ path_template("/affiliates/{id}/overrides/{override_id}", id=id, override_id=override_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/ai_chats.py b/src/whop_sdk/resources/ai_chats.py
index 6c9f4a1..16d60eb 100644
--- a/src/whop_sdk/resources/ai_chats.py
+++ b/src/whop_sdk/resources/ai_chats.py
@@ -9,7 +9,7 @@
from ..types import NotificationPreferences, ai_chat_list_params, ai_chat_create_params, ai_chat_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -135,7 +135,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -183,7 +183,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
body=maybe_transform(
{
"current_company_id": current_company_id,
@@ -287,7 +287,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -402,7 +402,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -450,7 +450,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
body=await async_maybe_transform(
{
"current_company_id": current_company_id,
@@ -554,7 +554,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/ai_chats/{id}",
+ path_template("/ai_chats/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/app_builds.py b/src/whop_sdk/resources/app_builds.py
index e4e0f85..80465b2 100644
--- a/src/whop_sdk/resources/app_builds.py
+++ b/src/whop_sdk/resources/app_builds.py
@@ -9,7 +9,7 @@
from ..types import app_build_list_params, app_build_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -149,7 +149,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/app_builds/{id}",
+ path_template("/app_builds/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -267,7 +267,7 @@ def promote(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/app_builds/{id}/promote",
+ path_template("/app_builds/{id}/promote", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -395,7 +395,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/app_builds/{id}",
+ path_template("/app_builds/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -513,7 +513,7 @@ async def promote(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/app_builds/{id}/promote",
+ path_template("/app_builds/{id}/promote", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/apps.py b/src/whop_sdk/resources/apps.py
index 46fd9b7..c04a53d 100644
--- a/src/whop_sdk/resources/apps.py
+++ b/src/whop_sdk/resources/apps.py
@@ -9,7 +9,7 @@
from ..types import AppType, app_list_params, app_create_params, app_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -145,7 +145,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/apps/{id}",
+ path_template("/apps/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -166,8 +166,10 @@ def update(
icon: Optional[app_update_params.Icon] | Omit = omit,
name: Optional[str] | Omit = omit,
oauth_client_type: Optional[Literal["public", "confidential"]] | Omit = omit,
+ openapi_path: Optional[str] | Omit = omit,
redirect_uris: Optional[SequenceNotStr[str]] | Omit = omit,
required_scopes: Optional[List[Literal["read_user"]]] | Omit = omit,
+ skills_path: Optional[str] | Omit = omit,
status: Optional[AppStatuses] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -208,11 +210,16 @@ def update(
oauth_client_type: How this app authenticates at the OAuth token endpoint.
+ openapi_path: The URL path to the OpenAPI spec file of the app, such as
+ '/assets/openapi.json'.
+
redirect_uris: The whitelisted OAuth callback URLs that users are redirected to after
authorizing the app
required_scopes: The permission scopes the app will request from users when they install it.
+ skills_path: The URL path to the skills directory of the app, such as '/assets/skills/'.
+
status: The status of an experience interface
extra_headers: Send extra headers
@@ -226,7 +233,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/apps/{id}",
+ path_template("/apps/{id}", id=id),
body=maybe_transform(
{
"app_store_description": app_store_description,
@@ -239,8 +246,10 @@ def update(
"icon": icon,
"name": name,
"oauth_client_type": oauth_client_type,
+ "openapi_path": openapi_path,
"redirect_uris": redirect_uris,
"required_scopes": required_scopes,
+ "skills_path": skills_path,
"status": status,
},
app_update_params.AppUpdateParams,
@@ -468,7 +477,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/apps/{id}",
+ path_template("/apps/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -489,8 +498,10 @@ async def update(
icon: Optional[app_update_params.Icon] | Omit = omit,
name: Optional[str] | Omit = omit,
oauth_client_type: Optional[Literal["public", "confidential"]] | Omit = omit,
+ openapi_path: Optional[str] | Omit = omit,
redirect_uris: Optional[SequenceNotStr[str]] | Omit = omit,
required_scopes: Optional[List[Literal["read_user"]]] | Omit = omit,
+ skills_path: Optional[str] | Omit = omit,
status: Optional[AppStatuses] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -531,11 +542,16 @@ async def update(
oauth_client_type: How this app authenticates at the OAuth token endpoint.
+ openapi_path: The URL path to the OpenAPI spec file of the app, such as
+ '/assets/openapi.json'.
+
redirect_uris: The whitelisted OAuth callback URLs that users are redirected to after
authorizing the app
required_scopes: The permission scopes the app will request from users when they install it.
+ skills_path: The URL path to the skills directory of the app, such as '/assets/skills/'.
+
status: The status of an experience interface
extra_headers: Send extra headers
@@ -549,7 +565,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/apps/{id}",
+ path_template("/apps/{id}", id=id),
body=await async_maybe_transform(
{
"app_store_description": app_store_description,
@@ -562,8 +578,10 @@ async def update(
"icon": icon,
"name": name,
"oauth_client_type": oauth_client_type,
+ "openapi_path": openapi_path,
"redirect_uris": redirect_uris,
"required_scopes": required_scopes,
+ "skills_path": skills_path,
"status": status,
},
app_update_params.AppUpdateParams,
diff --git a/src/whop_sdk/resources/authorized_users.py b/src/whop_sdk/resources/authorized_users.py
index 8ccdca5..0519e3e 100644
--- a/src/whop_sdk/resources/authorized_users.py
+++ b/src/whop_sdk/resources/authorized_users.py
@@ -9,7 +9,7 @@
from ..types import authorized_user_list_params, authorized_user_create_params, authorized_user_delete_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -139,7 +139,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/authorized_users/{id}",
+ path_template("/authorized_users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -262,7 +262,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/authorized_users/{id}",
+ path_template("/authorized_users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -387,7 +387,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/authorized_users/{id}",
+ path_template("/authorized_users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -510,7 +510,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/authorized_users/{id}",
+ path_template("/authorized_users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/whop_sdk/resources/chat_channels.py b/src/whop_sdk/resources/chat_channels.py
index 0ed7bd7..ef5da1a 100644
--- a/src/whop_sdk/resources/chat_channels.py
+++ b/src/whop_sdk/resources/chat_channels.py
@@ -8,7 +8,7 @@
from ..types import chat_channel_list_params, chat_channel_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -77,7 +77,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/chat_channels/{id}",
+ path_template("/chat_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -135,7 +135,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/chat_channels/{id}",
+ path_template("/chat_channels/{id}", id=id),
body=maybe_transform(
{
"ban_media": ban_media,
@@ -273,7 +273,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/chat_channels/{id}",
+ path_template("/chat_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -331,7 +331,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/chat_channels/{id}",
+ path_template("/chat_channels/{id}", id=id),
body=await async_maybe_transform(
{
"ban_media": ban_media,
diff --git a/src/whop_sdk/resources/checkout_configurations.py b/src/whop_sdk/resources/checkout_configurations.py
index 0160628..91d5e5d 100644
--- a/src/whop_sdk/resources/checkout_configurations.py
+++ b/src/whop_sdk/resources/checkout_configurations.py
@@ -10,7 +10,7 @@
from ..types import checkout_configuration_list_params, checkout_configuration_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import required_args, maybe_transform, async_maybe_transform
+from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -55,6 +55,10 @@ def create(
*,
plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Omit = omit,
@@ -87,6 +91,9 @@ def create(
affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -114,6 +121,10 @@ def create(
*,
plan_id: str,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Omit = omit,
@@ -147,6 +158,9 @@ def create(
affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -174,6 +188,10 @@ def create(
*,
company_id: str,
mode: Literal["setup"],
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
payment_method_configuration: Optional[
@@ -204,6 +222,9 @@ def create(
company_id: The unique identifier of the company to create the checkout configuration for.
Only required in setup mode.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -231,6 +252,12 @@ def create(
*,
plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan | Omit = omit,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling
+ ]
+ | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling]
+ | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Literal["setup"] | Omit = omit,
@@ -259,6 +286,7 @@ def create(
{
"plan": plan,
"affiliate_code": affiliate_code,
+ "checkout_styling": checkout_styling,
"currency": currency,
"metadata": metadata,
"mode": mode,
@@ -306,7 +334,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/checkout_configurations/{id}",
+ path_template("/checkout_configurations/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -421,6 +449,10 @@ async def create(
*,
plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Omit = omit,
@@ -453,6 +485,9 @@ async def create(
affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -480,6 +515,10 @@ async def create(
*,
plan_id: str,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Omit = omit,
@@ -513,6 +552,9 @@ async def create(
affiliate_code: An affiliate tracking code to attribute the checkout to a specific affiliate.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -540,6 +582,10 @@ async def create(
*,
company_id: str,
mode: Literal["setup"],
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling
+ ]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
payment_method_configuration: Optional[
@@ -570,6 +616,9 @@ async def create(
company_id: The unique identifier of the company to create the checkout configuration for.
Only required in setup mode.
+ checkout_styling: Checkout styling overrides for this session. Overrides plan and company
+ defaults.
+
currency: The available currencies on the platform
metadata: Custom key-value metadata to attach to the checkout configuration.
@@ -597,6 +646,12 @@ async def create(
*,
plan: checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanPlan | Omit = omit,
affiliate_code: Optional[str] | Omit = omit,
+ checkout_styling: Optional[
+ checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling
+ ]
+ | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling]
+ | Optional[checkout_configuration_create_params.CreateCheckoutSessionInputModeSetupCheckoutStyling]
+ | Omit = omit,
currency: Optional[Currency] | Omit = omit,
metadata: Optional[Dict[str, object]] | Omit = omit,
mode: Literal["payment"] | Literal["setup"] | Omit = omit,
@@ -625,6 +680,7 @@ async def create(
{
"plan": plan,
"affiliate_code": affiliate_code,
+ "checkout_styling": checkout_styling,
"currency": currency,
"metadata": metadata,
"mode": mode,
@@ -672,7 +728,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/checkout_configurations/{id}",
+ path_template("/checkout_configurations/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/companies.py b/src/whop_sdk/resources/companies.py
index 37cb077..3850775 100644
--- a/src/whop_sdk/resources/companies.py
+++ b/src/whop_sdk/resources/companies.py
@@ -9,7 +9,7 @@
from ..types import company_list_params, company_create_params, company_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -152,7 +152,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/companies/{id}",
+ path_template("/companies/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -163,8 +163,11 @@ def update(
self,
id: str,
*,
+ affiliate_application_required: Optional[bool] | Omit = omit,
+ affiliate_instructions: Optional[str] | Omit = omit,
banner_image: Optional[company_update_params.BannerImage] | Omit = omit,
description: Optional[str] | Omit = omit,
+ featured_affiliate_product_id: Optional[str] | Omit = omit,
logo: Optional[company_update_params.Logo] | Omit = omit,
route: Optional[str] | Omit = omit,
send_customer_emails: Optional[bool] | Omit = omit,
@@ -186,11 +189,20 @@ def update(
- `company:basic:read`
Args:
+ affiliate_application_required: Whether prospective affiliates must submit an application before they can
+ promote this company.
+
+ affiliate_instructions: Guidelines and instructions shown to affiliates explaining how to promote this
+ company's products.
+
banner_image: The company's banner image. Accepts PNG or JPEG format.
description: A promotional pitch displayed to potential customers on the company's store
page.
+ featured_affiliate_product_id: The ID of the product to feature on this company's affiliate page. Pass null to
+ clear.
+
logo: The company's logo image. Accepts PNG, JPEG, or GIF format.
route: The unique URL slug for the company's store page. Must be lowercase and can
@@ -216,11 +228,14 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/companies/{id}",
+ path_template("/companies/{id}", id=id),
body=maybe_transform(
{
+ "affiliate_application_required": affiliate_application_required,
+ "affiliate_instructions": affiliate_instructions,
"banner_image": banner_image,
"description": description,
+ "featured_affiliate_product_id": featured_affiliate_product_id,
"logo": logo,
"route": route,
"send_customer_emails": send_customer_emails,
@@ -441,7 +456,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/companies/{id}",
+ path_template("/companies/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -452,8 +467,11 @@ async def update(
self,
id: str,
*,
+ affiliate_application_required: Optional[bool] | Omit = omit,
+ affiliate_instructions: Optional[str] | Omit = omit,
banner_image: Optional[company_update_params.BannerImage] | Omit = omit,
description: Optional[str] | Omit = omit,
+ featured_affiliate_product_id: Optional[str] | Omit = omit,
logo: Optional[company_update_params.Logo] | Omit = omit,
route: Optional[str] | Omit = omit,
send_customer_emails: Optional[bool] | Omit = omit,
@@ -475,11 +493,20 @@ async def update(
- `company:basic:read`
Args:
+ affiliate_application_required: Whether prospective affiliates must submit an application before they can
+ promote this company.
+
+ affiliate_instructions: Guidelines and instructions shown to affiliates explaining how to promote this
+ company's products.
+
banner_image: The company's banner image. Accepts PNG or JPEG format.
description: A promotional pitch displayed to potential customers on the company's store
page.
+ featured_affiliate_product_id: The ID of the product to feature on this company's affiliate page. Pass null to
+ clear.
+
logo: The company's logo image. Accepts PNG, JPEG, or GIF format.
route: The unique URL slug for the company's store page. Must be lowercase and can
@@ -505,11 +532,14 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/companies/{id}",
+ path_template("/companies/{id}", id=id),
body=await async_maybe_transform(
{
+ "affiliate_application_required": affiliate_application_required,
+ "affiliate_instructions": affiliate_instructions,
"banner_image": banner_image,
"description": description,
+ "featured_affiliate_product_id": featured_affiliate_product_id,
"logo": logo,
"route": route,
"send_customer_emails": send_customer_emails,
diff --git a/src/whop_sdk/resources/company_token_transactions.py b/src/whop_sdk/resources/company_token_transactions.py
index aa7bf6c..2b3cbdd 100644
--- a/src/whop_sdk/resources/company_token_transactions.py
+++ b/src/whop_sdk/resources/company_token_transactions.py
@@ -13,7 +13,7 @@
company_token_transaction_create_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import required_args, maybe_transform, async_maybe_transform
+from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -281,7 +281,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/company_token_transactions/{id}",
+ path_template("/company_token_transactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -614,7 +614,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/company_token_transactions/{id}",
+ path_template("/company_token_transactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/course_chapters.py b/src/whop_sdk/resources/course_chapters.py
index 9d8345b..41c7ea1 100644
--- a/src/whop_sdk/resources/course_chapters.py
+++ b/src/whop_sdk/resources/course_chapters.py
@@ -8,7 +8,7 @@
from ..types import course_chapter_list_params, course_chapter_create_params, course_chapter_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -124,7 +124,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -164,7 +164,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
body=maybe_transform({"title": title}, course_chapter_update_params.CourseChapterUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -265,7 +265,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -371,7 +371,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -411,7 +411,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
body=await async_maybe_transform({"title": title}, course_chapter_update_params.CourseChapterUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -512,7 +512,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/course_chapters/{id}",
+ path_template("/course_chapters/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/course_lesson_interactions.py b/src/whop_sdk/resources/course_lesson_interactions.py
index 19d4943..0b19bce 100644
--- a/src/whop_sdk/resources/course_lesson_interactions.py
+++ b/src/whop_sdk/resources/course_lesson_interactions.py
@@ -8,7 +8,7 @@
from ..types import course_lesson_interaction_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -76,7 +76,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/course_lesson_interactions/{id}",
+ path_template("/course_lesson_interactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -212,7 +212,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/course_lesson_interactions/{id}",
+ path_template("/course_lesson_interactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/course_lessons.py b/src/whop_sdk/resources/course_lessons.py
index ef47ad3..443134b 100644
--- a/src/whop_sdk/resources/course_lessons.py
+++ b/src/whop_sdk/resources/course_lessons.py
@@ -16,7 +16,7 @@
course_lesson_submit_assessment_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -166,7 +166,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -254,7 +254,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
body=maybe_transform(
{
"assessment_completion_requirement": assessment_completion_requirement,
@@ -378,7 +378,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -411,7 +411,7 @@ def mark_as_completed(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return self._post(
- f"/course_lessons/{lesson_id}/mark_as_completed",
+ path_template("/course_lessons/{lesson_id}/mark_as_completed", lesson_id=lesson_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -445,7 +445,7 @@ def start(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return self._post(
- f"/course_lessons/{lesson_id}/start",
+ path_template("/course_lessons/{lesson_id}/start", lesson_id=lesson_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -481,7 +481,7 @@ def submit_assessment(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return self._post(
- f"/course_lessons/{lesson_id}/submit_assessment",
+ path_template("/course_lessons/{lesson_id}/submit_assessment", lesson_id=lesson_id),
body=maybe_transform(
{"answers": answers}, course_lesson_submit_assessment_params.CourseLessonSubmitAssessmentParams
),
@@ -618,7 +618,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -706,7 +706,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
body=await async_maybe_transform(
{
"assessment_completion_requirement": assessment_completion_requirement,
@@ -830,7 +830,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/course_lessons/{id}",
+ path_template("/course_lessons/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -863,7 +863,7 @@ async def mark_as_completed(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return await self._post(
- f"/course_lessons/{lesson_id}/mark_as_completed",
+ path_template("/course_lessons/{lesson_id}/mark_as_completed", lesson_id=lesson_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -897,7 +897,7 @@ async def start(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return await self._post(
- f"/course_lessons/{lesson_id}/start",
+ path_template("/course_lessons/{lesson_id}/start", lesson_id=lesson_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -933,7 +933,7 @@ async def submit_assessment(
if not lesson_id:
raise ValueError(f"Expected a non-empty value for `lesson_id` but received {lesson_id!r}")
return await self._post(
- f"/course_lessons/{lesson_id}/submit_assessment",
+ path_template("/course_lessons/{lesson_id}/submit_assessment", lesson_id=lesson_id),
body=await async_maybe_transform(
{"answers": answers}, course_lesson_submit_assessment_params.CourseLessonSubmitAssessmentParams
),
diff --git a/src/whop_sdk/resources/course_students.py b/src/whop_sdk/resources/course_students.py
index 83c1656..a7c111a 100644
--- a/src/whop_sdk/resources/course_students.py
+++ b/src/whop_sdk/resources/course_students.py
@@ -8,7 +8,7 @@
from ..types import course_student_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -76,7 +76,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/course_students/{id}",
+ path_template("/course_students/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -204,7 +204,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/course_students/{id}",
+ path_template("/course_students/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/courses.py b/src/whop_sdk/resources/courses.py
index a5c5b25..f8957ca 100644
--- a/src/whop_sdk/resources/courses.py
+++ b/src/whop_sdk/resources/courses.py
@@ -8,7 +8,7 @@
from ..types import Languages, CourseVisibilities, course_list_params, course_create_params, course_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -156,7 +156,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -229,7 +229,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
body=maybe_transform(
{
"certificate_after_completion_enabled": certificate_after_completion_enabled,
@@ -350,7 +350,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -486,7 +486,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -559,7 +559,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
body=await async_maybe_transform(
{
"certificate_after_completion_enabled": certificate_after_completion_enabled,
@@ -680,7 +680,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/courses/{id}",
+ path_template("/courses/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/dispute_alerts.py b/src/whop_sdk/resources/dispute_alerts.py
index 03b47ef..7bfc7a6 100644
--- a/src/whop_sdk/resources/dispute_alerts.py
+++ b/src/whop_sdk/resources/dispute_alerts.py
@@ -9,7 +9,7 @@
from ..types import dispute_alert_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -82,7 +82,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/dispute_alerts/{id}",
+ path_template("/dispute_alerts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -223,7 +223,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/dispute_alerts/{id}",
+ path_template("/dispute_alerts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/disputes.py b/src/whop_sdk/resources/disputes.py
index 0baa88d..81cfc21 100644
--- a/src/whop_sdk/resources/disputes.py
+++ b/src/whop_sdk/resources/disputes.py
@@ -9,7 +9,7 @@
from ..types import dispute_list_params, dispute_update_evidence_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -84,7 +84,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/disputes/{id}",
+ path_template("/disputes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -211,7 +211,7 @@ def submit_evidence(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/disputes/{id}/submit_evidence",
+ path_template("/disputes/{id}/submit_evidence", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -300,7 +300,7 @@ def update_evidence(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/disputes/{id}/update_evidence",
+ path_template("/disputes/{id}/update_evidence", id=id),
body=maybe_transform(
{
"access_activity_log": access_activity_log,
@@ -384,7 +384,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/disputes/{id}",
+ path_template("/disputes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -511,7 +511,7 @@ async def submit_evidence(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/disputes/{id}/submit_evidence",
+ path_template("/disputes/{id}/submit_evidence", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -600,7 +600,7 @@ async def update_evidence(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/disputes/{id}/update_evidence",
+ path_template("/disputes/{id}/update_evidence", id=id),
body=await async_maybe_transform(
{
"access_activity_log": access_activity_log,
diff --git a/src/whop_sdk/resources/dm_channels.py b/src/whop_sdk/resources/dm_channels.py
index 7e51c55..1bae5de 100644
--- a/src/whop_sdk/resources/dm_channels.py
+++ b/src/whop_sdk/resources/dm_channels.py
@@ -8,7 +8,7 @@
from ..types import dm_channel_list_params, dm_channel_create_params, dm_channel_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -126,7 +126,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -168,7 +168,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
body=maybe_transform({"custom_name": custom_name}, dm_channel_update_params.DmChannelUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -273,7 +273,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -381,7 +381,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -423,7 +423,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
body=await async_maybe_transform(
{"custom_name": custom_name}, dm_channel_update_params.DmChannelUpdateParams
),
@@ -530,7 +530,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/dm_channels/{id}",
+ path_template("/dm_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/dm_members.py b/src/whop_sdk/resources/dm_members.py
index f1a8ca1..be2de9b 100644
--- a/src/whop_sdk/resources/dm_members.py
+++ b/src/whop_sdk/resources/dm_members.py
@@ -14,7 +14,7 @@
dm_member_update_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -134,7 +134,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -178,7 +178,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
body=maybe_transform(
{
"notification_preference": notification_preference,
@@ -288,7 +288,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -396,7 +396,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -440,7 +440,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
body=await async_maybe_transform(
{
"notification_preference": notification_preference,
@@ -550,7 +550,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/dm_members/{id}",
+ path_template("/dm_members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/entries.py b/src/whop_sdk/resources/entries.py
index 41d5d23..6847354 100644
--- a/src/whop_sdk/resources/entries.py
+++ b/src/whop_sdk/resources/entries.py
@@ -10,7 +10,7 @@
from ..types import entry_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -81,7 +81,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/entries/{id}",
+ path_template("/entries/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -212,7 +212,7 @@ def approve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/entries/{id}/approve",
+ path_template("/entries/{id}/approve", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -252,7 +252,7 @@ def deny(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/entries/{id}/deny",
+ path_template("/entries/{id}/deny", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -311,7 +311,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/entries/{id}",
+ path_template("/entries/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -442,7 +442,7 @@ async def approve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/entries/{id}/approve",
+ path_template("/entries/{id}/approve", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -482,7 +482,7 @@ async def deny(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/entries/{id}/deny",
+ path_template("/entries/{id}/deny", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/experiences.py b/src/whop_sdk/resources/experiences.py
index 50542d1..b8444bd 100644
--- a/src/whop_sdk/resources/experiences.py
+++ b/src/whop_sdk/resources/experiences.py
@@ -17,7 +17,7 @@
experience_duplicate_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -142,7 +142,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -195,7 +195,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
body=maybe_transform(
{
"access_level": access_level,
@@ -317,7 +317,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -358,7 +358,7 @@ def attach(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/experiences/{id}/attach",
+ path_template("/experiences/{id}/attach", id=id),
body=maybe_transform({"product_id": product_id}, experience_attach_params.ExperienceAttachParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -400,7 +400,7 @@ def detach(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/experiences/{id}/detach",
+ path_template("/experiences/{id}/detach", id=id),
body=maybe_transform({"product_id": product_id}, experience_detach_params.ExperienceDetachParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -448,7 +448,7 @@ def duplicate(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/experiences/{id}/duplicate",
+ path_template("/experiences/{id}/duplicate", id=id),
body=maybe_transform({"name": name}, experience_duplicate_params.ExperienceDuplicateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -564,7 +564,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -617,7 +617,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
body=await async_maybe_transform(
{
"access_level": access_level,
@@ -739,7 +739,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/experiences/{id}",
+ path_template("/experiences/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -780,7 +780,7 @@ async def attach(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/experiences/{id}/attach",
+ path_template("/experiences/{id}/attach", id=id),
body=await async_maybe_transform(
{"product_id": product_id}, experience_attach_params.ExperienceAttachParams
),
@@ -824,7 +824,7 @@ async def detach(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/experiences/{id}/detach",
+ path_template("/experiences/{id}/detach", id=id),
body=await async_maybe_transform(
{"product_id": product_id}, experience_detach_params.ExperienceDetachParams
),
@@ -874,7 +874,7 @@ async def duplicate(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/experiences/{id}/duplicate",
+ path_template("/experiences/{id}/duplicate", id=id),
body=await async_maybe_transform({"name": name}, experience_duplicate_params.ExperienceDuplicateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
diff --git a/src/whop_sdk/resources/fee_markups.py b/src/whop_sdk/resources/fee_markups.py
index 9944dd2..63eb13e 100644
--- a/src/whop_sdk/resources/fee_markups.py
+++ b/src/whop_sdk/resources/fee_markups.py
@@ -8,7 +8,7 @@
from ..types import FeeMarkupType, fee_markup_list_params, fee_markup_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -210,7 +210,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/fee_markups/{id}",
+ path_template("/fee_markups/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -401,7 +401,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/fee_markups/{id}",
+ path_template("/fee_markups/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/files.py b/src/whop_sdk/resources/files.py
index 5729ec7..5e1ad1b 100644
--- a/src/whop_sdk/resources/files.py
+++ b/src/whop_sdk/resources/files.py
@@ -6,7 +6,7 @@
from ..types import file_create_params
from .._types import Body, Query, Headers, NotGiven, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -104,7 +104,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/files/{id}",
+ path_template("/files/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -194,7 +194,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/files/{id}",
+ path_template("/files/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/forum_posts.py b/src/whop_sdk/resources/forum_posts.py
index 0acb986..eacff2d 100644
--- a/src/whop_sdk/resources/forum_posts.py
+++ b/src/whop_sdk/resources/forum_posts.py
@@ -13,7 +13,7 @@
forum_post_update_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -181,7 +181,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/forum_posts/{id}",
+ path_template("/forum_posts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -234,7 +234,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/forum_posts/{id}",
+ path_template("/forum_posts/{id}", id=id),
body=maybe_transform(
{
"attachments": attachments,
@@ -475,7 +475,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/forum_posts/{id}",
+ path_template("/forum_posts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -528,7 +528,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/forum_posts/{id}",
+ path_template("/forum_posts/{id}", id=id),
body=await async_maybe_transform(
{
"attachments": attachments,
diff --git a/src/whop_sdk/resources/forums.py b/src/whop_sdk/resources/forums.py
index 3159079..15e0432 100644
--- a/src/whop_sdk/resources/forums.py
+++ b/src/whop_sdk/resources/forums.py
@@ -8,7 +8,7 @@
from ..types import forum_list_params, forum_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -78,7 +78,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/forums/{id}",
+ path_template("/forums/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -125,7 +125,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/forums/{id}",
+ path_template("/forums/{id}", id=id),
body=maybe_transform(
{
"email_notification_preference": email_notification_preference,
@@ -260,7 +260,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/forums/{id}",
+ path_template("/forums/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -307,7 +307,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/forums/{id}",
+ path_template("/forums/{id}", id=id),
body=await async_maybe_transform(
{
"email_notification_preference": email_notification_preference,
diff --git a/src/whop_sdk/resources/invoices.py b/src/whop_sdk/resources/invoices.py
index aec677f..b3ef3f2 100644
--- a/src/whop_sdk/resources/invoices.py
+++ b/src/whop_sdk/resources/invoices.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Union, Optional
+from typing import List, Union, Iterable, Optional
from datetime import datetime
from typing_extensions import Literal, overload
@@ -10,7 +10,7 @@
from ..types import invoice_list_params, invoice_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import required_args, maybe_transform, async_maybe_transform
+from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -27,6 +27,8 @@
from ..types.shared.invoice_status import InvoiceStatus
from ..types.shared.collection_method import CollectionMethod
from ..types.shared.invoice_list_item import InvoiceListItem
+from ..types.invoice_mark_paid_response import InvoiceMarkPaidResponse
+from ..types.invoice_mark_uncollectible_response import InvoiceMarkUncollectibleResponse
__all__ = ["InvoicesResource", "AsyncInvoicesResource"]
@@ -62,8 +64,13 @@ def create(
plan: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDPlan,
product: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDProduct,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -104,11 +111,20 @@ def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -136,8 +152,13 @@ def create(
plan: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressPlan,
product: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -178,11 +199,20 @@ def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -210,8 +240,13 @@ def create(
plan: invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDPlan,
product_id: str,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -251,11 +286,20 @@ def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -283,8 +327,13 @@ def create(
plan: invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressPlan,
product_id: str,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -324,11 +373,20 @@ def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -366,8 +424,16 @@ def create(
| invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct
| Omit = omit,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
email_address: str | Omit = omit,
@@ -390,8 +456,11 @@ def create(
"plan": plan,
"product": product,
"automatically_finalizes_at": automatically_finalizes_at,
+ "billing_address": billing_address,
"charge_buyer_fee": charge_buyer_fee,
"customer_name": customer_name,
+ "line_items": line_items,
+ "mailing_address_id": mailing_address_id,
"payment_method_id": payment_method_id,
"payment_token_id": payment_token_id,
"email_address": email_address,
@@ -436,7 +505,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/invoices/{id}",
+ path_template("/invoices/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -537,6 +606,80 @@ def list(
model=InvoiceListItem,
)
+ def mark_paid(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InvoiceMarkPaidResponse:
+ """
+ Mark an open invoice as paid when payment was collected outside of Whop.
+
+ Required permissions:
+
+ - `invoice:update`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/invoices/{id}/mark_paid", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvoiceMarkPaidResponse,
+ )
+
+ def mark_uncollectible(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InvoiceMarkUncollectibleResponse:
+ """
+ Mark an open invoice as uncollectible when payment is not expected.
+
+ Required permissions:
+
+ - `invoice:update`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/invoices/{id}/mark_uncollectible", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvoiceMarkUncollectibleResponse,
+ )
+
def void(
self,
id: str,
@@ -569,7 +712,7 @@ def void(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/invoices/{id}/void",
+ path_template("/invoices/{id}/void", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -608,8 +751,13 @@ async def create(
plan: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDPlan,
product: invoice_create_params.CreateInvoiceInputWithProductAndMemberIDProduct,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -650,11 +798,20 @@ async def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -682,8 +839,13 @@ async def create(
plan: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressPlan,
product: invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -724,11 +886,20 @@ async def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -756,8 +927,13 @@ async def create(
plan: invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDPlan,
product_id: str,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -797,11 +973,20 @@ async def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -829,8 +1014,13 @@ async def create(
plan: invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressPlan,
product_id: str,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -870,11 +1060,20 @@ async def create(
Only valid when collection_method is charge_automatically. If not provided, the
charge will be processed immediately.
+ billing_address: Inline billing address to create a new mailing address for this invoice. Cannot
+ be used together with mailing_address_id.
+
charge_buyer_fee: Whether to charge the customer a buyer fee on this invoice.
customer_name: The name of the customer. Required when creating an invoice for a customer who
is not yet a member of the company.
+ line_items: Optional line items that break down the invoice total. When provided, the sum of
+ (quantity \\** unit_price) for all items must equal the plan price.
+
+ mailing_address_id: The unique identifier of an existing mailing address to attach to this invoice.
+ Cannot be used together with billing_address.
+
payment_method_id: The unique identifier of the payment method to charge. Required when
collection_method is charge_automatically.
@@ -912,8 +1111,16 @@ async def create(
| invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressProduct
| Omit = omit,
automatically_finalizes_at: Union[str, datetime, None] | Omit = omit,
+ billing_address: Optional[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductAndEmailAddressBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndMemberIDBillingAddress]
+ | Optional[invoice_create_params.CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress]
+ | Omit = omit,
charge_buyer_fee: Optional[bool] | Omit = omit,
customer_name: Optional[str] | Omit = omit,
+ line_items: Optional[Iterable[invoice_create_params.CreateInvoiceInputWithProductAndMemberIDLineItem]]
+ | Omit = omit,
+ mailing_address_id: Optional[str] | Omit = omit,
payment_method_id: Optional[str] | Omit = omit,
payment_token_id: Optional[str] | Omit = omit,
email_address: str | Omit = omit,
@@ -936,8 +1143,11 @@ async def create(
"plan": plan,
"product": product,
"automatically_finalizes_at": automatically_finalizes_at,
+ "billing_address": billing_address,
"charge_buyer_fee": charge_buyer_fee,
"customer_name": customer_name,
+ "line_items": line_items,
+ "mailing_address_id": mailing_address_id,
"payment_method_id": payment_method_id,
"payment_token_id": payment_token_id,
"email_address": email_address,
@@ -982,7 +1192,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/invoices/{id}",
+ path_template("/invoices/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1083,6 +1293,80 @@ def list(
model=InvoiceListItem,
)
+ async def mark_paid(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InvoiceMarkPaidResponse:
+ """
+ Mark an open invoice as paid when payment was collected outside of Whop.
+
+ Required permissions:
+
+ - `invoice:update`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/invoices/{id}/mark_paid", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvoiceMarkPaidResponse,
+ )
+
+ async def mark_uncollectible(
+ self,
+ id: str,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InvoiceMarkUncollectibleResponse:
+ """
+ Mark an open invoice as uncollectible when payment is not expected.
+
+ Required permissions:
+
+ - `invoice:update`
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/invoices/{id}/mark_uncollectible", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InvoiceMarkUncollectibleResponse,
+ )
+
async def void(
self,
id: str,
@@ -1115,7 +1399,7 @@ async def void(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/invoices/{id}/void",
+ path_template("/invoices/{id}/void", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1136,6 +1420,12 @@ def __init__(self, invoices: InvoicesResource) -> None:
self.list = to_raw_response_wrapper(
invoices.list,
)
+ self.mark_paid = to_raw_response_wrapper(
+ invoices.mark_paid,
+ )
+ self.mark_uncollectible = to_raw_response_wrapper(
+ invoices.mark_uncollectible,
+ )
self.void = to_raw_response_wrapper(
invoices.void,
)
@@ -1154,6 +1444,12 @@ def __init__(self, invoices: AsyncInvoicesResource) -> None:
self.list = async_to_raw_response_wrapper(
invoices.list,
)
+ self.mark_paid = async_to_raw_response_wrapper(
+ invoices.mark_paid,
+ )
+ self.mark_uncollectible = async_to_raw_response_wrapper(
+ invoices.mark_uncollectible,
+ )
self.void = async_to_raw_response_wrapper(
invoices.void,
)
@@ -1172,6 +1468,12 @@ def __init__(self, invoices: InvoicesResource) -> None:
self.list = to_streamed_response_wrapper(
invoices.list,
)
+ self.mark_paid = to_streamed_response_wrapper(
+ invoices.mark_paid,
+ )
+ self.mark_uncollectible = to_streamed_response_wrapper(
+ invoices.mark_uncollectible,
+ )
self.void = to_streamed_response_wrapper(
invoices.void,
)
@@ -1190,6 +1492,12 @@ def __init__(self, invoices: AsyncInvoicesResource) -> None:
self.list = async_to_streamed_response_wrapper(
invoices.list,
)
+ self.mark_paid = async_to_streamed_response_wrapper(
+ invoices.mark_paid,
+ )
+ self.mark_uncollectible = async_to_streamed_response_wrapper(
+ invoices.mark_uncollectible,
+ )
self.void = async_to_streamed_response_wrapper(
invoices.void,
)
diff --git a/src/whop_sdk/resources/leads.py b/src/whop_sdk/resources/leads.py
index df6f992..d4ad590 100644
--- a/src/whop_sdk/resources/leads.py
+++ b/src/whop_sdk/resources/leads.py
@@ -9,7 +9,7 @@
from ..types import lead_list_params, lead_create_params, lead_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -146,7 +146,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/leads/{id}",
+ path_template("/leads/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -193,7 +193,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/leads/{id}",
+ path_template("/leads/{id}", id=id),
body=maybe_transform(
{
"metadata": metadata,
@@ -407,7 +407,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/leads/{id}",
+ path_template("/leads/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -454,7 +454,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/leads/{id}",
+ path_template("/leads/{id}", id=id),
body=await async_maybe_transform(
{
"metadata": metadata,
diff --git a/src/whop_sdk/resources/ledger_accounts.py b/src/whop_sdk/resources/ledger_accounts.py
index d213b5c..778e702 100644
--- a/src/whop_sdk/resources/ledger_accounts.py
+++ b/src/whop_sdk/resources/ledger_accounts.py
@@ -5,6 +5,7 @@
import httpx
from .._types import Body, Query, Headers, NotGiven, not_given
+from .._utils import path_template
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -70,7 +71,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/ledger_accounts/{id}",
+ path_template("/ledger_accounts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -129,7 +130,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/ledger_accounts/{id}",
+ path_template("/ledger_accounts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/members.py b/src/whop_sdk/resources/members.py
index 811f248..5fa0c04 100644
--- a/src/whop_sdk/resources/members.py
+++ b/src/whop_sdk/resources/members.py
@@ -10,7 +10,7 @@
from ..types import member_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -83,7 +83,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/members/{id}",
+ path_template("/members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -259,7 +259,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/members/{id}",
+ path_template("/members/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/memberships.py b/src/whop_sdk/resources/memberships.py
index 22af0af..c984344 100644
--- a/src/whop_sdk/resources/memberships.py
+++ b/src/whop_sdk/resources/memberships.py
@@ -13,9 +13,10 @@
membership_pause_params,
membership_cancel_params,
membership_update_params,
+ membership_add_free_days_params,
)
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -86,7 +87,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/memberships/{id}",
+ path_template("/memberships/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -129,7 +130,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/memberships/{id}",
+ path_template("/memberships/{id}", id=id),
body=maybe_transform({"metadata": metadata}, membership_update_params.MembershipUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -244,6 +245,51 @@ def list(
model=MembershipListResponse,
)
+ def add_free_days(
+ self,
+ id: str,
+ *,
+ free_days: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Membership:
+ """
+ Add free days to extend a membership's current billing period, expiration date,
+ or Stripe trial.
+
+ Required permissions:
+
+ - `member:manage`
+ - `member:email:read`
+ - `member:basic:read`
+
+ Args:
+ free_days: The number of free days to add (1-1095). Extends the billing period, expiration
+ date, or Stripe trial depending on plan type.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/memberships/{id}/add_free_days", id=id),
+ body=maybe_transform({"free_days": free_days}, membership_add_free_days_params.MembershipAddFreeDaysParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Membership,
+ )
+
def cancel(
self,
id: str,
@@ -280,7 +326,7 @@ def cancel(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/memberships/{id}/cancel",
+ path_template("/memberships/{id}/cancel", id=id),
body=maybe_transform(
{"cancellation_mode": cancellation_mode}, membership_cancel_params.MembershipCancelParams
),
@@ -328,7 +374,7 @@ def pause(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/memberships/{id}/pause",
+ path_template("/memberships/{id}/pause", id=id),
body=maybe_transform({"void_payments": void_payments}, membership_pause_params.MembershipPauseParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -370,7 +416,7 @@ def resume(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/memberships/{id}/resume",
+ path_template("/memberships/{id}/resume", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -410,7 +456,7 @@ def uncancel(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/memberships/{id}/uncancel",
+ path_template("/memberships/{id}/uncancel", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -469,7 +515,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/memberships/{id}",
+ path_template("/memberships/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -512,7 +558,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/memberships/{id}",
+ path_template("/memberships/{id}", id=id),
body=await async_maybe_transform({"metadata": metadata}, membership_update_params.MembershipUpdateParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -627,6 +673,53 @@ def list(
model=MembershipListResponse,
)
+ async def add_free_days(
+ self,
+ id: str,
+ *,
+ free_days: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Membership:
+ """
+ Add free days to extend a membership's current billing period, expiration date,
+ or Stripe trial.
+
+ Required permissions:
+
+ - `member:manage`
+ - `member:email:read`
+ - `member:basic:read`
+
+ Args:
+ free_days: The number of free days to add (1-1095). Extends the billing period, expiration
+ date, or Stripe trial depending on plan type.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/memberships/{id}/add_free_days", id=id),
+ body=await async_maybe_transform(
+ {"free_days": free_days}, membership_add_free_days_params.MembershipAddFreeDaysParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=Membership,
+ )
+
async def cancel(
self,
id: str,
@@ -663,7 +756,7 @@ async def cancel(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/memberships/{id}/cancel",
+ path_template("/memberships/{id}/cancel", id=id),
body=await async_maybe_transform(
{"cancellation_mode": cancellation_mode}, membership_cancel_params.MembershipCancelParams
),
@@ -711,7 +804,7 @@ async def pause(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/memberships/{id}/pause",
+ path_template("/memberships/{id}/pause", id=id),
body=await async_maybe_transform(
{"void_payments": void_payments}, membership_pause_params.MembershipPauseParams
),
@@ -755,7 +848,7 @@ async def resume(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/memberships/{id}/resume",
+ path_template("/memberships/{id}/resume", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -795,7 +888,7 @@ async def uncancel(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/memberships/{id}/uncancel",
+ path_template("/memberships/{id}/uncancel", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -816,6 +909,9 @@ def __init__(self, memberships: MembershipsResource) -> None:
self.list = to_raw_response_wrapper(
memberships.list,
)
+ self.add_free_days = to_raw_response_wrapper(
+ memberships.add_free_days,
+ )
self.cancel = to_raw_response_wrapper(
memberships.cancel,
)
@@ -843,6 +939,9 @@ def __init__(self, memberships: AsyncMembershipsResource) -> None:
self.list = async_to_raw_response_wrapper(
memberships.list,
)
+ self.add_free_days = async_to_raw_response_wrapper(
+ memberships.add_free_days,
+ )
self.cancel = async_to_raw_response_wrapper(
memberships.cancel,
)
@@ -870,6 +969,9 @@ def __init__(self, memberships: MembershipsResource) -> None:
self.list = to_streamed_response_wrapper(
memberships.list,
)
+ self.add_free_days = to_streamed_response_wrapper(
+ memberships.add_free_days,
+ )
self.cancel = to_streamed_response_wrapper(
memberships.cancel,
)
@@ -897,6 +999,9 @@ def __init__(self, memberships: AsyncMembershipsResource) -> None:
self.list = async_to_streamed_response_wrapper(
memberships.list,
)
+ self.add_free_days = async_to_streamed_response_wrapper(
+ memberships.add_free_days,
+ )
self.cancel = async_to_streamed_response_wrapper(
memberships.cancel,
)
diff --git a/src/whop_sdk/resources/messages.py b/src/whop_sdk/resources/messages.py
index 7331602..51e664a 100644
--- a/src/whop_sdk/resources/messages.py
+++ b/src/whop_sdk/resources/messages.py
@@ -8,7 +8,7 @@
from ..types import message_list_params, message_create_params, message_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -145,7 +145,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -190,7 +190,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
body=maybe_transform(
{
"attachments": attachments,
@@ -304,7 +304,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -430,7 +430,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -475,7 +475,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
body=await async_maybe_transform(
{
"attachments": attachments,
@@ -589,7 +589,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/messages/{id}",
+ path_template("/messages/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/payment_methods.py b/src/whop_sdk/resources/payment_methods.py
index 9e99365..6c75945 100644
--- a/src/whop_sdk/resources/payment_methods.py
+++ b/src/whop_sdk/resources/payment_methods.py
@@ -9,7 +9,7 @@
from ..types import payment_method_list_params, payment_method_retrieve_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -87,7 +87,7 @@ def retrieve(
return cast(
PaymentMethodRetrieveResponse,
self._get(
- f"/payment_methods/{id}",
+ path_template("/payment_methods/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -253,7 +253,7 @@ async def retrieve(
return cast(
PaymentMethodRetrieveResponse,
await self._get(
- f"/payment_methods/{id}",
+ path_template("/payment_methods/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/whop_sdk/resources/payments.py b/src/whop_sdk/resources/payments.py
index d36041d..db84e49 100644
--- a/src/whop_sdk/resources/payments.py
+++ b/src/whop_sdk/resources/payments.py
@@ -10,7 +10,7 @@
from ..types import payment_list_params, payment_create_params, payment_refund_params, payment_list_fees_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import required_args, maybe_transform, async_maybe_transform
+from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -250,7 +250,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/payments/{id}",
+ path_template("/payments/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -277,6 +277,8 @@ def list(
query: Optional[str] | Omit = omit,
statuses: Optional[List[ReceiptStatus]] | Omit = omit,
substatuses: Optional[List[FriendlyReceiptStatus]] | Omit = omit,
+ updated_after: Union[str, datetime, None] | Omit = omit,
+ updated_before: Union[str, datetime, None] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -335,6 +337,10 @@ def list(
substatuses: Filter payments by their current substatus for more granular filtering.
+ updated_after: Only return payments last updated after this timestamp.
+
+ updated_before: Only return payments last updated before this timestamp.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -370,6 +376,8 @@ def list(
"query": query,
"statuses": statuses,
"substatuses": substatuses,
+ "updated_after": updated_after,
+ "updated_before": updated_before,
},
payment_list_params.PaymentListParams,
),
@@ -420,7 +428,7 @@ def list_fees(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get_api_list(
- f"/payments/{id}/fees",
+ path_template("/payments/{id}/fees", id=id),
page=SyncCursorPage[PaymentListFeesResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -484,7 +492,7 @@ def refund(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/payments/{id}/refund",
+ path_template("/payments/{id}/refund", id=id),
body=maybe_transform({"partial_amount": partial_amount}, payment_refund_params.PaymentRefundParams),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
@@ -532,7 +540,7 @@ def retry(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/payments/{id}/retry",
+ path_template("/payments/{id}/retry", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -579,7 +587,7 @@ def void(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._post(
- f"/payments/{id}/void",
+ path_template("/payments/{id}/void", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -804,7 +812,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/payments/{id}",
+ path_template("/payments/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -831,6 +839,8 @@ def list(
query: Optional[str] | Omit = omit,
statuses: Optional[List[ReceiptStatus]] | Omit = omit,
substatuses: Optional[List[FriendlyReceiptStatus]] | Omit = omit,
+ updated_after: Union[str, datetime, None] | Omit = omit,
+ updated_before: Union[str, datetime, None] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -889,6 +899,10 @@ def list(
substatuses: Filter payments by their current substatus for more granular filtering.
+ updated_after: Only return payments last updated after this timestamp.
+
+ updated_before: Only return payments last updated before this timestamp.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -924,6 +938,8 @@ def list(
"query": query,
"statuses": statuses,
"substatuses": substatuses,
+ "updated_after": updated_after,
+ "updated_before": updated_before,
},
payment_list_params.PaymentListParams,
),
@@ -974,7 +990,7 @@ def list_fees(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get_api_list(
- f"/payments/{id}/fees",
+ path_template("/payments/{id}/fees", id=id),
page=AsyncCursorPage[PaymentListFeesResponse],
options=make_request_options(
extra_headers=extra_headers,
@@ -1038,7 +1054,7 @@ async def refund(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/payments/{id}/refund",
+ path_template("/payments/{id}/refund", id=id),
body=await async_maybe_transform(
{"partial_amount": partial_amount}, payment_refund_params.PaymentRefundParams
),
@@ -1088,7 +1104,7 @@ async def retry(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/payments/{id}/retry",
+ path_template("/payments/{id}/retry", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -1135,7 +1151,7 @@ async def void(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._post(
- f"/payments/{id}/void",
+ path_template("/payments/{id}/void", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/payout_accounts.py b/src/whop_sdk/resources/payout_accounts.py
index c59b88b..a6d57c3 100644
--- a/src/whop_sdk/resources/payout_accounts.py
+++ b/src/whop_sdk/resources/payout_accounts.py
@@ -5,6 +5,7 @@
import httpx
from .._types import Body, Query, Headers, NotGiven, not_given
+from .._utils import path_template
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -71,7 +72,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/payout_accounts/{id}",
+ path_template("/payout_accounts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -131,7 +132,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/payout_accounts/{id}",
+ path_template("/payout_accounts/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/payout_methods.py b/src/whop_sdk/resources/payout_methods.py
index 0333f57..c9fce4a 100644
--- a/src/whop_sdk/resources/payout_methods.py
+++ b/src/whop_sdk/resources/payout_methods.py
@@ -8,7 +8,7 @@
from ..types import payout_method_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -75,7 +75,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/payout_methods/{id}",
+ path_template("/payout_methods/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -197,7 +197,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/payout_methods/{id}",
+ path_template("/payout_methods/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/plans.py b/src/whop_sdk/resources/plans.py
index 413c3f8..a0f6dac 100644
--- a/src/whop_sdk/resources/plans.py
+++ b/src/whop_sdk/resources/plans.py
@@ -10,7 +10,7 @@
from ..types import plan_list_params, plan_create_params, plan_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -61,6 +61,7 @@ def create(
company_id: str,
product_id: str,
billing_period: Optional[int] | Omit = omit,
+ checkout_styling: Optional[plan_create_params.CheckoutStyling] | Omit = omit,
currency: Optional[Currency] | Omit = omit,
custom_fields: Optional[Iterable[plan_create_params.CustomField]] | Omit = omit,
description: Optional[str] | Omit = omit,
@@ -106,6 +107,9 @@ def create(
billing_period: The number of days between recurring charges. For example, 30 for monthly or 365
for yearly.
+ checkout_styling: Checkout styling overrides for this plan. Pass null to inherit from the company
+ default.
+
currency: The available currencies on the platform
custom_fields: An array of custom field definitions to collect from customers at checkout.
@@ -167,6 +171,7 @@ def create(
"company_id": company_id,
"product_id": product_id,
"billing_period": billing_period,
+ "checkout_styling": checkout_styling,
"currency": currency,
"custom_fields": custom_fields,
"description": description,
@@ -225,7 +230,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -237,6 +242,7 @@ def update(
id: str,
*,
billing_period: Optional[int] | Omit = omit,
+ checkout_styling: Optional[plan_update_params.CheckoutStyling] | Omit = omit,
currency: Optional[Currency] | Omit = omit,
custom_fields: Optional[Iterable[plan_update_params.CustomField]] | Omit = omit,
description: Optional[str] | Omit = omit,
@@ -277,6 +283,9 @@ def update(
billing_period: The number of days between recurring charges. For example, 30 for monthly or 365
for yearly.
+ checkout_styling: Checkout styling overrides for this plan. Pass null to remove all overrides and
+ inherit from the company default.
+
currency: The available currencies on the platform
custom_fields: An array of custom field definitions to collect from customers at checkout.
@@ -334,10 +343,11 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
body=maybe_transform(
{
"billing_period": billing_period,
+ "checkout_styling": checkout_styling,
"currency": currency,
"custom_fields": custom_fields,
"description": description,
@@ -495,7 +505,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -529,6 +539,7 @@ async def create(
company_id: str,
product_id: str,
billing_period: Optional[int] | Omit = omit,
+ checkout_styling: Optional[plan_create_params.CheckoutStyling] | Omit = omit,
currency: Optional[Currency] | Omit = omit,
custom_fields: Optional[Iterable[plan_create_params.CustomField]] | Omit = omit,
description: Optional[str] | Omit = omit,
@@ -574,6 +585,9 @@ async def create(
billing_period: The number of days between recurring charges. For example, 30 for monthly or 365
for yearly.
+ checkout_styling: Checkout styling overrides for this plan. Pass null to inherit from the company
+ default.
+
currency: The available currencies on the platform
custom_fields: An array of custom field definitions to collect from customers at checkout.
@@ -635,6 +649,7 @@ async def create(
"company_id": company_id,
"product_id": product_id,
"billing_period": billing_period,
+ "checkout_styling": checkout_styling,
"currency": currency,
"custom_fields": custom_fields,
"description": description,
@@ -693,7 +708,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -705,6 +720,7 @@ async def update(
id: str,
*,
billing_period: Optional[int] | Omit = omit,
+ checkout_styling: Optional[plan_update_params.CheckoutStyling] | Omit = omit,
currency: Optional[Currency] | Omit = omit,
custom_fields: Optional[Iterable[plan_update_params.CustomField]] | Omit = omit,
description: Optional[str] | Omit = omit,
@@ -745,6 +761,9 @@ async def update(
billing_period: The number of days between recurring charges. For example, 30 for monthly or 365
for yearly.
+ checkout_styling: Checkout styling overrides for this plan. Pass null to remove all overrides and
+ inherit from the company default.
+
currency: The available currencies on the platform
custom_fields: An array of custom field definitions to collect from customers at checkout.
@@ -802,10 +821,11 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
body=await async_maybe_transform(
{
"billing_period": billing_period,
+ "checkout_styling": checkout_styling,
"currency": currency,
"custom_fields": custom_fields,
"description": description,
@@ -963,7 +983,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/plans/{id}",
+ path_template("/plans/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/products.py b/src/whop_sdk/resources/products.py
index 6909de0..f2dce52 100644
--- a/src/whop_sdk/resources/products.py
+++ b/src/whop_sdk/resources/products.py
@@ -10,7 +10,7 @@
from ..types import product_list_params, product_create_params, product_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -96,7 +96,7 @@ def create(
Args:
company_id: The unique identifier of the company to create this product for.
- title: The display name of the product. Maximum 40 characters.
+ title: The display name of the product. Maximum 80 characters.
collect_shipping_address: Whether the checkout flow collects a shipping address from the customer.
@@ -208,7 +208,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -291,7 +291,7 @@ def update(
store_page_config: Layout and display configuration for this product on the company's store page.
- title: The display name of the product. Maximum 40 characters.
+ title: The display name of the product. Maximum 80 characters.
visibility: Visibility of a resource
@@ -306,7 +306,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
body=maybe_transform(
{
"collect_shipping_address": collect_shipping_address,
@@ -454,7 +454,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -524,7 +524,7 @@ async def create(
Args:
company_id: The unique identifier of the company to create this product for.
- title: The display name of the product. Maximum 40 characters.
+ title: The display name of the product. Maximum 80 characters.
collect_shipping_address: Whether the checkout flow collects a shipping address from the customer.
@@ -636,7 +636,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -719,7 +719,7 @@ async def update(
store_page_config: Layout and display configuration for this product on the company's store page.
- title: The display name of the product. Maximum 40 characters.
+ title: The display name of the product. Maximum 80 characters.
visibility: Visibility of a resource
@@ -734,7 +734,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
body=await async_maybe_transform(
{
"collect_shipping_address": collect_shipping_address,
@@ -882,7 +882,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/products/{id}",
+ path_template("/products/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/promo_codes.py b/src/whop_sdk/resources/promo_codes.py
index 4d8deb2..7d89304 100644
--- a/src/whop_sdk/resources/promo_codes.py
+++ b/src/whop_sdk/resources/promo_codes.py
@@ -9,7 +9,7 @@
from ..types import PromoCodeStatus, promo_code_list_params, promo_code_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -193,7 +193,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/promo_codes/{id}",
+ path_template("/promo_codes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -316,7 +316,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/promo_codes/{id}",
+ path_template("/promo_codes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -487,7 +487,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/promo_codes/{id}",
+ path_template("/promo_codes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -610,7 +610,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/promo_codes/{id}",
+ path_template("/promo_codes/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/reactions.py b/src/whop_sdk/resources/reactions.py
index 4688254..243ceaf 100644
--- a/src/whop_sdk/resources/reactions.py
+++ b/src/whop_sdk/resources/reactions.py
@@ -8,7 +8,7 @@
from ..types import reaction_list_params, reaction_create_params, reaction_delete_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -131,7 +131,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/reactions/{id}",
+ path_template("/reactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -239,7 +239,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/reactions/{id}",
+ path_template("/reactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -356,7 +356,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/reactions/{id}",
+ path_template("/reactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -464,7 +464,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/reactions/{id}",
+ path_template("/reactions/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
diff --git a/src/whop_sdk/resources/refunds.py b/src/whop_sdk/resources/refunds.py
index ff24a70..d845816 100644
--- a/src/whop_sdk/resources/refunds.py
+++ b/src/whop_sdk/resources/refunds.py
@@ -9,7 +9,7 @@
from ..types import refund_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -80,7 +80,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/refunds/{id}",
+ path_template("/refunds/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -225,7 +225,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/refunds/{id}",
+ path_template("/refunds/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/resolution_center_cases.py b/src/whop_sdk/resources/resolution_center_cases.py
index 3563f15..90eb6a4 100644
--- a/src/whop_sdk/resources/resolution_center_cases.py
+++ b/src/whop_sdk/resources/resolution_center_cases.py
@@ -9,7 +9,7 @@
from ..types import resolution_center_case_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -80,7 +80,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/resolution_center_cases/{id}",
+ path_template("/resolution_center_cases/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -220,7 +220,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/resolution_center_cases/{id}",
+ path_template("/resolution_center_cases/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/reviews.py b/src/whop_sdk/resources/reviews.py
index 3ce2c4d..0ac1ea3 100644
--- a/src/whop_sdk/resources/reviews.py
+++ b/src/whop_sdk/resources/reviews.py
@@ -9,7 +9,7 @@
from ..types import review_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -72,7 +72,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/reviews/{id}",
+ path_template("/reviews/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -202,7 +202,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/reviews/{id}",
+ path_template("/reviews/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/setup_intents.py b/src/whop_sdk/resources/setup_intents.py
index e85baf4..4c3b154 100644
--- a/src/whop_sdk/resources/setup_intents.py
+++ b/src/whop_sdk/resources/setup_intents.py
@@ -9,7 +9,7 @@
from ..types import setup_intent_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -79,7 +79,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/setup_intents/{id}",
+ path_template("/setup_intents/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -218,7 +218,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/setup_intents/{id}",
+ path_template("/setup_intents/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/shipments.py b/src/whop_sdk/resources/shipments.py
index 1b46c63..5a4eda5 100644
--- a/src/whop_sdk/resources/shipments.py
+++ b/src/whop_sdk/resources/shipments.py
@@ -8,7 +8,7 @@
from ..types import shipment_list_params, shipment_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -131,7 +131,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/shipments/{id}",
+ path_template("/shipments/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -318,7 +318,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/shipments/{id}",
+ path_template("/shipments/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/support_channels.py b/src/whop_sdk/resources/support_channels.py
index 7b5146a..7d919e4 100644
--- a/src/whop_sdk/resources/support_channels.py
+++ b/src/whop_sdk/resources/support_channels.py
@@ -9,7 +9,7 @@
from ..types import support_channel_list_params, support_channel_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -131,7 +131,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/support_channels/{id}",
+ path_template("/support_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -320,7 +320,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/support_channels/{id}",
+ path_template("/support_channels/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/transfers.py b/src/whop_sdk/resources/transfers.py
index 6252141..7ff65c6 100644
--- a/src/whop_sdk/resources/transfers.py
+++ b/src/whop_sdk/resources/transfers.py
@@ -10,7 +10,7 @@
from ..types import transfer_list_params, transfer_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -152,7 +152,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/transfers/{id}",
+ path_template("/transfers/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -369,7 +369,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/transfers/{id}",
+ path_template("/transfers/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/users.py b/src/whop_sdk/resources/users.py
index 7091072..6414c8e 100644
--- a/src/whop_sdk/resources/users.py
+++ b/src/whop_sdk/resources/users.py
@@ -8,7 +8,7 @@
from ..types import user_list_params, user_update_profile_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -72,7 +72,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/users/{id}",
+ path_template("/users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -169,7 +169,7 @@ def check_access(
if not resource_id:
raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}")
return self._get(
- f"/users/{id}/access/{resource_id}",
+ path_template("/users/{id}/access/{resource_id}", id=id, resource_id=resource_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -279,7 +279,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/users/{id}",
+ path_template("/users/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -376,7 +376,7 @@ async def check_access(
if not resource_id:
raise ValueError(f"Expected a non-empty value for `resource_id` but received {resource_id!r}")
return await self._get(
- f"/users/{id}/access/{resource_id}",
+ path_template("/users/{id}/access/{resource_id}", id=id, resource_id=resource_id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/verifications.py b/src/whop_sdk/resources/verifications.py
index 54364d2..9ee917e 100644
--- a/src/whop_sdk/resources/verifications.py
+++ b/src/whop_sdk/resources/verifications.py
@@ -8,7 +8,7 @@
from ..types import verification_list_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform
+from .._utils import path_template, maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -75,7 +75,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/verifications/{id}",
+ path_template("/verifications/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -197,7 +197,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/verifications/{id}",
+ path_template("/verifications/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/webhooks.py b/src/whop_sdk/resources/webhooks.py
index 340e6a6..3004144 100644
--- a/src/whop_sdk/resources/webhooks.py
+++ b/src/whop_sdk/resources/webhooks.py
@@ -9,7 +9,7 @@
from ..types import APIVersion, webhook_list_params, webhook_create_params, webhook_update_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._models import construct_type
from .._resource import SyncAPIResource, AsyncAPIResource
@@ -148,7 +148,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -200,7 +200,7 @@ def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._patch(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
body=maybe_transform(
{
"api_version": api_version,
@@ -311,7 +311,7 @@ def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._delete(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -460,7 +460,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -512,7 +512,7 @@ async def update(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._patch(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
body=await async_maybe_transform(
{
"api_version": api_version,
@@ -623,7 +623,7 @@ async def delete(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._delete(
- f"/webhooks/{id}",
+ path_template("/webhooks/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/resources/withdrawals.py b/src/whop_sdk/resources/withdrawals.py
index 51b7425..5d76900 100644
--- a/src/whop_sdk/resources/withdrawals.py
+++ b/src/whop_sdk/resources/withdrawals.py
@@ -9,7 +9,7 @@
from ..types import withdrawal_list_params, withdrawal_create_params
from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
+from .._utils import path_template, maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
@@ -144,7 +144,7 @@ def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return self._get(
- f"/withdrawals/{id}",
+ path_template("/withdrawals/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
@@ -344,7 +344,7 @@ async def retrieve(
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
return await self._get(
- f"/withdrawals/{id}",
+ path_template("/withdrawals/{id}", id=id),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
diff --git a/src/whop_sdk/types/__init__.py b/src/whop_sdk/types/__init__.py
index c4684b3..95e067c 100644
--- a/src/whop_sdk/types/__init__.py
+++ b/src/whop_sdk/types/__init__.py
@@ -133,6 +133,7 @@
from .payment_list_params import PaymentListParams as PaymentListParams
from .product_list_params import ProductListParams as ProductListParams
from .setup_intent_status import SetupIntentStatus as SetupIntentStatus
+from .tax_identifier_type import TaxIdentifierType as TaxIdentifierType
from .topup_create_params import TopupCreateParams as TopupCreateParams
from .verification_status import VerificationStatus as VerificationStatus
from .webhook_list_params import WebhookListParams as WebhookListParams
@@ -258,6 +259,7 @@
from .fee_markup_create_response import FeeMarkupCreateResponse as FeeMarkupCreateResponse
from .fee_markup_delete_response import FeeMarkupDeleteResponse as FeeMarkupDeleteResponse
from .forum_post_visibility_type import ForumPostVisibilityType as ForumPostVisibilityType
+from .invoice_mark_paid_response import InvoiceMarkPaidResponse as InvoiceMarkPaidResponse
from .invoice_paid_webhook_event import InvoicePaidWebhookEvent as InvoicePaidWebhookEvent
from .notification_create_params import NotificationCreateParams as NotificationCreateParams
from .payment_list_fees_response import PaymentListFeesResponse as PaymentListFeesResponse
@@ -328,6 +330,7 @@
from .payout_account_calculated_statuses import PayoutAccountCalculatedStatuses as PayoutAccountCalculatedStatuses
from .resolution_center_case_list_params import ResolutionCenterCaseListParams as ResolutionCenterCaseListParams
from .dispute_alert_created_webhook_event import DisputeAlertCreatedWebhookEvent as DisputeAlertCreatedWebhookEvent
+from .invoice_mark_uncollectible_response import InvoiceMarkUncollectibleResponse as InvoiceMarkUncollectibleResponse
from .payout_method_created_webhook_event import PayoutMethodCreatedWebhookEvent as PayoutMethodCreatedWebhookEvent
from .setup_intent_canceled_webhook_event import SetupIntentCanceledWebhookEvent as SetupIntentCanceledWebhookEvent
from .checkout_configuration_create_params import CheckoutConfigurationCreateParams as CheckoutConfigurationCreateParams
@@ -372,12 +375,24 @@
from .resolution_center_case_retrieve_response import (
ResolutionCenterCaseRetrieveResponse as ResolutionCenterCaseRetrieveResponse,
)
+from .invoice_marked_uncollectible_webhook_event import (
+ InvoiceMarkedUncollectibleWebhookEvent as InvoiceMarkedUncollectibleWebhookEvent,
+)
from .setup_intent_requires_action_webhook_event import (
SetupIntentRequiresActionWebhookEvent as SetupIntentRequiresActionWebhookEvent,
)
from .payout_account_status_updated_webhook_event import (
PayoutAccountStatusUpdatedWebhookEvent as PayoutAccountStatusUpdatedWebhookEvent,
)
+from .resolution_center_case_created_webhook_event import (
+ ResolutionCenterCaseCreatedWebhookEvent as ResolutionCenterCaseCreatedWebhookEvent,
+)
+from .resolution_center_case_decided_webhook_event import (
+ ResolutionCenterCaseDecidedWebhookEvent as ResolutionCenterCaseDecidedWebhookEvent,
+)
+from .resolution_center_case_updated_webhook_event import (
+ ResolutionCenterCaseUpdatedWebhookEvent as ResolutionCenterCaseUpdatedWebhookEvent,
+)
from .course_lesson_interaction_completed_webhook_event import (
CourseLessonInteractionCompletedWebhookEvent as CourseLessonInteractionCompletedWebhookEvent,
)
diff --git a/src/whop_sdk/types/affiliate.py b/src/whop_sdk/types/affiliate.py
index 26de2b8..e6809ff 100644
--- a/src/whop_sdk/types/affiliate.py
+++ b/src/whop_sdk/types/affiliate.py
@@ -39,7 +39,9 @@ class User(BaseModel):
class Affiliate(BaseModel):
- """An affiliate of a company or a global affiliate"""
+ """
+ An affiliate tracks a user's referral performance and commission earnings for a company, including retention rates, revenue metrics, and payout configurations.
+ """
id: str
"""The unique identifier for the affiliate."""
@@ -54,13 +56,16 @@ class Affiliate(BaseModel):
"""The datetime the affiliate was created."""
customer_retention_rate: str
- """How many referrals have remained since they joined as members"""
+ """The percentage of referred customers who are still active members"""
customer_retention_rate_ninety_days: str
- """A rolling 90-day retention rate for this affiliate"""
+ """The percentage of referred customers who remained active over the last 90 days"""
monthly_recurring_revenue_usd: str
- """The total MRR of the affiliate"""
+ """
+ The monthly recurring revenue generated by this affiliate's referrals, formatted
+ as a USD currency string
+ """
status: Optional[Status] = None
"""Statuses for resources"""
@@ -69,13 +74,19 @@ class Affiliate(BaseModel):
"""The total count of all overrides for this affiliate"""
total_referral_earnings_usd: str
- """The total earnings of the affiliate from the users they referred"""
+ """
+ The total commission earnings paid to this affiliate, formatted as a USD
+ currency string
+ """
total_referrals_count: int
"""The total referrals of the affiliate"""
total_revenue_usd: str
- """The total revenue of the affiliate from their referrals"""
+ """
+ The total revenue generated from this affiliate's referrals, formatted as a USD
+ currency string
+ """
updated_at: datetime
"""The datetime the affiliate was last updated."""
diff --git a/src/whop_sdk/types/affiliate_list_response.py b/src/whop_sdk/types/affiliate_list_response.py
index 9e24c35..64b57ca 100644
--- a/src/whop_sdk/types/affiliate_list_response.py
+++ b/src/whop_sdk/types/affiliate_list_response.py
@@ -39,7 +39,9 @@ class User(BaseModel):
class AffiliateListResponse(BaseModel):
- """An affiliate of a company or a global affiliate"""
+ """
+ An affiliate tracks a user's referral performance and commission earnings for a company, including retention rates, revenue metrics, and payout configurations.
+ """
id: str
"""The unique identifier for the affiliate."""
@@ -54,13 +56,16 @@ class AffiliateListResponse(BaseModel):
"""The datetime the affiliate was created."""
customer_retention_rate: str
- """How many referrals have remained since they joined as members"""
+ """The percentage of referred customers who are still active members"""
customer_retention_rate_ninety_days: str
- """A rolling 90-day retention rate for this affiliate"""
+ """The percentage of referred customers who remained active over the last 90 days"""
monthly_recurring_revenue_usd: str
- """The total MRR of the affiliate"""
+ """
+ The monthly recurring revenue generated by this affiliate's referrals, formatted
+ as a USD currency string
+ """
status: Optional[Status] = None
"""Statuses for resources"""
@@ -69,13 +74,19 @@ class AffiliateListResponse(BaseModel):
"""The total count of all overrides for this affiliate"""
total_referral_earnings_usd: str
- """The total earnings of the affiliate from the users they referred"""
+ """
+ The total commission earnings paid to this affiliate, formatted as a USD
+ currency string
+ """
total_referrals_count: int
"""The total referrals of the affiliate"""
total_revenue_usd: str
- """The total revenue of the affiliate from their referrals"""
+ """
+ The total revenue generated from this affiliate's referrals, formatted as a USD
+ currency string
+ """
updated_at: datetime
"""The datetime the affiliate was last updated."""
diff --git a/src/whop_sdk/types/affiliates/override_create_response.py b/src/whop_sdk/types/affiliates/override_create_response.py
index b7c63d4..08a85c7 100644
--- a/src/whop_sdk/types/affiliates/override_create_response.py
+++ b/src/whop_sdk/types/affiliates/override_create_response.py
@@ -13,7 +13,9 @@
class OverrideCreateResponse(BaseModel):
- """An object storing information about the affiliate"""
+ """
+ A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share
+ """
id: str
"""The unique identifier for the affiliate override."""
@@ -31,7 +33,11 @@ class OverrideCreateResponse(BaseModel):
"""The type of commission (percentage or flat_fee)."""
commission_value: float
- """The commission value (percentage 1-100 or flat fee in dollars)."""
+ """The commission amount.
+
+ A percentage (1-100) when commission_type is percentage, or a dollar amount when
+ flat_fee.
+ """
override_type: AffiliateOverrideRoles
"""The type of override (standard or rev_share)."""
diff --git a/src/whop_sdk/types/affiliates/override_list_response.py b/src/whop_sdk/types/affiliates/override_list_response.py
index 09ce176..f470429 100644
--- a/src/whop_sdk/types/affiliates/override_list_response.py
+++ b/src/whop_sdk/types/affiliates/override_list_response.py
@@ -13,7 +13,9 @@
class OverrideListResponse(BaseModel):
- """An object storing information about the affiliate"""
+ """
+ A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share
+ """
id: str
"""The unique identifier for the affiliate override."""
@@ -31,7 +33,11 @@ class OverrideListResponse(BaseModel):
"""The type of commission (percentage or flat_fee)."""
commission_value: float
- """The commission value (percentage 1-100 or flat fee in dollars)."""
+ """The commission amount.
+
+ A percentage (1-100) when commission_type is percentage, or a dollar amount when
+ flat_fee.
+ """
override_type: AffiliateOverrideRoles
"""The type of override (standard or rev_share)."""
diff --git a/src/whop_sdk/types/affiliates/override_retrieve_response.py b/src/whop_sdk/types/affiliates/override_retrieve_response.py
index 4e54c0f..61b738f 100644
--- a/src/whop_sdk/types/affiliates/override_retrieve_response.py
+++ b/src/whop_sdk/types/affiliates/override_retrieve_response.py
@@ -13,7 +13,9 @@
class OverrideRetrieveResponse(BaseModel):
- """An object storing information about the affiliate"""
+ """
+ A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share
+ """
id: str
"""The unique identifier for the affiliate override."""
@@ -31,7 +33,11 @@ class OverrideRetrieveResponse(BaseModel):
"""The type of commission (percentage or flat_fee)."""
commission_value: float
- """The commission value (percentage 1-100 or flat fee in dollars)."""
+ """The commission amount.
+
+ A percentage (1-100) when commission_type is percentage, or a dollar amount when
+ flat_fee.
+ """
override_type: AffiliateOverrideRoles
"""The type of override (standard or rev_share)."""
diff --git a/src/whop_sdk/types/affiliates/override_update_response.py b/src/whop_sdk/types/affiliates/override_update_response.py
index b9ed5c9..3b830e3 100644
--- a/src/whop_sdk/types/affiliates/override_update_response.py
+++ b/src/whop_sdk/types/affiliates/override_update_response.py
@@ -13,7 +13,9 @@
class OverrideUpdateResponse(BaseModel):
- """An object storing information about the affiliate"""
+ """
+ A commission configuration for an affiliate, defining payout terms for a specific plan or revenue share
+ """
id: str
"""The unique identifier for the affiliate override."""
@@ -31,7 +33,11 @@ class OverrideUpdateResponse(BaseModel):
"""The type of commission (percentage or flat_fee)."""
commission_value: float
- """The commission value (percentage 1-100 or flat fee in dollars)."""
+ """The commission amount.
+
+ A percentage (1-100) when commission_type is percentage, or a dollar amount when
+ flat_fee.
+ """
override_type: AffiliateOverrideRoles
"""The type of override (standard or rev_share)."""
diff --git a/src/whop_sdk/types/app_list_response.py b/src/whop_sdk/types/app_list_response.py
index 53563e2..8a0da2e 100644
--- a/src/whop_sdk/types/app_list_response.py
+++ b/src/whop_sdk/types/app_list_response.py
@@ -117,6 +117,26 @@ class AppListResponse(BaseModel):
Maximum 30 characters.
"""
+ openapi_path: Optional[str] = None
+ """
+ The URL path template for a specific view of this app, appended to the base
+ domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is
+ not configured.
+ """
+
+ origin: Optional[str] = None
+ """
+ The full origin URL for this app's proxied domain (e.g.,
+ 'https://myapp.apps.whop.com'). Null if no proxy domain is configured.
+ """
+
+ skills_path: Optional[str] = None
+ """
+ The URL path template for a specific view of this app, appended to the base
+ domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is
+ not configured.
+ """
+
status: AppStatuses
"""The current visibility status of this app on the Whop app store.
diff --git a/src/whop_sdk/types/app_update_params.py b/src/whop_sdk/types/app_update_params.py
index 2d5e48b..8320361 100644
--- a/src/whop_sdk/types/app_update_params.py
+++ b/src/whop_sdk/types/app_update_params.py
@@ -51,6 +51,12 @@ class AppUpdateParams(TypedDict, total=False):
oauth_client_type: Optional[Literal["public", "confidential"]]
"""How this app authenticates at the OAuth token endpoint."""
+ openapi_path: Optional[str]
+ """
+ The URL path to the OpenAPI spec file of the app, such as
+ '/assets/openapi.json'.
+ """
+
redirect_uris: Optional[SequenceNotStr[str]]
"""
The whitelisted OAuth callback URLs that users are redirected to after
@@ -60,6 +66,9 @@ class AppUpdateParams(TypedDict, total=False):
required_scopes: Optional[List[Literal["read_user"]]]
"""The permission scopes the app will request from users when they install it."""
+ skills_path: Optional[str]
+ """The URL path to the skills directory of the app, such as '/assets/skills/'."""
+
status: Optional[AppStatuses]
"""The status of an experience interface"""
diff --git a/src/whop_sdk/types/card_brands.py b/src/whop_sdk/types/card_brands.py
index 1243eea..bd4345a 100644
--- a/src/whop_sdk/types/card_brands.py
+++ b/src/whop_sdk/types/card_brands.py
@@ -43,5 +43,6 @@
"cabal",
"hipercard",
"jcblankapay",
+ "cmi",
"unknown",
]
diff --git a/src/whop_sdk/types/checkout_configuration_create_params.py b/src/whop_sdk/types/checkout_configuration_create_params.py
index cf71c43..ba31559 100644
--- a/src/whop_sdk/types/checkout_configuration_create_params.py
+++ b/src/whop_sdk/types/checkout_configuration_create_params.py
@@ -21,10 +21,13 @@
"CreateCheckoutSessionInputModePaymentWithPlanPlanImage",
"CreateCheckoutSessionInputModePaymentWithPlanPlanPaymentMethodConfiguration",
"CreateCheckoutSessionInputModePaymentWithPlanPlanProduct",
+ "CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling",
"CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration",
"CreateCheckoutSessionInputModePaymentWithPlanID",
+ "CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling",
"CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration",
"CreateCheckoutSessionInputModeSetup",
+ "CreateCheckoutSessionInputModeSetupCheckoutStyling",
"CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration",
]
@@ -38,6 +41,12 @@ class CreateCheckoutSessionInputModePaymentWithPlan(TypedDict, total=False):
affiliate_code: Optional[str]
"""An affiliate tracking code to attribute the checkout to a specific affiliate."""
+ checkout_styling: Optional[CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling]
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
currency: Optional[Currency]
"""The available currencies on the platform"""
@@ -275,6 +284,22 @@ class CreateCheckoutSessionInputModePaymentWithPlanPlan(TypedDict, total=False):
"""Visibility of a resource"""
+class CreateCheckoutSessionInputModePaymentWithPlanCheckoutStyling(TypedDict, total=False):
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
+ border_style: Optional[Literal["rounded", "pill", "rectangular"]]
+ """The different border-radius styles available for checkout pages."""
+
+ button_color: Optional[str]
+ """A hex color code for the button color (e.g. #FF5733)."""
+
+ font_family: Optional[Literal["system", "roboto", "open_sans"]]
+ """The different font families available for checkout pages."""
+
+
class CreateCheckoutSessionInputModePaymentWithPlanPaymentMethodConfiguration(TypedDict, total=False):
"""The explicit payment method configuration for the checkout session.
@@ -313,6 +338,12 @@ class CreateCheckoutSessionInputModePaymentWithPlanID(TypedDict, total=False):
affiliate_code: Optional[str]
"""An affiliate tracking code to attribute the checkout to a specific affiliate."""
+ checkout_styling: Optional[CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling]
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
currency: Optional[Currency]
"""The available currencies on the platform"""
@@ -335,6 +366,22 @@ class CreateCheckoutSessionInputModePaymentWithPlanID(TypedDict, total=False):
"""The URL of the page where the checkout is being initiated from."""
+class CreateCheckoutSessionInputModePaymentWithPlanIDCheckoutStyling(TypedDict, total=False):
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
+ border_style: Optional[Literal["rounded", "pill", "rectangular"]]
+ """The different border-radius styles available for checkout pages."""
+
+ button_color: Optional[str]
+ """A hex color code for the button color (e.g. #FF5733)."""
+
+ font_family: Optional[Literal["system", "roboto", "open_sans"]]
+ """The different font families available for checkout pages."""
+
+
class CreateCheckoutSessionInputModePaymentWithPlanIDPaymentMethodConfiguration(TypedDict, total=False):
"""The explicit payment method configuration for the checkout session.
@@ -372,6 +419,12 @@ class CreateCheckoutSessionInputModeSetup(TypedDict, total=False):
mode: Required[Literal["setup"]]
+ checkout_styling: Optional[CreateCheckoutSessionInputModeSetupCheckoutStyling]
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
currency: Optional[Currency]
"""The available currencies on the platform"""
@@ -392,6 +445,22 @@ class CreateCheckoutSessionInputModeSetup(TypedDict, total=False):
"""The URL of the page where the checkout is being initiated from."""
+class CreateCheckoutSessionInputModeSetupCheckoutStyling(TypedDict, total=False):
+ """Checkout styling overrides for this session.
+
+ Overrides plan and company defaults.
+ """
+
+ border_style: Optional[Literal["rounded", "pill", "rectangular"]]
+ """The different border-radius styles available for checkout pages."""
+
+ button_color: Optional[str]
+ """A hex color code for the button color (e.g. #FF5733)."""
+
+ font_family: Optional[Literal["system", "roboto", "open_sans"]]
+ """The different font families available for checkout pages."""
+
+
class CreateCheckoutSessionInputModeSetupPaymentMethodConfiguration(TypedDict, total=False):
"""The explicit payment method configuration for the checkout session.
diff --git a/src/whop_sdk/types/company_list_response.py b/src/whop_sdk/types/company_list_response.py
index 197728d..52d0916 100644
--- a/src/whop_sdk/types/company_list_response.py
+++ b/src/whop_sdk/types/company_list_response.py
@@ -84,6 +84,9 @@ class CompanyListResponse(BaseModel):
behalf of this company.
"""
+ target_audience: Optional[str] = None
+ """The target audience for the company. Null if not set."""
+
title: str
"""The display name of the company shown to customers."""
diff --git a/src/whop_sdk/types/company_update_params.py b/src/whop_sdk/types/company_update_params.py
index c475d5f..15aa74d 100644
--- a/src/whop_sdk/types/company_update_params.py
+++ b/src/whop_sdk/types/company_update_params.py
@@ -9,6 +9,18 @@
class CompanyUpdateParams(TypedDict, total=False):
+ affiliate_application_required: Optional[bool]
+ """
+ Whether prospective affiliates must submit an application before they can
+ promote this company.
+ """
+
+ affiliate_instructions: Optional[str]
+ """
+ Guidelines and instructions shown to affiliates explaining how to promote this
+ company's products.
+ """
+
banner_image: Optional[BannerImage]
"""The company's banner image. Accepts PNG or JPEG format."""
@@ -18,6 +30,12 @@ class CompanyUpdateParams(TypedDict, total=False):
page.
"""
+ featured_affiliate_product_id: Optional[str]
+ """The ID of the product to feature on this company's affiliate page.
+
+ Pass null to clear.
+ """
+
logo: Optional[Logo]
"""The company's logo image. Accepts PNG, JPEG, or GIF format."""
diff --git a/src/whop_sdk/types/invoice_create_params.py b/src/whop_sdk/types/invoice_create_params.py
index a3c6104..a197501 100644
--- a/src/whop_sdk/types/invoice_create_params.py
+++ b/src/whop_sdk/types/invoice_create_params.py
@@ -9,6 +9,7 @@
from .._utils import PropertyInfo
from .shared.plan_type import PlanType
from .shared.visibility import Visibility
+from .tax_identifier_type import TaxIdentifierType
from .shared.release_method import ReleaseMethod
from .shared.collection_method import CollectionMethod
@@ -18,16 +19,24 @@
"CreateInvoiceInputWithProductAndMemberIDPlan",
"CreateInvoiceInputWithProductAndMemberIDPlanCustomField",
"CreateInvoiceInputWithProductAndMemberIDProduct",
+ "CreateInvoiceInputWithProductAndMemberIDBillingAddress",
+ "CreateInvoiceInputWithProductAndMemberIDLineItem",
"CreateInvoiceInputWithProductAndEmailAddress",
"CreateInvoiceInputWithProductAndEmailAddressPlan",
"CreateInvoiceInputWithProductAndEmailAddressPlanCustomField",
"CreateInvoiceInputWithProductAndEmailAddressProduct",
+ "CreateInvoiceInputWithProductAndEmailAddressBillingAddress",
+ "CreateInvoiceInputWithProductAndEmailAddressLineItem",
"CreateInvoiceInputWithProductIDAndMemberID",
"CreateInvoiceInputWithProductIDAndMemberIDPlan",
"CreateInvoiceInputWithProductIDAndMemberIDPlanCustomField",
+ "CreateInvoiceInputWithProductIDAndMemberIDLineItem",
"CreateInvoiceInputWithProductIDAndEmailAddress",
"CreateInvoiceInputWithProductIDAndEmailAddressPlan",
"CreateInvoiceInputWithProductIDAndEmailAddressPlanCustomField",
+ "CreateInvoiceInputWithProductIDAndMemberIDBillingAddress",
+ "CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress",
+ "CreateInvoiceInputWithProductIDAndEmailAddressLineItem",
]
@@ -70,6 +79,12 @@ class CreateInvoiceInputWithProductAndMemberID(TypedDict, total=False):
charge will be processed immediately.
"""
+ billing_address: Optional[CreateInvoiceInputWithProductAndMemberIDBillingAddress]
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
charge_buyer_fee: Optional[bool]
"""Whether to charge the customer a buyer fee on this invoice."""
@@ -80,6 +95,19 @@ class CreateInvoiceInputWithProductAndMemberID(TypedDict, total=False):
company.
"""
+ line_items: Optional[Iterable[CreateInvoiceInputWithProductAndMemberIDLineItem]]
+ """Optional line items that break down the invoice total.
+
+ When provided, the sum of (quantity \\** unit_price) for all items must equal the
+ plan price.
+ """
+
+ mailing_address_id: Optional[str]
+ """The unique identifier of an existing mailing address to attach to this invoice.
+
+ Cannot be used together with billing_address.
+ """
+
payment_method_id: Optional[str]
"""The unique identifier of the payment method to charge.
@@ -186,6 +214,61 @@ class CreateInvoiceInputWithProductAndMemberIDProduct(TypedDict, total=False):
"""The ID of the product tax code to apply to this product."""
+class CreateInvoiceInputWithProductAndMemberIDBillingAddress(TypedDict, total=False):
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
+ city: Optional[str]
+ """The city of the address."""
+
+ country: Optional[str]
+ """The country of the address."""
+
+ line1: Optional[str]
+ """The line 1 of the address."""
+
+ line2: Optional[str]
+ """The line 2 of the address."""
+
+ name: Optional[str]
+ """The name of the customer."""
+
+ phone: Optional[str]
+ """The phone number of the customer."""
+
+ postal_code: Optional[str]
+ """The postal code of the address."""
+
+ state: Optional[str]
+ """The state of the address."""
+
+ tax_id_type: Optional[TaxIdentifierType]
+ """The type of tax identifier"""
+
+ tax_id_value: Optional[str]
+ """The value of the tax identifier."""
+
+
+class CreateInvoiceInputWithProductAndMemberIDLineItem(TypedDict, total=False):
+ """
+ A single line item to include on the invoice, with a label, quantity, and unit price.
+ """
+
+ label: Required[str]
+ """The label or description for this line item."""
+
+ unit_price: Required[float]
+ """The unit price for this line item.
+
+ Provided as a number in the specified currency. Eg: 10.43 for $10.43
+ """
+
+ quantity: Optional[float]
+ """The quantity of this line item. Defaults to 1."""
+
+
class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False):
collection_method: Required[CollectionMethod]
"""How the invoice should be collected.
@@ -226,6 +309,12 @@ class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False):
charge will be processed immediately.
"""
+ billing_address: Optional[CreateInvoiceInputWithProductAndEmailAddressBillingAddress]
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
charge_buyer_fee: Optional[bool]
"""Whether to charge the customer a buyer fee on this invoice."""
@@ -236,6 +325,19 @@ class CreateInvoiceInputWithProductAndEmailAddress(TypedDict, total=False):
company.
"""
+ line_items: Optional[Iterable[CreateInvoiceInputWithProductAndEmailAddressLineItem]]
+ """Optional line items that break down the invoice total.
+
+ When provided, the sum of (quantity \\** unit_price) for all items must equal the
+ plan price.
+ """
+
+ mailing_address_id: Optional[str]
+ """The unique identifier of an existing mailing address to attach to this invoice.
+
+ Cannot be used together with billing_address.
+ """
+
payment_method_id: Optional[str]
"""The unique identifier of the payment method to charge.
@@ -342,6 +444,61 @@ class CreateInvoiceInputWithProductAndEmailAddressProduct(TypedDict, total=False
"""The ID of the product tax code to apply to this product."""
+class CreateInvoiceInputWithProductAndEmailAddressBillingAddress(TypedDict, total=False):
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
+ city: Optional[str]
+ """The city of the address."""
+
+ country: Optional[str]
+ """The country of the address."""
+
+ line1: Optional[str]
+ """The line 1 of the address."""
+
+ line2: Optional[str]
+ """The line 2 of the address."""
+
+ name: Optional[str]
+ """The name of the customer."""
+
+ phone: Optional[str]
+ """The phone number of the customer."""
+
+ postal_code: Optional[str]
+ """The postal code of the address."""
+
+ state: Optional[str]
+ """The state of the address."""
+
+ tax_id_type: Optional[TaxIdentifierType]
+ """The type of tax identifier"""
+
+ tax_id_value: Optional[str]
+ """The value of the tax identifier."""
+
+
+class CreateInvoiceInputWithProductAndEmailAddressLineItem(TypedDict, total=False):
+ """
+ A single line item to include on the invoice, with a label, quantity, and unit price.
+ """
+
+ label: Required[str]
+ """The label or description for this line item."""
+
+ unit_price: Required[float]
+ """The unit price for this line item.
+
+ Provided as a number in the specified currency. Eg: 10.43 for $10.43
+ """
+
+ quantity: Optional[float]
+ """The quantity of this line item. Defaults to 1."""
+
+
class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False):
collection_method: Required[CollectionMethod]
"""How the invoice should be collected.
@@ -378,6 +535,12 @@ class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False):
charge will be processed immediately.
"""
+ billing_address: Optional[CreateInvoiceInputWithProductIDAndMemberIDBillingAddress]
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
charge_buyer_fee: Optional[bool]
"""Whether to charge the customer a buyer fee on this invoice."""
@@ -388,6 +551,19 @@ class CreateInvoiceInputWithProductIDAndMemberID(TypedDict, total=False):
company.
"""
+ line_items: Optional[Iterable[CreateInvoiceInputWithProductIDAndMemberIDLineItem]]
+ """Optional line items that break down the invoice total.
+
+ When provided, the sum of (quantity \\** unit_price) for all items must equal the
+ plan price.
+ """
+
+ mailing_address_id: Optional[str]
+ """The unique identifier of an existing mailing address to attach to this invoice.
+
+ Cannot be used together with billing_address.
+ """
+
payment_method_id: Optional[str]
"""The unique identifier of the payment method to charge.
@@ -481,6 +657,61 @@ class CreateInvoiceInputWithProductIDAndMemberIDPlan(TypedDict, total=False):
"""Visibility of a resource"""
+class CreateInvoiceInputWithProductIDAndMemberIDBillingAddress(TypedDict, total=False):
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
+ city: Optional[str]
+ """The city of the address."""
+
+ country: Optional[str]
+ """The country of the address."""
+
+ line1: Optional[str]
+ """The line 1 of the address."""
+
+ line2: Optional[str]
+ """The line 2 of the address."""
+
+ name: Optional[str]
+ """The name of the customer."""
+
+ phone: Optional[str]
+ """The phone number of the customer."""
+
+ postal_code: Optional[str]
+ """The postal code of the address."""
+
+ state: Optional[str]
+ """The state of the address."""
+
+ tax_id_type: Optional[TaxIdentifierType]
+ """The type of tax identifier"""
+
+ tax_id_value: Optional[str]
+ """The value of the tax identifier."""
+
+
+class CreateInvoiceInputWithProductIDAndMemberIDLineItem(TypedDict, total=False):
+ """
+ A single line item to include on the invoice, with a label, quantity, and unit price.
+ """
+
+ label: Required[str]
+ """The label or description for this line item."""
+
+ unit_price: Required[float]
+ """The unit price for this line item.
+
+ Provided as a number in the specified currency. Eg: 10.43 for $10.43
+ """
+
+ quantity: Optional[float]
+ """The quantity of this line item. Defaults to 1."""
+
+
class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False):
collection_method: Required[CollectionMethod]
"""How the invoice should be collected.
@@ -518,6 +749,12 @@ class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False):
charge will be processed immediately.
"""
+ billing_address: Optional[CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress]
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
charge_buyer_fee: Optional[bool]
"""Whether to charge the customer a buyer fee on this invoice."""
@@ -528,6 +765,19 @@ class CreateInvoiceInputWithProductIDAndEmailAddress(TypedDict, total=False):
company.
"""
+ line_items: Optional[Iterable[CreateInvoiceInputWithProductIDAndEmailAddressLineItem]]
+ """Optional line items that break down the invoice total.
+
+ When provided, the sum of (quantity \\** unit_price) for all items must equal the
+ plan price.
+ """
+
+ mailing_address_id: Optional[str]
+ """The unique identifier of an existing mailing address to attach to this invoice.
+
+ Cannot be used together with billing_address.
+ """
+
payment_method_id: Optional[str]
"""The unique identifier of the payment method to charge.
@@ -621,6 +871,61 @@ class CreateInvoiceInputWithProductIDAndEmailAddressPlan(TypedDict, total=False)
"""Visibility of a resource"""
+class CreateInvoiceInputWithProductIDAndEmailAddressBillingAddress(TypedDict, total=False):
+ """Inline billing address to create a new mailing address for this invoice.
+
+ Cannot be used together with mailing_address_id.
+ """
+
+ city: Optional[str]
+ """The city of the address."""
+
+ country: Optional[str]
+ """The country of the address."""
+
+ line1: Optional[str]
+ """The line 1 of the address."""
+
+ line2: Optional[str]
+ """The line 2 of the address."""
+
+ name: Optional[str]
+ """The name of the customer."""
+
+ phone: Optional[str]
+ """The phone number of the customer."""
+
+ postal_code: Optional[str]
+ """The postal code of the address."""
+
+ state: Optional[str]
+ """The state of the address."""
+
+ tax_id_type: Optional[TaxIdentifierType]
+ """The type of tax identifier"""
+
+ tax_id_value: Optional[str]
+ """The value of the tax identifier."""
+
+
+class CreateInvoiceInputWithProductIDAndEmailAddressLineItem(TypedDict, total=False):
+ """
+ A single line item to include on the invoice, with a label, quantity, and unit price.
+ """
+
+ label: Required[str]
+ """The label or description for this line item."""
+
+ unit_price: Required[float]
+ """The unit price for this line item.
+
+ Provided as a number in the specified currency. Eg: 10.43 for $10.43
+ """
+
+ quantity: Optional[float]
+ """The quantity of this line item. Defaults to 1."""
+
+
InvoiceCreateParams: TypeAlias = Union[
CreateInvoiceInputWithProductAndMemberID,
CreateInvoiceInputWithProductAndEmailAddress,
diff --git a/src/whop_sdk/types/invoice_mark_paid_response.py b/src/whop_sdk/types/invoice_mark_paid_response.py
new file mode 100644
index 0000000..4ea337e
--- /dev/null
+++ b/src/whop_sdk/types/invoice_mark_paid_response.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import TypeAlias
+
+__all__ = ["InvoiceMarkPaidResponse"]
+
+InvoiceMarkPaidResponse: TypeAlias = bool
diff --git a/src/whop_sdk/types/invoice_mark_uncollectible_response.py b/src/whop_sdk/types/invoice_mark_uncollectible_response.py
new file mode 100644
index 0000000..a34c66d
--- /dev/null
+++ b/src/whop_sdk/types/invoice_mark_uncollectible_response.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import TypeAlias
+
+__all__ = ["InvoiceMarkUncollectibleResponse"]
+
+InvoiceMarkUncollectibleResponse: TypeAlias = bool
diff --git a/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py b/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py
new file mode 100644
index 0000000..3152d5d
--- /dev/null
+++ b/src/whop_sdk/types/invoice_marked_uncollectible_webhook_event.py
@@ -0,0 +1,34 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .shared.invoice import Invoice
+
+__all__ = ["InvoiceMarkedUncollectibleWebhookEvent"]
+
+
+class InvoiceMarkedUncollectibleWebhookEvent(BaseModel):
+ id: str
+ """A unique ID for every single webhook request"""
+
+ api_version: Literal["v1"]
+ """The API version for this webhook"""
+
+ data: Invoice
+ """
+ An invoice represents an itemized bill sent by a company to a customer for a
+ specific product and plan, tracking the amount owed, due date, and payment
+ status.
+ """
+
+ timestamp: datetime
+ """The timestamp in ISO 8601 format that the webhook was sent at on the server"""
+
+ type: Literal["invoice.marked_uncollectible"]
+ """The webhook event type"""
+
+ company_id: Optional[str] = None
+ """The company ID that this webhook event is associated with"""
diff --git a/src/whop_sdk/types/payment_create_params.py b/src/whop_sdk/types/payment_create_params.py
index 2d03e3b..3335e5f 100644
--- a/src/whop_sdk/types/payment_create_params.py
+++ b/src/whop_sdk/types/payment_create_params.py
@@ -97,6 +97,14 @@ class CreatePaymentInputWithPlanPlan(TypedDict, total=False):
currency: Required[Currency]
"""The respective currency identifier for the plan."""
+ application_fee_amount: Optional[float]
+ """The application fee amount collected by the platform from this connected
+ account.
+
+ Provided as a number in dollars (e.g., 5.00 for $5.00). Must be less than the
+ total payment amount. Only valid for connected accounts with a parent company.
+ """
+
billing_period: Optional[int]
"""The interval in days at which the plan charges (renewal plans).
diff --git a/src/whop_sdk/types/payment_list_params.py b/src/whop_sdk/types/payment_list_params.py
index 5af6fe5..1fcc2a2 100644
--- a/src/whop_sdk/types/payment_list_params.py
+++ b/src/whop_sdk/types/payment_list_params.py
@@ -74,3 +74,9 @@ class PaymentListParams(TypedDict, total=False):
substatuses: Optional[List[FriendlyReceiptStatus]]
"""Filter payments by their current substatus for more granular filtering."""
+
+ updated_after: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
+ """Only return payments last updated after this timestamp."""
+
+ updated_before: Annotated[Union[str, datetime, None], PropertyInfo(format="iso8601")]
+ """Only return payments last updated before this timestamp."""
diff --git a/src/whop_sdk/types/payment_list_response.py b/src/whop_sdk/types/payment_list_response.py
index 438f5ec..e026626 100644
--- a/src/whop_sdk/types/payment_list_response.py
+++ b/src/whop_sdk/types/payment_list_response.py
@@ -348,6 +348,9 @@ class PaymentListResponse(BaseModel):
total: Optional[float] = None
"""The total to show to the creator (excluding buyer fees)."""
+ updated_at: datetime
+ """The datetime the payment was last updated."""
+
usd_total: Optional[float] = None
"""The total in USD to show to the creator (excluding buyer fees)."""
diff --git a/src/whop_sdk/types/payment_method_types.py b/src/whop_sdk/types/payment_method_types.py
index c61cc63..526c34f 100644
--- a/src/whop_sdk/types/payment_method_types.py
+++ b/src/whop_sdk/types/payment_method_types.py
@@ -94,5 +94,6 @@
"vipps",
"wechat_pay",
"zip",
+ "coinflow",
"unknown",
]
diff --git a/src/whop_sdk/types/payment_provider.py b/src/whop_sdk/types/payment_provider.py
index c2ba590..6d8567f 100644
--- a/src/whop_sdk/types/payment_provider.py
+++ b/src/whop_sdk/types/payment_provider.py
@@ -17,4 +17,6 @@
"claritypay",
"checkout_dot_com",
"airwallex",
+ "coinflow",
+ "sequra",
]
diff --git a/src/whop_sdk/types/plan_create_params.py b/src/whop_sdk/types/plan_create_params.py
index 5fd63de..aebe213 100644
--- a/src/whop_sdk/types/plan_create_params.py
+++ b/src/whop_sdk/types/plan_create_params.py
@@ -12,7 +12,7 @@
from .payment_method_types import PaymentMethodTypes
from .shared.release_method import ReleaseMethod
-__all__ = ["PlanCreateParams", "CustomField", "Image", "PaymentMethodConfiguration"]
+__all__ = ["PlanCreateParams", "CheckoutStyling", "CustomField", "Image", "PaymentMethodConfiguration"]
class PlanCreateParams(TypedDict, total=False):
@@ -28,6 +28,12 @@ class PlanCreateParams(TypedDict, total=False):
For example, 30 for monthly or 365 for yearly.
"""
+ checkout_styling: Optional[CheckoutStyling]
+ """Checkout styling overrides for this plan.
+
+ Pass null to inherit from the company default.
+ """
+
currency: Optional[Currency]
"""The available currencies on the platform"""
@@ -109,6 +115,22 @@ class PlanCreateParams(TypedDict, total=False):
"""Visibility of a resource"""
+class CheckoutStyling(TypedDict, total=False):
+ """Checkout styling overrides for this plan.
+
+ Pass null to inherit from the company default.
+ """
+
+ border_style: Optional[Literal["rounded", "pill", "rectangular"]]
+ """The different border-radius styles available for checkout pages."""
+
+ button_color: Optional[str]
+ """A hex color code for the button color (e.g. #FF5733)."""
+
+ font_family: Optional[Literal["system", "roboto", "open_sans"]]
+ """The different font families available for checkout pages."""
+
+
class CustomField(TypedDict, total=False):
field_type: Required[Literal["text"]]
"""The type of the custom field."""
diff --git a/src/whop_sdk/types/plan_update_params.py b/src/whop_sdk/types/plan_update_params.py
index 6750817..d98f100 100644
--- a/src/whop_sdk/types/plan_update_params.py
+++ b/src/whop_sdk/types/plan_update_params.py
@@ -10,7 +10,7 @@
from .shared.visibility import Visibility
from .payment_method_types import PaymentMethodTypes
-__all__ = ["PlanUpdateParams", "CustomField", "Image", "PaymentMethodConfiguration"]
+__all__ = ["PlanUpdateParams", "CheckoutStyling", "CustomField", "Image", "PaymentMethodConfiguration"]
class PlanUpdateParams(TypedDict, total=False):
@@ -20,6 +20,12 @@ class PlanUpdateParams(TypedDict, total=False):
For example, 30 for monthly or 365 for yearly.
"""
+ checkout_styling: Optional[CheckoutStyling]
+ """Checkout styling overrides for this plan.
+
+ Pass null to remove all overrides and inherit from the company default.
+ """
+
currency: Optional[Currency]
"""The available currencies on the platform"""
@@ -102,6 +108,22 @@ class PlanUpdateParams(TypedDict, total=False):
"""Visibility of a resource"""
+class CheckoutStyling(TypedDict, total=False):
+ """Checkout styling overrides for this plan.
+
+ Pass null to remove all overrides and inherit from the company default.
+ """
+
+ border_style: Optional[Literal["rounded", "pill", "rectangular"]]
+ """The different border-radius styles available for checkout pages."""
+
+ button_color: Optional[str]
+ """A hex color code for the button color (e.g. #FF5733)."""
+
+ font_family: Optional[Literal["system", "roboto", "open_sans"]]
+ """The different font families available for checkout pages."""
+
+
class CustomField(TypedDict, total=False):
field_type: Required[Literal["text"]]
"""The type of the custom field."""
diff --git a/src/whop_sdk/types/product_create_params.py b/src/whop_sdk/types/product_create_params.py
index ea86cc0..ed4c851 100644
--- a/src/whop_sdk/types/product_create_params.py
+++ b/src/whop_sdk/types/product_create_params.py
@@ -21,7 +21,7 @@ class ProductCreateParams(TypedDict, total=False):
"""The unique identifier of the company to create this product for."""
title: Required[str]
- """The display name of the product. Maximum 40 characters."""
+ """The display name of the product. Maximum 80 characters."""
collect_shipping_address: Optional[bool]
"""Whether the checkout flow collects a shipping address from the customer."""
diff --git a/src/whop_sdk/types/product_update_params.py b/src/whop_sdk/types/product_update_params.py
index d7e9dca..6082edf 100644
--- a/src/whop_sdk/types/product_update_params.py
+++ b/src/whop_sdk/types/product_update_params.py
@@ -78,7 +78,7 @@ class ProductUpdateParams(TypedDict, total=False):
"""Layout and display configuration for this product on the company's store page."""
title: Optional[str]
- """The display name of the product. Maximum 40 characters."""
+ """The display name of the product. Maximum 80 characters."""
visibility: Optional[Visibility]
"""Visibility of a resource"""
diff --git a/src/whop_sdk/types/resolution_center_case_created_webhook_event.py b/src/whop_sdk/types/resolution_center_case_created_webhook_event.py
new file mode 100644
index 0000000..ef32678
--- /dev/null
+++ b/src/whop_sdk/types/resolution_center_case_created_webhook_event.py
@@ -0,0 +1,221 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .shared.currency import Currency
+from .resolution_center_case_status import ResolutionCenterCaseStatus
+from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType
+from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse
+from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse
+from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse
+
+__all__ = [
+ "ResolutionCenterCaseCreatedWebhookEvent",
+ "Data",
+ "DataCompany",
+ "DataMember",
+ "DataPayment",
+ "DataResolutionEvent",
+ "DataUser",
+]
+
+
+class DataCompany(BaseModel):
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the company."""
+
+ title: str
+ """The display name of the company shown to customers."""
+
+
+class DataMember(BaseModel):
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the extra public member."""
+
+
+class DataPayment(BaseModel):
+ """The payment record that is the subject of this resolution case."""
+
+ id: str
+ """The unique identifier for the payment."""
+
+ created_at: datetime
+ """The datetime the payment was created."""
+
+ currency: Optional[Currency] = None
+ """The available currencies on the platform"""
+
+ paid_at: Optional[datetime] = None
+ """The time at which this payment was successfully collected.
+
+ Null if the payment has not yet succeeded. As a Unix timestamp.
+ """
+
+ subtotal: Optional[float] = None
+ """The payment amount before taxes and discounts are applied.
+
+ In the currency specified by the currency field.
+ """
+
+ total: float
+ """
+ The total amount charged to the customer for this payment, including taxes and
+ after any discounts. In the currency specified by the currency field.
+ """
+
+
+class DataResolutionEvent(BaseModel):
+ """
+ A resolution event is a message or action within a resolution case, such as a response, escalation, or status change.
+ """
+
+ id: str
+ """The unique identifier for the resolution event."""
+
+ action: Literal[
+ "created",
+ "responded",
+ "accepted",
+ "denied",
+ "appealed",
+ "withdrew",
+ "requested_more_info",
+ "escalated",
+ "dispute_opened",
+ "dispute_customer_won",
+ "dispute_merchant_won",
+ ]
+ """The type of action recorded in this event."""
+
+ created_at: datetime
+ """The datetime the resolution event was created."""
+
+ details: Optional[str] = None
+ """The message body or additional context provided with this resolution event.
+
+ Null if no details were included.
+ """
+
+ reporter_type: Literal["merchant", "customer", "platform", "system"]
+ """The party who performed this action."""
+
+
+class DataUser(BaseModel):
+ """The customer (buyer) who filed this resolution case."""
+
+ id: str
+ """The unique identifier for the user."""
+
+ name: Optional[str] = None
+ """The user's display name shown on their public profile."""
+
+ username: str
+ """The user's unique username shown on their public profile."""
+
+
+class Data(BaseModel):
+ """
+ A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome.
+ """
+
+ id: str
+ """The unique identifier for the resolution."""
+
+ company: Optional[DataCompany] = None
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ created_at: datetime
+ """The datetime the resolution was created."""
+
+ customer_appealed: bool
+ """Whether the customer has filed an appeal after the initial resolution decision."""
+
+ customer_response_actions: List[ResolutionCenterCaseCustomerResponse]
+ """The list of actions currently available to the customer."""
+
+ due_date: Optional[datetime] = None
+ """The deadline by which the next response is required.
+
+ Null if no deadline is currently active. As a Unix timestamp.
+ """
+
+ issue: ResolutionCenterCaseIssueType
+ """The category of the dispute."""
+
+ member: Optional[DataMember] = None
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ merchant_appealed: bool
+ """Whether the merchant has filed an appeal after the initial resolution decision."""
+
+ merchant_response_actions: List[ResolutionCenterCaseMerchantResponse]
+ """The list of actions currently available to the merchant."""
+
+ payment: DataPayment
+ """The payment record that is the subject of this resolution case."""
+
+ platform_response_actions: List[ResolutionCenterCasePlatformResponse]
+ """
+ The list of actions currently available to the Whop platform for moderating this
+ resolution.
+ """
+
+ resolution_events: List[DataResolutionEvent]
+ """
+ The most recent 50 messages, actions, and status changes that have occurred
+ during this resolution case.
+ """
+
+ status: ResolutionCenterCaseStatus
+ """
+ The current status of the resolution case, indicating which party needs to
+ respond or if the case is closed.
+ """
+
+ updated_at: datetime
+ """The datetime the resolution was last updated."""
+
+ user: DataUser
+ """The customer (buyer) who filed this resolution case."""
+
+
+class ResolutionCenterCaseCreatedWebhookEvent(BaseModel):
+ id: str
+ """A unique ID for every single webhook request"""
+
+ api_version: Literal["v1"]
+ """The API version for this webhook"""
+
+ data: Data
+ """
+ A resolution center case is a dispute or support case between a user and a
+ company, tracking the issue, status, and outcome.
+ """
+
+ timestamp: datetime
+ """The timestamp in ISO 8601 format that the webhook was sent at on the server"""
+
+ type: Literal["resolution_center_case.created"]
+ """The webhook event type"""
+
+ company_id: Optional[str] = None
+ """The company ID that this webhook event is associated with"""
diff --git a/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py b/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py
new file mode 100644
index 0000000..c4641db
--- /dev/null
+++ b/src/whop_sdk/types/resolution_center_case_decided_webhook_event.py
@@ -0,0 +1,221 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .shared.currency import Currency
+from .resolution_center_case_status import ResolutionCenterCaseStatus
+from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType
+from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse
+from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse
+from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse
+
+__all__ = [
+ "ResolutionCenterCaseDecidedWebhookEvent",
+ "Data",
+ "DataCompany",
+ "DataMember",
+ "DataPayment",
+ "DataResolutionEvent",
+ "DataUser",
+]
+
+
+class DataCompany(BaseModel):
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the company."""
+
+ title: str
+ """The display name of the company shown to customers."""
+
+
+class DataMember(BaseModel):
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the extra public member."""
+
+
+class DataPayment(BaseModel):
+ """The payment record that is the subject of this resolution case."""
+
+ id: str
+ """The unique identifier for the payment."""
+
+ created_at: datetime
+ """The datetime the payment was created."""
+
+ currency: Optional[Currency] = None
+ """The available currencies on the platform"""
+
+ paid_at: Optional[datetime] = None
+ """The time at which this payment was successfully collected.
+
+ Null if the payment has not yet succeeded. As a Unix timestamp.
+ """
+
+ subtotal: Optional[float] = None
+ """The payment amount before taxes and discounts are applied.
+
+ In the currency specified by the currency field.
+ """
+
+ total: float
+ """
+ The total amount charged to the customer for this payment, including taxes and
+ after any discounts. In the currency specified by the currency field.
+ """
+
+
+class DataResolutionEvent(BaseModel):
+ """
+ A resolution event is a message or action within a resolution case, such as a response, escalation, or status change.
+ """
+
+ id: str
+ """The unique identifier for the resolution event."""
+
+ action: Literal[
+ "created",
+ "responded",
+ "accepted",
+ "denied",
+ "appealed",
+ "withdrew",
+ "requested_more_info",
+ "escalated",
+ "dispute_opened",
+ "dispute_customer_won",
+ "dispute_merchant_won",
+ ]
+ """The type of action recorded in this event."""
+
+ created_at: datetime
+ """The datetime the resolution event was created."""
+
+ details: Optional[str] = None
+ """The message body or additional context provided with this resolution event.
+
+ Null if no details were included.
+ """
+
+ reporter_type: Literal["merchant", "customer", "platform", "system"]
+ """The party who performed this action."""
+
+
+class DataUser(BaseModel):
+ """The customer (buyer) who filed this resolution case."""
+
+ id: str
+ """The unique identifier for the user."""
+
+ name: Optional[str] = None
+ """The user's display name shown on their public profile."""
+
+ username: str
+ """The user's unique username shown on their public profile."""
+
+
+class Data(BaseModel):
+ """
+ A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome.
+ """
+
+ id: str
+ """The unique identifier for the resolution."""
+
+ company: Optional[DataCompany] = None
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ created_at: datetime
+ """The datetime the resolution was created."""
+
+ customer_appealed: bool
+ """Whether the customer has filed an appeal after the initial resolution decision."""
+
+ customer_response_actions: List[ResolutionCenterCaseCustomerResponse]
+ """The list of actions currently available to the customer."""
+
+ due_date: Optional[datetime] = None
+ """The deadline by which the next response is required.
+
+ Null if no deadline is currently active. As a Unix timestamp.
+ """
+
+ issue: ResolutionCenterCaseIssueType
+ """The category of the dispute."""
+
+ member: Optional[DataMember] = None
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ merchant_appealed: bool
+ """Whether the merchant has filed an appeal after the initial resolution decision."""
+
+ merchant_response_actions: List[ResolutionCenterCaseMerchantResponse]
+ """The list of actions currently available to the merchant."""
+
+ payment: DataPayment
+ """The payment record that is the subject of this resolution case."""
+
+ platform_response_actions: List[ResolutionCenterCasePlatformResponse]
+ """
+ The list of actions currently available to the Whop platform for moderating this
+ resolution.
+ """
+
+ resolution_events: List[DataResolutionEvent]
+ """
+ The most recent 50 messages, actions, and status changes that have occurred
+ during this resolution case.
+ """
+
+ status: ResolutionCenterCaseStatus
+ """
+ The current status of the resolution case, indicating which party needs to
+ respond or if the case is closed.
+ """
+
+ updated_at: datetime
+ """The datetime the resolution was last updated."""
+
+ user: DataUser
+ """The customer (buyer) who filed this resolution case."""
+
+
+class ResolutionCenterCaseDecidedWebhookEvent(BaseModel):
+ id: str
+ """A unique ID for every single webhook request"""
+
+ api_version: Literal["v1"]
+ """The API version for this webhook"""
+
+ data: Data
+ """
+ A resolution center case is a dispute or support case between a user and a
+ company, tracking the issue, status, and outcome.
+ """
+
+ timestamp: datetime
+ """The timestamp in ISO 8601 format that the webhook was sent at on the server"""
+
+ type: Literal["resolution_center_case.decided"]
+ """The webhook event type"""
+
+ company_id: Optional[str] = None
+ """The company ID that this webhook event is associated with"""
diff --git a/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py b/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py
new file mode 100644
index 0000000..349256f
--- /dev/null
+++ b/src/whop_sdk/types/resolution_center_case_updated_webhook_event.py
@@ -0,0 +1,221 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .shared.currency import Currency
+from .resolution_center_case_status import ResolutionCenterCaseStatus
+from .resolution_center_case_issue_type import ResolutionCenterCaseIssueType
+from .resolution_center_case_customer_response import ResolutionCenterCaseCustomerResponse
+from .resolution_center_case_merchant_response import ResolutionCenterCaseMerchantResponse
+from .resolution_center_case_platform_response import ResolutionCenterCasePlatformResponse
+
+__all__ = [
+ "ResolutionCenterCaseUpdatedWebhookEvent",
+ "Data",
+ "DataCompany",
+ "DataMember",
+ "DataPayment",
+ "DataResolutionEvent",
+ "DataUser",
+]
+
+
+class DataCompany(BaseModel):
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the company."""
+
+ title: str
+ """The display name of the company shown to customers."""
+
+
+class DataMember(BaseModel):
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ id: str
+ """The unique identifier for the extra public member."""
+
+
+class DataPayment(BaseModel):
+ """The payment record that is the subject of this resolution case."""
+
+ id: str
+ """The unique identifier for the payment."""
+
+ created_at: datetime
+ """The datetime the payment was created."""
+
+ currency: Optional[Currency] = None
+ """The available currencies on the platform"""
+
+ paid_at: Optional[datetime] = None
+ """The time at which this payment was successfully collected.
+
+ Null if the payment has not yet succeeded. As a Unix timestamp.
+ """
+
+ subtotal: Optional[float] = None
+ """The payment amount before taxes and discounts are applied.
+
+ In the currency specified by the currency field.
+ """
+
+ total: float
+ """
+ The total amount charged to the customer for this payment, including taxes and
+ after any discounts. In the currency specified by the currency field.
+ """
+
+
+class DataResolutionEvent(BaseModel):
+ """
+ A resolution event is a message or action within a resolution case, such as a response, escalation, or status change.
+ """
+
+ id: str
+ """The unique identifier for the resolution event."""
+
+ action: Literal[
+ "created",
+ "responded",
+ "accepted",
+ "denied",
+ "appealed",
+ "withdrew",
+ "requested_more_info",
+ "escalated",
+ "dispute_opened",
+ "dispute_customer_won",
+ "dispute_merchant_won",
+ ]
+ """The type of action recorded in this event."""
+
+ created_at: datetime
+ """The datetime the resolution event was created."""
+
+ details: Optional[str] = None
+ """The message body or additional context provided with this resolution event.
+
+ Null if no details were included.
+ """
+
+ reporter_type: Literal["merchant", "customer", "platform", "system"]
+ """The party who performed this action."""
+
+
+class DataUser(BaseModel):
+ """The customer (buyer) who filed this resolution case."""
+
+ id: str
+ """The unique identifier for the user."""
+
+ name: Optional[str] = None
+ """The user's display name shown on their public profile."""
+
+ username: str
+ """The user's unique username shown on their public profile."""
+
+
+class Data(BaseModel):
+ """
+ A resolution center case is a dispute or support case between a user and a company, tracking the issue, status, and outcome.
+ """
+
+ id: str
+ """The unique identifier for the resolution."""
+
+ company: Optional[DataCompany] = None
+ """The company involved in this resolution case.
+
+ Null if the company no longer exists.
+ """
+
+ created_at: datetime
+ """The datetime the resolution was created."""
+
+ customer_appealed: bool
+ """Whether the customer has filed an appeal after the initial resolution decision."""
+
+ customer_response_actions: List[ResolutionCenterCaseCustomerResponse]
+ """The list of actions currently available to the customer."""
+
+ due_date: Optional[datetime] = None
+ """The deadline by which the next response is required.
+
+ Null if no deadline is currently active. As a Unix timestamp.
+ """
+
+ issue: ResolutionCenterCaseIssueType
+ """The category of the dispute."""
+
+ member: Optional[DataMember] = None
+ """The membership record associated with the disputed payment.
+
+ Null if the membership no longer exists.
+ """
+
+ merchant_appealed: bool
+ """Whether the merchant has filed an appeal after the initial resolution decision."""
+
+ merchant_response_actions: List[ResolutionCenterCaseMerchantResponse]
+ """The list of actions currently available to the merchant."""
+
+ payment: DataPayment
+ """The payment record that is the subject of this resolution case."""
+
+ platform_response_actions: List[ResolutionCenterCasePlatformResponse]
+ """
+ The list of actions currently available to the Whop platform for moderating this
+ resolution.
+ """
+
+ resolution_events: List[DataResolutionEvent]
+ """
+ The most recent 50 messages, actions, and status changes that have occurred
+ during this resolution case.
+ """
+
+ status: ResolutionCenterCaseStatus
+ """
+ The current status of the resolution case, indicating which party needs to
+ respond or if the case is closed.
+ """
+
+ updated_at: datetime
+ """The datetime the resolution was last updated."""
+
+ user: DataUser
+ """The customer (buyer) who filed this resolution case."""
+
+
+class ResolutionCenterCaseUpdatedWebhookEvent(BaseModel):
+ id: str
+ """A unique ID for every single webhook request"""
+
+ api_version: Literal["v1"]
+ """The API version for this webhook"""
+
+ data: Data
+ """
+ A resolution center case is a dispute or support case between a user and a
+ company, tracking the issue, status, and outcome.
+ """
+
+ timestamp: datetime
+ """The timestamp in ISO 8601 format that the webhook was sent at on the server"""
+
+ type: Literal["resolution_center_case.updated"]
+ """The webhook event type"""
+
+ company_id: Optional[str] = None
+ """The company ID that this webhook event is associated with"""
diff --git a/src/whop_sdk/types/shared/app.py b/src/whop_sdk/types/shared/app.py
index ad75be7..9082899 100644
--- a/src/whop_sdk/types/shared/app.py
+++ b/src/whop_sdk/types/shared/app.py
@@ -205,6 +205,19 @@ class App(BaseModel):
Maximum 30 characters.
"""
+ openapi_path: Optional[str] = None
+ """
+ The URL path template for a specific view of this app, appended to the base
+ domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is
+ not configured.
+ """
+
+ origin: Optional[str] = None
+ """
+ The full origin URL for this app's proxied domain (e.g.,
+ 'https://myapp.apps.whop.com'). Null if no proxy domain is configured.
+ """
+
redirect_uris: List[str]
"""
The whitelisted OAuth callback URLs that users are redirected to after
@@ -217,6 +230,13 @@ class App(BaseModel):
required and optional permissions with justifications.
"""
+ skills_path: Optional[str] = None
+ """
+ The URL path template for a specific view of this app, appended to the base
+ domain (e.g., '/experiences/[experienceId]'). Null if the specified view type is
+ not configured.
+ """
+
stats: Optional[Stats] = None
"""
Aggregate usage statistics for this app, including daily, weekly, and monthly
diff --git a/src/whop_sdk/types/shared/app_view_type.py b/src/whop_sdk/types/shared/app_view_type.py
index 6665d5b..05a0086 100644
--- a/src/whop_sdk/types/shared/app_view_type.py
+++ b/src/whop_sdk/types/shared/app_view_type.py
@@ -4,4 +4,4 @@
__all__ = ["AppViewType"]
-AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics"]
+AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics", "skills", "openapi"]
diff --git a/src/whop_sdk/types/shared/company.py b/src/whop_sdk/types/shared/company.py
index e30b8c1..5155b67 100644
--- a/src/whop_sdk/types/shared/company.py
+++ b/src/whop_sdk/types/shared/company.py
@@ -6,7 +6,20 @@
from ..._models import BaseModel
-__all__ = ["Company", "Logo", "OwnerUser", "SocialLink"]
+__all__ = ["Company", "FeaturedAffiliateProduct", "Logo", "OwnerUser", "SocialLink"]
+
+
+class FeaturedAffiliateProduct(BaseModel):
+ """The product featured for affiliates to promote on this company's affiliate page.
+
+ Null if none is configured.
+ """
+
+ id: str
+ """The unique identifier for the product."""
+
+ name: str
+ """The display name of the product shown to customers. Maximum 50 characters."""
class Logo(BaseModel):
@@ -54,6 +67,12 @@ class Company(BaseModel):
id: str
"""The unique identifier for the company."""
+ affiliate_instructions: Optional[str] = None
+ """
+ Guidelines and instructions provided to affiliates explaining how to promote
+ this company's products.
+ """
+
created_at: datetime
"""The datetime the company was created."""
@@ -63,6 +82,12 @@ class Company(BaseModel):
customers on the store page.
"""
+ featured_affiliate_product: Optional[FeaturedAffiliateProduct] = None
+ """The product featured for affiliates to promote on this company's affiliate page.
+
+ Null if none is configured.
+ """
+
logo: Optional[Logo] = None
"""The company's logo."""
@@ -104,6 +129,9 @@ class Company(BaseModel):
company.
"""
+ target_audience: Optional[str] = None
+ """The target audience for the company. Null if not set."""
+
title: str
"""The display name of the company shown to customers."""
diff --git a/src/whop_sdk/types/shared/invoice_status.py b/src/whop_sdk/types/shared/invoice_status.py
index 255b6a7..7e48fb6 100644
--- a/src/whop_sdk/types/shared/invoice_status.py
+++ b/src/whop_sdk/types/shared/invoice_status.py
@@ -4,4 +4,4 @@
__all__ = ["InvoiceStatus"]
-InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "void"]
+InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "uncollectible", "void"]
diff --git a/src/whop_sdk/types/shared/payment.py b/src/whop_sdk/types/shared/payment.py
index 009f035..4d92b9e 100644
--- a/src/whop_sdk/types/shared/payment.py
+++ b/src/whop_sdk/types/shared/payment.py
@@ -154,7 +154,17 @@ class FinancingTransaction(BaseModel):
"""The date and time the payment transaction was created."""
status: Literal[
- "succeeded", "declined", "error", "pending", "created", "expired", "won", "rejected", "lost", "prevented"
+ "succeeded",
+ "declined",
+ "error",
+ "pending",
+ "created",
+ "expired",
+ "won",
+ "rejected",
+ "lost",
+ "prevented",
+ "canceled",
]
"""The status of the payment transaction."""
@@ -163,7 +173,7 @@ class FinancingTransaction(BaseModel):
"authorize",
"capture",
"refund",
- "cancel",
+ "canceled",
"verify",
"chargeback",
"pre_chargeback",
@@ -501,6 +511,9 @@ class Payment(BaseModel):
total: Optional[float] = None
"""The total to show to the creator (excluding buyer fees)."""
+ updated_at: datetime
+ """The datetime the payment was last updated."""
+
usd_total: Optional[float] = None
"""The total in USD to show to the creator (excluding buyer fees)."""
diff --git a/src/whop_sdk/types/shared_params/app_view_type.py b/src/whop_sdk/types/shared_params/app_view_type.py
index 65c818f..2b60454 100644
--- a/src/whop_sdk/types/shared_params/app_view_type.py
+++ b/src/whop_sdk/types/shared_params/app_view_type.py
@@ -6,4 +6,4 @@
__all__ = ["AppViewType"]
-AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics"]
+AppViewType: TypeAlias = Literal["hub", "discover", "dash", "dashboard", "analytics", "skills", "openapi"]
diff --git a/src/whop_sdk/types/shared_params/invoice_status.py b/src/whop_sdk/types/shared_params/invoice_status.py
index 1006ba8..906e062 100644
--- a/src/whop_sdk/types/shared_params/invoice_status.py
+++ b/src/whop_sdk/types/shared_params/invoice_status.py
@@ -6,4 +6,4 @@
__all__ = ["InvoiceStatus"]
-InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "void"]
+InvoiceStatus: TypeAlias = Literal["draft", "open", "paid", "past_due", "uncollectible", "void"]
diff --git a/src/whop_sdk/types/tax_identifier_type.py b/src/whop_sdk/types/tax_identifier_type.py
new file mode 100644
index 0000000..6b186a3
--- /dev/null
+++ b/src/whop_sdk/types/tax_identifier_type.py
@@ -0,0 +1,119 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["TaxIdentifierType"]
+
+TaxIdentifierType: TypeAlias = Literal[
+ "ad_nrt",
+ "ao_tin",
+ "ar_cuit",
+ "am_tin",
+ "aw_tin",
+ "au_abn",
+ "au_arn",
+ "eu_vat",
+ "az_tin",
+ "bs_tin",
+ "bh_vat",
+ "bd_bin",
+ "bb_tin",
+ "by_tin",
+ "bj_ifu",
+ "bo_tin",
+ "ba_tin",
+ "br_cnpj",
+ "br_cpf",
+ "bg_uic",
+ "bf_ifu",
+ "kh_tin",
+ "cm_niu",
+ "ca_bn",
+ "ca_gst_hst",
+ "ca_pst_bc",
+ "ca_pst_mb",
+ "ca_pst_sk",
+ "ca_qst",
+ "cv_nif",
+ "cl_tin",
+ "cn_tin",
+ "co_nit",
+ "cd_nif",
+ "cr_tin",
+ "hr_oib",
+ "do_rcn",
+ "ec_ruc",
+ "eg_tin",
+ "sv_nit",
+ "et_tin",
+ "eu_oss_vat",
+ "ge_vat",
+ "de_stn",
+ "gb_vat",
+ "gn_nif",
+ "hk_br",
+ "hu_tin",
+ "is_vat",
+ "in_gst",
+ "id_npwp",
+ "il_vat",
+ "jp_cn",
+ "jp_rn",
+ "jp_trn",
+ "kz_bin",
+ "ke_pin",
+ "kg_tin",
+ "la_tin",
+ "li_uid",
+ "li_vat",
+ "my_frp",
+ "my_itn",
+ "my_sst",
+ "mr_nif",
+ "mx_rfc",
+ "md_vat",
+ "me_pib",
+ "ma_vat",
+ "np_pan",
+ "nz_gst",
+ "ng_tin",
+ "mk_vat",
+ "no_vat",
+ "no_voec",
+ "om_vat",
+ "pe_ruc",
+ "ph_tin",
+ "pl_nip",
+ "ro_tin",
+ "ru_inn",
+ "ru_kpp",
+ "sa_vat",
+ "sn_ninea",
+ "rs_pib",
+ "sg_gst",
+ "sg_uen",
+ "si_tin",
+ "za_vat",
+ "kr_brn",
+ "es_cif",
+ "ch_uid",
+ "ch_vat",
+ "tw_vat",
+ "tj_tin",
+ "tz_vat",
+ "th_vat",
+ "tr_tin",
+ "ug_tin",
+ "ua_vat",
+ "ae_trn",
+ "us_ein",
+ "uy_ruc",
+ "uz_tin",
+ "uz_vat",
+ "ve_rif",
+ "vn_tin",
+ "zm_tin",
+ "zw_tin",
+ "sr_fin",
+ "xi_vat",
+]
diff --git a/src/whop_sdk/types/unwrap_webhook_event.py b/src/whop_sdk/types/unwrap_webhook_event.py
index 78041be..96f1582 100644
--- a/src/whop_sdk/types/unwrap_webhook_event.py
+++ b/src/whop_sdk/types/unwrap_webhook_event.py
@@ -29,8 +29,12 @@
from .membership_deactivated_webhook_event import MembershipDeactivatedWebhookEvent
from .setup_intent_succeeded_webhook_event import SetupIntentSucceededWebhookEvent
from .verification_succeeded_webhook_event import VerificationSucceededWebhookEvent
+from .invoice_marked_uncollectible_webhook_event import InvoiceMarkedUncollectibleWebhookEvent
from .setup_intent_requires_action_webhook_event import SetupIntentRequiresActionWebhookEvent
from .payout_account_status_updated_webhook_event import PayoutAccountStatusUpdatedWebhookEvent
+from .resolution_center_case_created_webhook_event import ResolutionCenterCaseCreatedWebhookEvent
+from .resolution_center_case_decided_webhook_event import ResolutionCenterCaseDecidedWebhookEvent
+from .resolution_center_case_updated_webhook_event import ResolutionCenterCaseUpdatedWebhookEvent
from .course_lesson_interaction_completed_webhook_event import CourseLessonInteractionCompletedWebhookEvent
from .membership_cancel_at_period_end_changed_webhook_event import MembershipCancelAtPeriodEndChangedWebhookEvent
@@ -39,6 +43,7 @@
UnwrapWebhookEvent: TypeAlias = Annotated[
Union[
InvoiceCreatedWebhookEvent,
+ InvoiceMarkedUncollectibleWebhookEvent,
InvoicePaidWebhookEvent,
InvoicePastDueWebhookEvent,
InvoiceVoidedWebhookEvent,
@@ -57,6 +62,9 @@
PayoutMethodCreatedWebhookEvent,
VerificationSucceededWebhookEvent,
PayoutAccountStatusUpdatedWebhookEvent,
+ ResolutionCenterCaseCreatedWebhookEvent,
+ ResolutionCenterCaseUpdatedWebhookEvent,
+ ResolutionCenterCaseDecidedWebhookEvent,
PaymentCreatedWebhookEvent,
PaymentSucceededWebhookEvent,
PaymentFailedWebhookEvent,
diff --git a/src/whop_sdk/types/webhook_event.py b/src/whop_sdk/types/webhook_event.py
index e2a5415..174e660 100644
--- a/src/whop_sdk/types/webhook_event.py
+++ b/src/whop_sdk/types/webhook_event.py
@@ -6,6 +6,7 @@
WebhookEvent: TypeAlias = Literal[
"invoice.created",
+ "invoice.marked_uncollectible",
"invoice.paid",
"invoice.past_due",
"invoice.voided",
@@ -24,6 +25,9 @@
"payout_method.created",
"verification.succeeded",
"payout_account.status_updated",
+ "resolution_center_case.created",
+ "resolution_center_case.updated",
+ "resolution_center_case.decided",
"payment.created",
"payment.succeeded",
"payment.failed",
diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py
index 1eb7bce..042e705 100644
--- a/tests/api_resources/test_apps.py
+++ b/tests/api_resources/test_apps.py
@@ -133,8 +133,10 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
icon={"id": "id"},
name="name",
oauth_client_type="public",
+ openapi_path="openapi_path",
redirect_uris=["string"],
required_scopes=["read_user"],
+ skills_path="skills_path",
status="live",
)
assert_matches_type(App, app, path=["response"])
@@ -339,8 +341,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
icon={"id": "id"},
name="name",
oauth_client_type="public",
+ openapi_path="openapi_path",
redirect_uris=["string"],
required_scopes=["read_user"],
+ skills_path="skills_path",
status="live",
)
assert_matches_type(App, app, path=["response"])
diff --git a/tests/api_resources/test_checkout_configurations.py b/tests/api_resources/test_checkout_configurations.py
index 8345d28..cb45542 100644
--- a/tests/api_resources/test_checkout_configurations.py
+++ b/tests/api_resources/test_checkout_configurations.py
@@ -89,6 +89,11 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None:
"visibility": "visible",
},
affiliate_code="affiliate_code",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
mode="payment",
@@ -148,6 +153,11 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None:
checkout_configuration = client.checkout_configurations.create(
plan_id="plan_xxxxxxxxxxxxx",
affiliate_code="affiliate_code",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
mode="payment",
@@ -202,6 +212,11 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None:
checkout_configuration = client.checkout_configurations.create(
company_id="biz_xxxxxxxxxxxxxx",
mode="setup",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
payment_method_configuration={
@@ -415,6 +430,11 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
"visibility": "visible",
},
affiliate_code="affiliate_code",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
mode="payment",
@@ -474,6 +494,11 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn
checkout_configuration = await async_client.checkout_configurations.create(
plan_id="plan_xxxxxxxxxxxxx",
affiliate_code="affiliate_code",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
mode="payment",
@@ -528,6 +553,11 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn
checkout_configuration = await async_client.checkout_configurations.create(
company_id="biz_xxxxxxxxxxxxxx",
mode="setup",
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
metadata={"foo": "bar"},
payment_method_configuration={
diff --git a/tests/api_resources/test_companies.py b/tests/api_resources/test_companies.py
index 30eb5eb..8b3e6f8 100644
--- a/tests/api_resources/test_companies.py
+++ b/tests/api_resources/test_companies.py
@@ -125,8 +125,11 @@ def test_method_update(self, client: Whop) -> None:
def test_method_update_with_all_params(self, client: Whop) -> None:
company = client.companies.update(
id="biz_xxxxxxxxxxxxxx",
+ affiliate_application_required=True,
+ affiliate_instructions="affiliate_instructions",
banner_image={"id": "id"},
description="description",
+ featured_affiliate_product_id="featured_affiliate_product_id",
logo={"id": "id"},
route="route",
send_customer_emails=True,
@@ -321,8 +324,11 @@ async def test_method_update(self, async_client: AsyncWhop) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> None:
company = await async_client.companies.update(
id="biz_xxxxxxxxxxxxxx",
+ affiliate_application_required=True,
+ affiliate_instructions="affiliate_instructions",
banner_image={"id": "id"},
description="description",
+ featured_affiliate_product_id="featured_affiliate_product_id",
logo={"id": "id"},
route="route",
send_customer_emails=True,
diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py
index 7db7c12..97377e3 100644
--- a/tests/api_resources/test_invoices.py
+++ b/tests/api_resources/test_invoices.py
@@ -9,7 +9,11 @@
from whop_sdk import Whop, AsyncWhop
from tests.utils import assert_matches_type
-from whop_sdk.types import InvoiceVoidResponse
+from whop_sdk.types import (
+ InvoiceVoidResponse,
+ InvoiceMarkPaidResponse,
+ InvoiceMarkUncollectibleResponse,
+)
from whop_sdk._utils import parse_datetime
from whop_sdk.pagination import SyncCursorPage, AsyncCursorPage
from whop_sdk.types.shared import Invoice, InvoiceListItem
@@ -70,8 +74,28 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None:
"product_tax_code_id": "ptc_xxxxxxxxxxxxxx",
},
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -163,8 +187,28 @@ def test_method_create_with_all_params_overload_2(self, client: Whop) -> None:
"product_tax_code_id": "ptc_xxxxxxxxxxxxxx",
},
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -253,8 +297,28 @@ def test_method_create_with_all_params_overload_3(self, client: Whop) -> None:
},
product_id="prod_xxxxxxxxxxxxx",
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -343,8 +407,28 @@ def test_method_create_with_all_params_overload_4(self, client: Whop) -> None:
},
product_id="prod_xxxxxxxxxxxxx",
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -481,6 +565,90 @@ def test_streaming_response_list(self, client: Whop) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_mark_paid(self, client: Whop) -> None:
+ invoice = client.invoices.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ )
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_mark_paid(self, client: Whop) -> None:
+ response = client.invoices.with_raw_response.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invoice = response.parse()
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_mark_paid(self, client: Whop) -> None:
+ with client.invoices.with_streaming_response.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invoice = response.parse()
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_mark_paid(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.invoices.with_raw_response.mark_paid(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_mark_uncollectible(self, client: Whop) -> None:
+ invoice = client.invoices.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ )
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_mark_uncollectible(self, client: Whop) -> None:
+ response = client.invoices.with_raw_response.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invoice = response.parse()
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_mark_uncollectible(self, client: Whop) -> None:
+ with client.invoices.with_streaming_response.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invoice = response.parse()
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_mark_uncollectible(self, client: Whop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.invoices.with_raw_response.mark_uncollectible(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_void(self, client: Whop) -> None:
@@ -579,8 +747,28 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
"product_tax_code_id": "ptc_xxxxxxxxxxxxxx",
},
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -672,8 +860,28 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn
"product_tax_code_id": "ptc_xxxxxxxxxxxxxx",
},
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -762,8 +970,28 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn
},
product_id="prod_xxxxxxxxxxxxx",
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -852,8 +1080,28 @@ async def test_method_create_with_all_params_overload_4(self, async_client: Asyn
},
product_id="prod_xxxxxxxxxxxxx",
automatically_finalizes_at=parse_datetime("2023-12-01T05:00:00.401Z"),
+ billing_address={
+ "city": "city",
+ "country": "country",
+ "line1": "line1",
+ "line2": "line2",
+ "name": "name",
+ "phone": "phone",
+ "postal_code": "postal_code",
+ "state": "state",
+ "tax_id_type": "ad_nrt",
+ "tax_id_value": "tax_id_value",
+ },
charge_buyer_fee=True,
customer_name="customer_name",
+ line_items=[
+ {
+ "label": "label",
+ "unit_price": 6.9,
+ "quantity": 6.9,
+ }
+ ],
+ mailing_address_id="ma_xxxxxxxxxxxxxxx",
payment_method_id="pmt_xxxxxxxxxxxxxx",
payment_token_id="payt_xxxxxxxxxxxxx",
)
@@ -990,6 +1238,90 @@ async def test_streaming_response_list(self, async_client: AsyncWhop) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_mark_paid(self, async_client: AsyncWhop) -> None:
+ invoice = await async_client.invoices.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ )
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_mark_paid(self, async_client: AsyncWhop) -> None:
+ response = await async_client.invoices.with_raw_response.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invoice = await response.parse()
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_mark_paid(self, async_client: AsyncWhop) -> None:
+ async with async_client.invoices.with_streaming_response.mark_paid(
+ "inv_xxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invoice = await response.parse()
+ assert_matches_type(InvoiceMarkPaidResponse, invoice, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_mark_paid(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.invoices.with_raw_response.mark_paid(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_mark_uncollectible(self, async_client: AsyncWhop) -> None:
+ invoice = await async_client.invoices.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ )
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_mark_uncollectible(self, async_client: AsyncWhop) -> None:
+ response = await async_client.invoices.with_raw_response.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ invoice = await response.parse()
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_mark_uncollectible(self, async_client: AsyncWhop) -> None:
+ async with async_client.invoices.with_streaming_response.mark_uncollectible(
+ "inv_xxxxxxxxxxxxxx",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ invoice = await response.parse()
+ assert_matches_type(InvoiceMarkUncollectibleResponse, invoice, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_mark_uncollectible(self, async_client: AsyncWhop) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.invoices.with_raw_response.mark_uncollectible(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_void(self, async_client: AsyncWhop) -> None:
diff --git a/tests/api_resources/test_payments.py b/tests/api_resources/test_payments.py
index e16cc67..628f7f7 100644
--- a/tests/api_resources/test_payments.py
+++ b/tests/api_resources/test_payments.py
@@ -43,6 +43,7 @@ def test_method_create_with_all_params_overload_1(self, client: Whop) -> None:
payment_method_id="pmt_xxxxxxxxxxxxxx",
plan={
"currency": "usd",
+ "application_fee_amount": 6.9,
"billing_period": 42,
"description": "description",
"expiration_days": 42,
@@ -230,6 +231,8 @@ def test_method_list_with_all_params(self, client: Whop) -> None:
query="query",
statuses=["draft"],
substatuses=["succeeded"],
+ updated_after=parse_datetime("2023-12-01T05:00:00.401Z"),
+ updated_before=parse_datetime("2023-12-01T05:00:00.401Z"),
)
assert_matches_type(SyncCursorPage[PaymentListResponse], payment, path=["response"])
@@ -470,6 +473,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn
payment_method_id="pmt_xxxxxxxxxxxxxx",
plan={
"currency": "usd",
+ "application_fee_amount": 6.9,
"billing_period": 42,
"description": "description",
"expiration_days": 42,
@@ -657,6 +661,8 @@ async def test_method_list_with_all_params(self, async_client: AsyncWhop) -> Non
query="query",
statuses=["draft"],
substatuses=["succeeded"],
+ updated_after=parse_datetime("2023-12-01T05:00:00.401Z"),
+ updated_before=parse_datetime("2023-12-01T05:00:00.401Z"),
)
assert_matches_type(AsyncCursorPage[PaymentListResponse], payment, path=["response"])
diff --git a/tests/api_resources/test_plans.py b/tests/api_resources/test_plans.py
index 296e431..33d2cfc 100644
--- a/tests/api_resources/test_plans.py
+++ b/tests/api_resources/test_plans.py
@@ -39,6 +39,11 @@ def test_method_create_with_all_params(self, client: Whop) -> None:
company_id="biz_xxxxxxxxxxxxxx",
product_id="prod_xxxxxxxxxxxxx",
billing_period=42,
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
custom_fields=[
{
@@ -158,6 +163,11 @@ def test_method_update_with_all_params(self, client: Whop) -> None:
plan = client.plans.update(
id="plan_xxxxxxxxxxxxx",
billing_period=42,
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
custom_fields=[
{
@@ -345,6 +355,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncWhop) -> N
company_id="biz_xxxxxxxxxxxxxx",
product_id="prod_xxxxxxxxxxxxx",
billing_period=42,
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
custom_fields=[
{
@@ -464,6 +479,11 @@ async def test_method_update_with_all_params(self, async_client: AsyncWhop) -> N
plan = await async_client.plans.update(
id="plan_xxxxxxxxxxxxx",
billing_period=42,
+ checkout_styling={
+ "border_style": "rounded",
+ "button_color": "button_color",
+ "font_family": "system",
+ },
currency="usd",
custom_fields=[
{
diff --git a/tests/test_utils/test_path.py b/tests/test_utils/test_path.py
new file mode 100644
index 0000000..bb4a49a
--- /dev/null
+++ b/tests/test_utils/test_path.py
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+from typing import Any
+
+import pytest
+
+from whop_sdk._utils._path import path_template
+
+
+@pytest.mark.parametrize(
+ "template, kwargs, expected",
+ [
+ ("/v1/{id}", dict(id="abc"), "/v1/abc"),
+ ("/v1/{a}/{b}", dict(a="x", b="y"), "/v1/x/y"),
+ ("/v1/{a}{b}/path/{c}?val={d}#{e}", dict(a="x", b="y", c="z", d="u", e="v"), "/v1/xy/path/z?val=u#v"),
+ ("/{w}/{w}", dict(w="echo"), "/echo/echo"),
+ ("/v1/static", {}, "/v1/static"),
+ ("", {}, ""),
+ ("/v1/?q={n}&count=10", dict(n=42), "/v1/?q=42&count=10"),
+ ("/v1/{v}", dict(v=None), "/v1/null"),
+ ("/v1/{v}", dict(v=True), "/v1/true"),
+ ("/v1/{v}", dict(v=False), "/v1/false"),
+ ("/v1/{v}", dict(v=".hidden"), "/v1/.hidden"), # dot prefix ok
+ ("/v1/{v}", dict(v="file.txt"), "/v1/file.txt"), # dot in middle ok
+ ("/v1/{v}", dict(v="..."), "/v1/..."), # triple dot ok
+ ("/v1/{a}{b}", dict(a=".", b="txt"), "/v1/.txt"), # dot var combining with adjacent to be ok
+ ("/items?q={v}#{f}", dict(v=".", f=".."), "/items?q=.#.."), # dots in query/fragment are fine
+ (
+ "/v1/{a}?query={b}",
+ dict(a="../../other/endpoint", b="a&bad=true"),
+ "/v1/..%2F..%2Fother%2Fendpoint?query=a%26bad%3Dtrue",
+ ),
+ ("/v1/{val}", dict(val="a/b/c"), "/v1/a%2Fb%2Fc"),
+ ("/v1/{val}", dict(val="a/b/c?query=value"), "/v1/a%2Fb%2Fc%3Fquery=value"),
+ ("/v1/{val}", dict(val="a/b/c?query=value&bad=true"), "/v1/a%2Fb%2Fc%3Fquery=value&bad=true"),
+ ("/v1/{val}", dict(val="%20"), "/v1/%2520"), # escapes escape sequences in input
+ # Query: slash and ? are safe, # is not
+ ("/items?q={v}", dict(v="a/b"), "/items?q=a/b"),
+ ("/items?q={v}", dict(v="a?b"), "/items?q=a?b"),
+ ("/items?q={v}", dict(v="a#b"), "/items?q=a%23b"),
+ ("/items?q={v}", dict(v="a b"), "/items?q=a%20b"),
+ # Fragment: slash and ? are safe
+ ("/docs#{v}", dict(v="a/b"), "/docs#a/b"),
+ ("/docs#{v}", dict(v="a?b"), "/docs#a?b"),
+ # Path: slash, ? and # are all encoded
+ ("/v1/{v}", dict(v="a/b"), "/v1/a%2Fb"),
+ ("/v1/{v}", dict(v="a?b"), "/v1/a%3Fb"),
+ ("/v1/{v}", dict(v="a#b"), "/v1/a%23b"),
+ # same var encoded differently by component
+ (
+ "/v1/{v}?q={v}#{v}",
+ dict(v="a/b?c#d"),
+ "/v1/a%2Fb%3Fc%23d?q=a/b?c%23d#a/b?c%23d",
+ ),
+ ("/v1/{val}", dict(val="x?admin=true"), "/v1/x%3Fadmin=true"), # query injection
+ ("/v1/{val}", dict(val="x#admin"), "/v1/x%23admin"), # fragment injection
+ ],
+)
+def test_interpolation(template: str, kwargs: dict[str, Any], expected: str) -> None:
+ assert path_template(template, **kwargs) == expected
+
+
+def test_missing_kwarg_raises_key_error() -> None:
+ with pytest.raises(KeyError, match="org_id"):
+ path_template("/v1/{org_id}")
+
+
+@pytest.mark.parametrize(
+ "template, kwargs",
+ [
+ ("{a}/path", dict(a=".")),
+ ("{a}/path", dict(a="..")),
+ ("/v1/{a}", dict(a=".")),
+ ("/v1/{a}", dict(a="..")),
+ ("/v1/{a}/path", dict(a=".")),
+ ("/v1/{a}/path", dict(a="..")),
+ ("/v1/{a}{b}", dict(a=".", b=".")), # adjacent vars → ".."
+ ("/v1/{a}.", dict(a=".")), # var + static → ".."
+ ("/v1/{a}{b}", dict(a="", b=".")), # empty + dot → "."
+ ("/v1/%2e/{x}", dict(x="ok")), # encoded dot in static text
+ ("/v1/%2e./{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/.%2E/{x}", dict(x="ok")), # mixed encoded ".." in static
+ ("/v1/{v}?q=1", dict(v="..")),
+ ("/v1/{v}#frag", dict(v="..")),
+ ],
+)
+def test_dot_segment_rejected(template: str, kwargs: dict[str, Any]) -> None:
+ with pytest.raises(ValueError, match="dot-segment"):
+ path_template(template, **kwargs)