Integrate the QuickBooks API with the Python Django
Last Updated :
09 Jul, 2024
QuickBooks is a powerful accounting software that helps businesses manage their finances efficiently. Integrating the QuickBooks API with a Django application can automate many financial processes, saving time and reducing errors. This article will guide you through the steps required to integrate the QuickBooks API with a Python Django application.
Integrate the QuickBooks API with Python Django
Before starting the integration, ensure you have the following:
Install Required Libraries
pip install intuit-oauth python-quickbooks django
Step 1: Setting Up QuickBooks Developer Account
- Sign Up: Create an account on the QuickBooks Developer Portal (https://developer.intuit.com/app/developer/homepage)
- Create an App: Once logged in, navigate to 'My Apps' and create a new app. Select 'QuickBooks Online and Payments'.
- Get Credentials: After creating the app, you will get the
Client ID
and Client Secret
. These credentials are essential for authentication.
Then you have to use these credentials to the tokens.py file of the payment app in Django that you cloned from the GitHub. Congratulations you successfully created the credentials to use QuickBooks in your Django application.
Setting Up the Project Folder
django-admin startproject <project_name>
cd <project_name>
python manage.py startapp <app_name>
Directory Structure
myproject/
│
├── manage.py
└── myproject/
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Configure Django Settings
Add the required settings in your settings.py
file:
# settings.py
QUICKBOOKS_CLIENT_ID = 'YOUR_CLIENT_ID'
QUICKBOOKS_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
QUICKBOOKS_REDIRECT_URI = 'http://localhost:8000/callback'
Step 2: Defining Models
Now you have to create your own model for storing the details(data) in the database.
Python
from django.db import models
class Payment(models.Model):
payment_id=models.CharField(max_length=255,primary_key=True,default=uuid4)
amount = models.DecimalField(max_digits=10, decimal_places=2)
status = models.CharField(max_length=20)
order_id=models.CharField(max_length=255,null=True,blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.trans_id)
Step 4: Defining the Route
Here the first route naming payment-list-create which will create the payment , Second route which is payment-details will display all the detaills from the database and the last route naming verify will verify the given payment.And you have to add the function which refreshing the OAuth tokens using the AuthClient class and associataed with a specific set of client secrets and tokens.
Python
from django.urls import path, include
from payment_integration import views
urlpatterns = [
...
path('api/payments/', views.PaymentListCreate.as_view(), name='payment-list-create'),
path('api/payments/<int:pk>/', views.PaymentDetail.as_view(), name='payment-detail'),
path("api/payments/verify/", views.QuickbooksVerifyPaymentView.as_view(), name='verify'),
]
Step 5: Writing API for Views
Now in this step you have to write an API class from create, verify and display the details operation. Incoming payment data communicate with Quickbooks online payment API and create payment transactions and returning the responses based on the success or failure of the opeartion.
API for create payment:
This view takes input a json payload containing the information required to create a payement. The payload containing the information required to create a payment . The payload includes details such as the payment amount , paymen_id , amount , status and related information depending upon the related informations.
Authorization and Headers:
- The post call takes a refresh_token to obtain an access token, this will set up the necessary authorizationand headers for making any other requests to Quickbooks API.
- Process the incoming request data which payment method to be used and structure it for card, digital wallet or internet banking.
API Request: It makes a post request to Quickbooks API with the payment data and process the response which is verifying if it was successfully created.
Database and Response - if payment creation is successful, it saves the details to Payment model and credentials a success response or returns an error responce.payment
Python
import uuid
import requests
from django.db import models
from django.utils.timezone import now
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Payment
from .views import *
class QuickbooksCreatePaymentView(APIView):
def post(self, request):
try:
response = refresh_token()
access_token = response["access_token"]
base_url = 'https://sandbox.api.intuit.com/quickbooks/v4/payments/charges/'
auth_header = 'Bearer {0}'.format(access_token)
headers = {
'Authorization': auth_header,
'Request-Id': str(uuid.uuid4()),
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0',
'Accept-Encoding': 'gzip, deflate, br'
}
data = request.data
amount = data.get('amount')
payment_method = data.get('payment_method')
if payment_method == 'card':
payment_data = {
'amount': float(amount),
'currency': data.get('currency'),
'card': {
'name': data.get('card_name'),
'address': data.get('address'),
'expYear': data.get('exp_year'),
'expMonth': data.get('exp_month'),
'number': data.get('number'),
'cvc': data.get('cvc')
},
'context': {
'mobile': False,
'isEcommerce': True
}
}
elif payment_method == 'digital_wallet':
payment_data = {
'amount': float(amount),
'currency': data.get('currency'),
'digitalWallet': {
'type': data.get('digital_wallet_type'),
'id': data.get('digital_wallet_id')
},
'context': {
'mobile': False,
'isEcommerce': True
}
}
elif payment_method == 'internet_banking':
payment_data = {
'amount': float(amount),
'currency': data.get('currency'),
'bankTransfer': {
'account': data.get('bank_account_number'),
'routingNumber': data.get('bank_routing_number')
},
'context': {
'mobile': False,
'isEcommerce': True
}
}
else:
return Response({'error': 'Invalid payment method'}, status=400)
response = requests.post(base_url, headers=headers, json=payment_data)
if response.status_code == 201:
response_data = response.json()
charge_id = response_data.get('id')
Payment.objects.create(
payment_id=uuid.uuid4(),
amount=amount,
status='Success',
order_id=charge_id,
created_at=now()
)
return Response({'message': 'Payment Success', 'charge_id': charge_id, 'success': True}, status=201)
else:
return Response({'error': 'Failed to create a payment', 'success': False}, status=response.status_code)
except Exception as e:
return Response({'error': str(e)}, status=500)
This view returns an HTTP response to the client based on the outcome of the payment creation process:
JavaScript
{
"amount": 100.00,
"currency": "USD",
"payment_method": "card",
"card_name": "John Doe",
"address": "123 Main St, Anytown, USA",
"exp_year": 2025,
"exp_month": 12,
"number": "4111111111111111",
"cvc": "123"
}
Success response
JavaScript
{
"message": "Payment Success",
"charge_id": "charge_id_from_quickbooks",
"success": true
}
Failure response
JavaScript
{
"error": "Invalid payment method",
"success": false
}
QuickBooks API Failure
If there is a problem with the QuickBooks API or if the response status code is not 201 (Created):
JavaScript
{
"error": "Failed to create a payment",
"success": false
}
Exception Handling
If an exception occurs during the request processing:
JavaScript
{
"error": "Detailed error message here",
"success": false
}
API for display and verifyPayment:
- Get Access Token: It expects a refresh_token function returning the access token.
- Get Data From Request: Gets charge ID from request data.
- Set Headers: This sets up authorization headers with the tokens.
- Make GET Request: It makes the GET request to the QuickBooks API to verify if the payment is done.
- Process Response:
- After verifying that the status code of the response is 200, the payment status is extracted using the data of the response.
- Using order_id, which is the charge ID, the respective Payment object is fetched.
- The status is set and saved on the Payment object.
- Error Handling:
- If a Payment with the given order_id is not found, then a Payment.DoesNotExist exception is caught and a 404 Not Found Response is returned.
- All other exceptions are caught and cause the response to return a 500 Internal Server Error.
Python
class QuickbooksVerifyPaymentView(APIView):
def post(self, request):
try:
response = refresh_token()
access_token = response["access_token"]
data = request.data
charge_id = data.get('charge_id')
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(f'https://sandbox.api.intuit.com/quickbooks/v4/payments/charges/{charge_id}', headers=headers)
if response.status_code == 200:
response_data = response.json()
status = response_data.get('status')
payment = Payment.objects.get(order_id=charge_id)
payment.status = status # Assuming the status can be directly mapped
payment.save()
return Response({'status': status, 'message': 'Payment Successfully Verified', 'success': True})
else:
return Response({'error': 'Failed to verify payment', 'success': False}, status=response.status_code)
except Payment.DoesNotExist:
return Response({'error': 'Payment not found', 'success': False}, status=404)
except Exception as e:
return Response({'error': str(e), 'success': False}, status=500)
Input JSON Sample
JavaScript
{
"charge_id": "charge_id_from_quickbooks"
}
Output JSON
JavaScript
{
"status": "status_from_quickbooks",
"message": "Payment Successfully Verified",
"success": true
}
Failure Response
JavaScript
{
"error": "Failed to verify payment",
"success": false
}
{
"error": "Payment not found",
"success": false
}
These are all the steps you have to follow to integrate the QuickBooks into your DjangoRestFramework project. Hope this will help you to understand integrate the Quick books payment with the Django Rest Framework.
API testing Video:
Similar Reads
Swagger Integration with Python Django
Integrating Swagger with Django REST Framework can be quite useful for documenting and testing your API. One popular tool for integrating Swagger with Django REST Framework is drf-yasg (Yet Another Swagger Generator). In this article, we will see how to integrate Swagger with the Django REST framewo
2 min read
Integrating TinyMCE with Django
TinyMCE is a online rich text editor which is fully flexible and provides customisation. mostly used to get dynamic data such as articles in GFG and much more, their is no static database for posts Installation - To integrate it with Django web app or website you need to first install its pip librar
2 min read
How to integrate Mysql database with Django?
Django is a Python-based web framework that allows you to quickly create efficient web applications. It is also called batteries included framework because Django provides built-in features for everything including Django Admin Interface, default database â SQLlite3, etc. Installation Let's first un
2 min read
Weather app using Django | Python
In this tutorial, we will learn how to create a Weather app that uses Django as backend. Django provides a Python Web framework based web framework that allows rapid development and clean, pragmatic design. Basic Setup - Change directory to weather â cd weather Start the server - python manage.py ru
2 min read
Python Django Queryset Filtering
Django has an inbuilt function for filtering the dataset. But it is lacking in the exclusion of dataset. So for this, we have other 2 solutions to filter out data which not equal to the mentioned dataset. Here, We are going to understand and learn through a mini Django project using Python. Let's cr
4 min read
How to Execute a Python Script from the Django Shell?
The Django shell is an interactive development and scripting environment that aids us in working with our Django project while experiencing it as if it were deployed already. It is most commonly used when one has to debug, test, or carry out one-time operations that require interaction with the Djan
4 min read
Learn to use Websockets with Django
Django Channels is an extension of the Django framework that allows for handling WebSockets, HTTP2, and other protocols. It integrates with Djangoâs existing ORM and works seamlessly alongside Django views. In this tutorial, we will create a small Django project that displays "GeeksforGeeks" on the
4 min read
Get the Absolute URL with Domain in Django
When developing web applications, generating the full URL (including the domain) is often necessary. For instance, sending confirmation emails with links, generating sitemaps, or creating social media share links require absolute URLs. Django provides several utilities and methods to achieve this se
3 min read
Views In Django | Python
Django Views are one of the vital participants of the MVT Structure of Django. As per Django Documentation, A view function is a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, a redirect, a 404 error, an XML document, an ima
6 min read
Python Django Projects with Source Code (Beginners to Advanced)
Python Django Projects with Source Code - Adding a project portfolio to your resume helps to show your skills and potential to your recruiter. Because in the tech space, real-time project experience matters a lot. Now, to make your resume powerful, we have come up with the top Django projects with s
5 min read