Search code examples
pythondjangoplaid

Connect plaid.io with django


I'm just trying to connect plaid.io with Django. To do that, I'm using the examples.

https://github.com/plaid/quickstart/tree/master/python

server.py

import os
import datetime
import plaid
from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify

app = Flask(__name__)


# Fill in your Plaid API keys - https://dashboard.plaid.com/account/keys
PLAID_CLIENT_ID = 'xxxxxxxxxxxxxx'
PLAID_SECRET = 'xxxxxxxxxxxxxx'
PLAID_PUBLIC_KEY = 'xxxxxxxxxxxxxx'
# Use 'sandbox' to test with Plaid's Sandbox environment (username: user_good,
# password: pass_good)
# Use `development` to test with live users and credentials and `production`
# to go live
PLAID_ENV='sandbox'


client = plaid.Client(client_id = PLAID_CLIENT_ID, secret=PLAID_SECRET,
                  public_key=PLAID_PUBLIC_KEY, environment=PLAID_ENV)

@app.route("/")
def index():
   return render_template('index.ejs', plaid_public_key=PLAID_PUBLIC_KEY, plaid_environment=PLAID_ENV)


access_token = None
public_token = None

@app.route("/get_access_token", methods=['POST'])
def get_access_token():
  global access_token
  public_token = request.form['public_token']
  exchange_response = client.Item.public_token.exchange(public_token)
  # print 'access token: ' + exchange_response['access_token']

  access_token = exchange_response['access_token']

  return jsonify(exchange_response)

@app.route("/set_access_token", methods=['POST'])
def set_access_token():
  global access_token
  access_token = request.form['access_token']
  # print 'access token: ' + access_token
  return jsonify({'error': False})

@app.route("/accounts", methods=['GET'])
def accounts():
  global access_token
  accounts = client.Auth.get(access_token)
  return jsonify(accounts)

@app.route("/item", methods=['GET', 'POST'])
def item():
  global access_token
  item_response = client.Item.get(access_token)
  institution_response = client.Institutions.get_by_id(item_response['item']['institution_id'])
  return jsonify({'item': item_response['item'], 'institution': institution_response['institution']})

@app.route("/transactions", methods=['GET', 'POST'])
def transactions():
  global access_token
  # Pull transactions for the last 30 days
  start_date = "{:%Y-%m-%d}".format(datetime.datetime.now() + datetime.timedelta(-30))
  end_date = "{:%Y-%m-%d}".format(datetime.datetime.now())

  response = client.Transactions.get(access_token, start_date, end_date)
  return jsonify(response)

@app.route("/create_public_token", methods=['GET'])
def create_public_token():
  global access_token
  # Create a one-time use public_token for the Item. This public_token can be used to
  # initialize Link in update mode for the user.
  response = client.Item.public_token.create(access_token)
  return jsonify(response)

if __name__ == "__main__":
    app.run()

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Plaid Walkthrough Example</title>
    <link rel="stylesheet" type="text/css" href="static/style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <div id="banner">
        <h1>Plaid Example Walkthrough</h1>
        <p id="intro">
            This is an example application that walks through integrating Plaid Link using the API to retrieve Auth and Transaction data.
        </p>
        <p id="steps">
            Great - you just created an Item! The server was successfully able to exchange the public_token for an access_token.
            Below are a few options - you can get account data, retrieve information about the Item itself, or pull transaction data.
        </p>
    </div>

    <div id="container">
        <p>
            Click the button below to open a list of Institutions - after you select one,
            you'll be guided through an authentication process. The public_token will be passed
            back to the example server, which will then exchange it for an access_token and log it
            to your console.
        </p>

        <button id="link-btn">Open Link</button>
    </div>

    <div id="app">
        <div class="box">
            <button id="get-accounts-btn">Get Accounts</button>
            <div id="get-accounts-data"></div>
        </div>

        <div class="box">
            <button id="get-item-btn">Get Item</button>
            <div id="upgrade-to-connect-data" class="inner"></div>
        </div>

        <div class="box" id="txnBox">
            <button id="get-transaction-data">Get Transactions</button>
            <div id="get-transactions-data"></div>
        </div>
    </div>

    <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>
    function getParameterByName(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, "\\$&");
        var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }
    ;(function($) {
        var handler = Plaid.create({
            apiVersion: 'v2',
            clientName: 'Plaid Walkthrough Demo',
            env: '{{ plaid_environment }}',
            product: ['transactions'],
            key: '{{ plaid_public_key }}',
            onSuccess: function(public_token) {
                $.post('/get_access_token', {public_token: public_token}, function() {
                    $('#container').fadeOut('fast', function() {
                        $('#intro').hide();
                        $('#app, #steps').fadeIn('slow');
                    });
                });
            },
        });

        $('#link-btn').on('click', function(e) {
            handler.open();
        });

        var accessToken =  getParameterByName('access_token');
        if (accessToken != null) {
            $.post('/set_access_token', {access_token: accessToken}, function() {
                $('#container').fadeOut('fast', function() {
                    $('#intro').hide();
                    $('#app, #steps').fadeIn('slow');
                });
            });
        }

        $('#get-accounts-btn').on('click', function(e) {
            $.get('/accounts', function(data) {
                $('#get-accounts-data').slideUp(function() {
                    var html = '';
                    data.accounts.forEach(function(account, idx) {
                        html += '<div class="inner">';
                        html += '<strong>' + account.name +
                                ' $' + (account.balances.available != null ? account.balances.available : account.balances.current) + '</strong><br>';
                        html += account.subtype + ' ' + account.mask;
                        html += '</div>';
                    });

                    $(this).html(html).slideDown();
                });
            });
        });

        $('#get-item-btn').on('click', function(e) {
            $.post('/item', function(data) {
                $('#upgrade-to-connect-data').slideUp(function() {
                    if(data.error)
                        $(this).html('<p>' + data.error + '</p>').slideDown();
                    else {
                        var html = '';
                        html += '<p>Here\'s some basic information about your Item:</p>';
                        html += '<p>Institution name:' + data.institution.name +'</p>';
                        html += '<p>Billed products: ' + data.item.billed_products.join(', ') + '</p>';
                        html += '<p>Available products: ' + data.item.available_products.join(', ') + '</p>';


                        $(this).html(html).slideDown();
                        $('#txnBox').slideDown();
                    }
                });
            });
        });

        $('#get-transaction-data').on('click', function(e) {
            $.post('/transactions', function(data) {
                if (data.error) {
                    $(this).html('<p>' + data.error + '</p>').slideDown();
                } else {
                $('#get-transactions-data').slideUp(function() {
                    var html = '<p>Pulled ' + data.transactions.length + ' transaction(s).</p>';
                    data.transactions.forEach(function(txn, idx) {
                        html += '<div class="inner">';
                        html += '<strong>' + txn.name + '</strong><br>';
                        html += '$' + txn.amount;
                        html += '<br><em>' + txn.date + '</em>';
                        html += '</div>';
                    });

                    $(this).slideUp(function() {
                        $(this).html(html).slideDown();
                    });
                });
                }
            });
        });
    })(jQuery);
    </script>
</body>
</html>

This is exactly the same example, with my tokens.

But in the terminal appears the next messages:

sandbox.plaid.com/link/client/get Failed to load resource: the server responded with a status of 400 (Bad Request) link.js:125 Error: Error retrieving info for public key. Make sure that the entered key is correct. If the error persists, contact support@plaid.com. at link.js:125 (anonymous) @ link.js:125 cdn.plaid.com/authenticate Failed to load resource: the server responded with a status of 403 (Forbidden)

Why I'm getting the 400 Bad Request Message ?


Solution

  • Finally, I find the problem. The current version of plaid.io doesn't works with python 3.x. The current version works with python 2.7. Once you get the specified version of python works without problem