solvapay-python 0.7.2__py3-none-any.whl → 0.9.0__py3-none-any.whl
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.
- solvapay/__init__.py +31 -1
- solvapay/_async_client.py +126 -184
- solvapay/_http.py +16 -215
- solvapay/_stability.py +60 -0
- solvapay/_transport/__init__.py +106 -0
- solvapay/_transport/_recipe.py +63 -0
- solvapay/_transport/httpx_transport.py +401 -0
- solvapay/_transport/middleware.py +409 -0
- solvapay/adapters/__init__.py +3 -0
- solvapay/adapters/asgi.py +119 -0
- solvapay/adapters/langchain.py +88 -0
- solvapay/adapters/mcp.py +158 -0
- solvapay/client.py +107 -182
- solvapay/idempotency.py +25 -4
- solvapay/langchain.py +9 -61
- solvapay/operations/__init__.py +7 -0
- solvapay/operations/_registry.py +117 -0
- solvapay/operations/checkout.py +75 -0
- solvapay/operations/customers.py +256 -0
- solvapay/operations/limits.py +77 -0
- solvapay/operations/merchant.py +71 -0
- solvapay/operations/plans.py +167 -0
- solvapay/operations/products.py +141 -0
- solvapay/operations/purchases.py +103 -0
- solvapay/operations/usage.py +75 -0
- solvapay/paywall/__init__.py +32 -0
- solvapay/paywall/core.py +152 -0
- solvapay/paywall/decorators.py +126 -0
- solvapay/paywall/meta.py +18 -0
- solvapay/paywall/policy.py +14 -0
- solvapay/paywall/resolvers.py +60 -0
- solvapay/paywall/state.py +23 -0
- solvapay/webhooks/__init__.py +43 -0
- solvapay/webhooks/envelope.py +16 -0
- solvapay/webhooks/pipeline.py +77 -0
- solvapay/webhooks/replay.py +74 -0
- solvapay/webhooks/rotation.py +36 -0
- solvapay/webhooks/sign.py +37 -0
- solvapay/{webhooks.py → webhooks/verify.py} +4 -22
- solvapay_python-0.9.0.dist-info/METADATA +318 -0
- solvapay_python-0.9.0.dist-info/RECORD +50 -0
- solvapay/paywall.py +0 -153
- solvapay_python-0.7.2.dist-info/METADATA +0 -357
- solvapay_python-0.7.2.dist-info/RECORD +0 -19
- {solvapay_python-0.7.2.dist-info → solvapay_python-0.9.0.dist-info}/WHEEL +0 -0
- {solvapay_python-0.7.2.dist-info → solvapay_python-0.9.0.dist-info}/licenses/LICENSE +0 -0
solvapay/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from solvapay import paywall
|
|
6
6
|
from solvapay._async_client import AsyncSolvaPay
|
|
7
|
+
from solvapay._stability import MANIFEST, deprecated, experimental, stable
|
|
7
8
|
from solvapay.client import SolvaPay
|
|
8
9
|
from solvapay.events import (
|
|
9
10
|
CheckoutSessionCreated,
|
|
@@ -38,7 +39,33 @@ from solvapay.models import BalanceResponse, Merchant, Plan, PlatformConfig, Pro
|
|
|
38
39
|
from solvapay.paywall import PaywallRequired
|
|
39
40
|
from solvapay.webhooks import verify_webhook
|
|
40
41
|
|
|
42
|
+
# Register stable exports in MANIFEST (HLD V1.2).
|
|
43
|
+
# stable(X) returns X unchanged — isinstance() continues to work (HLD SM1).
|
|
44
|
+
stable(SolvaPay)
|
|
45
|
+
stable(AsyncSolvaPay)
|
|
46
|
+
stable(SolvaPayError)
|
|
47
|
+
stable(APIError)
|
|
48
|
+
stable(AuthenticationError)
|
|
49
|
+
stable(PermissionError)
|
|
50
|
+
stable(NotFoundError)
|
|
51
|
+
stable(RateLimitError)
|
|
52
|
+
stable(InvalidRequestError)
|
|
53
|
+
stable(APIServerError)
|
|
54
|
+
stable(APIConnectionError)
|
|
55
|
+
stable(APITimeoutError)
|
|
56
|
+
stable(PaywallRequired)
|
|
57
|
+
stable(verify_webhook)
|
|
58
|
+
stable(BalanceResponse)
|
|
59
|
+
stable(Product)
|
|
60
|
+
stable(Plan)
|
|
61
|
+
stable(Merchant)
|
|
62
|
+
stable(PlatformConfig)
|
|
63
|
+
stable(WebhookEvent)
|
|
64
|
+
# SolvaPayAPIError is a back-compat alias — deprecated in v1.0, removed v2.0
|
|
65
|
+
deprecated(removed_in="2.0")(SolvaPayAPIError)
|
|
66
|
+
|
|
41
67
|
__all__ = [
|
|
68
|
+
"MANIFEST",
|
|
42
69
|
"APIConnectionError",
|
|
43
70
|
"APIError",
|
|
44
71
|
"APIServerError",
|
|
@@ -72,7 +99,10 @@ __all__ = [
|
|
|
72
99
|
"SolvaPayAPIError",
|
|
73
100
|
"SolvaPayError",
|
|
74
101
|
"WebhookEvent",
|
|
102
|
+
"deprecated",
|
|
103
|
+
"experimental",
|
|
75
104
|
"paywall",
|
|
105
|
+
"stable",
|
|
76
106
|
"verify_webhook",
|
|
77
107
|
]
|
|
78
|
-
__version__ = "0.
|
|
108
|
+
__version__ = "0.9.0"
|
solvapay/_async_client.py
CHANGED
|
@@ -7,37 +7,52 @@ Use `async with AsyncSolvaPay() as sv: ...` for proper teardown.
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
|
-
import
|
|
10
|
+
import warnings
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
13
|
from solvapay._config import resolve_api_key, resolve_base_url
|
|
14
|
-
from solvapay._http import AsyncHttpClient
|
|
15
|
-
from solvapay.exceptions import SolvaPayAPIError
|
|
14
|
+
from solvapay._http import AsyncHttpClient
|
|
16
15
|
from solvapay.models import (
|
|
17
16
|
BalanceResponse,
|
|
18
|
-
CancelPurchaseRequest,
|
|
19
|
-
CheckLimitsRequest,
|
|
20
17
|
CheckoutSession,
|
|
21
|
-
CheckoutSessionRequest,
|
|
22
|
-
CloneProductRequest,
|
|
23
|
-
CreateCustomerRequest,
|
|
24
|
-
CreatePlanRequest,
|
|
25
|
-
CreateProductRequest,
|
|
26
18
|
Customer,
|
|
27
19
|
LimitResponse,
|
|
28
20
|
Merchant,
|
|
29
21
|
Plan,
|
|
30
22
|
PlatformConfig,
|
|
31
23
|
Product,
|
|
32
|
-
TrackUsageRequest,
|
|
33
|
-
UpdateCustomerRequest,
|
|
34
|
-
UpdatePlanRequest,
|
|
35
24
|
)
|
|
25
|
+
from solvapay.operations.checkout import CheckoutOperations
|
|
26
|
+
from solvapay.operations.customers import CustomersOperations
|
|
27
|
+
from solvapay.operations.limits import LimitsOperations
|
|
28
|
+
from solvapay.operations.merchant import MerchantOperations
|
|
29
|
+
from solvapay.operations.plans import PlansOperations
|
|
30
|
+
from solvapay.operations.products import ProductsOperations
|
|
31
|
+
from solvapay.operations.purchases import PurchasesOperations
|
|
32
|
+
from solvapay.operations.usage import UsageOperations
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _shim_warn(new: str) -> None:
|
|
36
|
+
warnings.warn(
|
|
37
|
+
f"Flat method deprecated; use {new} instead",
|
|
38
|
+
DeprecationWarning,
|
|
39
|
+
stacklevel=3,
|
|
40
|
+
)
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
class AsyncSolvaPay:
|
|
39
44
|
"""Async SolvaPay API client.
|
|
40
45
|
|
|
46
|
+
Resource namespaces (v0.8+):
|
|
47
|
+
sv.customers.aensure / aget / aupdate / abalance
|
|
48
|
+
sv.checkout.acreate_session
|
|
49
|
+
sv.limits.acheck
|
|
50
|
+
sv.purchases.acancel / areactivate
|
|
51
|
+
sv.usage.atrack
|
|
52
|
+
sv.products.alist / aget / acreate / adelete / aclone
|
|
53
|
+
sv.plans.alist / acreate / aupdate / adelete
|
|
54
|
+
sv.merchant.aget / aget_platform_config
|
|
55
|
+
|
|
41
56
|
Args:
|
|
42
57
|
api_key: SolvaPay secret key. Falls back to SOLVAPAY_SECRET_KEY env var.
|
|
43
58
|
base_url: API base URL. Falls back to SOLVAPAY_API_BASE_URL env var,
|
|
@@ -46,7 +61,7 @@ class AsyncSolvaPay:
|
|
|
46
61
|
|
|
47
62
|
Example:
|
|
48
63
|
>>> async with AsyncSolvaPay() as sv:
|
|
49
|
-
... session = await sv.
|
|
64
|
+
... session = await sv.checkout.acreate_session(
|
|
50
65
|
... customer_ref="cus_123", product_ref="prd_0QKI8NHF"
|
|
51
66
|
... )
|
|
52
67
|
"""
|
|
@@ -58,23 +73,56 @@ class AsyncSolvaPay:
|
|
|
58
73
|
base_url: str | None = None,
|
|
59
74
|
timeout: float = 30.0,
|
|
60
75
|
logger: logging.Logger | None = None,
|
|
76
|
+
api_version: str | None = "2026-05-22",
|
|
61
77
|
) -> None:
|
|
62
78
|
self._http = AsyncHttpClient(
|
|
63
79
|
api_key=resolve_api_key(api_key),
|
|
64
80
|
base_url=resolve_base_url(base_url),
|
|
65
81
|
timeout=timeout,
|
|
66
82
|
logger=logger,
|
|
83
|
+
api_version=api_version,
|
|
67
84
|
)
|
|
85
|
+
# Eager namespace construction (HLD RN1).
|
|
86
|
+
_t = self._http._transport
|
|
87
|
+
self.customers = CustomersOperations(sync_transport=None, async_transport=_t)
|
|
88
|
+
self.checkout = CheckoutOperations(sync_transport=None, async_transport=_t)
|
|
89
|
+
self.limits = LimitsOperations(sync_transport=None, async_transport=_t)
|
|
90
|
+
self.purchases = PurchasesOperations(sync_transport=None, async_transport=_t)
|
|
91
|
+
self.usage = UsageOperations(sync_transport=None, async_transport=_t)
|
|
92
|
+
self.products = ProductsOperations(sync_transport=None, async_transport=_t)
|
|
93
|
+
self.plans = PlansOperations(sync_transport=None, async_transport=_t)
|
|
94
|
+
self.merchant = MerchantOperations(sync_transport=None, async_transport=_t)
|
|
95
|
+
self._closed = False
|
|
68
96
|
|
|
69
97
|
async def aclose(self) -> None:
|
|
98
|
+
self._closed = True
|
|
70
99
|
await self._http.aclose()
|
|
71
100
|
|
|
101
|
+
def __del__(self) -> None:
|
|
102
|
+
if not self._closed:
|
|
103
|
+
import asyncio
|
|
104
|
+
import warnings
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
loop = asyncio.get_event_loop()
|
|
108
|
+
except RuntimeError:
|
|
109
|
+
return
|
|
110
|
+
if loop.is_running():
|
|
111
|
+
warnings.warn(
|
|
112
|
+
"AsyncSolvaPay was not closed. "
|
|
113
|
+
"Use `async with AsyncSolvaPay(...)` or call `await sv.aclose()`.",
|
|
114
|
+
ResourceWarning,
|
|
115
|
+
stacklevel=2,
|
|
116
|
+
)
|
|
117
|
+
|
|
72
118
|
async def __aenter__(self) -> AsyncSolvaPay:
|
|
73
119
|
return self
|
|
74
120
|
|
|
75
121
|
async def __aexit__(self, *_: object) -> None:
|
|
76
122
|
await self.aclose()
|
|
77
123
|
|
|
124
|
+
# ── Deprecated flat shims — removed in v2.0 ──
|
|
125
|
+
|
|
78
126
|
async def create_checkout_session(
|
|
79
127
|
self,
|
|
80
128
|
*,
|
|
@@ -84,21 +132,14 @@ class AsyncSolvaPay:
|
|
|
84
132
|
return_url: str | None = None,
|
|
85
133
|
idempotency_key: str | None = None,
|
|
86
134
|
) -> CheckoutSession:
|
|
87
|
-
|
|
135
|
+
_shim_warn("sv.checkout.acreate_session()")
|
|
136
|
+
return await self.checkout.acreate_session(
|
|
88
137
|
customer_ref=customer_ref,
|
|
89
138
|
product_ref=product_ref,
|
|
90
139
|
plan_ref=plan_ref,
|
|
91
140
|
return_url=return_url,
|
|
141
|
+
idempotency_key=idempotency_key,
|
|
92
142
|
)
|
|
93
|
-
data = await self._http.send(
|
|
94
|
-
_RequestSpec(
|
|
95
|
-
"POST",
|
|
96
|
-
"/v1/sdk/checkout-sessions",
|
|
97
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
98
|
-
idempotency_key=idempotency_key,
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
return CheckoutSession.model_validate(data)
|
|
102
143
|
|
|
103
144
|
async def ensure_customer(
|
|
104
145
|
self,
|
|
@@ -109,35 +150,14 @@ class AsyncSolvaPay:
|
|
|
109
150
|
name: str | None = None,
|
|
110
151
|
idempotency_key: str | None = None,
|
|
111
152
|
) -> str:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
ref = existing.get("reference") or existing.get("customerRef")
|
|
118
|
-
if ref:
|
|
119
|
-
return str(ref)
|
|
120
|
-
except SolvaPayAPIError as exc:
|
|
121
|
-
if exc.status_code != 404:
|
|
122
|
-
raise
|
|
123
|
-
|
|
124
|
-
req = CreateCustomerRequest(
|
|
125
|
-
email=email or f"{customer_ref}-{int(time.time())}@auto-created.local",
|
|
126
|
-
external_ref=lookup_ref,
|
|
153
|
+
_shim_warn("sv.customers.aensure()")
|
|
154
|
+
return await self.customers.aensure(
|
|
155
|
+
customer_ref,
|
|
156
|
+
external_ref,
|
|
157
|
+
email=email,
|
|
127
158
|
name=name,
|
|
159
|
+
idempotency_key=idempotency_key,
|
|
128
160
|
)
|
|
129
|
-
created = await self._http.send(
|
|
130
|
-
_RequestSpec(
|
|
131
|
-
"POST",
|
|
132
|
-
"/v1/sdk/customers",
|
|
133
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
134
|
-
idempotency_key=idempotency_key,
|
|
135
|
-
)
|
|
136
|
-
)
|
|
137
|
-
ref = created.get("reference") or created.get("customerRef")
|
|
138
|
-
if not ref:
|
|
139
|
-
raise SolvaPayAPIError(200, f"customer create returned no reference: {created!r}")
|
|
140
|
-
return str(ref)
|
|
141
161
|
|
|
142
162
|
async def get_customer(
|
|
143
163
|
self,
|
|
@@ -146,19 +166,8 @@ class AsyncSolvaPay:
|
|
|
146
166
|
external_ref: str | None = None,
|
|
147
167
|
email: str | None = None,
|
|
148
168
|
) -> Customer:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
elif external_ref:
|
|
152
|
-
data = await self._http.send(
|
|
153
|
-
_RequestSpec("GET", "/v1/sdk/customers", params={"externalRef": external_ref})
|
|
154
|
-
)
|
|
155
|
-
elif email:
|
|
156
|
-
data = await self._http.send(
|
|
157
|
-
_RequestSpec("GET", "/v1/sdk/customers", params={"email": email})
|
|
158
|
-
)
|
|
159
|
-
else:
|
|
160
|
-
raise ValueError("Must provide customer_ref, external_ref, or email")
|
|
161
|
-
return Customer.model_validate(data)
|
|
169
|
+
_shim_warn("sv.customers.aget()")
|
|
170
|
+
return await self.customers.aget(customer_ref, external_ref=external_ref, email=email)
|
|
162
171
|
|
|
163
172
|
async def check_limits(
|
|
164
173
|
self,
|
|
@@ -169,19 +178,14 @@ class AsyncSolvaPay:
|
|
|
169
178
|
meter_name: str | None = None,
|
|
170
179
|
usage_type: str | None = None,
|
|
171
180
|
) -> LimitResponse:
|
|
172
|
-
|
|
181
|
+
_shim_warn("sv.limits.acheck()")
|
|
182
|
+
return await self.limits.acheck(
|
|
173
183
|
customer_ref=customer_ref,
|
|
174
184
|
product_ref=product_ref,
|
|
175
185
|
plan_ref=plan_ref,
|
|
176
186
|
meter_name=meter_name,
|
|
177
187
|
usage_type=usage_type,
|
|
178
188
|
)
|
|
179
|
-
data = await self._http.send(
|
|
180
|
-
_RequestSpec(
|
|
181
|
-
"POST", "/v1/sdk/limits", json=req.model_dump(by_alias=True, exclude_none=True)
|
|
182
|
-
)
|
|
183
|
-
)
|
|
184
|
-
return LimitResponse.model_validate(data)
|
|
185
189
|
|
|
186
190
|
async def track_usage(
|
|
187
191
|
self,
|
|
@@ -192,20 +196,13 @@ class AsyncSolvaPay:
|
|
|
192
196
|
units: float,
|
|
193
197
|
idempotency_key: str | None = None,
|
|
194
198
|
) -> dict[str, Any]:
|
|
195
|
-
"
|
|
196
|
-
|
|
199
|
+
_shim_warn("sv.usage.atrack()")
|
|
200
|
+
return await self.usage.atrack(
|
|
197
201
|
customer_ref=customer_ref,
|
|
198
202
|
product_ref=product_ref,
|
|
199
203
|
meter_name=meter_name,
|
|
200
204
|
units=units,
|
|
201
|
-
|
|
202
|
-
return await self._http.send(
|
|
203
|
-
_RequestSpec(
|
|
204
|
-
"POST",
|
|
205
|
-
"/v1/sdk/usages",
|
|
206
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
207
|
-
idempotency_key=idempotency_key,
|
|
208
|
-
)
|
|
205
|
+
idempotency_key=idempotency_key,
|
|
209
206
|
)
|
|
210
207
|
|
|
211
208
|
async def update_customer(
|
|
@@ -216,23 +213,14 @@ class AsyncSolvaPay:
|
|
|
216
213
|
name: str | None = None,
|
|
217
214
|
external_ref: str | None = None,
|
|
218
215
|
) -> Customer:
|
|
219
|
-
"
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
_RequestSpec(
|
|
223
|
-
"PATCH",
|
|
224
|
-
f"/v1/sdk/customers/{customer_ref}",
|
|
225
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
226
|
-
)
|
|
216
|
+
_shim_warn("sv.customers.aupdate()")
|
|
217
|
+
return await self.customers.aupdate(
|
|
218
|
+
customer_ref, email=email, name=name, external_ref=external_ref
|
|
227
219
|
)
|
|
228
|
-
return Customer.model_validate(data)
|
|
229
220
|
|
|
230
221
|
async def get_customer_balance(self, customer_ref: str) -> BalanceResponse:
|
|
231
|
-
"
|
|
232
|
-
|
|
233
|
-
_RequestSpec("GET", f"/v1/sdk/customers/{customer_ref}/balance")
|
|
234
|
-
)
|
|
235
|
-
return BalanceResponse.model_validate(data)
|
|
222
|
+
_shim_warn("sv.customers.abalance()")
|
|
223
|
+
return await self.customers.abalance(customer_ref)
|
|
236
224
|
|
|
237
225
|
async def cancel_purchase(
|
|
238
226
|
self,
|
|
@@ -241,83 +229,48 @@ class AsyncSolvaPay:
|
|
|
241
229
|
reason: str | None = None,
|
|
242
230
|
idempotency_key: str | None = None,
|
|
243
231
|
) -> dict[str, Any]:
|
|
244
|
-
"
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
_RequestSpec(
|
|
248
|
-
"POST",
|
|
249
|
-
f"/v1/sdk/purchases/{purchase_ref}/cancel",
|
|
250
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
251
|
-
idempotency_key=idempotency_key,
|
|
252
|
-
)
|
|
232
|
+
_shim_warn("sv.purchases.acancel()")
|
|
233
|
+
return await self.purchases.acancel(
|
|
234
|
+
purchase_ref, reason=reason, idempotency_key=idempotency_key
|
|
253
235
|
)
|
|
254
236
|
|
|
255
237
|
async def reactivate_purchase(
|
|
256
238
|
self, purchase_ref: str, *, idempotency_key: str | None = None
|
|
257
239
|
) -> dict[str, Any]:
|
|
258
|
-
"
|
|
259
|
-
return await self.
|
|
260
|
-
_RequestSpec(
|
|
261
|
-
"POST",
|
|
262
|
-
f"/v1/sdk/purchases/{purchase_ref}/reactivate",
|
|
263
|
-
idempotency_key=idempotency_key,
|
|
264
|
-
)
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
# --- Admin: Products ---
|
|
240
|
+
_shim_warn("sv.purchases.areactivate()")
|
|
241
|
+
return await self.purchases.areactivate(purchase_ref, idempotency_key=idempotency_key)
|
|
268
242
|
|
|
269
243
|
async def list_products(self) -> list[Product]:
|
|
270
|
-
"
|
|
271
|
-
|
|
272
|
-
items: list[Any] = data if isinstance(data, list) else data.get("products", [])
|
|
273
|
-
return [Product.model_validate(p) for p in items]
|
|
244
|
+
_shim_warn("sv.products.alist()")
|
|
245
|
+
return await self.products.alist()
|
|
274
246
|
|
|
275
247
|
async def get_product(self, product_ref: str) -> Product:
|
|
276
|
-
"
|
|
277
|
-
|
|
278
|
-
return Product.model_validate(data)
|
|
248
|
+
_shim_warn("sv.products.aget()")
|
|
249
|
+
return await self.products.aget(product_ref)
|
|
279
250
|
|
|
280
251
|
async def create_product(
|
|
281
252
|
self, *, name: str, type: str, default_currency: str, idempotency_key: str | None = None
|
|
282
253
|
) -> Product:
|
|
283
|
-
"
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
_RequestSpec(
|
|
287
|
-
"POST",
|
|
288
|
-
"/v1/sdk/products",
|
|
289
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
290
|
-
idempotency_key=idempotency_key,
|
|
291
|
-
)
|
|
254
|
+
_shim_warn("sv.products.acreate()")
|
|
255
|
+
return await self.products.acreate(
|
|
256
|
+
name=name, type=type, default_currency=default_currency, idempotency_key=idempotency_key
|
|
292
257
|
)
|
|
293
|
-
return Product.model_validate(data)
|
|
294
258
|
|
|
295
259
|
async def delete_product(self, product_ref: str) -> dict[str, Any]:
|
|
296
|
-
"
|
|
297
|
-
return await self.
|
|
260
|
+
_shim_warn("sv.products.adelete()")
|
|
261
|
+
return await self.products.adelete(product_ref)
|
|
298
262
|
|
|
299
263
|
async def clone_product(
|
|
300
264
|
self, product_ref: str, *, new_name: str, idempotency_key: str | None = None
|
|
301
265
|
) -> Product:
|
|
302
|
-
"
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
_RequestSpec(
|
|
306
|
-
"POST",
|
|
307
|
-
f"/v1/sdk/products/{product_ref}/clone",
|
|
308
|
-
json=req.model_dump(by_alias=True, exclude_none=True),
|
|
309
|
-
idempotency_key=idempotency_key,
|
|
310
|
-
)
|
|
266
|
+
_shim_warn("sv.products.aclone()")
|
|
267
|
+
return await self.products.aclone(
|
|
268
|
+
product_ref, new_name=new_name, idempotency_key=idempotency_key
|
|
311
269
|
)
|
|
312
|
-
return Product.model_validate(data)
|
|
313
|
-
|
|
314
|
-
# --- Admin: Plans ---
|
|
315
270
|
|
|
316
271
|
async def list_plans(self, product_ref: str) -> list[Plan]:
|
|
317
|
-
"
|
|
318
|
-
|
|
319
|
-
items: list[Any] = data if isinstance(data, list) else data.get("plans", [])
|
|
320
|
-
return [Plan.model_validate(p) for p in items]
|
|
272
|
+
_shim_warn("sv.plans.alist()")
|
|
273
|
+
return await self.plans.alist(product_ref)
|
|
321
274
|
|
|
322
275
|
async def create_plan(
|
|
323
276
|
self,
|
|
@@ -330,19 +283,16 @@ class AsyncSolvaPay:
|
|
|
330
283
|
interval: str | None = None,
|
|
331
284
|
idempotency_key: str | None = None,
|
|
332
285
|
) -> Plan:
|
|
333
|
-
"
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
idempotency_key=idempotency_key,
|
|
343
|
-
)
|
|
286
|
+
_shim_warn("sv.plans.acreate()")
|
|
287
|
+
return await self.plans.acreate(
|
|
288
|
+
product_ref,
|
|
289
|
+
name=name,
|
|
290
|
+
type=type,
|
|
291
|
+
price=price,
|
|
292
|
+
currency=currency,
|
|
293
|
+
interval=interval,
|
|
294
|
+
idempotency_key=idempotency_key,
|
|
344
295
|
)
|
|
345
|
-
return Plan.model_validate(data)
|
|
346
296
|
|
|
347
297
|
async def update_plan(
|
|
348
298
|
self,
|
|
@@ -355,33 +305,25 @@ class AsyncSolvaPay:
|
|
|
355
305
|
currency: str | None = None,
|
|
356
306
|
interval: str | None = None,
|
|
357
307
|
) -> Plan:
|
|
358
|
-
"
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
)
|
|
308
|
+
_shim_warn("sv.plans.aupdate()")
|
|
309
|
+
return await self.plans.aupdate(
|
|
310
|
+
product_ref,
|
|
311
|
+
plan_ref,
|
|
312
|
+
name=name,
|
|
313
|
+
type=type,
|
|
314
|
+
price=price,
|
|
315
|
+
currency=currency,
|
|
316
|
+
interval=interval,
|
|
368
317
|
)
|
|
369
|
-
return Plan.model_validate(data)
|
|
370
318
|
|
|
371
319
|
async def delete_plan(self, product_ref: str, plan_ref: str) -> dict[str, Any]:
|
|
372
|
-
"
|
|
373
|
-
return await self.
|
|
374
|
-
_RequestSpec("DELETE", f"/v1/sdk/products/{product_ref}/plans/{plan_ref}")
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
# --- Admin: Merchant + Platform ---
|
|
320
|
+
_shim_warn("sv.plans.adelete()")
|
|
321
|
+
return await self.plans.adelete(product_ref, plan_ref)
|
|
378
322
|
|
|
379
323
|
async def get_merchant(self) -> Merchant:
|
|
380
|
-
"
|
|
381
|
-
|
|
382
|
-
return Merchant.model_validate(data)
|
|
324
|
+
_shim_warn("sv.merchant.aget()")
|
|
325
|
+
return await self.merchant.aget()
|
|
383
326
|
|
|
384
327
|
async def get_platform_config(self) -> PlatformConfig:
|
|
385
|
-
"
|
|
386
|
-
|
|
387
|
-
return PlatformConfig.model_validate(data)
|
|
328
|
+
_shim_warn("sv.merchant.aget_platform_config()")
|
|
329
|
+
return await self.merchant.aget_platform_config()
|