bml-connect-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,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ali Fayaz (Quill) (quillfires)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ include requirements-dev.txt
5
+ include pyproject.toml
6
+
7
+ recursive-include src *.py
8
+ recursive-include tests *.py
9
+ recursive-include examples *.py
10
+
11
+ recursive-exclude * __pycache__
12
+ recursive-exclude * *.py[co]
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: bml-connect-python
3
+ Version: 1.0.0
4
+ Summary: Python SDK for Bank of Maldives Connect API with sync/async support
5
+ Author-email: Ali Fayaz <fayaz.quill@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/quillfires/bml-connect-python
8
+ Project-URL: Documentation, https://bml-connect-python.readthedocs.io
9
+ Project-URL: Repository, https://github.com/quillfires/bml-connect-python
10
+ Project-URL: Issues, https://github.com/quillfires/bml-connect-python/issues
11
+ Project-URL: Changelog, https://github.com/quillfires/bml-connect-python/releases
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.7
17
+ Classifier: Programming Language :: Python :: 3.8
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: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: Office/Business :: Financial :: Point-Of-Sale
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
25
+ Requires-Python: >=3.7
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests>=2.28.0
29
+ Requires-Dist: aiohttp>=3.8.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
32
+ Requires-Dist: pytest-asyncio>=0.20.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
34
+ Requires-Dist: black>=22.0.0; extra == "dev"
35
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
36
+ Requires-Dist: mypy>=0.990; extra == "dev"
37
+ Requires-Dist: pre-commit>=2.20.0; extra == "dev"
38
+ Requires-Dist: types-requests>=2.28.0; extra == "dev"
39
+ Provides-Extra: django
40
+ Requires-Dist: django>=3.2; extra == "django"
41
+ Provides-Extra: flask
42
+ Requires-Dist: flask>=2.0; extra == "flask"
43
+ Provides-Extra: fastapi
44
+ Requires-Dist: fastapi>=0.68.0; extra == "fastapi"
45
+ Requires-Dist: uvicorn>=0.15.0; extra == "fastapi"
46
+ Provides-Extra: sanic
47
+ Requires-Dist: sanic>=22.0.0; extra == "sanic"
48
+ Dynamic: license-file
49
+
50
+ # BML Connect Python SDK
51
+
52
+ [![PyPI Version](https://img.shields.io/pypi/v/bml-connect-python.svg)](https://pypi.org/project/bml-connect-python/)
53
+ [![Python Versions](https://img.shields.io/pypi/pyversions/bml-connect-python.svg)](https://pypi.org/project/bml-connect-python/)
54
+ [![License](https://img.shields.io/pypi/l/bml-connect-python.svg)](https://opensource.org/licenses/MIT)
55
+
56
+ Python SDK for Bank of Maldives Connect API with synchronous and asynchronous support.
57
+ Compatible with all Python frameworks including Django, Flask, FastAPI, and Sanic.
58
+
59
+ ---
60
+
61
+ ## Features
62
+
63
+ - **Sync/Async Support:** Choose your preferred programming style
64
+ - **Full API Coverage:** Transactions, webhooks, and signature verification
65
+ - **Type Annotations:** Full type hint support for better development experience
66
+ - **Error Handling:** Comprehensive error hierarchy for easy debugging
67
+ - **Framework Agnostic:** Works with any Python web framework
68
+ - **MIT Licensed:** Open source and free to use
69
+
70
+ ---
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ pip install bml-connect-python
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Quick Start
81
+
82
+ ### Synchronous Client
83
+
84
+ ```python
85
+ from bml_connect import BMLConnect, Environment
86
+
87
+ client = BMLConnect(
88
+ api_key="your_api_key",
89
+ app_id="your_app_id",
90
+ environment=Environment.SANDBOX
91
+ )
92
+
93
+ try:
94
+ transaction = client.transactions.create_transaction({
95
+ "amount": 1500, # 15.00 MVR
96
+ "currency": "MVR",
97
+ "provider": "alipay",
98
+ "redirectUrl": "https://yourstore.com/success",
99
+ "localId": "order_123",
100
+ "customerReference": "Customer #456"
101
+ })
102
+ print(f"Transaction ID: {transaction.transaction_id}")
103
+ print(f"Payment URL: {transaction.url}")
104
+ except Exception as e:
105
+ print(f"Error: {e}")
106
+ finally:
107
+ client.close()
108
+ ```
109
+
110
+ ### Asynchronous Client
111
+
112
+ ```python
113
+ import asyncio
114
+ from bml_connect import BMLConnect, Environment
115
+
116
+ async def main():
117
+ client = BMLConnect(
118
+ api_key="your_api_key",
119
+ app_id="your_app_id",
120
+ environment=Environment.SANDBOX,
121
+ async_mode=True
122
+ )
123
+ try:
124
+ transaction = await client.transactions.create_transaction({
125
+ "amount": 2000,
126
+ "currency": "MVR",
127
+ "provider": "wechat",
128
+ "redirectUrl": "https://yourstore.com/success"
129
+ })
130
+ print(f"Transaction ID: {transaction.transaction_id}")
131
+ finally:
132
+ await client.aclose()
133
+
134
+ asyncio.run(main())
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Webhook Verification
140
+
141
+ ### Flask Example
142
+
143
+ ```python
144
+ from flask import Flask, request, jsonify
145
+ from bml_connect import BMLConnect
146
+
147
+ app = Flask(__name__)
148
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
149
+
150
+ @app.route('/webhook', methods=['POST'])
151
+ def webhook():
152
+ payload = request.get_json()
153
+ signature = payload.get('signature')
154
+ if client.verify_webhook_signature(payload, signature):
155
+ # Process webhook
156
+ return jsonify({"status": "success"}), 200
157
+ else:
158
+ return jsonify({"error": "Invalid signature"}), 403
159
+ ```
160
+
161
+ ### FastAPI Example
162
+
163
+ ```python
164
+ from fastapi import FastAPI, Request, HTTPException
165
+ from bml_connect import BMLConnect
166
+
167
+ app = FastAPI()
168
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
169
+
170
+ @app.post("/webhook")
171
+ async def handle_webhook(request: Request):
172
+ payload = await request.json()
173
+ signature = payload.get("signature")
174
+ if client.verify_webhook_signature(payload, signature):
175
+ return {"status": "success"}
176
+ else:
177
+ raise HTTPException(403, "Invalid signature")
178
+ ```
179
+
180
+ ### Sanic Example
181
+
182
+ ```python
183
+ from sanic import Sanic, response
184
+ from bml_connect import BMLConnect
185
+
186
+ app = Sanic("BMLWebhook")
187
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
188
+
189
+ @app.post('/webhook')
190
+ async def webhook(request):
191
+ payload = request.json
192
+ signature = payload.get('signature')
193
+ if client.verify_webhook_signature(payload, signature):
194
+ return response.json({"status": "success"})
195
+ else:
196
+ return response.json({"error": "Invalid signature"}, status=403)
197
+ ```
198
+
199
+ ---
200
+
201
+ ## API Reference
202
+
203
+ ### Main Classes
204
+
205
+ - `BMLConnect`: Main entry point for the SDK.
206
+ - `Transaction`: Transaction object.
207
+ - `QRCode`: QR code details.
208
+ - `PaginatedResponse`: For paginated transaction lists.
209
+ - `Environment`: Enum for `SANDBOX` and `PRODUCTION`.
210
+ - `SignMethod`: Enum for signature methods.
211
+ - `TransactionState`: Enum for transaction states.
212
+
213
+ ### Error Classes
214
+
215
+ - `BMLConnectError`
216
+ - `AuthenticationError`
217
+ - `ValidationError`
218
+ - `NotFoundError`
219
+ - `ServerError`
220
+ - `RateLimitError`
221
+
222
+ ### Utilities
223
+
224
+ - `SignatureUtils.generate_signature(data, api_key, method)`
225
+ - `SignatureUtils.verify_signature(data, signature, api_key, method)`
226
+
227
+ ---
228
+
229
+ ## Development
230
+
231
+ ### Requirements
232
+
233
+ - Python 3.7+
234
+ - See `requirements.txt` and `requirements-dev.txt` for dependencies.
235
+
236
+ ### Testing
237
+
238
+ ```bash
239
+ pip install -e .[dev]
240
+ pytest
241
+ ```
242
+
243
+ ### Formatting & Linting
244
+
245
+ ```bash
246
+ black .
247
+ flake8 .
248
+ mypy .
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Packaging
254
+
255
+ - Uses `pyproject.toml` for build configuration.
256
+ - Source code is in `src/bml_connect/`.
257
+ - Examples in `examples/`.
258
+ - Tests in `tests/`.
259
+
260
+ ---
261
+
262
+ ## License
263
+
264
+ MIT License. See `LICENSE` for details.
265
+
266
+ ---
267
+
268
+ ## Links
269
+
270
+ - [Homepage](https://github.com/bankofmaldives/bml-connect-python)
271
+ - [Documentation](https://bml-connect-python.readthedocs.io)
272
+ - [API Reference](docs/api_reference.md)
273
+ - [Changelog](https://github.com/bankofmaldives/bml-connect-python/releases)
274
+
275
+ ---
276
+
277
+ ## Contributing
278
+
279
+ Pull requests and issues are welcome! See the documentation for guidelines.
@@ -0,0 +1,230 @@
1
+ # BML Connect Python SDK
2
+
3
+ [![PyPI Version](https://img.shields.io/pypi/v/bml-connect-python.svg)](https://pypi.org/project/bml-connect-python/)
4
+ [![Python Versions](https://img.shields.io/pypi/pyversions/bml-connect-python.svg)](https://pypi.org/project/bml-connect-python/)
5
+ [![License](https://img.shields.io/pypi/l/bml-connect-python.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Python SDK for Bank of Maldives Connect API with synchronous and asynchronous support.
8
+ Compatible with all Python frameworks including Django, Flask, FastAPI, and Sanic.
9
+
10
+ ---
11
+
12
+ ## Features
13
+
14
+ - **Sync/Async Support:** Choose your preferred programming style
15
+ - **Full API Coverage:** Transactions, webhooks, and signature verification
16
+ - **Type Annotations:** Full type hint support for better development experience
17
+ - **Error Handling:** Comprehensive error hierarchy for easy debugging
18
+ - **Framework Agnostic:** Works with any Python web framework
19
+ - **MIT Licensed:** Open source and free to use
20
+
21
+ ---
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install bml-connect-python
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Quick Start
32
+
33
+ ### Synchronous Client
34
+
35
+ ```python
36
+ from bml_connect import BMLConnect, Environment
37
+
38
+ client = BMLConnect(
39
+ api_key="your_api_key",
40
+ app_id="your_app_id",
41
+ environment=Environment.SANDBOX
42
+ )
43
+
44
+ try:
45
+ transaction = client.transactions.create_transaction({
46
+ "amount": 1500, # 15.00 MVR
47
+ "currency": "MVR",
48
+ "provider": "alipay",
49
+ "redirectUrl": "https://yourstore.com/success",
50
+ "localId": "order_123",
51
+ "customerReference": "Customer #456"
52
+ })
53
+ print(f"Transaction ID: {transaction.transaction_id}")
54
+ print(f"Payment URL: {transaction.url}")
55
+ except Exception as e:
56
+ print(f"Error: {e}")
57
+ finally:
58
+ client.close()
59
+ ```
60
+
61
+ ### Asynchronous Client
62
+
63
+ ```python
64
+ import asyncio
65
+ from bml_connect import BMLConnect, Environment
66
+
67
+ async def main():
68
+ client = BMLConnect(
69
+ api_key="your_api_key",
70
+ app_id="your_app_id",
71
+ environment=Environment.SANDBOX,
72
+ async_mode=True
73
+ )
74
+ try:
75
+ transaction = await client.transactions.create_transaction({
76
+ "amount": 2000,
77
+ "currency": "MVR",
78
+ "provider": "wechat",
79
+ "redirectUrl": "https://yourstore.com/success"
80
+ })
81
+ print(f"Transaction ID: {transaction.transaction_id}")
82
+ finally:
83
+ await client.aclose()
84
+
85
+ asyncio.run(main())
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Webhook Verification
91
+
92
+ ### Flask Example
93
+
94
+ ```python
95
+ from flask import Flask, request, jsonify
96
+ from bml_connect import BMLConnect
97
+
98
+ app = Flask(__name__)
99
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
100
+
101
+ @app.route('/webhook', methods=['POST'])
102
+ def webhook():
103
+ payload = request.get_json()
104
+ signature = payload.get('signature')
105
+ if client.verify_webhook_signature(payload, signature):
106
+ # Process webhook
107
+ return jsonify({"status": "success"}), 200
108
+ else:
109
+ return jsonify({"error": "Invalid signature"}), 403
110
+ ```
111
+
112
+ ### FastAPI Example
113
+
114
+ ```python
115
+ from fastapi import FastAPI, Request, HTTPException
116
+ from bml_connect import BMLConnect
117
+
118
+ app = FastAPI()
119
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
120
+
121
+ @app.post("/webhook")
122
+ async def handle_webhook(request: Request):
123
+ payload = await request.json()
124
+ signature = payload.get("signature")
125
+ if client.verify_webhook_signature(payload, signature):
126
+ return {"status": "success"}
127
+ else:
128
+ raise HTTPException(403, "Invalid signature")
129
+ ```
130
+
131
+ ### Sanic Example
132
+
133
+ ```python
134
+ from sanic import Sanic, response
135
+ from bml_connect import BMLConnect
136
+
137
+ app = Sanic("BMLWebhook")
138
+ client = BMLConnect(api_key="your_api_key", app_id="your_app_id")
139
+
140
+ @app.post('/webhook')
141
+ async def webhook(request):
142
+ payload = request.json
143
+ signature = payload.get('signature')
144
+ if client.verify_webhook_signature(payload, signature):
145
+ return response.json({"status": "success"})
146
+ else:
147
+ return response.json({"error": "Invalid signature"}, status=403)
148
+ ```
149
+
150
+ ---
151
+
152
+ ## API Reference
153
+
154
+ ### Main Classes
155
+
156
+ - `BMLConnect`: Main entry point for the SDK.
157
+ - `Transaction`: Transaction object.
158
+ - `QRCode`: QR code details.
159
+ - `PaginatedResponse`: For paginated transaction lists.
160
+ - `Environment`: Enum for `SANDBOX` and `PRODUCTION`.
161
+ - `SignMethod`: Enum for signature methods.
162
+ - `TransactionState`: Enum for transaction states.
163
+
164
+ ### Error Classes
165
+
166
+ - `BMLConnectError`
167
+ - `AuthenticationError`
168
+ - `ValidationError`
169
+ - `NotFoundError`
170
+ - `ServerError`
171
+ - `RateLimitError`
172
+
173
+ ### Utilities
174
+
175
+ - `SignatureUtils.generate_signature(data, api_key, method)`
176
+ - `SignatureUtils.verify_signature(data, signature, api_key, method)`
177
+
178
+ ---
179
+
180
+ ## Development
181
+
182
+ ### Requirements
183
+
184
+ - Python 3.7+
185
+ - See `requirements.txt` and `requirements-dev.txt` for dependencies.
186
+
187
+ ### Testing
188
+
189
+ ```bash
190
+ pip install -e .[dev]
191
+ pytest
192
+ ```
193
+
194
+ ### Formatting & Linting
195
+
196
+ ```bash
197
+ black .
198
+ flake8 .
199
+ mypy .
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Packaging
205
+
206
+ - Uses `pyproject.toml` for build configuration.
207
+ - Source code is in `src/bml_connect/`.
208
+ - Examples in `examples/`.
209
+ - Tests in `tests/`.
210
+
211
+ ---
212
+
213
+ ## License
214
+
215
+ MIT License. See `LICENSE` for details.
216
+
217
+ ---
218
+
219
+ ## Links
220
+
221
+ - [Homepage](https://github.com/bankofmaldives/bml-connect-python)
222
+ - [Documentation](https://bml-connect-python.readthedocs.io)
223
+ - [API Reference](docs/api_reference.md)
224
+ - [Changelog](https://github.com/bankofmaldives/bml-connect-python/releases)
225
+
226
+ ---
227
+
228
+ ## Contributing
229
+
230
+ Pull requests and issues are welcome! See the documentation for guidelines.
@@ -0,0 +1,52 @@
1
+ """
2
+ Basic Asynchronous Usage Example
3
+ ===============================
4
+
5
+ This example shows how to use the BML Connect SDK in asynchronous mode.
6
+ """
7
+
8
+ import asyncio
9
+ from bml_connect import BMLConnect, Environment
10
+
11
+ async def main():
12
+ # Initialize async client
13
+ client = BMLConnect(
14
+ api_key="your_api_key_here",
15
+ app_id="your_app_id_here",
16
+ environment=Environment.SANDBOX,
17
+ async_mode=True
18
+ )
19
+
20
+ try:
21
+ # Create a transaction
22
+ transaction = await client.transactions.create_transaction({
23
+ "amount": 2000, # 20.00 MVR
24
+ "currency": "MVR",
25
+ "provider": "wechat",
26
+ "redirectUrl": "https://yourstore.com/success"
27
+ })
28
+
29
+ print(f"Created transaction: {transaction.transaction_id}")
30
+ print(f"QR Code URL: {transaction.qr_code.url if transaction.qr_code else 'N/A'}")
31
+
32
+ # Get transaction details
33
+ details = await client.transactions.get_transaction(transaction.transaction_id)
34
+ print(f"Current status: {details.state.value if details.state else 'N/A'}")
35
+
36
+ # List transactions with filters
37
+ print("\nListing confirmed transactions...")
38
+ transactions = await client.transactions.list_transactions(
39
+ page=1,
40
+ per_page=5,
41
+ state="CONFIRMED"
42
+ )
43
+ print(f"Found {transactions.count} confirmed transactions")
44
+
45
+ except Exception as e:
46
+ print(f"Error: {str(e)}")
47
+ finally:
48
+ # Clean up async resources
49
+ await client.aclose()
50
+
51
+ if __name__ == "__main__":
52
+ asyncio.run(main())
@@ -0,0 +1,50 @@
1
+ """
2
+ Basic Synchronous Usage Example
3
+ ===============================
4
+
5
+ This example shows how to use the BML Connect SDK in synchronous mode.
6
+ """
7
+
8
+ from bml_connect import BMLConnect, Environment
9
+
10
+ # Initialize client
11
+ client = BMLConnect(
12
+ api_key="your_api_key_here",
13
+ app_id="your_app_id_here",
14
+ environment=Environment.SANDBOX
15
+ )
16
+
17
+ try:
18
+ # Create a transaction
19
+ transaction = client.transactions.create_transaction({
20
+ "amount": 1500, # 15.00 MVR
21
+ "currency": "MVR",
22
+ "provider": "alipay",
23
+ "redirectUrl": "https://yourstore.com/success",
24
+ "localId": "order_12345",
25
+ "customerReference": "Customer #789"
26
+ })
27
+
28
+ print("Transaction created successfully!")
29
+ print(f"ID: {transaction.transaction_id}")
30
+ print(f"Amount: {transaction.amount / 100:.2f} {transaction.currency}")
31
+ print(f"Status: {transaction.state.value if transaction.state else 'N/A'}")
32
+ print(f"Payment URL: {transaction.url}")
33
+
34
+ # Retrieve the same transaction
35
+ print("\nFetching transaction details...")
36
+ fetched = client.transactions.get_transaction(transaction.transaction_id)
37
+ print(f"Fetched status: {fetched.state.value if fetched.state else 'N/A'}")
38
+
39
+ # List recent transactions
40
+ print("\nListing recent transactions...")
41
+ transactions = client.transactions.list_transactions(page=1, per_page=3)
42
+ print(f"Found {transactions.count} transactions (showing first 3):")
43
+ for txn in transactions.items:
44
+ print(f"- {txn.transaction_id}: {txn.amount/100:.2f} {txn.currency} ({txn.state.value})")
45
+
46
+ except Exception as e:
47
+ print(f"Error: {str(e)}")
48
+ finally:
49
+ # Clean up resources
50
+ client.close()
@@ -0,0 +1,43 @@
1
+ """
2
+ FastAPI Webhook Handler Example
3
+ ===============================
4
+
5
+ This example shows how to handle BML Connect webhooks with FastAPI.
6
+ """
7
+
8
+ from fastapi import FastAPI, Request, HTTPException
9
+ from bml_connect import BMLConnect
10
+ import uvicorn
11
+
12
+ app = FastAPI(title="BML Connect Webhook Handler")
13
+ client = BMLConnect(api_key="your_api_key_here", app_id="your_app_id_here")
14
+
15
+ @app.post("/webhook")
16
+ async def handle_webhook(request: Request):
17
+ try:
18
+ payload = await request.json()
19
+ signature = payload.get("signature")
20
+
21
+ if not signature:
22
+ raise HTTPException(400, "Missing signature header")
23
+
24
+ if client.verify_webhook_signature(payload, signature):
25
+ # Process verified webhook
26
+ transaction_id = payload.get("transactionId")
27
+ status = payload.get("status")
28
+ amount = payload.get("amount", 0) / 100
29
+ currency = payload.get("currency", "MVR")
30
+
31
+ print(f"Received webhook for transaction {transaction_id}")
32
+ print(f"Status: {status}, Amount: {amount:.2f} {currency}")
33
+
34
+ # Add your business logic here (update database, send notification, etc.)
35
+
36
+ return {"status": "success"}
37
+ else:
38
+ raise HTTPException(403, "Invalid signature")
39
+ except Exception as e:
40
+ raise HTTPException(400, str(e))
41
+
42
+ if __name__ == "__main__":
43
+ uvicorn.run(app, host="0.0.0.0", port=8000)