From b151a03f7019746299abef60646a768ee4273005 Mon Sep 17 00:00:00 2001 From: stainless-bot Date: Fri, 15 Nov 2024 18:11:29 +0000 Subject: [PATCH] feat(api): api update --- .stats.yml | 4 +- api.md | 1 + src/orb/resources/invoices.py | 94 +++++++++++++++++++ src/orb/types/invoice.py | 24 +++++ .../types/invoice_fetch_upcoming_response.py | 24 +++++ tests/api_resources/test_invoices.py | 76 +++++++++++++++ 6 files changed, 221 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3114caa3..e670c774 100644 --- a/.stats.yml +++ b/.stats.yml @@ -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 diff --git a/api.md b/api.md index 366c8f9e..89f33f14 100644 --- a/api.md +++ b/api.md @@ -241,6 +241,7 @@ Methods: - client.invoices.fetch_upcoming(\*\*params) -> InvoiceFetchUpcomingResponse - client.invoices.issue(invoice_id, \*\*params) -> Invoice - client.invoices.mark_paid(invoice_id, \*\*params) -> Invoice +- client.invoices.pay(invoice_id) -> Invoice - client.invoices.void(invoice_id) -> Invoice # Items diff --git a/src/orb/resources/invoices.py b/src/orb/resources/invoices.py index ca4c14c2..a85c4c11 100644 --- a/src/orb/resources/invoices.py +++ b/src/orb/resources/invoices.py @@ -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, @@ -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, @@ -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, ) @@ -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, ) @@ -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, ) @@ -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, ) diff --git a/src/orb/types/invoice.py b/src/orb/types/invoice.py index 23c1786b..964e0f7d 100644 --- a/src/orb/types/invoice.py +++ b/src/orb/types/invoice.py @@ -35,6 +35,7 @@ "LineItemTaxAmount", "Maximum", "Minimum", + "PaymentAttempt", "ShippingAddress", "Subscription", ] @@ -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 @@ -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 diff --git a/src/orb/types/invoice_fetch_upcoming_response.py b/src/orb/types/invoice_fetch_upcoming_response.py index 443aeab9..8ec2e987 100644 --- a/src/orb/types/invoice_fetch_upcoming_response.py +++ b/src/orb/types/invoice_fetch_upcoming_response.py @@ -35,6 +35,7 @@ "LineItemTaxAmount", "Maximum", "Minimum", + "PaymentAttempt", "ShippingAddress", "Subscription", ] @@ -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 @@ -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 diff --git a/tests/api_resources/test_invoices.py b/tests/api_resources/test_invoices.py index b38553c5..e95f3a25 100644 --- a/tests/api_resources/test_invoices.py +++ b/tests/api_resources/test_invoices.py @@ -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( @@ -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(