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

Commit d40a30a

Browse files
Merge pull request #7 from WilliamOtieno/v1.0.0
V1.0.0
2 parents 0cc93a5 + 097db86 commit d40a30a

18 files changed

+691
-594
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
strategy:
1414
fail-fast: false
1515
matrix:
16-
python-version: ["3.7", "3.8", "3.9", "3.10"]
16+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
1717

1818
steps:
1919
- uses: actions/checkout@v2

README.md

Lines changed: 1 addition & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1 @@
1-
# Python Flutterwave
2-
3-
### Description
4-
Python Wrapper for interacting with the Flutterwave API
5-
6-
7-
### Contribution
8-
- Before making any further steps (for interested contributors), please refer to the [CONTRIBUTING GUIDE](/CONTRIBUTING.md).
9-
10-
11-
## Installation
12-
13-
- ``pip install python-flutterwave``
14-
15-
## Usage
16-
17-
- Create an account in Flutterwave [here](https://dashboard.flutterwave.com/signup?referrals=RV1284343) and obtain your `Secret Key` only.
18-
19-
```
20-
from python_flutterwave import payment
21-
22-
payment.token = 'YOUR_SECRET_KEY'
23-
```
24-
25-
```
26-
Here are all the possible values for payment options available on Flutterwave:
27-
0: "account"
28-
1: "card"
29-
2: "banktransfer"
30-
3: "mpesa"
31-
4: "mobilemoneyrwanda"
32-
5: "mobilemoneyzambia"
33-
6: "qr"
34-
7: "mobilemoneyuganda"
35-
8: "ussd"
36-
9: "credit"
37-
10: "barter"
38-
11: "mobilemoneyghana"
39-
12: "payattitude"
40-
13: "mobilemoneyfranco"
41-
14: "paga"
42-
15: "1voucher"
43-
16: "mobilemoneytanzania"
44-
```
45-
46-
- To trigger a standard payment that returns a redirect uri
47-
48-
```python
49-
uri = payment.initiate_payment(tx_ref="qwerty", amount=100, redirect_url='your_callback_url',
50-
payment_options='mpesa', customer_email='example@email.com',
51-
customer_phone_number='0123456789', currency='KES', customer_name='John Doe',
52-
title='Demo Payment', description='Just pay me...')
53-
print(uri)
54-
```
55-
- Redirect the user to that uri where he/she will make the payment.
56-
- After payment is made, the user will be redirected to the `redirect_url` you declared but Flutterwave will append some
57-
info regarding the payment i.e. `transaction_id` and `tx_ref`. If your url is `https://example.com/callback`
58-
then it may be `http://example.com/callback/?status=successful&tx_ref=qwerty&transaction_id=2784792`
59-
- You should save the transaction_id to your DB as it will be used to query the transaction details.
60-
61-
> There is no need to save the transaction_id as it is also possible to use tx_ref to get the payment details!
62-
> Check here - https://developer.flutterwave.com/reference/endpoints/transactions/
63-
64-
65-
- To check the transaction details e.g. successful or not, grab the transaction_id from the previous step.
66-
```python
67-
details = payment.get_payment_details(transaction_id)
68-
# or
69-
deailts = payment.get_payment_details_via_tx_ref(tx_ref)
70-
71-
print(details)
72-
```
73-
74-
- To trigger an automatic MPESA charge on your customer through STK push, first configure your Webhook url in the dashboard, it may be a
75-
simple server; Flutterwave will post some data regarding your transaction status in that url. This method call will
76-
return a Python dict object. You can decide what to do thereon.
77-
```python
78-
mpesa_trans_details = payment.trigger_mpesa_payment(tx_ref="qwertyuio", amount=100, currency='KES',
79-
email='johndoe@gmail.com', phone_number='1234567890',
80-
full_name='John Doe')
81-
print(mpesa_trans_details)
82-
```
83-
84-
- To initiate a USSD payment to your customer, configure your webhook url in the dashboard where Flutterwave will post data
85-
regarding the transaction. This method call will return a Python Dict object from which you can extract the USSD code to
86-
show your customer for payment completion. For other banks, you may also need to extract the `payment_code` from the result.
87-
88-
- By default, `NGN` is the only supported currency for USSD payments so this method automatically uses `NGN`
89-
- Only a number of banks support `USSD` so you have to refer to the docs to check your bank and its corresponding `account_bank` code.
90-
```
91-
At the moment, banks available for USSD payments (and their numeric codes) are:
92-
93-
Access Bank -- 044
94-
Ecobank -- 050
95-
Fidelity Bank -- 070
96-
First Bank of Nigeria -- 011
97-
First City Monument Bank (FCMB) -- 214
98-
GTBank -- 058
99-
Heritage Bank -- 030
100-
Keystone Bank -- 082
101-
Stanbic IBTC Bank -- 221
102-
Sterling Bank -- 232
103-
Union Bank -- 032
104-
United Bank for Africa -- 033
105-
Unity Bank -- 215
106-
VFD Microfinance Bank -- 090110
107-
Wema Bank -- 035
108-
Zenith Bank -- 057
109-
```
110-
111-
112-
```python
113-
details = payment.initiate_ussd_payment(tx_ref="123erd", amount=100, email='johndoe@gmail.com',
114-
phone_number='789456123', full_name='John Doe', account_bank='057')
115-
print(details)
116-
```
117-
118-
- For bank transactions, it is important to first verify the details given to you by the customer before granting incentives
119-
according to the specifications of your application.
120-
- To verify bank details call the function below that returns a Python dictionary with the data...
121-
```python
122-
details = payment.verify_bank_account_details(account_number= "0690000032", account_bank= "044")
123-
print(details)
124-
```
125-
126-
- For card transactions, it is advisable to ascertain the customer's card details before granting incentives according
127-
to the specifications of your application.
128-
- This function call takes the `card_bin` (usually the first 4-6 digits in debit/credit cards) and returns info regarding
129-
the card. A Python dict object is returned, thence use it according to your needs.
130-
```python
131-
details = payment.verify_card_details(card_bin=553188)
132-
print(details)
133-
```
134-
135-
[![Sponsor Python Flutterwave](https://cdn.buymeacoffee.com/buttons/default-red.png)](https://dashboard.flutterwave.com/donate/zvapzky1ozls)
1+
```New docs under development```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .bank import *
2+
from .card import *
3+
from .mobile import *
4+
from .validation import *
5+

python_flutterwave/charge/bank.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import os
2+
import requests
3+
import json
4+
5+
from python_flutterwave.decorators import handle_api_exceptions
6+
7+
8+
token = os.environ.get("SECRET_KEY")
9+
base_url = "https://api.flutterwave.com/v3/charges"
10+
11+
12+
@handle_api_exceptions
13+
def initiate_bank_charge(
14+
amount: int,
15+
email: str,
16+
tx_ref: str,
17+
) -> dict:
18+
"""
19+
Collect payments from your customers via bank transfers
20+
:param tx_ref: str
21+
:param amount: int
22+
:param email: str
23+
:return: dict
24+
"""
25+
26+
params = {"type": "bank_transfer"}
27+
payload = json.dumps(
28+
{
29+
"tx_ref": f"{tx_ref}",
30+
"amount": f"{amount}",
31+
"email": f"{email}",
32+
}
33+
)
34+
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
35+
36+
response = requests.post(url=base_url, headers=headers, data=payload, params=params)
37+
38+
return dict(response.json())
39+
40+
41+
@handle_api_exceptions
42+
def initiate_nigeria_bank_charge(
43+
amount: int,
44+
email: str,
45+
tx_ref: str,
46+
) -> dict:
47+
"""
48+
Charge Nigerian bank accounts using Flutterwave
49+
:param tx_ref: str
50+
:param amount: int
51+
:param email: str
52+
:return: dict
53+
"""
54+
55+
params = {"type": "mono"}
56+
payload = json.dumps(
57+
{
58+
"tx_ref": f"{tx_ref}",
59+
"amount": f"{amount}",
60+
"email": f"{email}",
61+
}
62+
)
63+
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
64+
65+
response = requests.post(url=base_url, headers=headers, data=payload, params=params)
66+
67+
return dict(response.json())
68+
69+
70+
@handle_api_exceptions
71+
def initiate_uk_eu_bank_charge(
72+
amount: int, email: str, tx_ref: str, phone_number: str, is_token_io: int
73+
) -> dict:
74+
"""
75+
Charge Customers UK and EU bank accounts
76+
:param tx_ref: str
77+
:param amount: int
78+
:param email: str
79+
:param phone_number: str
80+
:param is_token_io: int
81+
:return: dict
82+
"""
83+
84+
params = {"type": "account-ach-uk"}
85+
payload = json.dumps(
86+
{
87+
"tx_ref": f"{tx_ref}",
88+
"amount": f"{amount}",
89+
"email": f"{email}",
90+
"phone_number": f"{phone_number}",
91+
"is_token_io": is_token_io,
92+
}
93+
)
94+
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
95+
96+
response = requests.post(url=base_url, headers=headers, data=payload, params=params)
97+
98+
return dict(response.json())
99+
100+
101+
@handle_api_exceptions
102+
def initiate_ach_bank_charge(
103+
amount: int,
104+
email: str,
105+
tx_ref: str,
106+
phone_number: str,
107+
currency: str,
108+
) -> dict:
109+
"""
110+
Collect ACH payments for USD and ZAR transactions
111+
:param tx_ref: str
112+
:param amount: int
113+
:param email: str
114+
:param phone_number: str
115+
:param currency: str
116+
:return: dict
117+
"""
118+
119+
params = {"type": "account-ach-uk"}
120+
payload = json.dumps(
121+
{
122+
"tx_ref": f"{tx_ref}",
123+
"amount": f"{amount}",
124+
"currency": f"{currency}",
125+
"email": f"{email}",
126+
"phone_number": f"{phone_number}",
127+
}
128+
)
129+
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
130+
131+
response = requests.post(url=base_url, headers=headers, data=payload, params=params)
132+
133+
return dict(response.json())

python_flutterwave/charge/card.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import os
2+
import requests
3+
import json
4+
5+
from python_flutterwave.decorators import handle_api_exceptions
6+
7+
8+
token = os.environ.get("SECRET_KEY")
9+
base_url = "https://api.flutterwave.com/v3/charges"
10+
11+
12+
@handle_api_exceptions
13+
def initiate_card_charge(
14+
amount: int,
15+
card_number: int,
16+
cvv: int,
17+
expiry_month: int,
18+
expiry_year: int,
19+
email: str,
20+
tx_ref: str,
21+
) -> dict:
22+
"""
23+
This is used to initiate card payments.
24+
:param tx_ref: str
25+
:param amount: int
26+
:param card_number: int
27+
:param cvv: int
28+
:param expiry_month: int
29+
:param expiry_year: int
30+
:param email: str
31+
:return: dict
32+
"""
33+
34+
params = {"type": "card"}
35+
payload = json.dumps(
36+
{
37+
"tx_ref": f"{tx_ref}",
38+
"amount": f"{amount}",
39+
"card_number": f"{card_number}",
40+
"cvv": f"{cvv}",
41+
"expirty_month": f"{expiry_month}",
42+
"expirty_year": f"{expiry_year}",
43+
"email": f"{email}",
44+
}
45+
)
46+
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
47+
48+
response = requests.post(url=base_url, headers=headers, data=payload, params=params)
49+
50+
return dict(response.json())

0 commit comments

Comments
 (0)