Skip to content

feat(api): api update #430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
configured_endpoints: 96
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-1345a8e288e34d5477b0e189877225f83939a59078c22fbb5367712e376c5d19.yml
configured_endpoints: 97
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-bf3e71b33372f4a9307f4b6cb689ea46b3cf583ecc5d79eee9601cd0b0467c9a.yml
1 change: 1 addition & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ Methods:
- <code title="get /invoices/upcoming">client.invoices.<a href="./src/orb/resources/invoices.py">fetch_upcoming</a>(\*\*<a href="src/orb/types/invoice_fetch_upcoming_params.py">params</a>) -> <a href="./src/orb/types/invoice_fetch_upcoming_response.py">InvoiceFetchUpcomingResponse</a></code>
- <code title="post /invoices/{invoice_id}/issue">client.invoices.<a href="./src/orb/resources/invoices.py">issue</a>(invoice_id, \*\*<a href="src/orb/types/invoice_issue_params.py">params</a>) -> <a href="./src/orb/types/invoice.py">Invoice</a></code>
- <code title="post /invoices/{invoice_id}/mark_paid">client.invoices.<a href="./src/orb/resources/invoices.py">mark_paid</a>(invoice_id, \*\*<a href="src/orb/types/invoice_mark_paid_params.py">params</a>) -> <a href="./src/orb/types/invoice.py">Invoice</a></code>
- <code title="post /invoices/{invoice_id}/pay">client.invoices.<a href="./src/orb/resources/invoices.py">pay</a>(invoice_id) -> <a href="./src/orb/types/invoice.py">Invoice</a></code>
- <code title="post /invoices/{invoice_id}/void">client.invoices.<a href="./src/orb/resources/invoices.py">void</a>(invoice_id) -> <a href="./src/orb/types/invoice.py">Invoice</a></code>

# Items
Expand Down
94 changes: 94 additions & 0 deletions src/orb/resources/invoices.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,47 @@ def mark_paid(
cast_to=Invoice,
)

def pay(
self,
invoice_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,
idempotency_key: str | None = None,
) -> Invoice:
"""
This endpoint collects payment for an invoice using the customer's default
payment method. This action can only be taken on invoices with status "issued".

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

idempotency_key: Specify a custom idempotency key for this request
"""
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return self._post(
f"/invoices/{invoice_id}/pay",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
),
cast_to=Invoice,
)

def void(
self,
invoice_id: str,
Expand Down Expand Up @@ -964,6 +1005,47 @@ async def mark_paid(
cast_to=Invoice,
)

async def pay(
self,
invoice_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,
idempotency_key: str | None = None,
) -> Invoice:
"""
This endpoint collects payment for an invoice using the customer's default
payment method. This action can only be taken on invoices with status "issued".

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

idempotency_key: Specify a custom idempotency key for this request
"""
if not invoice_id:
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
return await self._post(
f"/invoices/{invoice_id}/pay",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
),
cast_to=Invoice,
)

async def void(
self,
invoice_id: str,
Expand Down Expand Up @@ -1037,6 +1119,9 @@ def __init__(self, invoices: Invoices) -> None:
self.mark_paid = _legacy_response.to_raw_response_wrapper(
invoices.mark_paid,
)
self.pay = _legacy_response.to_raw_response_wrapper(
invoices.pay,
)
self.void = _legacy_response.to_raw_response_wrapper(
invoices.void,
)
Expand Down Expand Up @@ -1067,6 +1152,9 @@ def __init__(self, invoices: AsyncInvoices) -> None:
self.mark_paid = _legacy_response.async_to_raw_response_wrapper(
invoices.mark_paid,
)
self.pay = _legacy_response.async_to_raw_response_wrapper(
invoices.pay,
)
self.void = _legacy_response.async_to_raw_response_wrapper(
invoices.void,
)
Expand Down Expand Up @@ -1097,6 +1185,9 @@ def __init__(self, invoices: Invoices) -> None:
self.mark_paid = to_streamed_response_wrapper(
invoices.mark_paid,
)
self.pay = to_streamed_response_wrapper(
invoices.pay,
)
self.void = to_streamed_response_wrapper(
invoices.void,
)
Expand Down Expand Up @@ -1127,6 +1218,9 @@ def __init__(self, invoices: AsyncInvoices) -> None:
self.mark_paid = async_to_streamed_response_wrapper(
invoices.mark_paid,
)
self.pay = async_to_streamed_response_wrapper(
invoices.pay,
)
self.void = async_to_streamed_response_wrapper(
invoices.void,
)
24 changes: 24 additions & 0 deletions src/orb/types/invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"LineItemTaxAmount",
"Maximum",
"Minimum",
"PaymentAttempt",
"ShippingAddress",
"Subscription",
]
Expand Down Expand Up @@ -744,6 +745,26 @@ class Minimum(BaseModel):
"""Minimum amount applied"""


class PaymentAttempt(BaseModel):
id: str
"""The ID of the payment attempt."""

amount: str
"""The amount of the payment attempt."""

created_at: datetime
"""The time at which the payment attempt was created."""

payment_provider: Optional[Literal["stripe"]] = None
"""The payment provider that attempted to collect the payment."""

payment_provider_id: Optional[str] = None
"""The ID of the payment attempt in the payment provider."""

succeeded: bool
"""Whether the payment attempt succeeded."""


class ShippingAddress(BaseModel):
city: Optional[str] = None

Expand Down Expand Up @@ -980,6 +1001,9 @@ class Invoice(BaseModel):
was paid.
"""

payment_attempts: List[PaymentAttempt]
"""A list of payment attempts associated with the invoice"""

payment_failed_at: Optional[datetime] = None
"""
If payment was attempted on this invoice but failed, this will be the time of
Expand Down
24 changes: 24 additions & 0 deletions src/orb/types/invoice_fetch_upcoming_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"LineItemTaxAmount",
"Maximum",
"Minimum",
"PaymentAttempt",
"ShippingAddress",
"Subscription",
]
Expand Down Expand Up @@ -744,6 +745,26 @@ class Minimum(BaseModel):
"""Minimum amount applied"""


class PaymentAttempt(BaseModel):
id: str
"""The ID of the payment attempt."""

amount: str
"""The amount of the payment attempt."""

created_at: datetime
"""The time at which the payment attempt was created."""

payment_provider: Optional[Literal["stripe"]] = None
"""The payment provider that attempted to collect the payment."""

payment_provider_id: Optional[str] = None
"""The ID of the payment attempt in the payment provider."""

succeeded: bool
"""Whether the payment attempt succeeded."""


class ShippingAddress(BaseModel):
city: Optional[str] = None

Expand Down Expand Up @@ -977,6 +998,9 @@ class InvoiceFetchUpcomingResponse(BaseModel):
was paid.
"""

payment_attempts: List[PaymentAttempt]
"""A list of payment attempts associated with the invoice"""

payment_failed_at: Optional[datetime] = None
"""
If payment was attempted on this invoice but failed, this will be the time of
Expand Down
76 changes: 76 additions & 0 deletions tests/api_resources/test_invoices.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,44 @@ def test_path_params_mark_paid(self, client: Orb) -> None:
payment_received_date=parse_date("2023-09-22"),
)

@parametrize
def test_method_pay(self, client: Orb) -> None:
invoice = client.invoices.pay(
"invoice_id",
)
assert_matches_type(Invoice, invoice, path=["response"])

@parametrize
def test_raw_response_pay(self, client: Orb) -> None:
response = client.invoices.with_raw_response.pay(
"invoice_id",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
invoice = response.parse()
assert_matches_type(Invoice, invoice, path=["response"])

@parametrize
def test_streaming_response_pay(self, client: Orb) -> None:
with client.invoices.with_streaming_response.pay(
"invoice_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

invoice = response.parse()
assert_matches_type(Invoice, invoice, path=["response"])

assert cast(Any, response.is_closed) is True

@parametrize
def test_path_params_pay(self, client: Orb) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
client.invoices.with_raw_response.pay(
"",
)

@parametrize
def test_method_void(self, client: Orb) -> None:
invoice = client.invoices.void(
Expand Down Expand Up @@ -792,6 +830,44 @@ async def test_path_params_mark_paid(self, async_client: AsyncOrb) -> None:
payment_received_date=parse_date("2023-09-22"),
)

@parametrize
async def test_method_pay(self, async_client: AsyncOrb) -> None:
invoice = await async_client.invoices.pay(
"invoice_id",
)
assert_matches_type(Invoice, invoice, path=["response"])

@parametrize
async def test_raw_response_pay(self, async_client: AsyncOrb) -> None:
response = await async_client.invoices.with_raw_response.pay(
"invoice_id",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
invoice = response.parse()
assert_matches_type(Invoice, invoice, path=["response"])

@parametrize
async def test_streaming_response_pay(self, async_client: AsyncOrb) -> None:
async with async_client.invoices.with_streaming_response.pay(
"invoice_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

invoice = await response.parse()
assert_matches_type(Invoice, invoice, path=["response"])

assert cast(Any, response.is_closed) is True

@parametrize
async def test_path_params_pay(self, async_client: AsyncOrb) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
await async_client.invoices.with_raw_response.pay(
"",
)

@parametrize
async def test_method_void(self, async_client: AsyncOrb) -> None:
invoice = await async_client.invoices.void(
Expand Down