payzcore 1.0.0__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.
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .eggs/
7
+ *.egg
8
+ .venv/
payzcore-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PayzCore
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,266 @@
1
+ Metadata-Version: 2.4
2
+ Name: payzcore
3
+ Version: 1.0.0
4
+ Summary: PayzCore Python SDK - Blockchain transaction monitoring API client
5
+ Project-URL: Homepage, https://payzcore.com
6
+ Project-URL: Documentation, https://docs.payzcore.com
7
+ Project-URL: Repository, https://github.com/payzcore/python-sdk
8
+ Project-URL: Changelog, https://docs.payzcore.com/docs/changelog/v1-0-0
9
+ Author-email: PayzCore <dev@payzcore.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,blockchain,cryptocurrency,monitoring,payzcore,stablecoin,usdc,usdt,webhook
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: httpx>=0.24.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ # PayzCore Python SDK
29
+
30
+ Python client for the [PayzCore](https://payzcore.com) blockchain transaction monitoring API.
31
+
32
+ ## Important
33
+
34
+ **PayzCore is a blockchain monitoring service, not a payment processor.** All payments are sent directly to your own wallet addresses. PayzCore never holds, transfers, or has access to your funds.
35
+
36
+ - **Your wallets, your funds** — You provide your own wallet (HD xPub or static addresses). Customers pay directly to your addresses.
37
+ - **Read-only monitoring** — PayzCore watches the blockchain for incoming transactions and sends webhook notifications. That's it.
38
+ - **Protection Key security** — Sensitive operations like wallet management, address changes, and API key regeneration require a Protection Key that only you set. PayzCore cannot perform these actions without your authorization.
39
+ - **Your responsibility** — You are responsible for securing your own wallets and private keys. PayzCore provides monitoring and notification only.
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install payzcore
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ### Payment Monitoring
50
+
51
+ ```python
52
+ from payzcore import PayzCore
53
+
54
+ client = PayzCore("pk_live_xxx")
55
+
56
+ # Create a payment monitoring request (network specified)
57
+ response = client.payments.create(
58
+ amount=50,
59
+ external_ref="user-123",
60
+ network="TRC20",
61
+ )
62
+ payment = response["payment"]
63
+ print(f"Send {payment['amount']} {payment['token']} to {payment['address']}")
64
+ print(f"Expires at: {payment['expires_at']}")
65
+ # Static wallet projects may also return: payment['notice'], payment['original_amount'], payment['requires_txid']
66
+
67
+ # Or let the customer choose the network on the payment page
68
+ response = client.payments.create(
69
+ amount=50,
70
+ external_ref="user-123",
71
+ )
72
+ p = response["payment"]
73
+ print(p["awaiting_network"]) # True
74
+ print(p["payment_url"]) # "https://app.payzcore.com/pay/xxx"
75
+ print(p["available_networks"]) # [{"network": "TRC20", "name": "Tron", "tokens": ["USDT"]}, ...]
76
+
77
+ # Create a USDC payment on Polygon
78
+ response = client.payments.create(
79
+ amount=100,
80
+ external_ref="order-456",
81
+ network="POLYGON",
82
+ token="USDC",
83
+ )
84
+
85
+ # Create a payment with static wallet (dedicated mode)
86
+ response = client.payments.create(
87
+ amount=50,
88
+ external_ref="user-789",
89
+ network="TRC20",
90
+ address="Txxxx...", # optional, static wallet dedicated mode only
91
+ )
92
+
93
+ # List payments
94
+ payments = client.payments.list(status="pending", limit=10)
95
+ for p in payments["payments"]:
96
+ print(f"{p['id']}: {p['status']} ({p['expected_amount']} {p['token']})")
97
+
98
+ # Get payment details (latest cached status from database)
99
+ detail = client.payments.get("payment-uuid")
100
+ print(f"Status: {detail['payment']['status']}")
101
+ for tx in detail["payment"]["transactions"]:
102
+ print(f" TX: {tx['tx_hash']} - {tx['amount']} {detail['payment']['token']}")
103
+
104
+ # Cancel a pending payment
105
+ result = client.payments.cancel("payment-uuid")
106
+ # result["payment"]["status"] == "cancelled"
107
+
108
+ # Submit tx hash for verification (pool + txid mode)
109
+ result = client.payments.confirm("payment-uuid", "abc123def456...")
110
+ # result["verified"], result["status"], result["amount_received"]
111
+ ```
112
+
113
+ ### Supported Networks and Tokens
114
+
115
+ | Network | Blockchain | Tokens |
116
+ |---------|------------|--------|
117
+ | `TRC20` | Tron | USDT |
118
+ | `BEP20` | BNB Smart Chain | USDT, USDC |
119
+ | `ERC20` | Ethereum | USDT, USDC |
120
+ | `POLYGON` | Polygon | USDT, USDC |
121
+ | `ARBITRUM` | Arbitrum | USDT, USDC |
122
+
123
+ The `token` parameter defaults to `"USDT"` if not specified, ensuring backward compatibility.
124
+
125
+ ### Project Management (Admin)
126
+
127
+ ```python
128
+ from payzcore import PayzCore
129
+
130
+ admin = PayzCore("mk_xxx", master_key=True)
131
+
132
+ # Create a project
133
+ project = admin.projects.create(
134
+ name="My Store",
135
+ slug="my-store",
136
+ webhook_url="https://example.com/webhooks/payzcore",
137
+ )
138
+ print(f"API Key: {project['project']['api_key']}")
139
+
140
+ # List projects
141
+ projects = admin.projects.list()
142
+ for p in projects["projects"]:
143
+ print(f"{p['name']} ({p['slug']}): {'active' if p['is_active'] else 'inactive'}")
144
+ ```
145
+
146
+ ### Webhook Verification
147
+
148
+ ```python
149
+ from payzcore import verify_signature, construct_event, WebhookSignatureError
150
+
151
+ # In your webhook handler
152
+ def handle_webhook(request):
153
+ body = request.body.decode("utf-8")
154
+ signature = request.headers["X-PayzCore-Signature"]
155
+ secret = "whsec_xxx" # From project creation
156
+
157
+ try:
158
+ event = construct_event(body, signature, secret)
159
+ except WebhookSignatureError:
160
+ return {"error": "Invalid signature"}, 401
161
+
162
+ if event["event"] == "payment.completed":
163
+ print(f"Payment {event['payment_id']} completed!")
164
+ print(f"Amount: {event['paid_amount']} {event['token']} on {event['network']}")
165
+
166
+ return {"ok": True}, 200
167
+ ```
168
+
169
+ > **Note:** The `address` parameter is only used with static wallet projects in dedicated mode. For HD wallet projects, this parameter is ignored.
170
+
171
+ ## Static Wallet Mode
172
+
173
+ When the PayzCore project is configured with a static wallet, the API works the same way but may return additional fields in the response:
174
+
175
+ | Field | Type | Description |
176
+ |-------|------|-------------|
177
+ | `notice` | `str` | Instructions for the payer (e.g. "Send exact amount") |
178
+ | `original_amount` | `str` | The original requested amount before any adjustments |
179
+ | `requires_txid` | `bool` | Whether the payer must submit their transaction ID |
180
+
181
+ In dedicated address mode, you can specify which static address to assign to a customer using the `address` parameter on payment creation. In shared address mode, the project's single static address is used automatically.
182
+
183
+ ## Before Going Live
184
+
185
+ **Always test your setup before accepting real payments:**
186
+
187
+ 1. **Verify your xPub** — In the PayzCore dashboard, click "Verify Key" when adding your wallet. Compare address #0 with your wallet app's first receiving address. They must match.
188
+ 2. **Send a test payment** — Create a monitoring request for $1–5 and send the funds to the assigned address. Verify they arrive in your wallet.
189
+ 3. **Test sweeping** — Send the test funds back out to confirm you control the derived addresses with your private keys.
190
+
191
+ > **Warning:** A wrong xPub key generates addresses you don't control. Funds sent to those addresses are permanently lost. PayzCore is watch-only and cannot recover funds. Please take 2 minutes to verify.
192
+
193
+ ## Configuration
194
+
195
+ ```python
196
+ client = PayzCore(
197
+ "pk_live_xxx",
198
+ base_url="https://api.payzcore.com", # API base URL
199
+ timeout=30.0, # Request timeout (seconds)
200
+ max_retries=2, # Retries on 5xx errors
201
+ master_key=False, # Use x-master-key header
202
+ )
203
+ ```
204
+
205
+ ## Error Handling
206
+
207
+ ```python
208
+ from payzcore import (
209
+ PayzCore,
210
+ PayzCoreError,
211
+ AuthenticationError,
212
+ ValidationError,
213
+ RateLimitError,
214
+ NotFoundError,
215
+ )
216
+
217
+ client = PayzCore("pk_live_xxx")
218
+
219
+ try:
220
+ payment = client.payments.create(
221
+ amount=50, network="TRC20", external_ref="user-123"
222
+ )
223
+ except AuthenticationError:
224
+ print("Invalid API key")
225
+ except ValidationError as e:
226
+ print(f"Invalid params: {e.message}")
227
+ if e.details:
228
+ for d in e.details:
229
+ print(f" {d['path']}: {d['message']}")
230
+ except RateLimitError as e:
231
+ print(f"Rate limited. Daily: {e.is_daily}, retry after: {e.retry_after}")
232
+ except NotFoundError:
233
+ print("Resource not found")
234
+ except PayzCoreError as e:
235
+ print(f"API error {e.status}: {e.message}")
236
+ ```
237
+
238
+ ### Error Classes
239
+
240
+ | Class | Status | When |
241
+ |-------|--------|------|
242
+ | `AuthenticationError` | 401 | Invalid/missing API key |
243
+ | `ForbiddenError` | 403 | Project deactivated |
244
+ | `NotFoundError` | 404 | Payment/resource not found |
245
+ | `ValidationError` | 400 | Invalid request body |
246
+ | `RateLimitError` | 429 | Rate limit or daily plan limit exceeded |
247
+ | `IdempotencyError` | 409 | `external_order_id` reused with different `external_ref` |
248
+ | `WebhookSignatureError` | — | Invalid webhook signature |
249
+
250
+ ## Requirements
251
+
252
+ - Python 3.9+
253
+ - httpx
254
+
255
+ ## See Also
256
+
257
+ - [Getting Started](https://docs.payzcore.com/getting-started) — Account setup and first payment
258
+ - [Authentication & API Keys](https://docs.payzcore.com/guides/authentication) — API key management
259
+ - [Webhooks Guide](https://docs.payzcore.com/guides/webhooks) — Events, headers, and signature verification
260
+ - [Supported Networks](https://docs.payzcore.com/guides/networks) — Available networks and tokens
261
+ - [Error Reference](https://docs.payzcore.com/guides/errors) — HTTP status codes and troubleshooting
262
+ - [API Reference](https://docs.payzcore.com) — Interactive API documentation (Scalar UI)
263
+
264
+ ## License
265
+
266
+ MIT
@@ -0,0 +1,239 @@
1
+ # PayzCore Python SDK
2
+
3
+ Python client for the [PayzCore](https://payzcore.com) blockchain transaction monitoring API.
4
+
5
+ ## Important
6
+
7
+ **PayzCore is a blockchain monitoring service, not a payment processor.** All payments are sent directly to your own wallet addresses. PayzCore never holds, transfers, or has access to your funds.
8
+
9
+ - **Your wallets, your funds** — You provide your own wallet (HD xPub or static addresses). Customers pay directly to your addresses.
10
+ - **Read-only monitoring** — PayzCore watches the blockchain for incoming transactions and sends webhook notifications. That's it.
11
+ - **Protection Key security** — Sensitive operations like wallet management, address changes, and API key regeneration require a Protection Key that only you set. PayzCore cannot perform these actions without your authorization.
12
+ - **Your responsibility** — You are responsible for securing your own wallets and private keys. PayzCore provides monitoring and notification only.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install payzcore
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### Payment Monitoring
23
+
24
+ ```python
25
+ from payzcore import PayzCore
26
+
27
+ client = PayzCore("pk_live_xxx")
28
+
29
+ # Create a payment monitoring request (network specified)
30
+ response = client.payments.create(
31
+ amount=50,
32
+ external_ref="user-123",
33
+ network="TRC20",
34
+ )
35
+ payment = response["payment"]
36
+ print(f"Send {payment['amount']} {payment['token']} to {payment['address']}")
37
+ print(f"Expires at: {payment['expires_at']}")
38
+ # Static wallet projects may also return: payment['notice'], payment['original_amount'], payment['requires_txid']
39
+
40
+ # Or let the customer choose the network on the payment page
41
+ response = client.payments.create(
42
+ amount=50,
43
+ external_ref="user-123",
44
+ )
45
+ p = response["payment"]
46
+ print(p["awaiting_network"]) # True
47
+ print(p["payment_url"]) # "https://app.payzcore.com/pay/xxx"
48
+ print(p["available_networks"]) # [{"network": "TRC20", "name": "Tron", "tokens": ["USDT"]}, ...]
49
+
50
+ # Create a USDC payment on Polygon
51
+ response = client.payments.create(
52
+ amount=100,
53
+ external_ref="order-456",
54
+ network="POLYGON",
55
+ token="USDC",
56
+ )
57
+
58
+ # Create a payment with static wallet (dedicated mode)
59
+ response = client.payments.create(
60
+ amount=50,
61
+ external_ref="user-789",
62
+ network="TRC20",
63
+ address="Txxxx...", # optional, static wallet dedicated mode only
64
+ )
65
+
66
+ # List payments
67
+ payments = client.payments.list(status="pending", limit=10)
68
+ for p in payments["payments"]:
69
+ print(f"{p['id']}: {p['status']} ({p['expected_amount']} {p['token']})")
70
+
71
+ # Get payment details (latest cached status from database)
72
+ detail = client.payments.get("payment-uuid")
73
+ print(f"Status: {detail['payment']['status']}")
74
+ for tx in detail["payment"]["transactions"]:
75
+ print(f" TX: {tx['tx_hash']} - {tx['amount']} {detail['payment']['token']}")
76
+
77
+ # Cancel a pending payment
78
+ result = client.payments.cancel("payment-uuid")
79
+ # result["payment"]["status"] == "cancelled"
80
+
81
+ # Submit tx hash for verification (pool + txid mode)
82
+ result = client.payments.confirm("payment-uuid", "abc123def456...")
83
+ # result["verified"], result["status"], result["amount_received"]
84
+ ```
85
+
86
+ ### Supported Networks and Tokens
87
+
88
+ | Network | Blockchain | Tokens |
89
+ |---------|------------|--------|
90
+ | `TRC20` | Tron | USDT |
91
+ | `BEP20` | BNB Smart Chain | USDT, USDC |
92
+ | `ERC20` | Ethereum | USDT, USDC |
93
+ | `POLYGON` | Polygon | USDT, USDC |
94
+ | `ARBITRUM` | Arbitrum | USDT, USDC |
95
+
96
+ The `token` parameter defaults to `"USDT"` if not specified, ensuring backward compatibility.
97
+
98
+ ### Project Management (Admin)
99
+
100
+ ```python
101
+ from payzcore import PayzCore
102
+
103
+ admin = PayzCore("mk_xxx", master_key=True)
104
+
105
+ # Create a project
106
+ project = admin.projects.create(
107
+ name="My Store",
108
+ slug="my-store",
109
+ webhook_url="https://example.com/webhooks/payzcore",
110
+ )
111
+ print(f"API Key: {project['project']['api_key']}")
112
+
113
+ # List projects
114
+ projects = admin.projects.list()
115
+ for p in projects["projects"]:
116
+ print(f"{p['name']} ({p['slug']}): {'active' if p['is_active'] else 'inactive'}")
117
+ ```
118
+
119
+ ### Webhook Verification
120
+
121
+ ```python
122
+ from payzcore import verify_signature, construct_event, WebhookSignatureError
123
+
124
+ # In your webhook handler
125
+ def handle_webhook(request):
126
+ body = request.body.decode("utf-8")
127
+ signature = request.headers["X-PayzCore-Signature"]
128
+ secret = "whsec_xxx" # From project creation
129
+
130
+ try:
131
+ event = construct_event(body, signature, secret)
132
+ except WebhookSignatureError:
133
+ return {"error": "Invalid signature"}, 401
134
+
135
+ if event["event"] == "payment.completed":
136
+ print(f"Payment {event['payment_id']} completed!")
137
+ print(f"Amount: {event['paid_amount']} {event['token']} on {event['network']}")
138
+
139
+ return {"ok": True}, 200
140
+ ```
141
+
142
+ > **Note:** The `address` parameter is only used with static wallet projects in dedicated mode. For HD wallet projects, this parameter is ignored.
143
+
144
+ ## Static Wallet Mode
145
+
146
+ When the PayzCore project is configured with a static wallet, the API works the same way but may return additional fields in the response:
147
+
148
+ | Field | Type | Description |
149
+ |-------|------|-------------|
150
+ | `notice` | `str` | Instructions for the payer (e.g. "Send exact amount") |
151
+ | `original_amount` | `str` | The original requested amount before any adjustments |
152
+ | `requires_txid` | `bool` | Whether the payer must submit their transaction ID |
153
+
154
+ In dedicated address mode, you can specify which static address to assign to a customer using the `address` parameter on payment creation. In shared address mode, the project's single static address is used automatically.
155
+
156
+ ## Before Going Live
157
+
158
+ **Always test your setup before accepting real payments:**
159
+
160
+ 1. **Verify your xPub** — In the PayzCore dashboard, click "Verify Key" when adding your wallet. Compare address #0 with your wallet app's first receiving address. They must match.
161
+ 2. **Send a test payment** — Create a monitoring request for $1–5 and send the funds to the assigned address. Verify they arrive in your wallet.
162
+ 3. **Test sweeping** — Send the test funds back out to confirm you control the derived addresses with your private keys.
163
+
164
+ > **Warning:** A wrong xPub key generates addresses you don't control. Funds sent to those addresses are permanently lost. PayzCore is watch-only and cannot recover funds. Please take 2 minutes to verify.
165
+
166
+ ## Configuration
167
+
168
+ ```python
169
+ client = PayzCore(
170
+ "pk_live_xxx",
171
+ base_url="https://api.payzcore.com", # API base URL
172
+ timeout=30.0, # Request timeout (seconds)
173
+ max_retries=2, # Retries on 5xx errors
174
+ master_key=False, # Use x-master-key header
175
+ )
176
+ ```
177
+
178
+ ## Error Handling
179
+
180
+ ```python
181
+ from payzcore import (
182
+ PayzCore,
183
+ PayzCoreError,
184
+ AuthenticationError,
185
+ ValidationError,
186
+ RateLimitError,
187
+ NotFoundError,
188
+ )
189
+
190
+ client = PayzCore("pk_live_xxx")
191
+
192
+ try:
193
+ payment = client.payments.create(
194
+ amount=50, network="TRC20", external_ref="user-123"
195
+ )
196
+ except AuthenticationError:
197
+ print("Invalid API key")
198
+ except ValidationError as e:
199
+ print(f"Invalid params: {e.message}")
200
+ if e.details:
201
+ for d in e.details:
202
+ print(f" {d['path']}: {d['message']}")
203
+ except RateLimitError as e:
204
+ print(f"Rate limited. Daily: {e.is_daily}, retry after: {e.retry_after}")
205
+ except NotFoundError:
206
+ print("Resource not found")
207
+ except PayzCoreError as e:
208
+ print(f"API error {e.status}: {e.message}")
209
+ ```
210
+
211
+ ### Error Classes
212
+
213
+ | Class | Status | When |
214
+ |-------|--------|------|
215
+ | `AuthenticationError` | 401 | Invalid/missing API key |
216
+ | `ForbiddenError` | 403 | Project deactivated |
217
+ | `NotFoundError` | 404 | Payment/resource not found |
218
+ | `ValidationError` | 400 | Invalid request body |
219
+ | `RateLimitError` | 429 | Rate limit or daily plan limit exceeded |
220
+ | `IdempotencyError` | 409 | `external_order_id` reused with different `external_ref` |
221
+ | `WebhookSignatureError` | — | Invalid webhook signature |
222
+
223
+ ## Requirements
224
+
225
+ - Python 3.9+
226
+ - httpx
227
+
228
+ ## See Also
229
+
230
+ - [Getting Started](https://docs.payzcore.com/getting-started) — Account setup and first payment
231
+ - [Authentication & API Keys](https://docs.payzcore.com/guides/authentication) — API key management
232
+ - [Webhooks Guide](https://docs.payzcore.com/guides/webhooks) — Events, headers, and signature verification
233
+ - [Supported Networks](https://docs.payzcore.com/guides/networks) — Available networks and tokens
234
+ - [Error Reference](https://docs.payzcore.com/guides/errors) — HTTP status codes and troubleshooting
235
+ - [API Reference](https://docs.payzcore.com) — Interactive API documentation (Scalar UI)
236
+
237
+ ## License
238
+
239
+ MIT
@@ -0,0 +1,160 @@
1
+ """PayzCore Python SDK - Blockchain transaction monitoring API client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .client import HttpClient
6
+ from .resources.payments import Payments
7
+ from .resources.projects import Projects
8
+
9
+ # Webhook utilities
10
+ from .webhook import (
11
+ SUPPORTED_NETWORKS,
12
+ SUPPORTED_TOKENS,
13
+ construct_event,
14
+ parse_webhook,
15
+ verify_signature,
16
+ )
17
+
18
+ # Error classes
19
+ from .errors import (
20
+ AuthenticationError,
21
+ ForbiddenError,
22
+ IdempotencyError,
23
+ NotFoundError,
24
+ PayzCoreError,
25
+ RateLimitError,
26
+ ValidationError,
27
+ WebhookSignatureError,
28
+ )
29
+
30
+ # Types
31
+ from .types import (
32
+ AvailableNetwork,
33
+ Network,
34
+ CreatePaymentParams,
35
+ CreatePaymentResponse,
36
+ CreateProjectParams,
37
+ CreateProjectResponse,
38
+ GetPaymentResponse,
39
+ ListPaymentsParams,
40
+ ListPaymentsResponse,
41
+ ListProjectsResponse,
42
+ Payment,
43
+ PaymentDetail,
44
+ PaymentListItem,
45
+ PaymentStatus,
46
+ Project,
47
+ ProjectListItem,
48
+ Token,
49
+ Transaction,
50
+ WebhookEventType,
51
+ WebhookPayload,
52
+ )
53
+
54
+ __version__ = "1.0.0"
55
+ __all__ = [
56
+ "PayzCore",
57
+ # Webhook
58
+ "verify_signature",
59
+ "construct_event",
60
+ "parse_webhook",
61
+ "SUPPORTED_NETWORKS",
62
+ "SUPPORTED_TOKENS",
63
+ # Errors
64
+ "PayzCoreError",
65
+ "AuthenticationError",
66
+ "ForbiddenError",
67
+ "IdempotencyError",
68
+ "NotFoundError",
69
+ "ValidationError",
70
+ "RateLimitError",
71
+ "WebhookSignatureError",
72
+ # Types
73
+ "AvailableNetwork",
74
+ "Network",
75
+ "Token",
76
+ "PaymentStatus",
77
+ "WebhookEventType",
78
+ "CreatePaymentParams",
79
+ "Payment",
80
+ "CreatePaymentResponse",
81
+ "PaymentListItem",
82
+ "ListPaymentsParams",
83
+ "ListPaymentsResponse",
84
+ "Transaction",
85
+ "PaymentDetail",
86
+ "GetPaymentResponse",
87
+ "CreateProjectParams",
88
+ "Project",
89
+ "CreateProjectResponse",
90
+ "ProjectListItem",
91
+ "ListProjectsResponse",
92
+ "WebhookPayload",
93
+ ]
94
+
95
+
96
+ class PayzCore:
97
+ """PayzCore API client.
98
+
99
+ Usage::
100
+
101
+ from payzcore import PayzCore
102
+
103
+ # Project API (payment monitoring)
104
+ client = PayzCore("pk_live_xxx")
105
+ payment = client.payments.create(
106
+ amount=50,
107
+ external_ref="user-123",
108
+ network="TRC20", # optional
109
+ )
110
+
111
+ # Admin API (project management)
112
+ admin = PayzCore("mk_xxx", master_key=True)
113
+ projects = admin.projects.list()
114
+ """
115
+
116
+ payments: Payments
117
+ projects: Projects
118
+
119
+ def __init__(
120
+ self,
121
+ api_key: str,
122
+ *,
123
+ base_url: str = "https://api.payzcore.com",
124
+ timeout: float = 30.0,
125
+ max_retries: int = 2,
126
+ master_key: bool = False,
127
+ ) -> None:
128
+ """Initialize PayzCore client.
129
+
130
+ Args:
131
+ api_key: Your API key (pk_live_xxx) or master key (mk_xxx).
132
+ base_url: API base URL. Default: https://api.payzcore.com
133
+ timeout: Request timeout in seconds. Default: 30.0
134
+ max_retries: Max retries on 5xx/network errors. Default: 2
135
+ master_key: Use master key auth (x-master-key header). Default: False
136
+ """
137
+ if not api_key:
138
+ raise ValueError(
139
+ "PayzCore API key is required. Pass your pk_live_xxx or mk_xxx key."
140
+ )
141
+
142
+ self._http_client = HttpClient(
143
+ api_key,
144
+ base_url=base_url,
145
+ timeout=timeout,
146
+ max_retries=max_retries,
147
+ master_key=master_key,
148
+ )
149
+ self.payments = Payments(self._http_client)
150
+ self.projects = Projects(self._http_client)
151
+
152
+ def close(self) -> None:
153
+ """Close the underlying HTTP connection pool."""
154
+ self._http_client.close()
155
+
156
+ def __enter__(self) -> "PayzCore":
157
+ return self
158
+
159
+ def __exit__(self, *args: object) -> None:
160
+ self.close()