agentref 5.0.0__tar.gz → 5.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentref-5.0.0 → agentref-5.0.2}/CHANGELOG.md +8 -0
- {agentref-5.0.0 → agentref-5.0.2}/PKG-INFO +16 -4
- {agentref-5.0.0 → agentref-5.0.2}/README.md +15 -3
- {agentref-5.0.0 → agentref-5.0.2}/agentref/_http.py +1 -1
- {agentref-5.0.0 → agentref-5.0.2}/agentref/client.py +6 -2
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/__init__.py +3 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/merchant.py +1 -25
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/programs.py +48 -4
- agentref-5.0.2/agentref/resources/webhooks.py +162 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/types/__init__.py +18 -4
- {agentref-5.0.0 → agentref-5.0.2}/agentref/types/models.py +126 -20
- {agentref-5.0.0 → agentref-5.0.2}/pyproject.toml +1 -1
- {agentref-5.0.0 → agentref-5.0.2}/tests/test_async.py +34 -2
- {agentref-5.0.0 → agentref-5.0.2}/tests/test_errors.py +12 -11
- {agentref-5.0.0 → agentref-5.0.2}/tests/test_http.py +9 -9
- {agentref-5.0.0 → agentref-5.0.2}/tests/test_programs.py +197 -41
- {agentref-5.0.0 → agentref-5.0.2}/.github/workflows/ci.yml +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/.github/workflows/publish.yml +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/.gitignore +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/__init__.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/errors.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/affiliates.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/billing.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/conversions.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/flags.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/notifications.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/payout_info.py +0 -0
- {agentref-5.0.0 → agentref-5.0.2}/agentref/resources/payouts.py +0 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 5.0.2
|
|
6
|
+
|
|
7
|
+
- Switched the default API host to `https://www.agentref.co/api/v1`.
|
|
8
|
+
- Removed stale domain-verification expectations and legacy tracking fallback fields from the public SDK contract.
|
|
9
|
+
- Updated tests and README to match the active API surface and supported key prefixes.
|
|
10
|
+
|
|
3
11
|
## 1.0.4
|
|
4
12
|
|
|
5
13
|
- **Fix:** `payout_info.update()` now sends `PATCH` instead of `PUT` to match the API contract.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentref
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.2
|
|
4
4
|
Summary: Official Python SDK for the AgentRef Affiliate API
|
|
5
5
|
Author-email: AgentRef <hi@agentref.dev>
|
|
6
6
|
License: MIT
|
|
@@ -47,18 +47,21 @@ async with AsyncAgentRef(api_key="ak_live_...") as client:
|
|
|
47
47
|
## Authentication
|
|
48
48
|
|
|
49
49
|
- Uses `Authorization: Bearer <key>`.
|
|
50
|
-
- Supports `
|
|
50
|
+
- Supports `ak_onb_*`, `ak_live_*`, `ak_aff_*`.
|
|
51
51
|
- Provide `api_key` directly or set `AGENTREF_API_KEY`.
|
|
52
52
|
|
|
53
53
|
## Resources
|
|
54
54
|
|
|
55
|
-
- `client.programs`: `list`, `list_all`, `get`, `create`, `update`, `delete`, `stats`, `list_affiliates`, `list_coupons`, `create_coupon`, `delete_coupon`, `list_invites`, `create_invite`, `update_marketplace`
|
|
55
|
+
- `client.programs`: `list`, `list_all`, `get`, `create`, `update`, `delete`, `stats`, `list_affiliates`, `list_coupons`, `create_coupon`, `delete_coupon`, `list_invites`, `create_invite`, `update_marketplace`, `connect_stripe`, `disconnect_stripe`
|
|
56
56
|
- `client.affiliates`: `list`, `get`, `approve`, `block`, `unblock`
|
|
57
57
|
- `client.conversions`: `list`, `stats`, `recent`
|
|
58
58
|
- `client.payouts`: `list`, `list_pending`, `stats`, `create`
|
|
59
59
|
- `client.flags`: `list`, `stats`, `resolve`
|
|
60
60
|
- `client.billing`: `current`, `tiers`, `subscribe`
|
|
61
|
-
- `client.merchant`: `get`, `update
|
|
61
|
+
- `client.merchant`: `get`, `update`
|
|
62
|
+
- `client.notifications`: `get`, `update`
|
|
63
|
+
- `client.payout_info`: `get`, `update`
|
|
64
|
+
- `client.webhooks`: `list`, `create`, `get`, `update`, `delete`, `rotate_secret`
|
|
62
65
|
|
|
63
66
|
## Pagination
|
|
64
67
|
|
|
@@ -99,3 +102,12 @@ except RateLimitError as e:
|
|
|
99
102
|
except AgentRefError as e:
|
|
100
103
|
print(e.status)
|
|
101
104
|
```
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
| Option | Default | Description |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `api_key` | `AGENTREF_API_KEY` | API key |
|
|
111
|
+
| `base_url` | `https://www.agentref.co/api/v1` | Base API URL |
|
|
112
|
+
| `timeout` | `30.0` | Request timeout in seconds |
|
|
113
|
+
| `max_retries` | `2` | Retry count for GET/HEAD and POST+idempotency_key |
|
|
@@ -30,18 +30,21 @@ async with AsyncAgentRef(api_key="ak_live_...") as client:
|
|
|
30
30
|
## Authentication
|
|
31
31
|
|
|
32
32
|
- Uses `Authorization: Bearer <key>`.
|
|
33
|
-
- Supports `
|
|
33
|
+
- Supports `ak_onb_*`, `ak_live_*`, `ak_aff_*`.
|
|
34
34
|
- Provide `api_key` directly or set `AGENTREF_API_KEY`.
|
|
35
35
|
|
|
36
36
|
## Resources
|
|
37
37
|
|
|
38
|
-
- `client.programs`: `list`, `list_all`, `get`, `create`, `update`, `delete`, `stats`, `list_affiliates`, `list_coupons`, `create_coupon`, `delete_coupon`, `list_invites`, `create_invite`, `update_marketplace`
|
|
38
|
+
- `client.programs`: `list`, `list_all`, `get`, `create`, `update`, `delete`, `stats`, `list_affiliates`, `list_coupons`, `create_coupon`, `delete_coupon`, `list_invites`, `create_invite`, `update_marketplace`, `connect_stripe`, `disconnect_stripe`
|
|
39
39
|
- `client.affiliates`: `list`, `get`, `approve`, `block`, `unblock`
|
|
40
40
|
- `client.conversions`: `list`, `stats`, `recent`
|
|
41
41
|
- `client.payouts`: `list`, `list_pending`, `stats`, `create`
|
|
42
42
|
- `client.flags`: `list`, `stats`, `resolve`
|
|
43
43
|
- `client.billing`: `current`, `tiers`, `subscribe`
|
|
44
|
-
- `client.merchant`: `get`, `update
|
|
44
|
+
- `client.merchant`: `get`, `update`
|
|
45
|
+
- `client.notifications`: `get`, `update`
|
|
46
|
+
- `client.payout_info`: `get`, `update`
|
|
47
|
+
- `client.webhooks`: `list`, `create`, `get`, `update`, `delete`, `rotate_secret`
|
|
45
48
|
|
|
46
49
|
## Pagination
|
|
47
50
|
|
|
@@ -82,3 +85,12 @@ except RateLimitError as e:
|
|
|
82
85
|
except AgentRefError as e:
|
|
83
86
|
print(e.status)
|
|
84
87
|
```
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
| Option | Default | Description |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `api_key` | `AGENTREF_API_KEY` | API key |
|
|
94
|
+
| `base_url` | `https://www.agentref.co/api/v1` | Base API URL |
|
|
95
|
+
| `timeout` | `30.0` | Request timeout in seconds |
|
|
96
|
+
| `max_retries` | `2` | Retry count for GET/HEAD and POST+idempotency_key |
|
|
@@ -14,6 +14,7 @@ from .resources import (
|
|
|
14
14
|
AsyncPayoutInfoResource,
|
|
15
15
|
AsyncPayoutsResource,
|
|
16
16
|
AsyncProgramsResource,
|
|
17
|
+
AsyncWebhooksResource,
|
|
17
18
|
BillingResource,
|
|
18
19
|
ConversionsResource,
|
|
19
20
|
FlagsResource,
|
|
@@ -22,6 +23,7 @@ from .resources import (
|
|
|
22
23
|
PayoutInfoResource,
|
|
23
24
|
PayoutsResource,
|
|
24
25
|
ProgramsResource,
|
|
26
|
+
WebhooksResource,
|
|
25
27
|
)
|
|
26
28
|
|
|
27
29
|
|
|
@@ -30,7 +32,7 @@ class AgentRef:
|
|
|
30
32
|
self,
|
|
31
33
|
api_key: Optional[str] = None,
|
|
32
34
|
*,
|
|
33
|
-
base_url: str = "https://www.agentref.
|
|
35
|
+
base_url: str = "https://www.agentref.co/api/v1",
|
|
34
36
|
timeout: float = 30.0,
|
|
35
37
|
max_retries: int = 2,
|
|
36
38
|
) -> None:
|
|
@@ -50,6 +52,7 @@ class AgentRef:
|
|
|
50
52
|
self.merchant = MerchantResource(self._http)
|
|
51
53
|
self.notifications = NotificationsResource(self._http)
|
|
52
54
|
self.payout_info = PayoutInfoResource(self._http)
|
|
55
|
+
self.webhooks = WebhooksResource(self._http)
|
|
53
56
|
|
|
54
57
|
def close(self) -> None:
|
|
55
58
|
self._http.close()
|
|
@@ -62,7 +65,7 @@ class AsyncAgentRef:
|
|
|
62
65
|
self,
|
|
63
66
|
api_key: Optional[str] = None,
|
|
64
67
|
*,
|
|
65
|
-
base_url: str = "https://www.agentref.
|
|
68
|
+
base_url: str = "https://www.agentref.co/api/v1",
|
|
66
69
|
timeout: float = 30.0,
|
|
67
70
|
max_retries: int = 2,
|
|
68
71
|
) -> None:
|
|
@@ -82,6 +85,7 @@ class AsyncAgentRef:
|
|
|
82
85
|
self.merchant = AsyncMerchantResource(self._http)
|
|
83
86
|
self.notifications = AsyncNotificationsResource(self._http)
|
|
84
87
|
self.payout_info = AsyncPayoutInfoResource(self._http)
|
|
88
|
+
self.webhooks = AsyncWebhooksResource(self._http)
|
|
85
89
|
|
|
86
90
|
async def __aenter__(self) -> "AsyncAgentRef":
|
|
87
91
|
await self._http.__aenter__()
|
|
@@ -7,6 +7,7 @@ from .notifications import AsyncNotificationsResource, NotificationsResource
|
|
|
7
7
|
from .payout_info import AsyncPayoutInfoResource, PayoutInfoResource
|
|
8
8
|
from .payouts import AsyncPayoutsResource, PayoutsResource
|
|
9
9
|
from .programs import AsyncProgramsResource, ProgramsResource
|
|
10
|
+
from .webhooks import AsyncWebhooksResource, WebhooksResource
|
|
10
11
|
|
|
11
12
|
__all__ = [
|
|
12
13
|
"ProgramsResource",
|
|
@@ -16,6 +17,7 @@ __all__ = [
|
|
|
16
17
|
"FlagsResource",
|
|
17
18
|
"BillingResource",
|
|
18
19
|
"MerchantResource",
|
|
20
|
+
"WebhooksResource",
|
|
19
21
|
"NotificationsResource",
|
|
20
22
|
"PayoutInfoResource",
|
|
21
23
|
"AsyncProgramsResource",
|
|
@@ -25,6 +27,7 @@ __all__ = [
|
|
|
25
27
|
"AsyncFlagsResource",
|
|
26
28
|
"AsyncBillingResource",
|
|
27
29
|
"AsyncMerchantResource",
|
|
30
|
+
"AsyncWebhooksResource",
|
|
28
31
|
"AsyncNotificationsResource",
|
|
29
32
|
"AsyncPayoutInfoResource",
|
|
30
33
|
]
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from .._http import AsyncHttpClient, SyncHttpClient
|
|
6
|
-
from ..types.models import Merchant,
|
|
6
|
+
from ..types.models import Merchant, UpdateMerchantParams
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class MerchantResource:
|
|
@@ -18,37 +18,25 @@ class MerchantResource:
|
|
|
18
18
|
self,
|
|
19
19
|
*,
|
|
20
20
|
company_name: Optional[str] = None,
|
|
21
|
-
website: Optional[str] = None,
|
|
22
21
|
logo_url: Optional[str] = None,
|
|
23
22
|
timezone: Optional[str] = None,
|
|
24
23
|
default_cookie_duration: Optional[int] = None,
|
|
25
24
|
default_payout_threshold: Optional[int] = None,
|
|
26
25
|
tracking_requires_consent: Optional[bool] = None,
|
|
27
26
|
tracking_param_aliases: Optional[list[str]] = None,
|
|
28
|
-
tracking_legacy_metadata_fallback_enabled: Optional[bool] = None,
|
|
29
27
|
) -> Merchant:
|
|
30
28
|
payload = UpdateMerchantParams(
|
|
31
29
|
company_name=company_name,
|
|
32
|
-
website=website,
|
|
33
30
|
logo_url=logo_url,
|
|
34
31
|
timezone=timezone,
|
|
35
32
|
default_cookie_duration=default_cookie_duration,
|
|
36
33
|
default_payout_threshold=default_payout_threshold,
|
|
37
34
|
tracking_requires_consent=tracking_requires_consent,
|
|
38
35
|
tracking_param_aliases=tracking_param_aliases,
|
|
39
|
-
tracking_legacy_metadata_fallback_enabled=tracking_legacy_metadata_fallback_enabled,
|
|
40
36
|
).model_dump(by_alias=True, exclude_none=True)
|
|
41
37
|
envelope = self._http.request("PATCH", "/merchant", json=payload)
|
|
42
38
|
return Merchant.model_validate(envelope["data"])
|
|
43
39
|
|
|
44
|
-
def connect_stripe(self) -> StripeConnectSession:
|
|
45
|
-
envelope = self._http.request("POST", "/merchant/connect-stripe")
|
|
46
|
-
return StripeConnectSession.model_validate(envelope["data"])
|
|
47
|
-
|
|
48
|
-
def domain_status(self) -> MerchantDomainStatus:
|
|
49
|
-
envelope = self._http.request("GET", "/merchant/domain-status")
|
|
50
|
-
return MerchantDomainStatus.model_validate(envelope["data"])
|
|
51
|
-
|
|
52
40
|
|
|
53
41
|
class AsyncMerchantResource:
|
|
54
42
|
def __init__(self, http: AsyncHttpClient) -> None:
|
|
@@ -62,33 +50,21 @@ class AsyncMerchantResource:
|
|
|
62
50
|
self,
|
|
63
51
|
*,
|
|
64
52
|
company_name: Optional[str] = None,
|
|
65
|
-
website: Optional[str] = None,
|
|
66
53
|
logo_url: Optional[str] = None,
|
|
67
54
|
timezone: Optional[str] = None,
|
|
68
55
|
default_cookie_duration: Optional[int] = None,
|
|
69
56
|
default_payout_threshold: Optional[int] = None,
|
|
70
57
|
tracking_requires_consent: Optional[bool] = None,
|
|
71
58
|
tracking_param_aliases: Optional[list[str]] = None,
|
|
72
|
-
tracking_legacy_metadata_fallback_enabled: Optional[bool] = None,
|
|
73
59
|
) -> Merchant:
|
|
74
60
|
payload = UpdateMerchantParams(
|
|
75
61
|
company_name=company_name,
|
|
76
|
-
website=website,
|
|
77
62
|
logo_url=logo_url,
|
|
78
63
|
timezone=timezone,
|
|
79
64
|
default_cookie_duration=default_cookie_duration,
|
|
80
65
|
default_payout_threshold=default_payout_threshold,
|
|
81
66
|
tracking_requires_consent=tracking_requires_consent,
|
|
82
67
|
tracking_param_aliases=tracking_param_aliases,
|
|
83
|
-
tracking_legacy_metadata_fallback_enabled=tracking_legacy_metadata_fallback_enabled,
|
|
84
68
|
).model_dump(by_alias=True, exclude_none=True)
|
|
85
69
|
envelope = await self._http.request("PATCH", "/merchant", json=payload)
|
|
86
70
|
return Merchant.model_validate(envelope["data"])
|
|
87
|
-
|
|
88
|
-
async def connect_stripe(self) -> StripeConnectSession:
|
|
89
|
-
envelope = await self._http.request("POST", "/merchant/connect-stripe")
|
|
90
|
-
return StripeConnectSession.model_validate(envelope["data"])
|
|
91
|
-
|
|
92
|
-
async def domain_status(self) -> MerchantDomainStatus:
|
|
93
|
-
envelope = await self._http.request("GET", "/merchant/domain-status")
|
|
94
|
-
return MerchantDomainStatus.model_validate(envelope["data"])
|
|
@@ -5,10 +5,14 @@ from typing import Any, AsyncGenerator, Dict, Generator, List, Literal, Optional
|
|
|
5
5
|
from .._http import AsyncHttpClient, SyncHttpClient
|
|
6
6
|
from ..types.models import (
|
|
7
7
|
Affiliate,
|
|
8
|
+
ConnectProgramStripeParams,
|
|
9
|
+
ConnectProgramStripeResponse,
|
|
8
10
|
Coupon,
|
|
11
|
+
DisconnectProgramStripeResponse,
|
|
9
12
|
Invite,
|
|
10
13
|
PaginatedResponse,
|
|
11
14
|
Program,
|
|
15
|
+
ProgramDetail,
|
|
12
16
|
ProgramStats,
|
|
13
17
|
UpdateProgramMarketplaceParams,
|
|
14
18
|
)
|
|
@@ -52,9 +56,9 @@ class ProgramsResource:
|
|
|
52
56
|
break
|
|
53
57
|
page += 1
|
|
54
58
|
|
|
55
|
-
def get(self, id: str) ->
|
|
59
|
+
def get(self, id: str) -> ProgramDetail:
|
|
56
60
|
envelope = self._http.request("GET", f"/programs/{id}")
|
|
57
|
-
return
|
|
61
|
+
return ProgramDetail.model_validate(envelope["data"])
|
|
58
62
|
|
|
59
63
|
def create(
|
|
60
64
|
self,
|
|
@@ -62,6 +66,7 @@ class ProgramsResource:
|
|
|
62
66
|
name: str,
|
|
63
67
|
commission_type: Literal["one_time", "recurring", "recurring_limited"],
|
|
64
68
|
commission_percent: float,
|
|
69
|
+
website: Optional[str] = None,
|
|
65
70
|
cookie_duration: Optional[int] = None,
|
|
66
71
|
payout_threshold: Optional[int] = None,
|
|
67
72
|
auto_approve_affiliates: Optional[bool] = None,
|
|
@@ -76,6 +81,7 @@ class ProgramsResource:
|
|
|
76
81
|
"name": name,
|
|
77
82
|
"commissionType": commission_type,
|
|
78
83
|
"commissionPercent": commission_percent,
|
|
84
|
+
"website": website,
|
|
79
85
|
"cookieDuration": cookie_duration,
|
|
80
86
|
"payoutThreshold": payout_threshold,
|
|
81
87
|
"autoApproveAffiliates": auto_approve_affiliates,
|
|
@@ -100,6 +106,7 @@ class ProgramsResource:
|
|
|
100
106
|
name: Optional[str] = None,
|
|
101
107
|
commission_type: Optional[Literal["one_time", "recurring", "recurring_limited"]] = None,
|
|
102
108
|
commission_percent: Optional[float] = None,
|
|
109
|
+
website: Optional[str] = None,
|
|
103
110
|
cookie_duration: Optional[int] = None,
|
|
104
111
|
payout_threshold: Optional[int] = None,
|
|
105
112
|
auto_approve_affiliates: Optional[bool] = None,
|
|
@@ -114,6 +121,7 @@ class ProgramsResource:
|
|
|
114
121
|
"name": name,
|
|
115
122
|
"commissionType": commission_type,
|
|
116
123
|
"commissionPercent": commission_percent,
|
|
124
|
+
"website": website,
|
|
117
125
|
"cookieDuration": cookie_duration,
|
|
118
126
|
"payoutThreshold": payout_threshold,
|
|
119
127
|
"autoApproveAffiliates": auto_approve_affiliates,
|
|
@@ -248,6 +256,22 @@ class ProgramsResource:
|
|
|
248
256
|
data = envelope.get("data", {})
|
|
249
257
|
return data if isinstance(data, dict) else {}
|
|
250
258
|
|
|
259
|
+
def connect_stripe(
|
|
260
|
+
self,
|
|
261
|
+
id: str,
|
|
262
|
+
*,
|
|
263
|
+
method: Optional[Literal["oauth_url"]] = None,
|
|
264
|
+
) -> ConnectProgramStripeResponse:
|
|
265
|
+
payload = ConnectProgramStripeParams(
|
|
266
|
+
method=method,
|
|
267
|
+
).model_dump(by_alias=True, exclude_none=True)
|
|
268
|
+
envelope = self._http.request("POST", f"/programs/{id}/connect-stripe", json=payload or None)
|
|
269
|
+
return ConnectProgramStripeResponse.model_validate(envelope["data"])
|
|
270
|
+
|
|
271
|
+
def disconnect_stripe(self, id: str) -> DisconnectProgramStripeResponse:
|
|
272
|
+
envelope = self._http.request("DELETE", f"/programs/{id}/connect-stripe")
|
|
273
|
+
return DisconnectProgramStripeResponse.model_validate(envelope["data"])
|
|
274
|
+
|
|
251
275
|
|
|
252
276
|
class AsyncProgramsResource:
|
|
253
277
|
def __init__(self, http: AsyncHttpClient) -> None:
|
|
@@ -287,9 +311,9 @@ class AsyncProgramsResource:
|
|
|
287
311
|
break
|
|
288
312
|
page += 1
|
|
289
313
|
|
|
290
|
-
async def get(self, id: str) ->
|
|
314
|
+
async def get(self, id: str) -> ProgramDetail:
|
|
291
315
|
envelope = await self._http.request("GET", f"/programs/{id}")
|
|
292
|
-
return
|
|
316
|
+
return ProgramDetail.model_validate(envelope["data"])
|
|
293
317
|
|
|
294
318
|
async def create(
|
|
295
319
|
self,
|
|
@@ -297,6 +321,7 @@ class AsyncProgramsResource:
|
|
|
297
321
|
name: str,
|
|
298
322
|
commission_type: Literal["one_time", "recurring", "recurring_limited"],
|
|
299
323
|
commission_percent: float,
|
|
324
|
+
website: Optional[str] = None,
|
|
300
325
|
cookie_duration: Optional[int] = None,
|
|
301
326
|
payout_threshold: Optional[int] = None,
|
|
302
327
|
auto_approve_affiliates: Optional[bool] = None,
|
|
@@ -311,6 +336,7 @@ class AsyncProgramsResource:
|
|
|
311
336
|
"name": name,
|
|
312
337
|
"commissionType": commission_type,
|
|
313
338
|
"commissionPercent": commission_percent,
|
|
339
|
+
"website": website,
|
|
314
340
|
"cookieDuration": cookie_duration,
|
|
315
341
|
"payoutThreshold": payout_threshold,
|
|
316
342
|
"autoApproveAffiliates": auto_approve_affiliates,
|
|
@@ -335,6 +361,7 @@ class AsyncProgramsResource:
|
|
|
335
361
|
name: Optional[str] = None,
|
|
336
362
|
commission_type: Optional[Literal["one_time", "recurring", "recurring_limited"]] = None,
|
|
337
363
|
commission_percent: Optional[float] = None,
|
|
364
|
+
website: Optional[str] = None,
|
|
338
365
|
cookie_duration: Optional[int] = None,
|
|
339
366
|
payout_threshold: Optional[int] = None,
|
|
340
367
|
auto_approve_affiliates: Optional[bool] = None,
|
|
@@ -349,6 +376,7 @@ class AsyncProgramsResource:
|
|
|
349
376
|
"name": name,
|
|
350
377
|
"commissionType": commission_type,
|
|
351
378
|
"commissionPercent": commission_percent,
|
|
379
|
+
"website": website,
|
|
352
380
|
"cookieDuration": cookie_duration,
|
|
353
381
|
"payoutThreshold": payout_threshold,
|
|
354
382
|
"autoApproveAffiliates": auto_approve_affiliates,
|
|
@@ -482,3 +510,19 @@ class AsyncProgramsResource:
|
|
|
482
510
|
envelope = await self._http.request("PATCH", f"/programs/{id}/marketplace", json=body)
|
|
483
511
|
data = envelope.get("data", {})
|
|
484
512
|
return data if isinstance(data, dict) else {}
|
|
513
|
+
|
|
514
|
+
async def connect_stripe(
|
|
515
|
+
self,
|
|
516
|
+
id: str,
|
|
517
|
+
*,
|
|
518
|
+
method: Optional[Literal["oauth_url"]] = None,
|
|
519
|
+
) -> ConnectProgramStripeResponse:
|
|
520
|
+
payload = ConnectProgramStripeParams(
|
|
521
|
+
method=method,
|
|
522
|
+
).model_dump(by_alias=True, exclude_none=True)
|
|
523
|
+
envelope = await self._http.request("POST", f"/programs/{id}/connect-stripe", json=payload or None)
|
|
524
|
+
return ConnectProgramStripeResponse.model_validate(envelope["data"])
|
|
525
|
+
|
|
526
|
+
async def disconnect_stripe(self, id: str) -> DisconnectProgramStripeResponse:
|
|
527
|
+
envelope = await self._http.request("DELETE", f"/programs/{id}/connect-stripe")
|
|
528
|
+
return DisconnectProgramStripeResponse.model_validate(envelope["data"])
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import List, Literal, Optional
|
|
4
|
+
|
|
5
|
+
from .._http import AsyncHttpClient, SyncHttpClient
|
|
6
|
+
from ..types.models import (
|
|
7
|
+
CreateWebhookEndpointParams,
|
|
8
|
+
SuccessResponse,
|
|
9
|
+
WebhookEndpoint,
|
|
10
|
+
WebhookSecretResponse,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
_UNSET = object()
|
|
14
|
+
WebhookEventType = Literal[
|
|
15
|
+
"program.created",
|
|
16
|
+
"program.updated",
|
|
17
|
+
"affiliate.joined",
|
|
18
|
+
"affiliate.approved",
|
|
19
|
+
"affiliate.blocked",
|
|
20
|
+
"affiliate.unblocked",
|
|
21
|
+
"conversion.created",
|
|
22
|
+
"conversion.refunded",
|
|
23
|
+
"payout.created",
|
|
24
|
+
"payout.processing",
|
|
25
|
+
"payout.completed",
|
|
26
|
+
"payout.failed",
|
|
27
|
+
"flag.resolved",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class WebhooksResource:
|
|
32
|
+
def __init__(self, http: SyncHttpClient) -> None:
|
|
33
|
+
self._http = http
|
|
34
|
+
|
|
35
|
+
def list(self, *, program_id: Optional[str] = None) -> List[WebhookEndpoint]:
|
|
36
|
+
envelope = self._http.request("GET", "/webhooks", params={"programId": program_id})
|
|
37
|
+
data = envelope.get("data", [])
|
|
38
|
+
if not isinstance(data, list):
|
|
39
|
+
return []
|
|
40
|
+
return [WebhookEndpoint.model_validate(item) for item in data]
|
|
41
|
+
|
|
42
|
+
def create(
|
|
43
|
+
self,
|
|
44
|
+
*,
|
|
45
|
+
name: str,
|
|
46
|
+
url: str,
|
|
47
|
+
subscribed_events: List[WebhookEventType],
|
|
48
|
+
program_id: Optional[str] = None,
|
|
49
|
+
schema_version: Optional[Literal[2]] = None,
|
|
50
|
+
) -> WebhookSecretResponse:
|
|
51
|
+
payload = CreateWebhookEndpointParams(
|
|
52
|
+
name=name,
|
|
53
|
+
url=url,
|
|
54
|
+
subscribed_events=subscribed_events,
|
|
55
|
+
program_id=program_id,
|
|
56
|
+
schema_version=schema_version,
|
|
57
|
+
).model_dump(by_alias=True, exclude_none=True)
|
|
58
|
+
envelope = self._http.request("POST", "/webhooks", json=payload)
|
|
59
|
+
return WebhookSecretResponse.model_validate(envelope["data"])
|
|
60
|
+
|
|
61
|
+
def get(self, id: str) -> WebhookEndpoint:
|
|
62
|
+
envelope = self._http.request("GET", f"/webhooks/{id}")
|
|
63
|
+
return WebhookEndpoint.model_validate(envelope["data"])
|
|
64
|
+
|
|
65
|
+
def update(
|
|
66
|
+
self,
|
|
67
|
+
id: str,
|
|
68
|
+
*,
|
|
69
|
+
name: Optional[str] = None,
|
|
70
|
+
url: Optional[str] = None,
|
|
71
|
+
subscribed_events: Optional[List[WebhookEventType]] = None,
|
|
72
|
+
program_id: object = _UNSET,
|
|
73
|
+
schema_version: Optional[Literal[2]] = None,
|
|
74
|
+
) -> WebhookEndpoint:
|
|
75
|
+
payload: dict[str, object] = {}
|
|
76
|
+
if name is not None:
|
|
77
|
+
payload["name"] = name
|
|
78
|
+
if url is not None:
|
|
79
|
+
payload["url"] = url
|
|
80
|
+
if subscribed_events is not None:
|
|
81
|
+
payload["subscribedEvents"] = subscribed_events
|
|
82
|
+
if program_id is not _UNSET:
|
|
83
|
+
payload["programId"] = program_id
|
|
84
|
+
if schema_version is not None:
|
|
85
|
+
payload["schemaVersion"] = schema_version
|
|
86
|
+
envelope = self._http.request("PATCH", f"/webhooks/{id}", json=payload)
|
|
87
|
+
return WebhookEndpoint.model_validate(envelope["data"])
|
|
88
|
+
|
|
89
|
+
def delete(self, id: str) -> SuccessResponse:
|
|
90
|
+
envelope = self._http.request("DELETE", f"/webhooks/{id}")
|
|
91
|
+
return SuccessResponse.model_validate(envelope["data"])
|
|
92
|
+
|
|
93
|
+
def rotate_secret(self, id: str) -> WebhookSecretResponse:
|
|
94
|
+
envelope = self._http.request("POST", f"/webhooks/{id}/rotate-secret")
|
|
95
|
+
return WebhookSecretResponse.model_validate(envelope["data"])
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class AsyncWebhooksResource:
|
|
99
|
+
def __init__(self, http: AsyncHttpClient) -> None:
|
|
100
|
+
self._http = http
|
|
101
|
+
|
|
102
|
+
async def list(self, *, program_id: Optional[str] = None) -> List[WebhookEndpoint]:
|
|
103
|
+
envelope = await self._http.request("GET", "/webhooks", params={"programId": program_id})
|
|
104
|
+
data = envelope.get("data", [])
|
|
105
|
+
if not isinstance(data, list):
|
|
106
|
+
return []
|
|
107
|
+
return [WebhookEndpoint.model_validate(item) for item in data]
|
|
108
|
+
|
|
109
|
+
async def create(
|
|
110
|
+
self,
|
|
111
|
+
*,
|
|
112
|
+
name: str,
|
|
113
|
+
url: str,
|
|
114
|
+
subscribed_events: List[WebhookEventType],
|
|
115
|
+
program_id: Optional[str] = None,
|
|
116
|
+
schema_version: Optional[Literal[2]] = None,
|
|
117
|
+
) -> WebhookSecretResponse:
|
|
118
|
+
payload = CreateWebhookEndpointParams(
|
|
119
|
+
name=name,
|
|
120
|
+
url=url,
|
|
121
|
+
subscribed_events=subscribed_events,
|
|
122
|
+
program_id=program_id,
|
|
123
|
+
schema_version=schema_version,
|
|
124
|
+
).model_dump(by_alias=True, exclude_none=True)
|
|
125
|
+
envelope = await self._http.request("POST", "/webhooks", json=payload)
|
|
126
|
+
return WebhookSecretResponse.model_validate(envelope["data"])
|
|
127
|
+
|
|
128
|
+
async def get(self, id: str) -> WebhookEndpoint:
|
|
129
|
+
envelope = await self._http.request("GET", f"/webhooks/{id}")
|
|
130
|
+
return WebhookEndpoint.model_validate(envelope["data"])
|
|
131
|
+
|
|
132
|
+
async def update(
|
|
133
|
+
self,
|
|
134
|
+
id: str,
|
|
135
|
+
*,
|
|
136
|
+
name: Optional[str] = None,
|
|
137
|
+
url: Optional[str] = None,
|
|
138
|
+
subscribed_events: Optional[List[WebhookEventType]] = None,
|
|
139
|
+
program_id: object = _UNSET,
|
|
140
|
+
schema_version: Optional[Literal[2]] = None,
|
|
141
|
+
) -> WebhookEndpoint:
|
|
142
|
+
payload: dict[str, object] = {}
|
|
143
|
+
if name is not None:
|
|
144
|
+
payload["name"] = name
|
|
145
|
+
if url is not None:
|
|
146
|
+
payload["url"] = url
|
|
147
|
+
if subscribed_events is not None:
|
|
148
|
+
payload["subscribedEvents"] = subscribed_events
|
|
149
|
+
if program_id is not _UNSET:
|
|
150
|
+
payload["programId"] = program_id
|
|
151
|
+
if schema_version is not None:
|
|
152
|
+
payload["schemaVersion"] = schema_version
|
|
153
|
+
envelope = await self._http.request("PATCH", f"/webhooks/{id}", json=payload)
|
|
154
|
+
return WebhookEndpoint.model_validate(envelope["data"])
|
|
155
|
+
|
|
156
|
+
async def delete(self, id: str) -> SuccessResponse:
|
|
157
|
+
envelope = await self._http.request("DELETE", f"/webhooks/{id}")
|
|
158
|
+
return SuccessResponse.model_validate(envelope["data"])
|
|
159
|
+
|
|
160
|
+
async def rotate_secret(self, id: str) -> WebhookSecretResponse:
|
|
161
|
+
envelope = await self._http.request("POST", f"/webhooks/{id}/rotate-secret")
|
|
162
|
+
return WebhookSecretResponse.model_validate(envelope["data"])
|
|
@@ -6,11 +6,11 @@ from .models import (
|
|
|
6
6
|
Conversion,
|
|
7
7
|
ConversionStats,
|
|
8
8
|
Coupon,
|
|
9
|
+
CreateWebhookEndpointParams,
|
|
9
10
|
Flag,
|
|
10
11
|
FlagStats,
|
|
11
12
|
Invite,
|
|
12
13
|
Merchant,
|
|
13
|
-
MerchantDomainStatus,
|
|
14
14
|
NotificationPreferences,
|
|
15
15
|
PaginatedResponse,
|
|
16
16
|
PaginationMeta,
|
|
@@ -19,19 +19,27 @@ from .models import (
|
|
|
19
19
|
Payout,
|
|
20
20
|
PayoutStats,
|
|
21
21
|
Program,
|
|
22
|
+
ProgramDetail,
|
|
22
23
|
ProgramStats,
|
|
23
24
|
ResolveFlagParams,
|
|
24
|
-
|
|
25
|
+
ConnectProgramStripeParams,
|
|
26
|
+
ConnectProgramStripeResponse,
|
|
27
|
+
DisconnectProgramStripeResponse,
|
|
28
|
+
SuccessResponse,
|
|
25
29
|
UpdateMerchantParams,
|
|
26
30
|
UpdateNotificationPreferencesParams,
|
|
27
31
|
UpdatePayoutInfoParams,
|
|
28
32
|
UpdateProgramMarketplaceParams,
|
|
33
|
+
UpdateWebhookEndpointParams,
|
|
34
|
+
WebhookEndpoint,
|
|
35
|
+
WebhookSecretResponse,
|
|
29
36
|
)
|
|
30
37
|
|
|
31
38
|
__all__ = [
|
|
32
39
|
"PaginationMeta",
|
|
33
40
|
"PaginatedResponse",
|
|
34
41
|
"Program",
|
|
42
|
+
"ProgramDetail",
|
|
35
43
|
"ProgramStats",
|
|
36
44
|
"Affiliate",
|
|
37
45
|
"Conversion",
|
|
@@ -46,8 +54,10 @@ __all__ = [
|
|
|
46
54
|
"BillingStatus",
|
|
47
55
|
"Merchant",
|
|
48
56
|
"UpdateMerchantParams",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
57
|
+
"ConnectProgramStripeParams",
|
|
58
|
+
"ConnectProgramStripeResponse",
|
|
59
|
+
"DisconnectProgramStripeResponse",
|
|
60
|
+
"SuccessResponse",
|
|
51
61
|
"CreatePayoutParams",
|
|
52
62
|
"UpdateProgramMarketplaceParams",
|
|
53
63
|
"Coupon",
|
|
@@ -56,4 +66,8 @@ __all__ = [
|
|
|
56
66
|
"UpdatePayoutInfoParams",
|
|
57
67
|
"NotificationPreferences",
|
|
58
68
|
"UpdateNotificationPreferencesParams",
|
|
69
|
+
"WebhookEndpoint",
|
|
70
|
+
"CreateWebhookEndpointParams",
|
|
71
|
+
"UpdateWebhookEndpointParams",
|
|
72
|
+
"WebhookSecretResponse",
|
|
59
73
|
]
|