When implementing payment options in an app, it's always a good idea to have a payment process that's as brief and straightforward as possible. In this article, we're going to build a checkout modal to process one time payments on web apps using Rave, Django and JavaScript. To solve the issue of using pip
and virtualenv
together, we'll use pipenv
to create our development environment. If you need help setting up pipenv
, please check out this guide.
Setting up a Project
The first thing we'll do is install Django. Then we'll start a new project which we'll name djangorave
. In this project, we'll create our first app which we'll call payments
. Navigate to your terminal and input the following commands:
# install Django
$ pipenv install django
# activate the pipenv shell to start a new shell subprocess
$ pipenv shell
(rave-checkout-python) $ django-admin startproject djangorave
(rave-checkout-python) $ python manage.py startapp payments
Note that the virtual environment rave-checkout-python
is just a part of my code directory, yours can be anything you choose. Let's add the newly installed app to the INSTALLED_APPS
configuration in settings.py
:
INSTALLED_APPS = [
'django.contrib',
'django.contrib.admin',
'django.contrib .auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#update the newly installed app
'payments.apps.PaymentsConfig',
]
Next, in the same folder we'll update the urls.py
file to include the payments
app:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('payments.urls')),
]
Our next step is to create a homepage for our application. In the djangorave
parent folder, create a folder named templates
and in it, your homepage:
(rave-checkout-python) $ mkdir templates
(rave-checkout-python) $ touch templates/homepage.html
Then we'll update the settings.py
file so Django can access the templates
folder:
#djangorave/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'], # add this line
'APP_DIRS': True,
},
]
We'll just fill the homepage with a basic message for now:
# templates/homepage.html
My First Django app
Then in the payments
folder, we'll create a views.py
file where Django class-based and generic views will be used to render the homepage:
# payments/views.py
from django.views.generic.base import TemplateView
class HomePageView(TemplateView):
template_name = 'homepage.html'
The view exists but it doesn't have a URL path yet. Let's change this by creating a urls.py
in our payments
app where we'll assign a path to our view:
#payments/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.HomePageView.as_view(), name='homepage'),
]
At this point, our app is good enough to be viewed on the browser. Let's synchronize the changes we've made so far to our database and start the app on our local server:
# use the migrate command to sync to your database
(rave-checkout-python) $ python manage.py migrate
# start a local webserver with the runserver command
(rave-checkout-python) $ python manage.py runserver
This starts up your app on http://127.0.0.1:8000/
. Navigate to this path on your browser and you should see your home page:
Integrate Rave
The second phase of building this app will be to integrate Rave into the app. Head on to Rave's website and sign up for an account. On your dashboard, first switch from live mode to test mode then navigate to Settings > API
and get your API keys:
Copy your public and secret keys and paste them at the bottom of your settings.py
file. Be sure to include the inverted commas:
#settings.py
RAVE_PUBLIC_KEY = 'YOUR PUBLIC KEY HERE'
RAVE_SECRET_KEY = 'YOUR SECRET KEY HERE'
Building the checkout form
Now we have our API keys, let's add Rave's inline script to our homepage.html
file:
<form>
<script src="https://api.ravepay.co/flwv3-pug/getpaidx/api/flwpbf-inline.js"></script>
<h3>SUPPORT NATURE WITH AS LOW AS $1</h3>
<button type="button" onClick="payWithRave()">Donate Here</button>
</form>
<script>
const publicKey = "{{ key }}";
function payWithRave() {
var x = getpaidSetup({
PBFPubKey: publicKey,
customer_email: "user@example.com",
amount: 1,
customer_phone: "234099940409",
currency: "USD",
txref: "rave-123456",
custom_title: "Wildlife Park",
onclose: function() {},
callback: function(response) {
var txref = response.tx.txRef;
console.log("This is the response returned after a charge", response);
x.close();
}
});
}
</script>
In the above template, you'll notice there's a {{ key }}
attribute assigned to the publickey
constant. It should hold the value of our Rave public key. Let's update its value in views.py
:
# payments/views.py
from django.conf import settings
from django.views.generic.base import TemplateView
class HomePageView(TemplateView):
template_name = 'homepage.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['key'] = settings.RAVE_PUBLIC_KEY
return context
Hit the refresh button and a basic HTML page that we can work with comes up:
Click on the Donate Here
button and a modal customized by Rave opens up for you to make payment:
Make a test payment by using one of Rave's test cards here. Let's use 5531 8866 5214 2950
, ensure that the expiry date and CVV number are correctly inputted as well. If prompted for an OTP or PIN, use the specified values in the list of cards:
To confirm that payment was successful, head on to your Rave dashboard and click on Transactions
to access your transaction history:
Payment verification from the user's end
Sure our merchants can tell that payments are being made to their Rave account but how can a user tell that their payment was successful? Let's create a page that displays a success message to a user whenever they make a successful payment. In the templates
folder, create a new file success.html
:
# templates/success.html
<h3>Your payment was successful<h3/>
Next, we'll create a view for success.html
:
#payments/views.py
from django.shortcuts import render
from django.conf import settings
from django.views.generic.base import TemplateView
class HomePageView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['key'] = settings.RAVE_PUBLIC_KEY
context['logo'] = settings.WILDLIFE_LOGO
return context
# create the view here
class Success(TemplateView):
template_name = 'success.html'
Then we'll create a URL Pattern for the view:
#payments/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('success.html', views.Success.as_view(), name='success') #add this line,
path('', views.HomePageView.as_view(), name='home'),
]
Lastly, we'll include success.html
in the callback function in homepage.html
:
callback: function(response) {
var txref = response.tx.txRef;
console.log("This is the response returned after a charge", response);
if (
response.tx.chargeResponseCode == "00" ||
response.tx.chargeResponseCode == "0"
) {
document.location.href = "success.html"
// redirect to a success page
} else {
// redirect to a failure page.
}
x.close();
}
Seems we're good to go. Let's make a test payment and see what the flow looks like:
Summary
In a more practical scenario, we would use a more secure connection and also be more careful with handling our API keys by storing them securely in environment variables. Should you need the source code of this demo, you can find it here.
Top comments (7)
Nice work @fullstackmafia ,
I have something like this already with more security using Django decouple .env etc
I want to ask for an ideal way to generate unique txref for each transaction as opposed to the default txref: "rave-123456",?
I have an ecommercebapplication which i am building, I want to use DJANGORAVE to make payment. I have issues with how to pass the amount and email context to the JavaScript file, please help me.
How did you sort out this challenge??
This is nice, but is there anyway I can get and order id after transaction is successful? I want to update a model instance after payment. Please help.
Never mind, I figured it out.
How do i add this to sign up forms??
where does the money goes can't we configure an account where all the payment go there