pesapal-python 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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pesapal SDK Contributors
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,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: pesapal-python
3
+ Version: 1.0.0
4
+ Summary: Python SDK for the Pesapal API v3 (authentication, orders, transaction status, refunds, cancellations) with an optional Selenium mobile-money helper.
5
+ Author: Pesapal SDK Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/robin-001/pesapal-py
8
+ Project-URL: Documentation, https://github.com/robin-001/pesapal-py#readme
9
+ Project-URL: Source, https://github.com/robin-001/pesapal-py
10
+ Project-URL: Bug Tracker, https://github.com/robin-001/pesapal-py/issues
11
+ Keywords: pesapal,payments,mobile money,uganda,kenya,api
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Office/Business :: Financial
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: requests>=2.25
27
+ Requires-Dist: python-dotenv>=1.0
28
+ Provides-Extra: mobilemoney
29
+ Requires-Dist: selenium>=4.10; extra == "mobilemoney"
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7; extra == "dev"
32
+ Requires-Dist: responses>=0.23; extra == "dev"
33
+ Requires-Dist: build; extra == "dev"
34
+ Requires-Dist: twine; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # pesapal-python
38
+
39
+ A lightweight Python SDK for the [Pesapal API v3](https://developer.pesapal.com/),
40
+ covering authentication, order submission, transaction status, refunds and
41
+ cancellations, plus an optional Selenium helper to trigger the mobile-money
42
+ STK push from the hosted payment page.
43
+
44
+ ## Features
45
+
46
+ - **Authenticate** and transparently cache/refresh the bearer token.
47
+ - **Register IPN** URLs and list them (needed to obtain a `notification_id`).
48
+ - **Submit orders** and get back the `redirect_url` / `order_tracking_id`.
49
+ - **Initiate mobile money** payment by driving the hosted iframe (optional).
50
+ - **Get transaction status** for an order.
51
+ - **Refund** completed transactions.
52
+ - **Cancel** pending orders.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install pesapal-python
58
+ ```
59
+
60
+ To use the Selenium mobile-money helper (requires Google Chrome + chromedriver):
61
+
62
+ ```bash
63
+ pip install "pesapal-python[mobilemoney]"
64
+ ```
65
+
66
+ ## Configuration via `.env`
67
+
68
+ Copy `.env.example` to `.env` and fill in your credentials:
69
+
70
+ ```dotenv
71
+ PESAPAL_CONSUMER_KEY=xxx
72
+ PESAPAL_CONSUMER_SECRET=xxx=
73
+ PESAPAL_PRODUCTION_BASE_URL=https://pay.pesapal.com/v3
74
+ PESAPAL_SANDBOX_BASE_URL=https://cybqa.pesapal.com/pesapalv3
75
+ ```
76
+
77
+ Then build the client straight from the environment:
78
+
79
+ ```python
80
+ from pesapal import PesapalClient
81
+
82
+ client = PesapalClient.from_env(sandbox=True) # loads .env automatically
83
+ ```
84
+
85
+ `from_env` reads `PESAPAL_CONSUMER_KEY` / `PESAPAL_CONSUMER_SECRET` and picks the
86
+ base URL from `PESAPAL_SANDBOX_BASE_URL` or `PESAPAL_PRODUCTION_BASE_URL`
87
+ depending on `sandbox`, falling back to the built-in defaults.
88
+
89
+ ## Quick start
90
+
91
+ ```python
92
+ from pesapal import PesapalClient, OrderRequest, BillingAddress
93
+
94
+ client = PesapalClient(
95
+ consumer_key="YOUR_CONSUMER_KEY",
96
+ consumer_secret="YOUR_CONSUMER_SECRET",
97
+ sandbox=True, # omit or set False for production
98
+ )
99
+
100
+ # 1. Authenticate (optional — called automatically on first request)
101
+ client.authenticate()
102
+
103
+ # 2. Register an IPN URL (once) to obtain a notification_id
104
+ ipn = client.register_ipn("https://your-app.com/ipn", "POST")
105
+ notification_id = ipn["ipn_id"]
106
+
107
+ # 3. Submit an order
108
+ order = OrderRequest(
109
+ amount=1000,
110
+ currency="UGX",
111
+ description="Order #1234",
112
+ callback_url="https://your-app.com/callback",
113
+ notification_id=notification_id,
114
+ branch="HQ",
115
+ billing_address=BillingAddress(
116
+ email_address="customer@example.com",
117
+ phone_number="0775000000",
118
+ country_code="UG",
119
+ first_name="Jane",
120
+ last_name="Doe",
121
+ ),
122
+ )
123
+ submitted = client.submit_order(order)
124
+ order_tracking_id = submitted["order_tracking_id"]
125
+ redirect_url = submitted["redirect_url"]
126
+
127
+ # 4. Initiate mobile money (drives the hosted form; phone is prepopulated)
128
+ result = client.initiate_mobile_money_payment(redirect_url, headless=True)
129
+ print(result.success, result.tracking_id, result.response_id)
130
+
131
+ # 5. Check transaction status
132
+ status = client.get_transaction_status(order_tracking_id)
133
+ print(status["payment_status_description"])
134
+
135
+ # 6. Refund a completed transaction
136
+ client.refund(
137
+ confirmation_code=status["confirmation_code"],
138
+ amount=1000,
139
+ username="Operator Name",
140
+ remarks="Service not offered",
141
+ )
142
+
143
+ # 7. Cancel a pending order
144
+ client.cancel_order(order_tracking_id)
145
+ ```
146
+
147
+ ## Environments
148
+
149
+ | Environment | Base URL |
150
+ | ----------- | ------------------------------------------ |
151
+ | Production | `https://pay.pesapal.com/v3` |
152
+ | Sandbox | `https://cybqa.pesapal.com/pesapalv3` |
153
+
154
+ Select with `PesapalClient(..., sandbox=True)` or pass a custom `base_url`.
155
+
156
+ ## Error handling
157
+
158
+ All API failures raise a subclass of `PesapalError`:
159
+
160
+ ```python
161
+ from pesapal import PesapalAPIError, PesapalAuthError
162
+
163
+ try:
164
+ client.submit_order(order)
165
+ except PesapalAuthError as exc:
166
+ ... # bad credentials / token problem
167
+ except PesapalAPIError as exc:
168
+ print(exc.status_code, exc.error, exc.response)
169
+ ```
170
+
171
+ The mobile-money helper does **not** raise on failure; it returns a
172
+ `MobileMoneyResult` with `success=False` and an `error` message.
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,140 @@
1
+ # pesapal-python
2
+
3
+ A lightweight Python SDK for the [Pesapal API v3](https://developer.pesapal.com/),
4
+ covering authentication, order submission, transaction status, refunds and
5
+ cancellations, plus an optional Selenium helper to trigger the mobile-money
6
+ STK push from the hosted payment page.
7
+
8
+ ## Features
9
+
10
+ - **Authenticate** and transparently cache/refresh the bearer token.
11
+ - **Register IPN** URLs and list them (needed to obtain a `notification_id`).
12
+ - **Submit orders** and get back the `redirect_url` / `order_tracking_id`.
13
+ - **Initiate mobile money** payment by driving the hosted iframe (optional).
14
+ - **Get transaction status** for an order.
15
+ - **Refund** completed transactions.
16
+ - **Cancel** pending orders.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install pesapal-python
22
+ ```
23
+
24
+ To use the Selenium mobile-money helper (requires Google Chrome + chromedriver):
25
+
26
+ ```bash
27
+ pip install "pesapal-python[mobilemoney]"
28
+ ```
29
+
30
+ ## Configuration via `.env`
31
+
32
+ Copy `.env.example` to `.env` and fill in your credentials:
33
+
34
+ ```dotenv
35
+ PESAPAL_CONSUMER_KEY=xxx
36
+ PESAPAL_CONSUMER_SECRET=xxx=
37
+ PESAPAL_PRODUCTION_BASE_URL=https://pay.pesapal.com/v3
38
+ PESAPAL_SANDBOX_BASE_URL=https://cybqa.pesapal.com/pesapalv3
39
+ ```
40
+
41
+ Then build the client straight from the environment:
42
+
43
+ ```python
44
+ from pesapal import PesapalClient
45
+
46
+ client = PesapalClient.from_env(sandbox=True) # loads .env automatically
47
+ ```
48
+
49
+ `from_env` reads `PESAPAL_CONSUMER_KEY` / `PESAPAL_CONSUMER_SECRET` and picks the
50
+ base URL from `PESAPAL_SANDBOX_BASE_URL` or `PESAPAL_PRODUCTION_BASE_URL`
51
+ depending on `sandbox`, falling back to the built-in defaults.
52
+
53
+ ## Quick start
54
+
55
+ ```python
56
+ from pesapal import PesapalClient, OrderRequest, BillingAddress
57
+
58
+ client = PesapalClient(
59
+ consumer_key="YOUR_CONSUMER_KEY",
60
+ consumer_secret="YOUR_CONSUMER_SECRET",
61
+ sandbox=True, # omit or set False for production
62
+ )
63
+
64
+ # 1. Authenticate (optional — called automatically on first request)
65
+ client.authenticate()
66
+
67
+ # 2. Register an IPN URL (once) to obtain a notification_id
68
+ ipn = client.register_ipn("https://your-app.com/ipn", "POST")
69
+ notification_id = ipn["ipn_id"]
70
+
71
+ # 3. Submit an order
72
+ order = OrderRequest(
73
+ amount=1000,
74
+ currency="UGX",
75
+ description="Order #1234",
76
+ callback_url="https://your-app.com/callback",
77
+ notification_id=notification_id,
78
+ branch="HQ",
79
+ billing_address=BillingAddress(
80
+ email_address="customer@example.com",
81
+ phone_number="0775000000",
82
+ country_code="UG",
83
+ first_name="Jane",
84
+ last_name="Doe",
85
+ ),
86
+ )
87
+ submitted = client.submit_order(order)
88
+ order_tracking_id = submitted["order_tracking_id"]
89
+ redirect_url = submitted["redirect_url"]
90
+
91
+ # 4. Initiate mobile money (drives the hosted form; phone is prepopulated)
92
+ result = client.initiate_mobile_money_payment(redirect_url, headless=True)
93
+ print(result.success, result.tracking_id, result.response_id)
94
+
95
+ # 5. Check transaction status
96
+ status = client.get_transaction_status(order_tracking_id)
97
+ print(status["payment_status_description"])
98
+
99
+ # 6. Refund a completed transaction
100
+ client.refund(
101
+ confirmation_code=status["confirmation_code"],
102
+ amount=1000,
103
+ username="Operator Name",
104
+ remarks="Service not offered",
105
+ )
106
+
107
+ # 7. Cancel a pending order
108
+ client.cancel_order(order_tracking_id)
109
+ ```
110
+
111
+ ## Environments
112
+
113
+ | Environment | Base URL |
114
+ | ----------- | ------------------------------------------ |
115
+ | Production | `https://pay.pesapal.com/v3` |
116
+ | Sandbox | `https://cybqa.pesapal.com/pesapalv3` |
117
+
118
+ Select with `PesapalClient(..., sandbox=True)` or pass a custom `base_url`.
119
+
120
+ ## Error handling
121
+
122
+ All API failures raise a subclass of `PesapalError`:
123
+
124
+ ```python
125
+ from pesapal import PesapalAPIError, PesapalAuthError
126
+
127
+ try:
128
+ client.submit_order(order)
129
+ except PesapalAuthError as exc:
130
+ ... # bad credentials / token problem
131
+ except PesapalAPIError as exc:
132
+ print(exc.status_code, exc.error, exc.response)
133
+ ```
134
+
135
+ The mobile-money helper does **not** raise on failure; it returns a
136
+ `MobileMoneyResult` with `success=False` and an `error` message.
137
+
138
+ ## License
139
+
140
+ MIT
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pesapal-python"
7
+ version = "1.0.0"
8
+ description = "Python SDK for the Pesapal API v3 (authentication, orders, transaction status, refunds, cancellations) with an optional Selenium mobile-money helper."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Pesapal SDK Contributors" }]
13
+ keywords = ["pesapal", "payments", "mobile money", "uganda", "kenya", "api"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.8",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Office/Business :: Financial",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ dependencies = [
28
+ "requests>=2.25",
29
+ "python-dotenv>=1.0",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ mobilemoney = ["selenium>=4.10"]
34
+ dev = ["pytest>=7", "responses>=0.23", "build", "twine"]
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/robin-001/pesapal-py"
38
+ Documentation = "https://github.com/robin-001/pesapal-py#readme"
39
+ Source = "https://github.com/robin-001/pesapal-py"
40
+ "Bug Tracker" = "https://github.com/robin-001/pesapal-py/issues"
41
+
42
+ [tool.pytest.ini_options]
43
+ pythonpath = ["src"]
44
+ testpaths = ["tests"]
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+
49
+ [tool.setuptools.package-data]
50
+ pesapal = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,39 @@
1
+ """Python SDK for the Pesapal API v3.
2
+
3
+ Public API::
4
+
5
+ from pesapal import PesapalClient, OrderRequest, BillingAddress
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from .client import (
11
+ PRODUCTION_BASE_URL,
12
+ SANDBOX_BASE_URL,
13
+ PesapalClient,
14
+ )
15
+ from .exceptions import (
16
+ PesapalAPIError,
17
+ PesapalAuthError,
18
+ PesapalConfigError,
19
+ PesapalError,
20
+ PesapalMobileMoneyError,
21
+ )
22
+ from .models import BillingAddress, MobileMoneyResult, OrderRequest
23
+
24
+ __version__ = "1.0.0"
25
+
26
+ __all__ = [
27
+ "PesapalClient",
28
+ "OrderRequest",
29
+ "BillingAddress",
30
+ "MobileMoneyResult",
31
+ "PesapalError",
32
+ "PesapalConfigError",
33
+ "PesapalAuthError",
34
+ "PesapalAPIError",
35
+ "PesapalMobileMoneyError",
36
+ "PRODUCTION_BASE_URL",
37
+ "SANDBOX_BASE_URL",
38
+ "__version__",
39
+ ]