zenopay-sdk 0.1.0__py3-none-any.whl → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zenopay-sdk
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A modern Python SDK for the ZenoPay payment API
5
5
  Project-URL: Homepage, https://github.com/elusionhub/zenopay-python-sdk
6
6
  Project-URL: Documentation, https://github.com/elusionhub/zenopay-python-sdk#readme
@@ -52,7 +52,7 @@ Description-Content-Type: text/markdown
52
52
 
53
53
  # ZenoPay Python SDK
54
54
 
55
- Modern Python SDK for ZenoPay payment API with async/sync support and webhook handling.
55
+ Modern Python SDK for ZenoPay payment API with async/sync support, order management, and disbursements.
56
56
 
57
57
  ## Installation
58
58
 
@@ -65,20 +65,22 @@ pip install zenopay-sdk
65
65
  ```python
66
66
  from elusion.zenopay import ZenoPay
67
67
  from elusion.zenopay.models.order import NewOrder
68
+ from elusion.zenopay.utils import generate_order_id
68
69
 
69
- # Initialize client
70
- client = ZenoPay(account_id="your_account_id")
70
+ # Initialize client (uses environment variables)
71
+ client = ZenoPay()
71
72
 
72
73
  # Create order (sync)
73
74
  with client:
74
75
  order = NewOrder(
76
+ order_id=generate_order_id(),
75
77
  buyer_email="customer@example.com",
76
78
  buyer_name="John Doe",
77
- buyer_phone="0700000000",
79
+ buyer_phone="07XXXXXXXX",
78
80
  amount=1000
79
81
  )
80
82
  response = client.orders.sync.create(order)
81
- print(f"Order ID: {response.data.order_id}")
83
+ print(f"Order ID: {response.results.order_id}")
82
84
  ```
83
85
 
84
86
  ## Configuration
@@ -86,88 +88,158 @@ with client:
86
88
  ### Environment Variables
87
89
 
88
90
  ```bash
89
- export ZENOPAY_ACCOUNT_ID="your_account_id"
90
- export ZENOPAY_API_KEY="your_api_key" # Optional
91
- export ZENOPAY_SECRET_KEY="your_secret_key" # Optional
91
+ export ZENOPAY_API_KEY="your_api_key"
92
92
  ```
93
93
 
94
94
  ### Code Configuration
95
95
 
96
96
  ```python
97
97
  client = ZenoPay(
98
- account_id="your_account_id",
99
98
  api_key="your_api_key",
100
- secret_key="your_secret_key",
101
99
  timeout=30.0
102
100
  )
103
101
  ```
104
102
 
105
- ## API Usage
103
+ ## Orders API
106
104
 
107
105
  ### Synchronous Operations
108
106
 
109
107
  ```python
108
+ from elusion.zenopay import ZenoPay
109
+ from elusion.zenopay.models.order import NewOrder
110
+ from elusion.zenopay.utils import generate_order_id
111
+
112
+ client = ZenoPay()
113
+
110
114
  # Create order
111
- with client:
112
- order_data = {
113
- "buyer_email": "test@example.com",
114
- "buyer_name": "Test User",
115
- "buyer_phone": "0700000000",
116
- "amount": 5000,
117
- "webhook_url": "https://yoursite.com/webhook"
118
- }
119
- response = client.orders.sync.create(order_data)
120
- order_id = response.data.order_id
115
+ def create_order():
116
+ with client:
117
+ order = NewOrder(
118
+ order_id=generate_order_id(),
119
+ buyer_email="test@example.com",
120
+ buyer_name="Test User",
121
+ buyer_phone="07XXXXXXXX",
122
+ amount=1000,
123
+ )
124
+ response = client.orders.sync.create(order)
125
+ return response.results.order_id
121
126
 
122
127
  # Check status
123
- with client:
124
- status = client.orders.sync.get_status(order_id)
125
- print(f"Payment status: {status.data.payment_status}")
128
+ def check_status(order_id: str):
129
+ with client:
130
+ response = client.orders.sync.check_status(order_id)
131
+ return response.results
126
132
 
127
133
  # Check if paid
128
- with client:
129
- is_paid = client.orders.sync.check_payment(order_id)
134
+ def check_payment(order_id: str):
135
+ with client:
136
+ return client.orders.sync.check_payment(order_id)
137
+
138
+ # Wait for payment completion
139
+ def wait_for_payment(order_id: str):
140
+ with client:
141
+ return client.orders.sync.wait_for_payment(order_id)
142
+
143
+ # Usage example
144
+ if __name__ == "__main__":
145
+ order_id = create_order()
146
+ status = check_status(order_id)
147
+ is_paid = check_payment(order_id)
148
+
149
+ print(f"Order: {order_id}")
150
+ print(f"Status: {status.data[0].payment_status}")
130
151
  print(f"Paid: {is_paid}")
131
152
 
132
- # Wait for payment
133
- with client:
134
- try:
135
- completed = client.orders.sync.wait_for_payment(order_id, timeout=300)
136
- print("Payment completed!")
137
- except TimeoutError:
138
- print("Payment timeout")
153
+ order_content = wait_for_payment(order_id)
154
+ print(f"Order completed: {order_content}")
139
155
  ```
140
156
 
141
157
  ### Asynchronous Operations
142
158
 
143
159
  ```python
144
160
  import asyncio
161
+ from elusion.zenopay import ZenoPay
162
+ from elusion.zenopay.models.order import NewOrder
163
+ from elusion.zenopay.utils import generate_order_id
164
+
165
+ client = ZenoPay()
166
+
167
+ # Create order (async)
168
+ async def create_order_async():
169
+ async with client:
170
+ order = NewOrder(
171
+ order_id=generate_order_id(),
172
+ buyer_email="test@example.com",
173
+ buyer_name="Test User",
174
+ buyer_phone="07XXXXXXXX",
175
+ amount=1000,
176
+ webhook_url="https://example.com/webhook",
177
+ metadata={"key": "value"},
178
+ )
179
+ response = await client.orders.create(order)
180
+ return response.results.order_id
181
+
182
+ # Check status (async)
183
+ async def check_status_async(order_id: str):
184
+ async with client:
185
+ response = await client.orders.check_status(order_id)
186
+ return response.results.data[0].payment_status
145
187
 
146
- async def create_payment():
188
+ # Check payment (async)
189
+ async def check_payment_async(order_id: str):
147
190
  async with client:
148
- order_data = {
149
- "buyer_email": "test@example.com",
150
- "buyer_name": "Test User",
151
- "buyer_phone": "0700000000",
152
- "amount": 5000
153
- }
154
-
155
- # Create order
156
- response = await client.orders.create(order_data)
157
- order_id = response.data.order_id
158
-
159
- # Check status
160
- status = await client.orders.get_status(order_id)
161
- print(f"Status: {status.data.payment_status}")
162
-
163
- # Wait for completion
164
- try:
165
- completed = await client.orders.wait_for_payment(order_id)
166
- print("Payment completed!")
167
- except TimeoutError:
168
- print("Payment timeout")
169
-
170
- asyncio.run(create_payment())
191
+ return await client.orders.check_payment(order_id)
192
+
193
+ # Usage example
194
+ async def async_example():
195
+ order_id = await create_order_async()
196
+ status = await check_status_async(order_id)
197
+ is_paid = await check_payment_async(order_id)
198
+
199
+ print(f"Async Order: {order_id}")
200
+ print(f"Async Status: {status}")
201
+ print(f"Async Paid: {is_paid}")
202
+
203
+ asyncio.run(async_example())
204
+ ```
205
+
206
+ ## Disbursements API
207
+
208
+ ### Mobile Money Disbursements
209
+
210
+ ```python
211
+ from elusion.zenopay import ZenoPay
212
+ from elusion.zenopay.models.disbursement import NewDisbursement, UtilityCodes
213
+ from elusion.zenopay.utils import generate_order_id
214
+
215
+ client = ZenoPay()
216
+
217
+ def disburse():
218
+ response = client.disbursements.sync.disburse(
219
+ disbursement_data=NewDisbursement(
220
+ amount=5000,
221
+ pin=0000, # Your ZenoPay PIN
222
+ transid=generate_order_id(),
223
+ utilitycode=UtilityCodes.CASHIN,
224
+ utilityref="07XXXXXXXX" # Phone number
225
+ )
226
+ )
227
+ return response.results.zenopay_response.result
228
+
229
+ # Usage
230
+ if __name__ == "__main__":
231
+ result = disburse()
232
+ print(f"Disbursement result: {result}")
233
+ ```
234
+
235
+ ### Available Utility Codes
236
+
237
+ ```python
238
+ from elusion.zenopay.models.disbursement import UtilityCodes
239
+
240
+ # Available disbursement types
241
+ UtilityCodes.CASHIN # Mobile money cash-in
242
+ # Add other available codes as needed
171
243
  ```
172
244
 
173
245
  ## Webhook Handling
@@ -198,9 +270,10 @@ response = client.webhooks.process_webhook_request(webhook_data)
198
270
 
199
271
  ```python
200
272
  from flask import Flask, request, jsonify
273
+ from elusion.zenopay import ZenoPay
201
274
 
202
275
  app = Flask(__name__)
203
- client = ZenoPay(account_id="your_account_id")
276
+ client = ZenoPay()
204
277
 
205
278
  def handle_completed_payment(event):
206
279
  order_id = event.payload.order_id
@@ -223,9 +296,10 @@ if __name__ == '__main__':
223
296
 
224
297
  ```python
225
298
  from fastapi import FastAPI, Request
299
+ from elusion.zenopay import ZenoPay
226
300
 
227
301
  app = FastAPI()
228
- client = ZenoPay(account_id="your_account_id")
302
+ client = ZenoPay()
229
303
 
230
304
  def handle_completed_payment(event):
231
305
  order_id = event.payload.order_id
@@ -247,33 +321,38 @@ async def webhook(request: Request):
247
321
  from elusion.zenopay.exceptions import (
248
322
  ZenoPayError,
249
323
  ZenoPayValidationError,
250
- ZenoPayNetworkError
324
+ ZenoPayNetworkError,
325
+ ZenoPayAuthenticationError
251
326
  )
252
327
 
253
328
  try:
254
329
  with client:
255
- response = client.orders.sync.create(order_data)
330
+ response = client.orders.sync.create(order)
256
331
  except ZenoPayValidationError as e:
257
332
  print(f"Validation error: {e.message}")
258
333
  print(f"Details: {e.validation_errors}")
334
+ except ZenoPayAuthenticationError as e:
335
+ print(f"Authentication error: {e.message}")
259
336
  except ZenoPayNetworkError as e:
260
337
  print(f"Network error: {e.message}")
261
338
  except ZenoPayError as e:
262
339
  print(f"General error: {e.message}")
263
340
  ```
264
341
 
265
- ## Order Models
342
+ ## Models
266
343
 
267
- ### Creating Orders
344
+ ### Order Models
268
345
 
269
346
  ```python
270
347
  from elusion.zenopay.models.order import NewOrder
348
+ from elusion.zenopay.utils import generate_order_id
271
349
 
272
- # Using model
350
+ # Create order with all fields
273
351
  order = NewOrder(
352
+ order_id=generate_order_id(),
274
353
  buyer_email="customer@example.com",
275
354
  buyer_name="John Doe",
276
- buyer_phone="0700000000",
355
+ buyer_phone="07XXXXXXXX",
277
356
  amount=1000,
278
357
  webhook_url="https://yoursite.com/webhook",
279
358
  metadata={
@@ -282,13 +361,30 @@ order = NewOrder(
282
361
  }
283
362
  )
284
363
 
285
- # Using dictionary
286
- order_data = {
287
- "buyer_email": "customer@example.com",
288
- "buyer_name": "John Doe",
289
- "buyer_phone": "0700000000",
290
- "amount": 1000
291
- }
364
+ # Minimal order
365
+ order = NewOrder(
366
+ order_id=generate_order_id(),
367
+ buyer_email="customer@example.com",
368
+ buyer_name="John Doe",
369
+ buyer_phone="07XXXXXXXX",
370
+ amount=1000
371
+ )
372
+ ```
373
+
374
+ ### Disbursement Models
375
+
376
+ ```python
377
+ from elusion.zenopay.models.disbursement import NewDisbursement, UtilityCodes
378
+ from elusion.zenopay.utils import generate_order_id
379
+
380
+ # Mobile money disbursement
381
+ disbursement = NewDisbursement(
382
+ amount=5000,
383
+ pin=0000, # Your ZenoPay PIN
384
+ transid=generate_order_id(),
385
+ utilitycode=UtilityCodes.CASHIN,
386
+ utilityref="07XXXXXXXX" # Phone number
387
+ )
292
388
  ```
293
389
 
294
390
  ### Response Models
@@ -296,14 +392,15 @@ order_data = {
296
392
  ```python
297
393
  # Order creation response
298
394
  response = client.orders.sync.create(order)
299
- print(f"Order ID: {response.data.order_id}")
300
- print(f"Status: {response.data.status}")
301
- print(f"Message: {response.data.message}")
395
+ print(f"Order ID: {response.results.order_id}")
302
396
 
303
397
  # Status check response
304
- status = client.orders.sync.get_status(order_id)
305
- print(f"Payment Status: {status.data.payment_status}")
306
- print(f"Order ID: {status.data.order_id}")
398
+ status = client.orders.sync.check_status(order_id)
399
+ print(f"Payment Status: {status.results.data[0].payment_status}")
400
+
401
+ # Disbursement response
402
+ response = client.disbursements.sync.disburse(disbursement_data)
403
+ print(f"Result: {response.results.zenopay_response.result}")
307
404
  ```
308
405
 
309
406
  ## API Reference
@@ -313,10 +410,16 @@ print(f"Order ID: {status.data.order_id}")
313
410
  | Method | Sync | Async | Description |
314
411
  | ---------------- | --------------------------------------- | ---------------------------------------- | -------------------------- |
315
412
  | Create Order | `client.orders.sync.create()` | `await client.orders.create()` | Create new payment order |
316
- | Get Status | `client.orders.sync.get_status()` | `await client.orders.get_status()` | Check order payment status |
413
+ | Check Status | `client.orders.sync.check_status()` | `await client.orders.check_status()` | Check order payment status |
317
414
  | Check Payment | `client.orders.sync.check_payment()` | `await client.orders.check_payment()` | Returns boolean if paid |
318
415
  | Wait for Payment | `client.orders.sync.wait_for_payment()` | `await client.orders.wait_for_payment()` | Poll until completed |
319
416
 
417
+ ### Disbursement Operations
418
+
419
+ | Method | Sync | Async | Description |
420
+ | -------- | -------------------------------------- | --------------------------------------- | ----------------------- |
421
+ | Disburse | `client.disbursements.sync.disburse()` | `await client.disbursements.disburse()` | Send money disbursement |
422
+
320
423
  ### Webhook Events
321
424
 
322
425
  | Event | Handler Method | Description |
@@ -326,15 +429,6 @@ print(f"Order ID: {status.data.order_id}")
326
429
  | PENDING | `client.webhooks.on_payment_pending()` | Payment initiated |
327
430
  | CANCELLED | `client.webhooks.on_payment_cancelled()` | Payment cancelled |
328
431
 
329
- ## Testing
330
-
331
- ```python
332
- # Create test webhook
333
- test_event = client.webhooks.create_test_webhook("test-order-123", "COMPLETED")
334
- response = client.webhooks.handle_webhook(test_event)
335
- print(f"Test response: {response.status}")
336
- ```
337
-
338
432
  ## Best Practices
339
433
 
340
434
  ### Context Managers
@@ -373,9 +467,20 @@ Use environment variables for sensitive configuration:
373
467
 
374
468
  ```python
375
469
  # Don't hardcode credentials
376
- client = ZenoPay(account_id=os.getenv('ZENOPAY_ACCOUNT_ID'))
470
+ client = ZenoPay(api_key=os.getenv('ZENOPAY_API_KEY'))
471
+ ```
472
+
473
+ ### Generate Unique Order IDs
474
+
475
+ Always use the built-in utility to generate unique order IDs:
476
+
477
+ ```python
478
+ from elusion.zenopay.utils import generate_order_id
479
+
480
+ order_id = generate_order_id() # Generates UUID-based unique ID
377
481
  ```
378
482
 
483
+
379
484
  ## Support
380
485
 
381
486
  - **GitHub**: [zenopay-python-sdk](https://github.com/elusionhub/zenopay-python-sdk)
@@ -0,0 +1,25 @@
1
+ elusion/__init__.py,sha256=p6Agc374IXnYGeJutUZIcfHb-EO-J7vrvUq-Escm_DQ,103
2
+ elusion/zenopay/__init__.py,sha256=T8VVs5TfH2dWonqG1rCu4lGrBKPn-w_egahhAE8xJn8,887
3
+ elusion/zenopay/client.py,sha256=2dT0waURac37ppY1bZRD1saqaARUJ3WAYrfww82Eahs,4315
4
+ elusion/zenopay/config.py,sha256=HYyH9wOSleMORfsXdlEklkejdYQtASc09N2g1JRtDA8,3731
5
+ elusion/zenopay/exceptions.py,sha256=FiZzqwcMpsXqWcBIBupzbS0qdIAbTaw92EpOvPWi-C0,7236
6
+ elusion/zenopay/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ elusion/zenopay/http/__init__.py,sha256=5ODIX-1O_7dGt9y9ky4-oTx8OKDf8qielusi3TXz1v0,84
8
+ elusion/zenopay/http/client.py,sha256=QE-LnamoHV8QcUTyDcmKQUGw9NoIUYipshYWjWNax2E,14236
9
+ elusion/zenopay/models/__init__.py,sha256=P0KmjucqtOdzPvvbAYlSOt6KeUZbkY7I5QGH6xVsS8I,959
10
+ elusion/zenopay/models/common.py,sha256=q6IEu-31ZPjMj9yn0bK36sc2nlxFdrk3ZMBEb4bwHb0,2637
11
+ elusion/zenopay/models/disbursement.py,sha256=9a1Ow4N0ez-J0qLctIxoCixIKd4aERch0u5l-M3lm9E,2552
12
+ elusion/zenopay/models/order.py,sha256=FkvY8ryrDvYuyOA8UX8cq8gfacA3t7rAMO-VrPNemKM,6458
13
+ elusion/zenopay/models/payment.py,sha256=nOa17Eym9tz8FDdZkEcpZyDvrj_r2MZmWrehanyocsE,11184
14
+ elusion/zenopay/models/webhook.py,sha256=0pSOHCabKWo5gl0MrdFQHJizh7fiNdbmh-y45Yx-tbY,4147
15
+ elusion/zenopay/services/__init__.py,sha256=0Gv-DqHaUyoyBwvNpEdU1IaFWYXjdfrPbdwqzhl1saA,258
16
+ elusion/zenopay/services/base.py,sha256=O9f871S1eJ-eBoTsfQhBLMrNjQq5G0nPD7fxaaTqVFc,6153
17
+ elusion/zenopay/services/disbursements.py,sha256=IXXGd1KNlw4e-kU0CQhbNgFhnyujCI40aRAQ-NC9nF4,1722
18
+ elusion/zenopay/services/orders.py,sha256=tY0fNMZpXOgjih1Wibui6WgUdjf29hdvNUI9BAJNvtk,5013
19
+ elusion/zenopay/services/webhooks.py,sha256=ZLQj6TqXCmFbshZ6ZXUQIHOz7Prcf3qPLWnAxYY2mq0,7328
20
+ elusion/zenopay/utils/__init__.py,sha256=f2k7eKJo83Fof2T6NHOvwlmWE5q_d5TaluK1EHt6KkY,207
21
+ elusion/zenopay/utils/helpers.py,sha256=7n2LGQtdSb95z-hx3ph7u8GyFQjfQ3oeAKp7P-lu_ok,2312
22
+ zenopay_sdk-0.2.0.dist-info/METADATA,sha256=kDKZ2GKqYIZ4zXqAHavGbauy3CpPspXEHxE4NJcXUX4,14099
23
+ zenopay_sdk-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
+ zenopay_sdk-0.2.0.dist-info/licenses/LICENSE,sha256=jW5Z5KjqFn7c9kMHh3bL0dqsWjjv5oXQ8Cb3YbHiY1A,1067
25
+ zenopay_sdk-0.2.0.dist-info/RECORD,,
@@ -1,23 +0,0 @@
1
- elusion/__init__.py,sha256=p6Agc374IXnYGeJutUZIcfHb-EO-J7vrvUq-Escm_DQ,103
2
- elusion/zenopay/__init__.py,sha256=XBGmKCdXYE2VKz-SrpRIHr4ZsIDfLlDIWxcuFGNMKPI,887
3
- elusion/zenopay/client.py,sha256=5aXSvREWSvtheUzyPwspHYmDuEkDsclhYz9QUpXIBY0,6974
4
- elusion/zenopay/config.py,sha256=v1ITpT1nq7jXKuIW2Q8_L4icJes6shJnYhru1VnBUcU,3763
5
- elusion/zenopay/exceptions.py,sha256=FiZzqwcMpsXqWcBIBupzbS0qdIAbTaw92EpOvPWi-C0,7236
6
- elusion/zenopay/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- elusion/zenopay/http/__init__.py,sha256=5ODIX-1O_7dGt9y9ky4-oTx8OKDf8qielusi3TXz1v0,84
8
- elusion/zenopay/http/client.py,sha256=9gpDUpveuFJ3fX5J3in2lh-hZniz4M7hptnZyFojFHY,10496
9
- elusion/zenopay/models/__init__.py,sha256=Z6sCC7U2xi7gOrShXY5OdKG3EloeynifY2BtCLzGXa4,802
10
- elusion/zenopay/models/common.py,sha256=_R14-pi0eynbYbl-9jrhgsnIWMwUV21oHWb0ttJzJzI,2906
11
- elusion/zenopay/models/order.py,sha256=zkCgfU_U9oTa_nAmmgyQAPXitJ3f8kq0ZnjaONukGWs,9471
12
- elusion/zenopay/models/payment.py,sha256=nOa17Eym9tz8FDdZkEcpZyDvrj_r2MZmWrehanyocsE,11184
13
- elusion/zenopay/models/webhook.py,sha256=0pSOHCabKWo5gl0MrdFQHJizh7fiNdbmh-y45Yx-tbY,4147
14
- elusion/zenopay/services/__init__.py,sha256=F8AmAON2gUPep90KoT36jelsIqTiAxtcYLYiRLKtDSw,175
15
- elusion/zenopay/services/base.py,sha256=VHAycs_FtF_V9baPZ1oVpcWWAGwVqJdYffd31efTJkQ,5357
16
- elusion/zenopay/services/orders.py,sha256=CrPFkFT9-9ktSqJ3MWhH_mQX41V_51lalDEJ5vn8_3I,5056
17
- elusion/zenopay/services/webhooks.py,sha256=ZLQj6TqXCmFbshZ6ZXUQIHOz7Prcf3qPLWnAxYY2mq0,7328
18
- elusion/zenopay/utils/__init__.py,sha256=I7QQ2yt-uLEpqLwBB-r_7ZO-Ifp99qxsYhLoUtHlwuw,139
19
- elusion/zenopay/utils/helpers.py,sha256=qsARrYRWuLYnoR67kvMhTEJf8E1mzMptToRgrBGytvg,1004
20
- zenopay_sdk-0.1.0.dist-info/METADATA,sha256=zcD9357Y4vODX3VtqPxgjeR1FuWbnNR39gDTZ-UHuwY,11043
21
- zenopay_sdk-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
22
- zenopay_sdk-0.1.0.dist-info/licenses/LICENSE,sha256=jW5Z5KjqFn7c9kMHh3bL0dqsWjjv5oXQ8Cb3YbHiY1A,1067
23
- zenopay_sdk-0.1.0.dist-info/RECORD,,