This project provides Django integration for Flutterwave payments and subscriptions.
Current functionality:
- Allow users to make payments (once off and subscription)
- Create payment buttons which launch inline payment modals
- Maintain a payment transaction history linked to users
- Python >= 3.6
- Django >= 2.0
pip install djangoflutterwave
Add "djangoflutterwave"
to your INSTALLED_APPS
Run Django migrations:
manage.py migrate
Add the following to your settings.py
:
FLW_PRODUCTION_PUBLIC_KEY = "your key"
FLW_PRODUCTION_SECRET_KEY = "your key"
FLW_SANDBOX_PUBLIC_KEY = "your key"
FLW_SANDBOX_SECRET_KEY = "your key"
FLW_SANDBOX = True
The above config will ensure djangoflutterwave
uses your sandbox. Once you're ready to
go live, set FLW_SANDBOX = False
Add djangoflutterwave
to your urls.py
:
path("djangoflutterwave/", include("djangoflutterwave.urls", namespace="djangoflutterwave"))
Add the following url as a webhook in your Flutterwave dashboard. This will be used by
Flutterwave to POST
payment transactions to your site:
http://yoursite.com/djangoflutterwave/transaction/
Note:
while in development, a tool like ngrok (or similar) may prove useful to ensure
your localhost is accessible to Flutterwave for the above webhook calls.
djangoflutterwave
provides two models, namely:
- The
FlwPlanModel
allows you to createonce off
orsubscription
plans. When creating asubscription
plan, you will need to create the plan in Flutterwave first and then enter the corresonding information as aFlwPlanModel
instance (ie:flw_plan_id
field corresponds to the FlutterwavePlan ID
). - The
FlwTransactionModel
creates transactions when Flutterwave POSTS to the above mentioned webhook url. This provides a history of all transactions (once off or recurring), linked to the relevantFlwPlanModel
anduser
.
A payment button can be created as follows:
- Create a new plan (ie:
FlwPlanModel
) using the django admin. - In the view where you wish the button to appear, add the above created
FlwPlanModel
instance to your context, eg:
from djangoflutterwave.models import FlwPlanModel
class SignUpView(TemplateView):
"""Sign Up view"""
template_name = "my_payment_template.html"
def get_context_data(self, **kwargs):
"""Add payment type to context data"""
kwargs = super().get_context_data(**kwargs)
kwargs["pro_plan"] = FlwPlanModel.objects.filter(
name="Pro Plan"
).first()
return kwargs
- In your template, add the button wherever you wish for it to appear as follows:
{% include 'djangoflutterwave/pay_button.html' with plan=pro_plan %}
Note:
You can add multiple buttons to a single template by simply adding multiple
plans to your context data and then including each of them with their own include
tag as above.
- Add the following to your django base template (or anywhere in your template heirarchy that ensures it is loaded before your payment buttons):
<script
type="text/javascript"
src="https://checkout.flutterwave.com/v3.js"
></script>
<script src="{% static 'djangoflutterwave/js/payment.js' %}"></script>
Use the pay_button_css_classes
field on the FlwPlanModel
model to add css classes to
buttons which will be rendered in your template.
Following a user payment, they will be redirected to the transaction detail page
located at /djangoflutterwave/<str:tx_ref>/
.
A default transaction detail template is already available, however if you want
to override it, you may do so by creating a new template in your root
templates directory, ie: /templates/djangoflutterwave/transaction.html
You will have access to {{ transaction }}
within that template.
As an alternative to rendering the above mentioned buttons in a django template, an API end point is provided for retrieving payment params which can then be used in an API based app (eg: Vue, React).
End point: djangoflutterwave/payment-params/?plan=nameofplanhere
The above end point requires an authenticated user and will return the following:
{
"public_key": "flutterwave public key",
"tx_ref": "transaction ref",
"amount": 123.45,
"currency": "USD",
"payment_plan": 3453,
"customer": {
"email": "foo@bar.com",
"name": "John Smith"
},
"customizations": {
"title": "Pro Plan",
"logo": "http://example.com/image.png"
}
}
Below is a basic example of implementing Django Flutterwave into a Vue app:
<template>
<div>
<button @click="makePayment">Sign up</button>
</div>
</template>
<script>
import axios from "axios";
const token = localStorage.getItem("user-token") || "";
axios.defaults.headers.common["Authorization"] = `Token ${token}`;
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
export default {
data() {
return {
params: {},
};
},
mounted: function() {
let flw = document.createElement("script");
flw.setAttribute("src", "https://checkout.flutterwave.com/v3.js");
flw.async = true;
document.head.appendChild(flw);
},
created() {
let params = axios.get("/djangoflutterwave/payment-params/?plan=proplan");
this.params = params;
},
methods: {
makePayment() {
FlutterwaveCheckout({
...this.params,
callback: function(data) {
// This function is called after a successful payment. Add your code here.
},
});
},
},
};
</script>
The important points to note are:
- All initial setup is the same as per the above documentation.
- To call the end point, the user must be authenticated (ie: add their token).
https://checkout.flutterwave.com/v3.js
must be loaded as a script.- A plan name is used to call the API end point which returns the payment params. Those payment params are then used in the
makePayment
method. - There is a call back function which should be used to specify what to do after a payment has been completed.
If you wish to contribute to the project, there is an example app that demonstrates general usage.
git clone https://github.com/bdelate/django-flutterwave.git
cd django-flutterwave
Create file example/env/dev.env
and populate it with the following:
FLW_SANDBOX_PUBLIC_KEY=your_sandbox_public_key
FLW_SANDBOX_SECRET_KEY=your_sandbox_secret_key
FLW_PRODUCTION_PUBLIC_KEY=test
FLW_PRODUCTION_SECRET_KEY=test
Run the following commands:
make build
make migrate
make import
make dup
Flutterwave requires payments to be associated with users who have an email address. Therefore, create and login with a new django user or use the existing user which will have been created by the above import command:
username: admin
password: adminadmin
Navigate to http://localhost:8000/