Skip to content

Commit 13bf498

Browse files
feat(api): api update (#430)
1 parent 8cb2a3b commit 13bf498

File tree

6 files changed

+221
-2
lines changed

6 files changed

+221
-2
lines changed

.stats.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
configured_endpoints: 96
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-1345a8e288e34d5477b0e189877225f83939a59078c22fbb5367712e376c5d19.yml
1+
configured_endpoints: 97
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-bf3e71b33372f4a9307f4b6cb689ea46b3cf583ecc5d79eee9601cd0b0467c9a.yml

api.md

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ Methods:
220220
- <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>
221221
- <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.py">Invoice</a></code>
222222
- <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>
223+
- <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>
223224
- <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>
224225

225226
# Items

src/orb/resources/invoices.py

+94
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,47 @@ def mark_paid(
451451
cast_to=Invoice,
452452
)
453453

454+
def pay(
455+
self,
456+
invoice_id: str,
457+
*,
458+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
459+
# The extra values given here take precedence over values defined on the client or passed to this method.
460+
extra_headers: Headers | None = None,
461+
extra_query: Query | None = None,
462+
extra_body: Body | None = None,
463+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
464+
idempotency_key: str | None = None,
465+
) -> Invoice:
466+
"""
467+
This endpoint collects payment for an invoice using the customer's default
468+
payment method. This action can only be taken on invoices with status "issued".
469+
470+
Args:
471+
extra_headers: Send extra headers
472+
473+
extra_query: Add additional query parameters to the request
474+
475+
extra_body: Add additional JSON properties to the request
476+
477+
timeout: Override the client-level default timeout for this request, in seconds
478+
479+
idempotency_key: Specify a custom idempotency key for this request
480+
"""
481+
if not invoice_id:
482+
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
483+
return self._post(
484+
f"/invoices/{invoice_id}/pay",
485+
options=make_request_options(
486+
extra_headers=extra_headers,
487+
extra_query=extra_query,
488+
extra_body=extra_body,
489+
timeout=timeout,
490+
idempotency_key=idempotency_key,
491+
),
492+
cast_to=Invoice,
493+
)
494+
454495
def void(
455496
self,
456497
invoice_id: str,
@@ -917,6 +958,47 @@ async def mark_paid(
917958
cast_to=Invoice,
918959
)
919960

961+
async def pay(
962+
self,
963+
invoice_id: str,
964+
*,
965+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
966+
# The extra values given here take precedence over values defined on the client or passed to this method.
967+
extra_headers: Headers | None = None,
968+
extra_query: Query | None = None,
969+
extra_body: Body | None = None,
970+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
971+
idempotency_key: str | None = None,
972+
) -> Invoice:
973+
"""
974+
This endpoint collects payment for an invoice using the customer's default
975+
payment method. This action can only be taken on invoices with status "issued".
976+
977+
Args:
978+
extra_headers: Send extra headers
979+
980+
extra_query: Add additional query parameters to the request
981+
982+
extra_body: Add additional JSON properties to the request
983+
984+
timeout: Override the client-level default timeout for this request, in seconds
985+
986+
idempotency_key: Specify a custom idempotency key for this request
987+
"""
988+
if not invoice_id:
989+
raise ValueError(f"Expected a non-empty value for `invoice_id` but received {invoice_id!r}")
990+
return await self._post(
991+
f"/invoices/{invoice_id}/pay",
992+
options=make_request_options(
993+
extra_headers=extra_headers,
994+
extra_query=extra_query,
995+
extra_body=extra_body,
996+
timeout=timeout,
997+
idempotency_key=idempotency_key,
998+
),
999+
cast_to=Invoice,
1000+
)
1001+
9201002
async def void(
9211003
self,
9221004
invoice_id: str,
@@ -990,6 +1072,9 @@ def __init__(self, invoices: Invoices) -> None:
9901072
self.mark_paid = _legacy_response.to_raw_response_wrapper(
9911073
invoices.mark_paid,
9921074
)
1075+
self.pay = _legacy_response.to_raw_response_wrapper(
1076+
invoices.pay,
1077+
)
9931078
self.void = _legacy_response.to_raw_response_wrapper(
9941079
invoices.void,
9951080
)
@@ -1020,6 +1105,9 @@ def __init__(self, invoices: AsyncInvoices) -> None:
10201105
self.mark_paid = _legacy_response.async_to_raw_response_wrapper(
10211106
invoices.mark_paid,
10221107
)
1108+
self.pay = _legacy_response.async_to_raw_response_wrapper(
1109+
invoices.pay,
1110+
)
10231111
self.void = _legacy_response.async_to_raw_response_wrapper(
10241112
invoices.void,
10251113
)
@@ -1050,6 +1138,9 @@ def __init__(self, invoices: Invoices) -> None:
10501138
self.mark_paid = to_streamed_response_wrapper(
10511139
invoices.mark_paid,
10521140
)
1141+
self.pay = to_streamed_response_wrapper(
1142+
invoices.pay,
1143+
)
10531144
self.void = to_streamed_response_wrapper(
10541145
invoices.void,
10551146
)
@@ -1080,6 +1171,9 @@ def __init__(self, invoices: AsyncInvoices) -> None:
10801171
self.mark_paid = async_to_streamed_response_wrapper(
10811172
invoices.mark_paid,
10821173
)
1174+
self.pay = async_to_streamed_response_wrapper(
1175+
invoices.pay,
1176+
)
10831177
self.void = async_to_streamed_response_wrapper(
10841178
invoices.void,
10851179
)

src/orb/types/invoice.py

+24
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"LineItemTaxAmount",
3535
"Maximum",
3636
"Minimum",
37+
"PaymentAttempt",
3738
"ShippingAddress",
3839
"Subscription",
3940
]
@@ -743,6 +744,26 @@ class Minimum(BaseModel):
743744
"""Minimum amount applied"""
744745

745746

747+
class PaymentAttempt(BaseModel):
748+
id: str
749+
"""The ID of the payment attempt."""
750+
751+
amount: str
752+
"""The amount of the payment attempt."""
753+
754+
created_at: datetime
755+
"""The time at which the payment attempt was created."""
756+
757+
payment_provider: Optional[Literal["stripe"]] = None
758+
"""The payment provider that attempted to collect the payment."""
759+
760+
payment_provider_id: Optional[str] = None
761+
"""The ID of the payment attempt in the payment provider."""
762+
763+
succeeded: bool
764+
"""Whether the payment attempt succeeded."""
765+
766+
746767
class ShippingAddress(BaseModel):
747768
city: Optional[str] = None
748769

@@ -970,6 +991,9 @@ class Invoice(BaseModel):
970991
was paid.
971992
"""
972993

994+
payment_attempts: List[PaymentAttempt]
995+
"""A list of payment attempts associated with the invoice"""
996+
973997
payment_failed_at: Optional[datetime] = None
974998
"""
975999
If payment was attempted on this invoice but failed, this will be the time of

src/orb/types/invoice_fetch_upcoming_response.py

+24
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"LineItemTaxAmount",
3535
"Maximum",
3636
"Minimum",
37+
"PaymentAttempt",
3738
"ShippingAddress",
3839
"Subscription",
3940
]
@@ -743,6 +744,26 @@ class Minimum(BaseModel):
743744
"""Minimum amount applied"""
744745

745746

747+
class PaymentAttempt(BaseModel):
748+
id: str
749+
"""The ID of the payment attempt."""
750+
751+
amount: str
752+
"""The amount of the payment attempt."""
753+
754+
created_at: datetime
755+
"""The time at which the payment attempt was created."""
756+
757+
payment_provider: Optional[Literal["stripe"]] = None
758+
"""The payment provider that attempted to collect the payment."""
759+
760+
payment_provider_id: Optional[str] = None
761+
"""The ID of the payment attempt in the payment provider."""
762+
763+
succeeded: bool
764+
"""Whether the payment attempt succeeded."""
765+
766+
746767
class ShippingAddress(BaseModel):
747768
city: Optional[str] = None
748769

@@ -967,6 +988,9 @@ class InvoiceFetchUpcomingResponse(BaseModel):
967988
was paid.
968989
"""
969990

991+
payment_attempts: List[PaymentAttempt]
992+
"""A list of payment attempts associated with the invoice"""
993+
970994
payment_failed_at: Optional[datetime] = None
971995
"""
972996
If payment was attempted on this invoice but failed, this will be the time of

tests/api_resources/test_invoices.py

+76
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,44 @@ def test_path_params_mark_paid(self, client: Orb) -> None:
379379
payment_received_date=parse_date("2023-09-22"),
380380
)
381381

382+
@parametrize
383+
def test_method_pay(self, client: Orb) -> None:
384+
invoice = client.invoices.pay(
385+
"invoice_id",
386+
)
387+
assert_matches_type(Invoice, invoice, path=["response"])
388+
389+
@parametrize
390+
def test_raw_response_pay(self, client: Orb) -> None:
391+
response = client.invoices.with_raw_response.pay(
392+
"invoice_id",
393+
)
394+
395+
assert response.is_closed is True
396+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
397+
invoice = response.parse()
398+
assert_matches_type(Invoice, invoice, path=["response"])
399+
400+
@parametrize
401+
def test_streaming_response_pay(self, client: Orb) -> None:
402+
with client.invoices.with_streaming_response.pay(
403+
"invoice_id",
404+
) as response:
405+
assert not response.is_closed
406+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
407+
408+
invoice = response.parse()
409+
assert_matches_type(Invoice, invoice, path=["response"])
410+
411+
assert cast(Any, response.is_closed) is True
412+
413+
@parametrize
414+
def test_path_params_pay(self, client: Orb) -> None:
415+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
416+
client.invoices.with_raw_response.pay(
417+
"",
418+
)
419+
382420
@parametrize
383421
def test_method_void(self, client: Orb) -> None:
384422
invoice = client.invoices.void(
@@ -778,6 +816,44 @@ async def test_path_params_mark_paid(self, async_client: AsyncOrb) -> None:
778816
payment_received_date=parse_date("2023-09-22"),
779817
)
780818

819+
@parametrize
820+
async def test_method_pay(self, async_client: AsyncOrb) -> None:
821+
invoice = await async_client.invoices.pay(
822+
"invoice_id",
823+
)
824+
assert_matches_type(Invoice, invoice, path=["response"])
825+
826+
@parametrize
827+
async def test_raw_response_pay(self, async_client: AsyncOrb) -> None:
828+
response = await async_client.invoices.with_raw_response.pay(
829+
"invoice_id",
830+
)
831+
832+
assert response.is_closed is True
833+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
834+
invoice = response.parse()
835+
assert_matches_type(Invoice, invoice, path=["response"])
836+
837+
@parametrize
838+
async def test_streaming_response_pay(self, async_client: AsyncOrb) -> None:
839+
async with async_client.invoices.with_streaming_response.pay(
840+
"invoice_id",
841+
) as response:
842+
assert not response.is_closed
843+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
844+
845+
invoice = await response.parse()
846+
assert_matches_type(Invoice, invoice, path=["response"])
847+
848+
assert cast(Any, response.is_closed) is True
849+
850+
@parametrize
851+
async def test_path_params_pay(self, async_client: AsyncOrb) -> None:
852+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `invoice_id` but received ''"):
853+
await async_client.invoices.with_raw_response.pay(
854+
"",
855+
)
856+
781857
@parametrize
782858
async def test_method_void(self, async_client: AsyncOrb) -> None:
783859
invoice = await async_client.invoices.void(

0 commit comments

Comments
 (0)