Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Django barebones token flow #1

Merged
merged 2 commits into from
Mar 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions budget/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path

from . import views

app_name = 'budget'
urlpatterns = [
path('', views.index, name='index'),
]

3 changes: 3 additions & 0 deletions budget/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
return HttpResponse("Hello budget")
2 changes: 2 additions & 0 deletions mysite/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
# Application definition

INSTALLED_APPS = [
'budget.apps.BudgetConfig',
'plaid_api.apps.PlaidApiConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
Expand Down
4 changes: 3 additions & 1 deletion mysite/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include

urlpatterns = [
path('budget/', include('budget.urls')),
path('plaid/', include('plaid_api.urls')),
path('admin/', admin.site.urls),
]
Empty file added plaid_api/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions plaid_api/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions plaid_api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class PlaidApiConfig(AppConfig):
name = 'plaid_api'
Empty file.
3 changes: 3 additions & 0 deletions plaid_api/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
60 changes: 60 additions & 0 deletions plaid_api/templates/plaid_api/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<h1>Hello plaid</h1>
<p>{{ plaid_public_key }}</p>
<p>{{ plaid_environment }}</p>
<p>{{ plaid_products }}</p>

<button id="link-button">Link Account</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>

<script type="text/javascript">
(function($) {
var handler = Plaid.create({
clientName: 'Plaid Quickstart',
env: '{{ plaid_environment }}',
key: '{{ plaid_public_key }}',
product: ['transactions'],
// Optional – use webhooks to get transaction and error updates
// webhook: 'https://requestb.in',
onLoad: function() {
// Optional, called when Link loads
},
onSuccess: function(public_token, metadata) {
// Send the public_token to your app server.
// The metadata object contains info about the institution the
// user selected and the account ID or IDs, if the
// Select Account view is enabled.
$.post('/plaid/get_access_token', {
'public_token': public_token,
'csrfmiddlewaretoken': '{{ csrf_token }}'
});
},
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
}
// metadata contains information about the institution
// that the user selected and the most recent API request IDs.
// Storing this information can be helpful for support.
},
onEvent: function(eventName, metadata) {
// Optionally capture Link flow events, streamed through
// this callback as your users connect an Item to Plaid.
// For example:
// eventName = "TRANSITION_VIEW"
// metadata = {
// link_session_id: "123-abc",
// mfa_type: "questions",
// timestamp: "2017-09-14T14:42:19.350Z",
// view_name: "MFA",
// }
}
});

$('#link-button').on('click', function(e) {
handler.open();
});
})(jQuery);
</script>
3 changes: 3 additions & 0 deletions plaid_api/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
9 changes: 9 additions & 0 deletions plaid_api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path

from . import views

app_name = 'plaid_api'
urlpatterns = [
path('', views.index, name='index'),
path('get_access_token', views.get_access_token),
]
62 changes: 62 additions & 0 deletions plaid_api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import json
import os
import plaid

from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_http_methods

PLAID_CLIENT_ID = os.getenv('PLAID_CLIENT_ID')
PLAID_SECRET = os.getenv('PLAID_SECRET')
PLAID_PUBLIC_KEY = os.getenv('PLAID_PUBLIC_KEY')
PLAID_ENV = os.getenv('PLAID_ENV', 'sandbox')
PLAID_PRODUCTS = os.getenv('PLAID_PRODUCTS', 'transactions')

client = plaid.Client(
client_id=PLAID_CLIENT_ID,
secret=PLAID_SECRET,
public_key=PLAID_PUBLIC_KEY,
environment=PLAID_ENV,
api_version='2018-05-22',
)

access_token = None


def index(request):
"""Show login landing page"""
context = {
'plaid_public_key': PLAID_PUBLIC_KEY,
'plaid_environment': PLAID_ENV,
'plaid_products': PLAID_PRODUCTS,
}
return render(request, "plaid_api/index.html", context)


@require_http_methods(['POST', 'GET'])
def get_access_token(request):
"""Return plaid access token via POST only"""
global access_token
public_token = request.POST['public_token']
try:
exchange_response = client.Item.public_token.exchange(public_token)
except plaid.errors.PlaidError as e:
return jsonify(format_error(e))

pretty_print_response(exchange_response)
access_token = exchange_response['access_token']
return JsonResponse(exchange_response)

def pretty_print_response(response):
print(json.dumps(response, indent=2, sort_keys=True))

def format_error(e):
return {
'error': {
'display_message': e.display_message,
'error_code': e.code,
'error_type': e.type,
'error_message': e.message
}
}