Skip to content

Commit f765dd7

Browse files
Domantasclaude
andcommitted
feat(payments): get_payments_webhook_log — the received payment webhooks of a project (sync and async)
GET /{version}/payments/webhooks/log was the one payments route the Python SDK lacked (typegen coverage matrix, gateway campaign audit/payments item 8). Tests: request shape (sync) and the route + query through httpx (async). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4aa3be9 commit f765dd7

3 files changed

Lines changed: 68 additions & 0 deletions

File tree

‎docs/hub/payments.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ Access with `norbix.hub.payments`.
1818
| `enable_payments_integration` | `PUT` | `/{version}/payments/integrations/{Id}/enable` | `project` |
1919
| `get_payments_integration` | `GET` | `/{version}/payments/integrations/{id}` | `project` |
2020
| `get_payments_integrations` | `GET` | `/{version}/payments/integrations` | `project` |
21+
| `get_payments_webhook_log` | `GET` | `/{version}/payments/webhooks/log` | `project` |
2122
| `save_payments_integration` | `POST` | `/{version}/payments/integrations` | `project` |
2223
| `test_payments_integration` | `POST` | `/{version}/payments/integrations/test` | `project` |

‎src/norbix_python/hub/payments.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ def enable_payments(self, *, timeout: float | None = None, bearer_token: str | N
3535
bearer_token=bearer_token,
3636
)
3737

38+
def get_payments_webhook_log(self, *, timeout: float | None = None, bearer_token: str | None = None, **request: Any) -> Any:
39+
"""GET /{version}/payments/webhooks/log — the received payment webhooks of the project, newest first (optional ``integration_id``, ``limit``)."""
40+
return self._transport.send(
41+
target="hub",
42+
path="/{version}/payments/webhooks/log",
43+
method="GET",
44+
path_params={},
45+
request=request,
46+
scope="project",
47+
timeout=timeout,
48+
bearer_token=bearer_token,
49+
)
50+
3851
def delete_payments_trigger(self, trigger_id: str, *, timeout: float | None = None, bearer_token: str | None = None, **request: Any) -> Any:
3952
"""DELETE /{version}/payments/triggers/{triggerId}"""
4053
return self._transport.send(
@@ -248,6 +261,19 @@ async def enable_payments(self, *, timeout: float | None = None, bearer_token: s
248261
bearer_token=bearer_token,
249262
)
250263

264+
async def get_payments_webhook_log(self, *, timeout: float | None = None, bearer_token: str | None = None, **request: Any) -> Any:
265+
"""GET /{version}/payments/webhooks/log — the received payment webhooks of the project, newest first (optional ``integration_id``, ``limit``)."""
266+
return await self._transport.send(
267+
target="hub",
268+
path="/{version}/payments/webhooks/log",
269+
method="GET",
270+
path_params={},
271+
request=request,
272+
scope="project",
273+
timeout=timeout,
274+
bearer_token=bearer_token,
275+
)
276+
251277
async def delete_payments_trigger(self, trigger_id: str, *, timeout: float | None = None, bearer_token: str | None = None, **request: Any) -> Any:
252278
"""DELETE /{version}/payments/triggers/{triggerId}"""
253279
return await self._transport.send(

‎tests/hub/test_payments.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def test_hub_payments_module_surface() -> None:
99
module = client.hub.payments
1010
assert callable(module.disable_payments)
1111
assert callable(module.enable_payments)
12+
assert callable(module.get_payments_webhook_log)
1213
assert callable(module.delete_payments_trigger)
1314
assert callable(module.disable_payments_trigger)
1415
assert callable(module.enable_payments_trigger)
@@ -136,3 +137,43 @@ def test_hub_payments_test_payments_integration_request_shape() -> None:
136137
assert transport.last_request['method'] == 'POST'
137138
assert transport.last_request is not None
138139
assert transport.last_request['url'].startswith('https://')
140+
141+
142+
def test_hub_payments_get_payments_webhook_log_request_shape() -> None:
143+
client, transport = make_client(account_id=None)
144+
client.hub.payments.get_payments_webhook_log(integration_id="int_stripe", limit=20)
145+
assert transport.last_request is not None
146+
assert transport.last_request['method'] == 'GET'
147+
assert '/payments/webhooks/log' in transport.last_request['url']
148+
assert 'integration_id=int_stripe' in transport.last_request['url'] or 'integrationId=int_stripe' in transport.last_request['url']
149+
150+
151+
def test_async_hub_payments_get_payments_webhook_log_hits_the_route() -> None:
152+
import asyncio
153+
from urllib.parse import parse_qs, urlparse
154+
155+
import httpx
156+
157+
from norbix_python import AsyncNorbix
158+
159+
seen: list[httpx.Request] = []
160+
log = {"list": [{"integrationId": "int_stripe", "eventName": "payment_intent.succeeded", "statusCode": 200}]}
161+
162+
def handler(request: httpx.Request) -> httpx.Response:
163+
seen.append(request)
164+
return httpx.Response(200, json=log)
165+
166+
async def run() -> object:
167+
client = AsyncNorbix(
168+
project_id='test-project',
169+
bearer_token='test-token',
170+
http_client=httpx.AsyncClient(transport=httpx.MockTransport(handler)),
171+
)
172+
try:
173+
return await client.hub.payments.get_payments_webhook_log(integration_id="int_stripe", limit=20)
174+
finally:
175+
await client.aclose()
176+
177+
assert asyncio.run(run()) == log
178+
assert [(r.method, urlparse(str(r.url)).path) for r in seen] == [('GET', '/v3/payments/webhooks/log')]
179+
assert parse_qs(urlparse(str(seen[0].url)).query).get('limit') == ['20']

0 commit comments

Comments
 (0)