Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.

Commit 3e3eae3

Browse files
committed
v0.7.9
- Added Exceptions
1 parent ab94114 commit 3e3eae3

11 files changed

+87
-15
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ jobs:
3333
- name: Test with pytest
3434
run: |
3535
export SECRET_KEY=${{ secrets.SECRET_KEY }}
36+
export FW_SECRET_KEY=${{ secrets.FW_SECRET }}
3637
pytest

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[build-system]
22
requires = [
33
"setuptools>=54",
4-
"wheel"
4+
"wheel",
5+
"requests"
56
]
67
build-backend = "setuptools.build_meta"

python_flutterwave/exceptions.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
class TokenException(Exception):
3+
def __init__(self, token, message):
4+
self.token = token
5+
self.message = message
6+
7+
def __str__(self):
8+
return f"{self.token} -> {self.message}"
9+
10+
11+
class CustomerDetailException(Exception):
12+
def __init__(self, message: str):
13+
self.message = message
14+
15+
def __str__(self):
16+
return self.message
17+
18+
19+
class TransactionDetailException(Exception):
20+
def __init__(self, trans_id, message: str):
21+
self.message = message
22+
self.trans_id = trans_id
23+
24+
def __str__(self):
25+
return f"{self.trans_id} -> {self.message}"

python_flutterwave/payment.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
11
import requests
22
import json
33
from typing import Optional
4+
from .exceptions import *
45

56
token = ""
67

78

8-
def initiate_payment(tx_ref: str, amount: float, redirect_url: str, customer_name: str,
9-
customer_email: str, currency: Optional[str] = None, payment_options: Optional[str] = None,
10-
title: Optional[str] = None, description: Optional[str] = None,
11-
customer_phone_number: Optional[str] = None,
12-
) -> str:
13-
"""This is used to initiate standard payments. It takes in the arguments and returns the url to redirect users for
14-
payments """
9+
def initiate_payment(tx_ref: str, amount: float, redirect_url: str, customer_email: str,
10+
customer_name: Optional[str] = None, currency: Optional[str] = None,
11+
customer_phone_number: Optional[str] = None, payment_options: Optional[str] = None,
12+
title: Optional[str] = None, description: Optional[str] = None) -> str:
13+
"""
14+
This is used to initiate standard payments. It takes in the arguments and returns the url to redirect users for
15+
payments
16+
:param tx_ref: str
17+
:param amount: float
18+
:param redirect_url: str
19+
:param customer_email: str
20+
:param customer_name: Optional[str]
21+
:param customer_phone_number: Optional[str]
22+
:param currency: Optional[str]
23+
:param payment_options: Optional[str]
24+
:param title: Optional[str]
25+
:param description: Optional[str]
26+
:return: str
27+
"""
1528
payment_url = "https://api.flutterwave.com/v3/payments"
29+
30+
if token == "" or token is None:
31+
raise TokenException(token=token, message="Authentication token absent")
32+
if customer_email is None or customer_email == "":
33+
raise CustomerDetailException(message="Customer email not provided")
34+
1635
payload = json.dumps({
1736
"tx_ref": f"{tx_ref}",
1837
"amount": f"{amount}",
@@ -35,6 +54,10 @@ def initiate_payment(tx_ref: str, amount: float, redirect_url: str, customer_nam
3554
}
3655

3756
response = requests.request(method="POST", url=payment_url, headers=headers, data=payload)
57+
if response.status_code == 401:
58+
raise TokenException(token=token, message='Invalid token provided')
59+
if response.status_code == 400:
60+
raise Exception(f"{response.json()['message']}")
3861
link = response.json()["data"]["link"]
3962
return link
4063

@@ -46,12 +69,21 @@ def get_payment_details(trans_id: str) -> dict:
4669
"""
4770
url = f"https://api.flutterwave.com/v3/transactions/{trans_id}/verify"
4871

72+
if token == "" or token is None:
73+
raise TokenException(token=token, message="Authentication token absent")
74+
4975
payload = {}
5076
headers = {
5177
'Authorization': f'Bearer {token}'
5278
}
5379

5480
response = requests.request("GET", url, headers=headers, data=payload)
81+
if response.status_code == 401:
82+
raise TokenException(token=token, message='Invalid token provided')
83+
if response.status_code == 400:
84+
raise TransactionDetailException(trans_id=trans_id, message=f"{response.json()['message']}")
85+
if response.status_code == 401:
86+
raise TransactionDetailException(trans_id=trans_id, message=response.json()['message'])
5587
return dict(response.json())
5688

5789

@@ -63,7 +95,8 @@ def trigger_mpesa_payment(tx_ref: str, amount: float, currency: str, phone_numbe
6395
in the dashboard.
6496
"""
6597
url = "https://api.flutterwave.com/v3/charges?type=mpesa"
66-
98+
if token == "" or token is None:
99+
raise TokenException(token=token, message="Authentication token absent")
67100
payload = json.dumps({
68101
"tx_ref": f"{tx_ref}",
69102
"amount": f"{amount}",
@@ -78,6 +111,9 @@ def trigger_mpesa_payment(tx_ref: str, amount: float, currency: str, phone_numbe
78111
}
79112

80113
response = requests.request("POST", url, headers=headers, data=payload)
114+
if response.status_code == 401:
115+
raise TokenException(token=token, message='Invalid token provided')
116+
81117
return dict(response.json())
82118

83119

@@ -119,6 +155,8 @@ def verify_bank_account_details(account_number: str, account_bank: str) -> dict:
119155
:param account_bank: str
120156
:return: dict
121157
"""
158+
if token == "" or token is None:
159+
raise TokenException(token=token, message="Authentication token absent")
122160

123161
url = "https://api.flutterwave.com/v3/accounts/resolve"
124162

@@ -142,6 +180,8 @@ def verify_card_details(card_bin: str) -> dict:
142180
:return: dict
143181
"""
144182
url = f"https://api.flutterwave.com/v3/card-bins/{card_bin}"
183+
if token == "" or token is None:
184+
raise TokenException(token=token, message="Authentication token absent")
145185

146186
payload = {}
147187
headers = {

python_flutterwave/tests/test_initiate_payment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class TestStandardPayment(unittest.TestCase):
1010

1111
def setUp(self) -> None:
12-
self.token = os.environ.get("SECRET_KEY")
12+
self.token = os.environ.get("FW_SECRET_KEY")
1313
self.tx_ref = f"{''.join(random.choice(string.ascii_letters) for i in range(10))}"
1414
self.amount = 10.0
1515
self.currency = 'KES'

python_flutterwave/tests/test_initiate_ussd_payment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class TestInitiateUSSDPayment(unittest.TestCase):
1010

1111
def setUp(self) -> None:
12-
self.token = os.environ.get("SECRET_KEY")
12+
self.token = os.environ.get("FW_SECRET_KEY")
1313
self.tx_ref = f"{''.join(random.choice(string.ascii_letters) for i in range(10))}"
1414
self.amount = 10.0
1515
self.account_bank = "044"

python_flutterwave/tests/test_trigger_mpesa_payment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class TestTriggerMpesaPayment(unittest.TestCase):
1010

1111
def setUp(self) -> None:
12-
self.token = os.environ.get("SECRET_KEY")
12+
self.token = os.environ.get("FW_SECRET_KEY")
1313
self.tx_ref = f"{''.join(random.choice(string.ascii_letters) for i in range(10))}"
1414
self.amount = 10.0
1515
self.currency = 'KES'

python_flutterwave/tests/test_verify_bank_account_details.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class TestVerifyBankAccountDetails(unittest.TestCase):
77
def setUp(self) -> None:
8-
self.token = os.environ.get("SECRET_KEY")
8+
self.token = os.environ.get("FW_SECRET_KEY")
99
self.account_number = "0690000032"
1010
self.account_bank = "044"
1111

python_flutterwave/tests/test_verify_card_details.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
class TestVerifyCardDetails(unittest.TestCase):
77
def setUp(self) -> None:
8-
self.token = os.environ.get("SECRET_KEY")
8+
self.token = os.environ.get("FW_SECRET_KEY")
99
self.card_bin = "553188"
1010

1111
payment.token = self.token

requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
certifi==2022.6.15
2+
charset-normalizer==2.1.0
3+
idna==3.3
4+
requests==2.28.1
5+
urllib3==1.26.10

0 commit comments

Comments
 (0)