diff --git a/README.md b/README.md index a112e35..b36b533 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,14 @@ All API methods return a response dictionary with either `data` or `error`: instance_id="your_instance_id_here" ) - response = await blindpay.receivers.get("receiver-id") + response = await blindpay.customers.get("customer-id") if response['error']: print(f"Error: {response['error']['message']}") return - receiver = response['data'] - print(f"Receiver: {receiver}") + customer = response['data'] + print(f"Customer: {customer}") ``` ## Types diff --git a/src/blindpay/resources/customers/customers.py b/src/blindpay/resources/customers/customers.py index 43b98cd..92caea4 100644 --- a/src/blindpay/resources/customers/customers.py +++ b/src/blindpay/resources/customers/customers.py @@ -1,7 +1,7 @@ from typing import List, Optional, Union from urllib.parse import urlencode -from typing_extensions import Literal, TypedDict +from typing_extensions import Literal, NotRequired, TypedDict from ..._internal.api_client import InternalApiClient, InternalApiClientSync from ...types import ( @@ -302,7 +302,10 @@ class TransactionLimit(TypedDict): class Owner(TypedDict): id: str instance_id: str - customer_id: str + # Not yet added by the response middleware for nested owners; both keys are + # optional until the API sends customer_id here directly (post-#1799). + receiver_id: NotRequired[str] + customer_id: NotRequired[str] role: OwnerRole first_name: str last_name: str diff --git a/src/blindpay/resources/payins/payins.py b/src/blindpay/resources/payins/payins.py index 2fb1510..df9cffe 100644 --- a/src/blindpay/resources/payins/payins.py +++ b/src/blindpay/resources/payins/payins.py @@ -103,6 +103,7 @@ class Payin(TypedDict): class ListPayinsInput(PaginationParams): status: Optional[TransactionStatus] receiver_id: Optional[str] + customer_id: Optional[str] class ListPayinsResponse(TypedDict): diff --git a/src/blindpay/resources/payouts/payouts.py b/src/blindpay/resources/payouts/payouts.py index ee03f31..a234660 100644 --- a/src/blindpay/resources/payouts/payouts.py +++ b/src/blindpay/resources/payouts/payouts.py @@ -103,6 +103,7 @@ class Payout(TypedDict): class ListPayoutsInput(PaginationParams, total=False): receiver_id: str + customer_id: str class ListPayoutsResponse(TypedDict): diff --git a/src/blindpay/resources/webhooks/webhooks.py b/src/blindpay/resources/webhooks/webhooks.py index a75dcba..b937f74 100644 --- a/src/blindpay/resources/webhooks/webhooks.py +++ b/src/blindpay/resources/webhooks/webhooks.py @@ -6,8 +6,18 @@ from ...types import BlindpayApiResponse WebhookEvents = Literal[ + # deprecated: use "customer.new" instead. See + # https://www.blindpay.com/changelog/2026-06-04-customers-rename "receiver.new", + # deprecated: use "customer.update" instead. See + # https://www.blindpay.com/changelog/2026-06-04-customers-rename "receiver.update", + # deprecated: use "customer.delete" instead. See + # https://www.blindpay.com/changelog/2026-06-04-customers-rename + "receiver.delete", + "customer.new", + "customer.update", + "customer.delete", "bankAccount.new", "payout.new", "payout.update", diff --git a/src/blindpay/types.py b/src/blindpay/types.py index 5f4e0b9..5e1dff3 100644 --- a/src/blindpay/types.py +++ b/src/blindpay/types.py @@ -408,5 +408,7 @@ class TrackingPartnerFee(TypedDict): ManualExecutionStatus = Literal["failed"] - +# Deprecated: use WebhookEvents from blindpay.resources.webhooks, which lists every +# event. Kept exported so this stays an additive release; scheduled for removal in the +# next major. WebhookEvent = Literal["receiver.delete"] diff --git a/tests/resources/test_blockchain_wallets.py b/tests/resources/test_blockchain_wallets.py index 124edb3..1018790 100644 --- a/tests/resources/test_blockchain_wallets.py +++ b/tests/resources/test_blockchain_wallets.py @@ -46,6 +46,8 @@ async def test_list_blockchain_wallets(self): assert response["error"] is None assert response["data"] == mocked_wallets + assert response["data"] is not None + assert response["data"][0]["customer_id"] == "re_000000000000" mock_request.assert_called_once_with( "GET", "/instances/in_000000000000/customers/re_000000000000/blockchain-wallets" ) @@ -326,6 +328,8 @@ def test_list_blockchain_wallets(self): assert response["error"] is None assert response["data"] == mocked_wallets + assert response["data"] is not None + assert response["data"][0]["customer_id"] == "re_000000000000" mock_request.assert_called_once_with( "GET", "/instances/in_000000000000/customers/re_000000000000/blockchain-wallets" ) diff --git a/tests/resources/test_offramp_wallets.py b/tests/resources/test_offramp_wallets.py index 0dbdea2..11455c1 100644 --- a/tests/resources/test_offramp_wallets.py +++ b/tests/resources/test_offramp_wallets.py @@ -38,6 +38,8 @@ async def test_list_offramp_wallets(self): assert response["error"] is None assert response["data"] == mocked_offramp_wallets + assert response["data"] is not None + assert response["data"][0]["customer_id"] == "re_000000000000" mock_request.assert_called_once_with( "GET", "/instances/in_000000000000/customers/re_000000000000/bank-accounts/ba_000000000000/offramp-wallets", diff --git a/uv.lock b/uv.lock index 52335b6..306e87e 100644 --- a/uv.lock +++ b/uv.lock @@ -27,7 +27,7 @@ wheels = [ [[package]] name = "blindpay" -version = "2.1.0" +version = "2.4.0" source = { editable = "." } dependencies = [ { name = "httpx" },