loading...

How to build a custom checkout page in minutes with Django and JavaScript.

fullstackmafia profile image fullStackMafia🀄 ・5 min read

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:

Alt Text

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:

Alt Text

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:

Alt Text

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:

Alt Text

To confirm that payment was successful, head on to your Rave dashboard and click on Transactions to access your transaction history:

Alt Text

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.

Posted on by:

fullstackmafia profile

fullStackMafia🀄

@fullstackmafia

Software Developer, avid technical writer and tech community builder. I love helping developers understand concepts around JavaScript.

Discussion

markdown guide
 

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.

 

where does the money goes can't we configure an account where all the payment go there